Skip to content

Commit d3d2603

Browse files
committedJun 22, 2016
Port new MapToolIdentify tests from master
Includes the test for identifying invalid polygons showing (still passing as of 2.14) - see #13635
1 parent 6111bee commit d3d2603

File tree

2 files changed

+141
-0
lines changed

2 files changed

+141
-0
lines changed
 

‎tests/src/app/testqgsmaptoolidentifyaction.cpp

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <QtTest/QtTest>
1717
#include "qgsapplication.h"
1818
#include "qgsvectorlayer.h"
19+
#include "qgsrasterlayer.h"
1920
#include "qgsfeature.h"
2021
#include "qgsgeometry.h"
2122
#include "qgsvectordataprovider.h"
@@ -24,6 +25,8 @@
2425
#include "qgsunittypes.h"
2526
#include "qgsmaptoolidentifyaction.h"
2627

28+
#include "cpl_conv.h"
29+
2730
class TestQgsMapToolIdentifyAction : public QObject
2831
{
2932
Q_OBJECT
@@ -40,9 +43,38 @@ class TestQgsMapToolIdentifyAction : public QObject
4043
void lengthCalculation(); //test calculation of derived length attributes
4144
void perimeterCalculation(); //test calculation of derived perimeter attribute
4245
void areaCalculation(); //test calculation of derived area attribute
46+
void identifyRasterFloat32(); // test pixel identification and decimal precision
47+
void identifyRasterFloat64(); // test pixel identification and decimal precision
48+
void identifyInvalidPolygons(); // test selecting invalid polygons
4349

4450
private:
4551
QgsMapCanvas* canvas;
52+
53+
QString testIdentifyRaster( QgsRasterLayer* layer, double xGeoref, double yGeoref );
54+
QList<QgsMapToolIdentify::IdentifyResult> testIdentifyVector( QgsVectorLayer* layer, double xGeoref, double yGeoref );
55+
56+
// Release return with delete []
57+
unsigned char *
58+
hex2bytes( const char *hex, int *size )
59+
{
60+
QByteArray ba = QByteArray::fromHex( hex );
61+
unsigned char *out = new unsigned char[ba.size()];
62+
memcpy( out, ba.data(), ba.size() );
63+
*size = ba.size();
64+
return out;
65+
}
66+
67+
// TODO: make this a QgsGeometry member...
68+
QgsGeometry geomFromHexWKB( const char *hexwkb )
69+
{
70+
int wkbsize;
71+
unsigned char *wkb = hex2bytes( hexwkb, &wkbsize );
72+
QgsGeometry geom;
73+
// NOTE: QgsGeometry takes ownership of wkb
74+
geom.fromWkb( wkb, wkbsize );
75+
return geom;
76+
}
77+
4678
};
4779

4880
void TestQgsMapToolIdentifyAction::initTestCase()
@@ -241,6 +273,109 @@ void TestQgsMapToolIdentifyAction::areaCalculation()
241273
QVERIFY( qgsDoubleNear( area, 389.6117, 0.001 ) );
242274
}
243275

