Skip to content

Commit

Permalink
Port new MapToolIdentify tests from master
Browse files Browse the repository at this point in the history
Includes the test for identifying invalid polygons showing
(still passing as of 2.14) - see #13635
  • Loading branch information
strk committed Jun 22, 2016
1 parent 6111bee commit d3d2603
Show file tree
Hide file tree
Showing 2 changed files with 141 additions and 0 deletions.
135 changes: 135 additions & 0 deletions tests/src/app/testqgsmaptoolidentifyaction.cpp
Expand Up @@ -16,6 +16,7 @@
#include <QtTest/QtTest>
#include "qgsapplication.h"
#include "qgsvectorlayer.h"
#include "qgsrasterlayer.h"
#include "qgsfeature.h"
#include "qgsgeometry.h"
#include "qgsvectordataprovider.h"
Expand All @@ -24,6 +25,8 @@
#include "qgsunittypes.h"
#include "qgsmaptoolidentifyaction.h"

#include "cpl_conv.h"

class TestQgsMapToolIdentifyAction : public QObject
{
Q_OBJECT
Expand All @@ -40,9 +43,38 @@ class TestQgsMapToolIdentifyAction : public QObject
void lengthCalculation(); //test calculation of derived length attributes
void perimeterCalculation(); //test calculation of derived perimeter attribute
void areaCalculation(); //test calculation of derived area attribute
void identifyRasterFloat32(); // test pixel identification and decimal precision
void identifyRasterFloat64(); // test pixel identification and decimal precision
void identifyInvalidPolygons(); // test selecting invalid polygons

private:
QgsMapCanvas* canvas;

QString testIdentifyRaster( QgsRasterLayer* layer, double xGeoref, double yGeoref );
QList<QgsMapToolIdentify::IdentifyResult> testIdentifyVector( QgsVectorLayer* layer, double xGeoref, double yGeoref );

// Release return with delete []
unsigned char *
hex2bytes( const char *hex, int *size )
{
QByteArray ba = QByteArray::fromHex( hex );
unsigned char *out = new unsigned char[ba.size()];
memcpy( out, ba.data(), ba.size() );
*size = ba.size();
return out;
}

// TODO: make this a QgsGeometry member...
QgsGeometry geomFromHexWKB( const char *hexwkb )
{
int wkbsize;
unsigned char *wkb = hex2bytes( hexwkb, &wkbsize );
QgsGeometry geom;
// NOTE: QgsGeometry takes ownership of wkb
geom.fromWkb( wkb, wkbsize );
return geom;
}

};

void TestQgsMapToolIdentifyAction::initTestCase()
Expand Down Expand Up @@ -241,6 +273,109 @@ void TestQgsMapToolIdentifyAction::areaCalculation()
QVERIFY( qgsDoubleNear( area, 389.6117, 0.001 ) );
}

// private
QString TestQgsMapToolIdentifyAction::testIdentifyRaster( QgsRasterLayer* layer, double xGeoref, double yGeoref )
{
QScopedPointer< QgsMapToolIdentifyAction > action( new QgsMapToolIdentifyAction( canvas ) );
QgsPoint mapPoint = canvas->getCoordinateTransform()->transform( xGeoref, yGeoref );
QList<QgsMapToolIdentify::IdentifyResult> result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer*>() << layer );
if ( result.length() != 1 )
return "";
return result[0].mAttributes["Band 1"];
}

// private
QList<QgsMapToolIdentify::IdentifyResult>
TestQgsMapToolIdentifyAction::testIdentifyVector( QgsVectorLayer* layer, double xGeoref, double yGeoref )
{
QScopedPointer< QgsMapToolIdentifyAction > action( new QgsMapToolIdentifyAction( canvas ) );
QgsPoint mapPoint = canvas->getCoordinateTransform()->transform( xGeoref, yGeoref );
QList<QgsMapToolIdentify::IdentifyResult> result = action->identify( mapPoint.x(), mapPoint.y(), QList<QgsMapLayer*>() << layer );
return result;
}

