1 /***************************************************************************
2   testalignraster.cpp
3   --------------------------------------
4   Date                 : June 2015
5   Copyright            : (C) 2015 by Martin Dobias
6   Email                : wonder dot sk at gmail dot com
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 #include "qgstest.h"
17 
18 #include "qgsalignraster.h"
19 #include "qgsapplication.h"
20 #include "qgscoordinatereferencesystem.h"
21 #include "qgsrectangle.h"
22 
23 #include <QDir>
24 
25 #include <gdal.h>
26 
27 
28 
_tempFile(const QString & name)29 static QString _tempFile( const QString &name )
30 {
31   return QStringLiteral( "%1/aligntest-%2.tif" ).arg( QDir::tempPath(), name );
32 }
33 
34 
35 class TestAlignRaster : public QObject
36 {
37     Q_OBJECT
38 
39     QString SRC_FILE;
40   private slots:
41 
initTestCase()42     void initTestCase()
43     {
44       GDALAllRegister();
45 
46       SRC_FILE = QStringLiteral( TEST_DATA_DIR ) + "/float1-16.tif";
47 
48       QgsApplication::init(); // needed for CRS database
49     }
50 
testRasterInfo()51     void testRasterInfo()
52     {
53       const QgsAlignRaster::RasterInfo out( SRC_FILE );
54       QVERIFY( out.isValid() );
55       QCOMPARE( out.cellSize(), QSizeF( 0.2, 0.2 ) );
56       QCOMPARE( out.gridOffset(), QPointF( 0.0, 0.0 ) );
57       QCOMPARE( out.extent(), QgsRectangle( 106.0, -7.0, 106.8, -6.2 ) );
58     }
59 
testClip()60     void testClip()
61     {
62       const QString tmpFile( _tempFile( QStringLiteral( "clip" ) ) );
63 
64       QgsAlignRaster align;
65       QgsAlignRaster::List rasters;
66       rasters << QgsAlignRaster::Item( SRC_FILE, tmpFile );
67       align.setRasters( rasters );
68       align.setParametersFromRaster( SRC_FILE );
69       align.setClipExtent( 106.3, -6.65, 106.35, -6.5 );
70       const bool res = align.run();
71       QVERIFY( res );
72 
73       QgsAlignRaster::RasterInfo out( tmpFile );
74       QVERIFY( out.isValid() );
75       QCOMPARE( out.rasterSize(), QSize( 1, 2 ) );
76       QCOMPARE( out.cellSize(), QSizeF( 0.2, 0.2 ) );
77       QCOMPARE( out.identify( 106.3, -6.7 ), 10. );
78       QCOMPARE( out.identify( 106.3, -6.5 ), 6. );
79     }
80 
testClipOutside()81     void testClipOutside()
82     {
83       const QString tmpFile( _tempFile( QStringLiteral( "clip-outside" ) ) );
84 
85       QgsAlignRaster align;
86       QgsAlignRaster::List rasters;
87       rasters << QgsAlignRaster::Item( SRC_FILE, tmpFile );
88       align.setRasters( rasters );
89       align.setParametersFromRaster( SRC_FILE );
90       align.setClipExtent( 1, 1, 2, 2 );
91       const bool res = align.run();
92       QVERIFY( !res );
93     }
94 
testChangeGridOffsetNN()95     void testChangeGridOffsetNN()
96     {
97       const QString tmpFile( _tempFile( QStringLiteral( "change-grid-offset-nn" ) ) );
98 
99       QgsAlignRaster align;
100       QgsAlignRaster::List rasters;
101       rasters << QgsAlignRaster::Item( SRC_FILE, tmpFile );
102       align.setRasters( rasters );
103       align.setParametersFromRaster( SRC_FILE );
104       QPointF offset = align.gridOffset();
105       offset.rx() += 0.25;
106       align.setGridOffset( offset );
107       const bool res = align.run();
108       QVERIFY( res );
109 
110       QgsAlignRaster::RasterInfo out( tmpFile );
111       QVERIFY( out.isValid() );
112       QCOMPARE( out.rasterSize(), QSize( 3, 4 ) );
113       QCOMPARE( out.cellSize(), QSizeF( 0.2, 0.2 ) );
114       QCOMPARE( out.identify( 106.1, -6.9 ), 13. );
115       QCOMPARE( out.identify( 106.2, -6.9 ), 13. );
116       QCOMPARE( out.identify( 106.3, -6.9 ), 14. );
117     }
118 
testChangeGridOffsetBilinear()119     void testChangeGridOffsetBilinear()
120     {
121       const QString tmpFile( _tempFile( QStringLiteral( "change-grid-offset-bilinear" ) ) );
122 
123       QgsAlignRaster align;
124       QgsAlignRaster::List rasters;
125       rasters << QgsAlignRaster::Item( SRC_FILE, tmpFile );
126       rasters[0].resampleMethod = QgsAlignRaster::RA_Bilinear;
127       align.setRasters( rasters );
128       align.setParametersFromRaster( SRC_FILE );
129       QPointF offset = align.gridOffset();
130       offset.rx() += 0.1;
131       align.setGridOffset( offset );
132       const bool res = align.run();
133       QVERIFY( res );
134 
135       QgsAlignRaster::RasterInfo out( tmpFile );
136       QVERIFY( out.isValid() );
137       QCOMPARE( out.rasterSize(), QSize( 3, 4 ) );
138       QCOMPARE( out.cellSize(), QSizeF( 0.2, 0.2 ) );
139       QCOMPARE( out.identify( 106.2, -6.9 ), 13.5 );
140     }
141 
testSmallerCellSize()142     void testSmallerCellSize()
143     {
144       const QString tmpFile( _tempFile( QStringLiteral( "smaller-cell-size" ) ) );
145 
146       QgsAlignRaster align;
147       QgsAlignRaster::List rasters;
148       rasters << QgsAlignRaster::Item( SRC_FILE, tmpFile );
149       rasters[0].resampleMethod = QgsAlignRaster::RA_Bilinear;
150       align.setRasters( rasters );
151       align.setParametersFromRaster( SRC_FILE );
152       align.setCellSize( 0.1, 0.1 );
153       const bool res = align.run();
154       QVERIFY( res );
155 
156       QgsAlignRaster::RasterInfo out( tmpFile );
157       QVERIFY( out.isValid() );
158       QCOMPARE( out.rasterSize(), QSize( 8, 8 ) );
159       QCOMPARE( out.cellSize(), QSizeF( 0.1, 0.1 ) );
160       QCOMPARE( out.identify( 106.15, -6.35 ), 2.25 );
161 
162     }
163 
164 
testBiggerCellSize()165     void testBiggerCellSize()
166     {
167       const QString tmpFile( _tempFile( QStringLiteral( "bigger-cell-size" ) ) );
168 
169       QgsAlignRaster align;
170       QgsAlignRaster::List rasters;
171       rasters << QgsAlignRaster::Item( SRC_FILE, tmpFile );
172       rasters[0].resampleMethod = QgsAlignRaster::RA_Average;
173       align.setRasters( rasters );
174       align.setParametersFromRaster( SRC_FILE, QString(), QSizeF( 0.4, 0.4 ) );
175       const bool res = align.run();
176       QVERIFY( res );
177 
178       QgsAlignRaster::RasterInfo out( tmpFile );
179       QVERIFY( out.isValid() );
180       QCOMPARE( out.rasterSize(), QSize( 2, 2 ) );
181       QCOMPARE( out.cellSize(), QSizeF( 0.4, 0.4 ) );
182       QCOMPARE( out.identify( 106.2, -6.9 ), 11.5 );
183     }
184 
185 
testRescaleBiggerCellSize()186     void testRescaleBiggerCellSize()
187     {
188       const QString tmpFile( _tempFile( QStringLiteral( "rescale-bigger-cell-size" ) ) );
189 
190       QgsAlignRaster align;
191       QgsAlignRaster::List rasters;
192       rasters << QgsAlignRaster::Item( SRC_FILE, tmpFile );
193       rasters[0].resampleMethod = QgsAlignRaster::RA_Average;
194       rasters[0].rescaleValues = true;
195       align.setRasters( rasters );
196       align.setParametersFromRaster( SRC_FILE, QString(), QSizeF( 0.4, 0.4 ) );
197       const bool res = align.run();
198       QVERIFY( res );
199 
200       QgsAlignRaster::RasterInfo out( tmpFile );
201       QVERIFY( out.isValid() );
202       QCOMPARE( out.rasterSize(), QSize( 2, 2 ) );
203       QCOMPARE( out.cellSize(), QSizeF( 0.4, 0.4 ) );
204       QCOMPARE( out.identify( 106.2, -6.4 ), 14. ); // = (1+2+5+6)
205     }
206 
testReprojectToOtherCRS()207     void testReprojectToOtherCRS()
208     {
209       const QString tmpFile( _tempFile( QStringLiteral( "reproject-utm-47n" ) ) );
210 
211       // reproject from WGS84 to UTM zone 47N
212       // (the true UTM zone for this raster is 48N, but here it is
213       // more obvious the different shape of the resulting raster)
214       const QgsCoordinateReferenceSystem destCRS( QStringLiteral( "EPSG:32647" ) );
215       QVERIFY( destCRS.isValid() );
216 
217       QgsAlignRaster align;
218       QgsAlignRaster::List rasters;
219       rasters << QgsAlignRaster::Item( SRC_FILE, tmpFile );
220       align.setRasters( rasters );
221       align.setParametersFromRaster( SRC_FILE, destCRS.toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) );
222       const bool res = align.run();
223       QVERIFY( res );
224 
225       QgsAlignRaster::RasterInfo out( tmpFile );
226       QVERIFY( out.isValid() );
227       const QgsCoordinateReferenceSystem outCRS( out.crs() );
228       QCOMPARE( outCRS, destCRS );
229       QCOMPARE( out.rasterSize(), QSize( 4, 4 ) );
230       // tolerance of 1 to keep the test more robust
231       QGSCOMPARENEAR( out.cellSize().width(), 22293, 1 ); // ~ 22293.256065
232       QGSCOMPARENEAR( out.cellSize().height(), 22293, 1 ); // ~ 22293.256065
233       QGSCOMPARENEAR( out.gridOffset().x(), 4327, 1 ); // ~ 4327.168434
234       QGSCOMPARENEAR( out.gridOffset().y(), 637, 1 ); // ~ 637.007990
235       QCOMPARE( out.identify( 1308405, -746611 ), 10. );
236     }
237 
testSuggestedReferenceLayer()238     void testSuggestedReferenceLayer()
239     {
240       QgsAlignRaster align;
241 
242       QCOMPARE( align.suggestedReferenceLayer(), -1 );
243 
244       QgsAlignRaster::List rasters;
245       rasters << QgsAlignRaster::Item( SRC_FILE, QString() );
246       align.setRasters( rasters );
247 
248       QCOMPARE( align.suggestedReferenceLayer(), 0 );
249 
250     }
251 
252 };
253 
254 QGSTEST_MAIN( TestAlignRaster )
255 
256 #include "testqgsalignraster.moc"
257