276+
// private
277+
QString TestQgsMapToolIdentifyAction::testIdentifyRaster( QgsRasterLayer* layer, double xGeoref, double yGeoref )
278+
{
279+
QScopedPointer< QgsMapToolIdentifyAction > action( new QgsMapToolIdentifyAction( canvas ) );
280+
QgsPoint mapPoint = canvas->getCoordinateTransform()->transform( xGeoref, yGeoref );
281+
QList<QgsMapToolIdentify::IdentifyResult> result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer*>() << layer );
282+
if ( result.length() != 1 )
283+
return "";
284+
return result[0].mAttributes["Band 1"];
285+
}
286+
287+
// private
288+
QList<QgsMapToolIdentify::IdentifyResult>
289+
TestQgsMapToolIdentifyAction::testIdentifyVector( QgsVectorLayer* layer, double xGeoref, double yGeoref )
290+
{
291+
QScopedPointer< QgsMapToolIdentifyAction > action( new QgsMapToolIdentifyAction( canvas ) );
292+
QgsPoint mapPoint = canvas->getCoordinateTransform()->transform( xGeoref, yGeoref );
293+
QList<QgsMapToolIdentify::IdentifyResult> result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer*>() << layer );
294+
return result;
295+
}
296+
297+
void TestQgsMapToolIdentifyAction::identifyRasterFloat32()
298+
{
299+
//create a temporary layer
300+
QString raster = QString( TEST_DATA_DIR ) + "/raster/test.asc";
301+
302+
// By default the QgsRasterLayer forces AAIGRID_DATATYPE=Float64
303+
CPLSetConfigOption( "AAIGRID_DATATYPE", "Float32" );
304+
QScopedPointer< QgsRasterLayer> tempLayer( new QgsRasterLayer( raster ) );
305+
CPLSetConfigOption( "AAIGRID_DATATYPE", nullptr );
306+
307+
QVERIFY( tempLayer->isValid() );
308+
309+
canvas->setExtent( QgsRectangle( 0, 0, 7, 1 ) );
310+
311+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 0.5, 0.5 ), QString( "-999.9" ) );
312+
313+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 1.5, 0.5 ), QString( "-999.987" ) );
314+
315+
// More than 6 significant digits : precision loss in Float32
316+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 2.5, 0.5 ), QString( "1.2345678" ) ); // in .asc file : 1.2345678
317+
318+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 3.5, 0.5 ), QString( "123456" ) );
319+
320+
// More than 6 significant digits: no precision loss here for that particular value
321+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 4.5, 0.5 ), QString( "1234567" ) );
322+
323+
// More than 6 significant digits: no precision loss here for that particular value
324+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 5.5, 0.5 ), QString( "-999.9876" ) );
325+
326+
// More than 6 significant digits: no precision loss here
327+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 6.5, 0.5 ), QString( "1.2345678901234" ) ); // in .asc file : 1.2345678901234
328+
}
329+
330+
void TestQgsMapToolIdentifyAction::identifyRasterFloat64()
331+
{
332+
//create a temporary layer
333+
QString raster = QString( TEST_DATA_DIR ) + "/raster/test.asc";
334+
QScopedPointer< QgsRasterLayer> tempLayer( new QgsRasterLayer( raster ) );
335+
QVERIFY( tempLayer->isValid() );
336+
337+
canvas->setExtent( QgsRectangle( 0, 0, 7, 1 ) );
338+
339+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 0.5, 0.5 ), QString( "-999.9" ) );
340+
341+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 1.5, 0.5 ), QString( "-999.987" ) );
342+
343+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 2.5, 0.5 ), QString( "1.2345678" ) );
344+
345+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 3.5, 0.5 ), QString( "123456" ) );
346+
347+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 4.5, 0.5 ), QString( "1234567" ) );
348+
349+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 5.5, 0.5 ), QString( "-999.9876" ) );
350+
351+
QCOMPARE( testIdentifyRaster( tempLayer.data(), 6.5, 0.5 ), QString( "1.2345678901234" ) );
352+
}
353+
354+
void TestQgsMapToolIdentifyAction::identifyInvalidPolygons()
355+
{
356+
//create a temporary layer
357+
QScopedPointer< QgsVectorLayer > memoryLayer( new QgsVectorLayer( "Polygon?field=pk:int", "vl", "memory" ) );
358+
QVERIFY( memoryLayer->isValid() );
359+
QgsFeature f1( memoryLayer->dataProvider()->fields(), 1 );
360+
f1.setAttribute( "pk", 1 );
361+
f1.setGeometry( geomFromHexWKB(
362+
"010300000001000000030000000000000000000000000000000000000000000000000024400000000000000000000000000000244000000000000024400000000000000000"
363+
) );
364+
// TODO: check why we need the ->dataProvider() part, since
365+
// there's a QgsVectorLayer::addFeatures method too
366+
//memoryLayer->addFeatures( QgsFeatureList() << f1 );
367+
memoryLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 );
368+
369+
canvas->setExtent( QgsRectangle( 0, 0, 10, 10 ) );
370+
QList<QgsMapToolIdentify::IdentifyResult> identified;
371+
identified = testIdentifyVector( memoryLayer.data(), 4, 6 );
372+
QCOMPARE( identified.length(), 0 );
373+
identified = testIdentifyVector( memoryLayer.data(), 6, 4 );
374+
QCOMPARE( identified.length(), 1 );
375+
QCOMPARE( identified[0].mFeature.attribute( "pk" ), QVariant( 1 ) );
376+
377+
}
378+
244379

245380
QTEST_MAIN( TestQgsMapToolIdentifyAction )
246381
#include "testqgsmaptoolidentifyaction.moc"

‎tests/testdata/raster/test.asc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
ncols 7
2+
nrows 1
3+
xllcorner 0
4+
yllcorner 0
5+
cellsize 1
6+
-999.9 -999.987 1.2345678 123456 1234567 -999.9876 1.2345678901234

0 commit comments

Comments
 (0)
Please sign in to comment.