void TestQgsMapToolIdentifyAction::identifyRasterFloat32()
{
//create a temporary layer
QString raster = QString( TEST_DATA_DIR ) + "/raster/test.asc";

// By default the QgsRasterLayer forces AAIGRID_DATATYPE=Float64
CPLSetConfigOption( "AAIGRID_DATATYPE", "Float32" );
QScopedPointer< QgsRasterLayer> tempLayer( new QgsRasterLayer( raster ) );
CPLSetConfigOption( "AAIGRID_DATATYPE", nullptr );

QVERIFY( tempLayer->isValid() );

canvas->setExtent( QgsRectangle( 0, 0, 7, 1 ) );

QCOMPARE( testIdentifyRaster( tempLayer.data(), 0.5, 0.5 ), QString( "-999.9" ) );

QCOMPARE( testIdentifyRaster( tempLayer.data(), 1.5, 0.5 ), QString( "-999.987" ) );

// More than 6 significant digits : precision loss in Float32
QCOMPARE( testIdentifyRaster( tempLayer.data(), 2.5, 0.5 ), QString( "1.2345678" ) ); // in .asc file : 1.2345678

QCOMPARE( testIdentifyRaster( tempLayer.data(), 3.5, 0.5 ), QString( "123456" ) );

// More than 6 significant digits: no precision loss here for that particular value
QCOMPARE( testIdentifyRaster( tempLayer.data(), 4.5, 0.5 ), QString( "1234567" ) );

// More than 6 significant digits: no precision loss here for that particular value
QCOMPARE( testIdentifyRaster( tempLayer.data(), 5.5, 0.5 ), QString( "-999.9876" ) );

// More than 6 significant digits: no precision loss here
QCOMPARE( testIdentifyRaster( tempLayer.data(), 6.5, 0.5 ), QString( "1.2345678901234" ) ); // in .asc file : 1.2345678901234
}

void TestQgsMapToolIdentifyAction::identifyRasterFloat64()
{
//create a temporary layer
QString raster = QString( TEST_DATA_DIR ) + "/raster/test.asc";
QScopedPointer< QgsRasterLayer> tempLayer( new QgsRasterLayer( raster ) );
QVERIFY( tempLayer->isValid() );

canvas->setExtent( QgsRectangle( 0, 0, 7, 1 ) );

QCOMPARE( testIdentifyRaster( tempLayer.data(), 0.5, 0.5 ), QString( "-999.9" ) );

QCOMPARE( testIdentifyRaster( tempLayer.data(), 1.5, 0.5 ), QString( "-999.987" ) );

QCOMPARE( testIdentifyRaster( tempLayer.data(), 2.5, 0.5 ), QString( "1.2345678" ) );

QCOMPARE( testIdentifyRaster( tempLayer.data(), 3.5, 0.5 ), QString( "123456" ) );

QCOMPARE( testIdentifyRaster( tempLayer.data(), 4.5, 0.5 ), QString( "1234567" ) );

QCOMPARE( testIdentifyRaster( tempLayer.data(), 5.5, 0.5 ), QString( "-999.9876" ) );

QCOMPARE( testIdentifyRaster( tempLayer.data(), 6.5, 0.5 ), QString( "1.2345678901234" ) );
}

void TestQgsMapToolIdentifyAction::identifyInvalidPolygons()
{
//create a temporary layer
QScopedPointer< QgsVectorLayer > memoryLayer( new QgsVectorLayer( "Polygon?field=pk:int", "vl", "memory" ) );
QVERIFY( memoryLayer->isValid() );
QgsFeature f1( memoryLayer->dataProvider()->fields(), 1 );
f1.setAttribute( "pk", 1 );
f1.setGeometry( geomFromHexWKB(
"010300000001000000030000000000000000000000000000000000000000000000000024400000000000000000000000000000244000000000000024400000000000000000"
) );
// TODO: check why we need the ->dataProvider() part, since
// there's a QgsVectorLayer::addFeatures method too
//memoryLayer->addFeatures( QgsFeatureList() << f1 );
memoryLayer->dataProvider()->addFeatures( QgsFeatureList() << f1 );

canvas->setExtent( QgsRectangle( 0, 0, 10, 10 ) );
QList<QgsMapToolIdentify::IdentifyResult> identified;
identified = testIdentifyVector( memoryLayer.data(), 4, 6 );
QCOMPARE( identified.length(), 0 );
identified = testIdentifyVector( memoryLayer.data(), 6, 4 );
QCOMPARE( identified.length(), 1 );
QCOMPARE( identified[0].mFeature.attribute( "pk" ), QVariant( 1 ) );

}


QTEST_MAIN( TestQgsMapToolIdentifyAction )
#include "testqgsmaptoolidentifyaction.moc"
Expand Down
6 changes: 6 additions & 0 deletions tests/testdata/raster/test.asc
@@ -0,0 +1,6 @@
ncols 7
nrows 1
xllcorner 0
yllcorner 0
cellsize 1
-999.9 -999.987 1.2345678 123456 1234567 -999.9876 1.2345678901234

0 comments on commit d3d2603

Please sign in to comment.