1 /***************************************************************************
2     testqgsrasterlayersaveasdialog.cpp
3      --------------------------------------
4     Date                 : May 2019
5     Copyright            : (C) 2019 Alessandro Pasotti
6     Email                : elpaso at itopen dot it
7  ***************************************************************************
8  *                                                                         *
9  *   This program is free software; you can redistribute it and/or modify  *
10  *   it under the terms of the GNU General Public License as published by  *
11  *   the Free Software Foundation; either version 2 of the License, or     *
12  *   (at your option) any later version.                                   *
13  *                                                                         *
14  ***************************************************************************/
15 
16 
17 #include "qgstest.h"
18 #include <QTemporaryFile>
19 
20 #include "qgscoordinatetransformcontext.h"
21 #include "qgsrasterlayersaveasdialog.h"
22 #include "qgsvectorfilewriter.h"
23 #include "qgsvectorlayer.h"
24 #include "qgsrasterlayer.h"
25 #include "qgsrasterfilewriter.h"
26 #include "qgsrasterpipe.h"
27 #include "qgsgui.h"
28 
29 class TestQgsRasterLayerSaveAsDialog : public QObject
30 {
31     Q_OBJECT
32   public:
33     TestQgsRasterLayerSaveAsDialog() = default;
34 
35   private slots:
36     void initTestCase(); // will be called before the first testfunction is executed.
37     void cleanupTestCase(); // will be called after the last testfunction was executed.
38     void init(); // will be called before each testfunction is executed.
39     void cleanup(); // will be called after every testfunction.
40     void outputLayerExists();
41 
42   private:
43 
44     QString prepareDb();
45 
46 };
47 
initTestCase()48 void TestQgsRasterLayerSaveAsDialog::initTestCase()
49 {
50   QgsApplication::init();
51   QgsApplication::initQgis();
52 }
53 
cleanupTestCase()54 void TestQgsRasterLayerSaveAsDialog::cleanupTestCase()
55 {
56   QgsApplication::exitQgis();
57 }
58 
init()59 void TestQgsRasterLayerSaveAsDialog::init()
60 {
61 }
62 
cleanup()63 void TestQgsRasterLayerSaveAsDialog::cleanup()
64 {
65 }
66 
outputLayerExists()67 void TestQgsRasterLayerSaveAsDialog::outputLayerExists()
68 {
69   const QString fileName { prepareDb() };
70 
71   // Try to add a raster layer to the DB
72   const QString dataDir( TEST_DATA_DIR ); //defined in CmakeLists.txt
73   const QString rasterPath { dataDir + "/landsat.tif" };
74 
75   QgsRasterLayer rl( rasterPath, QStringLiteral( "my_raster" ) );
76   QVERIFY( rl.isValid() );
77 
78   QgsRasterLayerSaveAsDialog d( &rl, rl.dataProvider(), rl.extent(), rl.crs(), rl.crs() );
79   d.mFormatComboBox->setCurrentIndex( d.mFormatComboBox->findData( QStringLiteral( "GPKG" ) ) );
80   QCOMPARE( d.mFormatComboBox->currentData().toString(), QString( "GPKG" ) );
81   QVERIFY( ! d.outputLayerExists() );
82   d.mFilename->setFilePath( fileName );
83   d.mLayerName->setText( QStringLiteral( "my_imported_raster" ) );
84   QVERIFY( ! d.outputLayerExists() );
85 
86   // Write the raster into the destination file
87   const auto pipe { *rl.pipe() };
88   const auto rasterUri { QStringLiteral( "GPKG:%1:%2" ).arg( d.outputFileName() ).arg( d.outputLayerName() ) };
89   auto fileWriter { QgsRasterFileWriter( d.outputFileName() ) };
90   fileWriter.setCreateOptions( d.createOptions() );
91   fileWriter.setOutputFormat( d.outputFormat() );
92   fileWriter.setBuildPyramidsFlag( d.buildPyramidsFlag() );
93   fileWriter.setPyramidsList( d.pyramidsList() );
94   fileWriter.setPyramidsResampling( d.pyramidsResamplingMethod() );
95   fileWriter.setPyramidsFormat( d.pyramidsFormat() );
96   fileWriter.setPyramidsConfigOptions( d.pyramidsConfigOptions() );
97   fileWriter.writeRaster( &pipe, 10, 10, rl.extent(), rl.crs(), rl.transformContext() );
98   {
99     QVERIFY( QgsRasterLayer( rasterUri, QStringLiteral( "my_raster2" ) ).isValid() );
100   }
101   QVERIFY( d.outputLayerExists() );
102   // Now try to save with the same name of the existing vector layer
103   d.mLayerName->setText( QStringLiteral( "test_vector_layer" ) );
104   QVERIFY( d.outputLayerExists() );
105   auto fileWriter2 { QgsRasterFileWriter( d.outputFileName() ) };
106   fileWriter2.writeRaster( &pipe, 10, 10, rl.extent(), rl.crs(), rl.transformContext() );
107   {
108     const auto rasterUri2 { QStringLiteral( "GPKG:%1:%2" ).arg( d.outputFileName() ).arg( d.outputLayerName() ) };
109     QVERIFY( ! QgsRasterLayer( rasterUri2, QStringLiteral( "my_raster2" ) ).isValid() );
110   }
111 }
112 
prepareDb()113 QString TestQgsRasterLayerSaveAsDialog::prepareDb()
114 {
115   // Preparation: make a test gpk DB with a vector layer in it
116   QTemporaryFile tmpFile( QDir::tempPath() +  QStringLiteral( "/test_qgsrasterlayersavesdialog_XXXXXX.gpkg" ) );
117   tmpFile.setAutoRemove( false );
118   tmpFile.open();
119   const QString fileName( tmpFile.fileName( ) );
120   QgsVectorLayer vl( QStringLiteral( "Point?field=firstfield:string(1024)" ), "test_vector_layer", "memory" );
121 
122   QgsVectorFileWriter::SaveVectorOptions saveOptions;
123   saveOptions.fileEncoding = QStringLiteral( "UTF-8" );
124   const std::unique_ptr< QgsVectorFileWriter > writer( QgsVectorFileWriter::create( fileName, vl.fields(), QgsWkbTypes::Point, vl.crs(), QgsCoordinateTransformContext(), saveOptions ) );
125 
126   QgsFeature f { vl.fields() };
127   f.setAttribute( 0, QString( 1024, 'x' ) );
128   f.setGeometry( QgsGeometry::fromWkt( QStringLiteral( "point(9 45)" ) ) );
129   vl.startEditing();
130   vl.addFeature( f );
131   QgsVectorFileWriter::SaveVectorOptions options;
132   options.driverName = QStringLiteral( "GPKG" );
133   options.layerName = QStringLiteral( "test_vector_layer" );
134   QString errorMessage;
135   QgsVectorFileWriter::writeAsVectorFormatV3(
136     &vl,
137     fileName,
138     vl.transformContext(),
139     options,
140     &errorMessage,
141     nullptr,
142     nullptr
143   );
144   const QgsVectorLayer vl2( QStringLiteral( "%1|layername=test_vector_layer" ).arg( fileName ), "test_vector_layer", "ogr" );
145   Q_ASSERT( vl2.isValid() );
146   return tmpFile.fileName( );
147 }
148 
149 QGSTEST_MAIN( TestQgsRasterLayerSaveAsDialog )
150 
151 #include "testqgsrasterlayersaveasdialog.moc"
152