/*************************************************************************** testqgsogcutils.cpp -------------------------------------- Date : March 2016 Copyright : (C) 2016 Even Rouault Email : even.rouault at spatialys.com *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "qgstest.h" #include //qgis includes... #include #include #include "qgsapplication.h" #include "qgslogger.h" /** \ingroup UnitTests * This is a unit test for GML parsing */ class TestQgsGML : public QObject { Q_OBJECT private slots: void initTestCase() { // // Runs once before any tests are run // // init QGIS's paths - true means that all path will be inited from prefix QgsApplication::init(); } void cleanupTestCase() { } void testFromURL(); void testFromByteArray(); void testStreamingParser(); void testStreamingParserInvalidGML(); void testPointGML2(); void testLineStringGML2(); void testPolygonGML2(); void testMultiPointGML2(); void testMultiLineStringGML2(); void testMultiPolygonGML2(); void testPointGML3(); void testPointGML3_EPSG_4326(); void testPointGML3_urn_EPSG_4326(); void testPointGML3_EPSG_4326_honour_EPSG(); void testPointGML3_EPSG_4326_honour_EPSG_invert(); void testLineStringGML3(); void testLineStringGML3_LineStringSegment(); void testPolygonGML3(); void testPolygonGML3_srsDimension_on_Polygon(); void testMultiLineStringGML3(); void testMultiPolygonGML3(); void testPointGML3_2(); void testBoundingBoxGML2(); void testBoundingBoxGML3(); void testNumberMatchedNumberReturned(); void testException(); void testTuple(); void testRenamedFields(); void testTruncatedResponse(); void testPartialFeature(); void testThroughOGRGeometry(); void testThroughOGRGeometry_urn_EPSG_4326(); void testAccents(); }; const QString data1( "" "unknown" "" "" "1" "1234567890123" "1.23" "foo" "2016-04-10T12:34:56.789Z" "" "" "10,20" "" "" "" "" "" ); void TestQgsGML::testFromURL() { QgsFields fields; fields.append( QgsField( QStringLiteral( "intfield" ), QVariant::Int, QStringLiteral( "int" ) ) ); QgsGml gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QgsWkbTypes::Type wkbType; QTemporaryFile tmpFile; tmpFile.open(); tmpFile.write( data1.toAscii() ); tmpFile.flush(); QCOMPARE( gmlParser.getFeatures( QUrl::fromLocalFile( tmpFile.fileName() ).toString(), &wkbType ), 0 ); QCOMPARE( wkbType, QgsWkbTypes::Point ); QMap featureMaps = gmlParser.featuresMap(); QCOMPARE( featureMaps.size(), 1 ); QCOMPARE( gmlParser.idsMap().size(), 1 ); QCOMPARE( gmlParser.crs().authid(), QString( "EPSG:27700" ) ); delete featureMaps[ 0 ]; } void TestQgsGML::testFromByteArray() { QgsFields fields; fields.append( QgsField( QStringLiteral( "intfield" ), QVariant::Int, QStringLiteral( "int" ) ) ); QgsGml gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QgsWkbTypes::Type wkbType; QCOMPARE( gmlParser.getFeatures( data1.toAscii(), &wkbType ), 0 ); QMap featureMaps = gmlParser.featuresMap(); QCOMPARE( featureMaps.size(), 1 ); QVERIFY( featureMaps.constFind( 0 ) != featureMaps.constEnd() ); QCOMPARE( featureMaps[ 0 ]->attributes().size(), 1 ); QMap idsMap = gmlParser.idsMap(); QVERIFY( idsMap.constFind( 0 ) != idsMap.constEnd() ); QCOMPARE( idsMap[ 0 ], QString( "mytypename.1" ) ); delete featureMaps[ 0 ]; } void TestQgsGML::testStreamingParser() { QgsFields fields; fields.append( QgsField( QStringLiteral( "intfield" ), QVariant::Int, QStringLiteral( "int" ) ) ); fields.append( QgsField( QStringLiteral( "longfield" ), QVariant::LongLong, QStringLiteral( "longlong" ) ) ); fields.append( QgsField( QStringLiteral( "doublefield" ), QVariant::Double, QStringLiteral( "double" ) ) ); fields.append( QgsField( QStringLiteral( "strfield" ), QVariant::String, QStringLiteral( "string" ) ) ); fields.append( QgsField( QStringLiteral( "datetimefield" ), QVariant::DateTime, QStringLiteral( "datetime" ) ) ); QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( data1.mid( 0, data1.size() / 2 ).toAscii(), false ), true ); QCOMPARE( gmlParser.getAndStealReadyFeatures().size(), 0 ); QCOMPARE( gmlParser.processData( data1.mid( data1.size() / 2 ).toAscii(), true ), true ); QCOMPARE( gmlParser.isException(), false ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QCOMPARE( features[0].first->attributes().size(), 5 ); QCOMPARE( features[0].first->attributes().at( 0 ), QVariant( 1 ) ); QCOMPARE( features[0].first->attributes().at( 1 ), QVariant( Q_INT64_C( 1234567890123 ) ) ); QCOMPARE( features[0].first->attributes().at( 2 ), QVariant( 1.23 ) ); QCOMPARE( features[0].first->attributes().at( 3 ), QVariant( "foo" ) ); QCOMPARE( features[0].first->attributes().at( 4 ), QVariant( QDateTime( QDate( 2016, 4, 10 ), QTime( 12, 34, 56, 789 ), Qt::UTC ) ) ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Point ); QCOMPARE( features[0].first->geometry().asPoint(), QgsPointXY( 10, 20 ) ); QCOMPARE( features[0].second, QString( "mytypename.1" ) ); QCOMPARE( gmlParser.getAndStealReadyFeatures().size(), 0 ); QCOMPARE( gmlParser.getEPSGCode(), 27700 ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Point ); delete features[0].first; } void TestQgsGML::testStreamingParserInvalidGML() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( "", true ), false ); QCOMPARE( gmlParser.getAndStealReadyFeatures().size(), 0 ); } void TestQgsGML::testPointGML2() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "10,20" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Point ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Point ); QCOMPARE( features[0].first->geometry().asPoint(), QgsPointXY( 10, 20 ) ); delete features[0].first; } void TestQgsGML::testLineStringGML2() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "10,20 30,40" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::LineString ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::LineString ); QgsPolyline line = features[0].first->geometry().asPolyline(); QCOMPARE( line.size(), 2 ); QCOMPARE( line[0], QgsPointXY( 10, 20 ) ); QCOMPARE( line[1], QgsPointXY( 30, 40 ) ); delete features[0].first; } void TestQgsGML::testPolygonGML2() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "" "" "0,0 0,10 10,10 10,0 0,0" "" "" "" "" "1,1 1,9 9,9 1,1" "" "" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Polygon ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Polygon ); QgsPolygon poly = features[0].first->geometry().asPolygon(); QCOMPARE( poly.size(), 2 ); QCOMPARE( poly[0].size(), 5 ); QCOMPARE( poly[1].size(), 4 ); delete features[0].first; } void TestQgsGML::testMultiPointGML2() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "" "" "10,20" "" "" "" "" "30,40" "" "" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::MultiPoint ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::MultiPoint ); QgsMultiPoint multi = features[0].first->geometry().asMultiPoint(); QCOMPARE( multi.size(), 2 ); QCOMPARE( multi[0], QgsPointXY( 10, 20 ) ); QCOMPARE( multi[1], QgsPointXY( 30, 40 ) ); delete features[0].first; } void TestQgsGML::testMultiLineStringGML2() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "" "" "10,20 30,40" "" "" "" "" "50,60 70,80 90,100" "" "" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::MultiLineString ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::MultiLineString ); QgsMultiPolyline multi = features[0].first->geometry().asMultiPolyline(); QCOMPARE( multi.size(), 2 ); QCOMPARE( multi[0].size(), 2 ); QCOMPARE( multi[0][0], QgsPointXY( 10, 20 ) ); QCOMPARE( multi[0][1], QgsPointXY( 30, 40 ) ); QCOMPARE( multi[1].size(), 3 ); delete features[0].first; } void TestQgsGML::testMultiPolygonGML2() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "" "" "" "" "0,0 0,10 10,10 10,0 0,0" "" "" "" "" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::MultiPolygon ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::MultiPolygon ); QgsMultiPolygon multi = features[0].first->geometry().asMultiPolygon(); QCOMPARE( multi.size(), 1 ); QCOMPARE( multi[0].size(), 1 ); QCOMPARE( multi[0][0].size(), 5 ); delete features[0].first; } void TestQgsGML::testPointGML3() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "10 20" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Point ); QCOMPARE( gmlParser.getEPSGCode(), 27700 ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].second, QString( "mytypename.1" ) ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Point ); QCOMPARE( features[0].first->geometry().asPoint(), QgsPointXY( 10, 20 ) ); delete features[0].first; } void TestQgsGML::testPointGML3_EPSG_4326() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "2 49" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Point ); QCOMPARE( gmlParser.getEPSGCode(), 4326 ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].second, QString( "mytypename.1" ) ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Point ); QCOMPARE( features[0].first->geometry().asPoint(), QgsPointXY( 2, 49 ) ); delete features[0].first; } void TestQgsGML::testPointGML3_urn_EPSG_4326() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "49 2" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Point ); QCOMPARE( gmlParser.getEPSGCode(), 4326 ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].second, QString( "mytypename.1" ) ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Point ); QCOMPARE( features[0].first->geometry().asPoint(), QgsPointXY( 2, 49 ) ); delete features[0].first; } void TestQgsGML::testPointGML3_EPSG_4326_honour_EPSG() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields, QgsGmlStreamingParser::Honour_EPSG ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "49 2" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Point ); QCOMPARE( gmlParser.getEPSGCode(), 4326 ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].second, QString( "mytypename.1" ) ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Point ); QCOMPARE( features[0].first->geometry().asPoint(), QgsPointXY( 2, 49 ) ); delete features[0].first; } void TestQgsGML::testPointGML3_EPSG_4326_honour_EPSG_invert() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields, QgsGmlStreamingParser::Honour_EPSG, true ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "2 49" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Point ); QCOMPARE( gmlParser.getEPSGCode(), 4326 ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].second, QString( "mytypename.1" ) ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Point ); QCOMPARE( features[0].first->geometry().asPoint(), QgsPointXY( 2, 49 ) ); delete features[0].first; } void TestQgsGML::testLineStringGML3() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "10 20 30 40" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::LineString ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::LineString ); QgsPolyline line = features[0].first->geometry().asPolyline(); QCOMPARE( line.size(), 2 ); QCOMPARE( line[0], QgsPointXY( 10, 20 ) ); QCOMPARE( line[1], QgsPointXY( 30, 40 ) ); delete features[0].first; } void TestQgsGML::testLineStringGML3_LineStringSegment() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "10 20 30 40" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::LineString ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::LineString ); QgsPolyline line = features[0].first->geometry().asPolyline(); QCOMPARE( line.size(), 2 ); QCOMPARE( line[0], QgsPointXY( 10, 20 ) ); QCOMPARE( line[1], QgsPointXY( 30, 40 ) ); delete features[0].first; } void TestQgsGML::testPolygonGML3() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "" "" "0 0 0 10 10 10 10 0 0 0" "" "" "" "" "1 1 1 9 9 9 1 1" "" "" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Polygon ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Polygon ); QgsPolygon poly = features[0].first->geometry().asPolygon(); QCOMPARE( poly.size(), 2 ); QCOMPARE( poly[0].size(), 5 ); QCOMPARE( poly[1].size(), 4 ); delete features[0].first; } void TestQgsGML::testPolygonGML3_srsDimension_on_Polygon() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "" "" "0 0 -100 0 10 -100 10 10 -100 10 0 -100 0 0 -100" "" "" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Polygon ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Polygon ); QgsPolygon poly = features[0].first->geometry().asPolygon(); QCOMPARE( poly.size(), 1 ); QCOMPARE( poly[0].size(), 5 ); delete features[0].first; } void TestQgsGML::testMultiLineStringGML3() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "" "" "10 20 30 40" "" "" "" "" "50 60 70 80 90 100" "" "" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::MultiLineString ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::MultiLineString ); QgsMultiPolyline multi = features[0].first->geometry().asMultiPolyline(); QCOMPARE( multi.size(), 2 ); QCOMPARE( multi[0].size(), 2 ); QCOMPARE( multi[0][0], QgsPointXY( 10, 20 ) ); QCOMPARE( multi[0][1], QgsPointXY( 30, 40 ) ); QCOMPARE( multi[1].size(), 3 ); delete features[0].first; } void TestQgsGML::testMultiPolygonGML3() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "" "" "" "" "0 0 0 10 10 10 10 0 0 0" "" "" "" "" "" "" "" "" "0 0 0 10 10 10 10 0 0 0" "" "" "" "" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::MultiPolygon ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::MultiPolygon ); QgsMultiPolygon multi = features[0].first->geometry().asMultiPolygon(); QCOMPARE( multi.size(), 2 ); QCOMPARE( multi[0].size(), 1 ); QCOMPARE( multi[0][0].size(), 5 ); delete features[0].first; } void TestQgsGML::testPointGML3_2() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" /* First use of gml: */ "" "" "10 20" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Point ); QCOMPARE( gmlParser.getEPSGCode(), 27700 ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].second, QString( "mytypename.1" ) ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Point ); QCOMPARE( features[0].first->geometry().asPoint(), QgsPointXY( 10, 20 ) ); delete features[0].first; } void TestQgsGML::testBoundingBoxGML2() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "0,0 10,10" "" "" "" "" "" ), true ), true ); //QCOMPARE(gmlParser.wkbType(), QgsWkbTypes::Polygon); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Polygon ); QgsPolygon poly = features[0].first->geometry().asPolygon(); QCOMPARE( poly.size(), 1 ); QCOMPARE( poly[0].size(), 5 ); delete features[0].first; } void TestQgsGML::testBoundingBoxGML3() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "0 0" "10 10" "" "" "" "" "" ), true ), true ); //QCOMPARE(gmlParser.wkbType(), QgsWkbTypes::Polygon); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Polygon ); QgsPolygon poly = features[0].first->geometry().asPolygon(); QCOMPARE( poly.size(), 1 ); QCOMPARE( poly[0].size(), 5 ); delete features[0].first; } void TestQgsGML::testNumberMatchedNumberReturned() { QgsFields fields; // No attribute { QgsGmlStreamingParser gmlParser( QLatin1String( "" ), QLatin1String( "" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" ), true ), true ); QCOMPARE( gmlParser.numberReturned(), -1 ); QCOMPARE( gmlParser.numberMatched(), -1 ); } // Valid numberOfFeatures { QgsGmlStreamingParser gmlParser( QLatin1String( "" ), QLatin1String( "" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" ), true ), true ); QCOMPARE( gmlParser.numberReturned(), 1 ); } // Invalid numberOfFeatures { QgsGmlStreamingParser gmlParser( QLatin1String( "" ), QLatin1String( "" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" ), true ), true ); QCOMPARE( gmlParser.numberReturned(), -1 ); } // Valid numberReturned { QgsGmlStreamingParser gmlParser( QLatin1String( "" ), QLatin1String( "" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" ), true ), true ); QCOMPARE( gmlParser.numberReturned(), 1 ); } // Invalid numberReturned { QgsGmlStreamingParser gmlParser( QLatin1String( "" ), QLatin1String( "" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" ), true ), true ); QCOMPARE( gmlParser.numberReturned(), -1 ); } // Valid numberMatched { QgsGmlStreamingParser gmlParser( QLatin1String( "" ), QLatin1String( "" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" ), true ), true ); QCOMPARE( gmlParser.numberMatched(), 1 ); } // numberMatched=unknown { QgsGmlStreamingParser gmlParser( QLatin1String( "" ), QLatin1String( "" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" ), true ), true ); QCOMPARE( gmlParser.numberMatched(), -1 ); } } void TestQgsGML::testException() { QgsGmlStreamingParser gmlParser( QLatin1String( "" ), QLatin1String( "" ), QgsFields() ); QCOMPARE( gmlParser.processData( QByteArray( "" " " " my_exception" " " "" ), true ), true ); QCOMPARE( gmlParser.isException(), true ); QCOMPARE( gmlParser.exceptionText(), QString( "my_exception" ) ); } void TestQgsGML::testTuple() { QgsFields fields; fields.append( QgsField( QStringLiteral( "my_first_attr" ), QVariant::Int, QStringLiteral( "int" ) ) ); fields.append( QgsField( QStringLiteral( "my_second_attr" ), QVariant::Int, QStringLiteral( "int" ) ) ); QList layerProperties; QgsGmlStreamingParser::LayerProperties prop; prop.mName = QStringLiteral( "ns:firstlayer" ); prop.mGeometryAttribute = QStringLiteral( "geom" ); layerProperties.append( prop ); prop.mName = QStringLiteral( "ns:secondlayer" ); prop.mGeometryAttribute = QStringLiteral( "geom" ); layerProperties.append( prop ); QMap< QString, QPair > mapFieldNameToSrcLayerNameFieldName; mapFieldNameToSrcLayerNameFieldName.insert( QStringLiteral( "my_first_attr" ), QPair( QStringLiteral( "ns:firstlayer" ), QStringLiteral( "a" ) ) ); mapFieldNameToSrcLayerNameFieldName.insert( QStringLiteral( "my_second_attr" ), QPair( QStringLiteral( "ns:secondlayer" ), QStringLiteral( "a" ) ) ); QgsGmlStreamingParser gmlParser( layerProperties, fields, mapFieldNameToSrcLayerNameFieldName ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "1" "10 20" "" "" "" "" "2" "20 40" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.isException(), false ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Point ); QCOMPARE( gmlParser.getEPSGCode(), 27700 ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QCOMPARE( features[0].first->attributes().size(), 2 ); QCOMPARE( features[0].first->attributes().at( 0 ), QVariant( 1 ) ); QCOMPARE( features[0].first->attributes().at( 1 ), QVariant( 2 ) ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].second, QString( "firstlayer.1|secondlayer.1" ) ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Point ); QCOMPARE( features[0].first->geometry().asPoint(), QgsPointXY( 10, 20 ) ); delete features[0].first; } void TestQgsGML::testRenamedFields() { QgsFields fields; fields.append( QgsField( QStringLiteral( "my_first_attr" ), QVariant::Int, QStringLiteral( "int" ) ) ); QList layerProperties; QgsGmlStreamingParser::LayerProperties prop; prop.mName = QStringLiteral( "ns:mylayer" ); prop.mGeometryAttribute = QStringLiteral( "geom" ); layerProperties.append( prop ); QMap< QString, QPair > mapFieldNameToSrcLayerNameFieldName; mapFieldNameToSrcLayerNameFieldName.insert( QStringLiteral( "my_first_attr" ), QPair( QStringLiteral( "ns:mylayer" ), QStringLiteral( "b" ) ) ); QgsGmlStreamingParser gmlParser( layerProperties, fields, mapFieldNameToSrcLayerNameFieldName ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "1" "2" "10 20" "" "" "" ), true ), true ); QCOMPARE( gmlParser.isException(), false ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Point ); QCOMPARE( gmlParser.getEPSGCode(), 27700 ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QCOMPARE( features[0].first->attributes().size(), 1 ); QCOMPARE( features[0].first->attributes().at( 0 ), QVariant( 2 ) ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].second, QString( "mylayer.1" ) ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::Point ); QCOMPARE( features[0].first->geometry().asPoint(), QgsPointXY( 10, 20 ) ); delete features[0].first; } void TestQgsGML::testTruncatedResponse() { QgsGmlStreamingParser gmlParser( QLatin1String( "" ), QLatin1String( "" ), QgsFields() ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" ), true ), true ); QCOMPARE( gmlParser.isTruncatedResponse(), true ); } void TestQgsGML::testPartialFeature() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "10,20" ), true ), false ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 0 ); } void TestQgsGML::testThroughOGRGeometry() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "" "" "" "0 0 0 10 10 10 10 0 0 0" "" "" "" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Polygon ); QCOMPARE( gmlParser.getEPSGCode(), 27700 ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::MultiPolygon ); QgsMultiPolygon multi = features[0].first->geometry().asMultiPolygon(); QCOMPARE( multi.size(), 1 ); QCOMPARE( multi[0].size(), 1 ); QCOMPARE( multi[0][0].size(), 5 ); delete features[0].first; } void TestQgsGML::testThroughOGRGeometry_urn_EPSG_4326() { QgsFields fields; QgsGmlStreamingParser gmlParser( QStringLiteral( "mytypename" ), QStringLiteral( "mygeom" ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "" "" "" "49 2 49 3 59 3 49 2" "" "" "" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::Polygon ); QCOMPARE( gmlParser.getEPSGCode(), 4326 ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::MultiPolygon ); QgsMultiPolygon multi = features[0].first->geometry().asMultiPolygon(); QCOMPARE( multi.size(), 1 ); QCOMPARE( multi[0].size(), 1 ); QCOMPARE( multi[0][0].size(), 4 ); QgsDebugMsg( multi[0][0][0].toString() ); QCOMPARE( multi[0][0][0], QgsPointXY( 2, 49 ) ); delete features[0].first; } void TestQgsGML::testAccents() { QgsFields fields; QgsGmlStreamingParser gmlParser( QString::fromUtf8( QByteArray( "my\xc3\xa9typename" ) ), QString::fromUtf8( QByteArray( "my\xc3\xa9geom" ) ), fields ); QCOMPARE( gmlParser.processData( QByteArray( "" "" "" "" "" "" "" "" "" "0 0 0 10 10 10 10 0 0 0" "" "" "" "" "" "" "" "" "0 0 0 10 10 10 10 0 0 0" "" "" "" "" "" "" "" "" "" ), true ), true ); QCOMPARE( gmlParser.wkbType(), QgsWkbTypes::MultiPolygon ); QVector features = gmlParser.getAndStealReadyFeatures(); QCOMPARE( features.size(), 1 ); QVERIFY( features[0].first->hasGeometry() ); QCOMPARE( features[0].first->geometry().wkbType(), QgsWkbTypes::MultiPolygon ); QgsMultiPolygon multi = features[0].first->geometry().asMultiPolygon(); QCOMPARE( multi.size(), 2 ); QCOMPARE( multi[0].size(), 1 ); QCOMPARE( multi[0][0].size(), 5 ); delete features[0].first; } QGSTEST_MAIN( TestQgsGML ) #include "testqgsgml.moc"