/*************************************************************************** testqgsogcutils.cpp -------------------------------------- Date : March 2013 Copyright : (C) 2013 Martin Dobias Email : wonder.sk at gmail dot 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" /** \ingroup UnitTests * This is a unit test for OGC utilities */ class TestQgsOgcUtils : public QObject { Q_OBJECT private slots: void initTestCase() { // Needed on Qt 5 so that the serialization of XML is consistent among all executions #if QT_VERSION < QT_VERSION_CHECK( 5, 6 ,0) extern Q_CORE_EXPORT QBasicAtomicInt qt_qhash_seed; qt_qhash_seed.store( 0 ); #else qSetGlobalQHashSeed( 0 ); #endif // // Runs once before any tests are run // // init QGIS's paths - true means that all path will be inited from prefix QgsApplication::init(); QgsApplication::initQgis(); } void cleanupTestCase() { QgsApplication::exitQgis(); } void testGeometryFromGML(); void testGeometryToGML(); void testExpressionFromOgcFilter(); void testExpressionFromOgcFilter_data(); void testExpressionToOgcFilter(); void testExpressionToOgcFilter_data(); void testExpressionToOgcFilterWFS11(); void testExpressionToOgcFilterWFS11_data(); void testExpressionToOgcFilterWFS20(); void testExpressionToOgcFilterWFS20_data(); void testSQLStatementToOgcFilter(); void testSQLStatementToOgcFilter_data(); }; void TestQgsOgcUtils::testGeometryFromGML() { // Test GML2 QgsGeometry geom( QgsOgcUtils::geometryFromGML( QStringLiteral( "123,456" ) ) ); QVERIFY( geom ); QVERIFY( geom.wkbType() == QgsWkbTypes::Point ); QVERIFY( geom.asPoint() == QgsPointXY( 123, 456 ) ); QgsGeometry geomBox( QgsOgcUtils::geometryFromGML( QStringLiteral( "135.2239,34.4879 135.8578,34.8471" ) ) ); QVERIFY( geomBox ); QVERIFY( geomBox.wkbType() == QgsWkbTypes::Polygon ); // Test GML3 geom = QgsOgcUtils::geometryFromGML( QStringLiteral( "123 456" ) ); QVERIFY( geom ); QVERIFY( geom.wkbType() == QgsWkbTypes::Point ); QVERIFY( geom.asPoint() == QgsPointXY( 123, 456 ) ); geomBox = QgsOgcUtils::geometryFromGML( QStringLiteral( "135.2239 34.4879135.8578 34.8471" ) ); QVERIFY( geomBox ); QVERIFY( geomBox.wkbType() == QgsWkbTypes::Polygon ); } static bool compareElements( QDomElement &element1, QDomElement &element2 ) { QString tag1 = element1.tagName(); tag1.replace( QRegExp( ".*:" ), QLatin1String( "" ) ); QString tag2 = element2.tagName(); tag2.replace( QRegExp( ".*:" ), QLatin1String( "" ) ); if ( tag1 != tag2 ) { qDebug( "Different tag names: %s, %s", tag1.toAscii().data(), tag2.toAscii().data() ); return false ; } if ( element1.hasAttributes() != element2.hasAttributes() ) { qDebug( "Different hasAttributes: %s, %s", tag1.toAscii().data(), tag2.toAscii().data() ); return false; } if ( element1.hasAttributes() ) { QDomNamedNodeMap attrs1 = element1.attributes(); QDomNamedNodeMap attrs2 = element2.attributes(); if ( attrs1.size() != attrs2.size() ) { qDebug( "Different attributes size: %s, %s", tag1.toAscii().data(), tag2.toAscii().data() ); return false; } for ( int i = 0 ; i < attrs1.size() ; ++i ) { QDomNode node1 = attrs1.item( i ); QDomAttr attr1 = node1.toAttr(); if ( !element2.hasAttribute( attr1.name() ) ) { qDebug( "Element2 has not attribute: %s, %s, %s", tag1.toAscii().data(), tag2.toAscii().data(), attr1.name().toAscii().data() ); return false; } if ( element2.attribute( attr1.name() ) != attr1.value() ) { qDebug( "Element2 attribute has not the same value: %s, %s, %s", tag1.toAscii().data(), tag2.toAscii().data(), attr1.name().toAscii().data() ); return false; } } } if ( element1.hasChildNodes() != element2.hasChildNodes() ) { qDebug( "Different childNodes: %s, %s", tag1.toAscii().data(), tag2.toAscii().data() ); return false; } if ( element1.hasChildNodes() ) { QDomNodeList nodes1 = element1.childNodes(); QDomNodeList nodes2 = element2.childNodes(); if ( nodes1.size() != nodes2.size() ) { qDebug( "Different childNodes size: %s, %s", tag1.toAscii().data(), tag2.toAscii().data() ); return false; } for ( int i = 0 ; i < nodes1.size() ; ++i ) { QDomNode node1 = nodes1.at( i ); QDomNode node2 = nodes2.at( i ); if ( node1.isElement() && node2.isElement() ) { QDomElement elt1 = node1.toElement(); QDomElement elt2 = node2.toElement(); if ( !compareElements( elt1, elt2 ) ) return false; } else if ( node1.isText() && node2.isText() ) { QDomText txt1 = node1.toText(); QDomText txt2 = node2.toText(); if ( txt1.data() != txt2.data() ) { qDebug( "Different text data: %s %s", tag1.toAscii().data(), txt1.data().toAscii().data() ); qDebug( "Different text data: %s %s", tag2.toAscii().data(), txt2.data().toAscii().data() ); return false; } } } } if ( element1.text() != element2.text() ) { qDebug( "Different text: %s %s", tag1.toAscii().data(), element1.text().toAscii().data() ); qDebug( "Different text: %s %s", tag2.toAscii().data(), element2.text().toAscii().data() ); return false; } return true; } static QDomElement comparableElement( const QString &xmlText ) { QDomDocument doc; if ( !doc.setContent( xmlText ) ) return QDomElement(); return doc.documentElement(); } void TestQgsOgcUtils::testGeometryToGML() { QDomDocument doc; QgsGeometry geomPoint( QgsGeometry::fromPoint( QgsPointXY( 111, 222 ) ) ); QgsGeometry geomLine( QgsGeometry::fromWkt( QStringLiteral( "LINESTRING(111 222, 222 222)" ) ) ); // Elements to compare QDomElement xmlElem; QDomElement ogcElem; // Test GML2 QDomElement elemInvalid = QgsOgcUtils::geometryToGML( QgsGeometry(), doc ); QVERIFY( elemInvalid.isNull() ); QDomElement elemPoint = QgsOgcUtils::geometryToGML( geomPoint, doc ); QVERIFY( !elemPoint.isNull() ); doc.appendChild( elemPoint ); xmlElem = comparableElement( QStringLiteral( "111,222" ) ); ogcElem = comparableElement( doc.toString( -1 ) ); QVERIFY( compareElements( xmlElem, ogcElem ) ); doc.removeChild( elemPoint ); QDomElement elemLine = QgsOgcUtils::geometryToGML( geomLine, doc ); QVERIFY( !elemLine.isNull() ); doc.appendChild( elemLine ); xmlElem = comparableElement( QStringLiteral( "111,222 222,222" ) ); ogcElem = comparableElement( doc.toString( -1 ) ); QVERIFY( compareElements( xmlElem, ogcElem ) ); doc.removeChild( elemLine ); // Test GML3 elemInvalid = QgsOgcUtils::geometryToGML( QgsGeometry(), doc, QStringLiteral( "GML3" ) ); QVERIFY( elemInvalid.isNull() ); elemPoint = QgsOgcUtils::geometryToGML( geomPoint, doc, QStringLiteral( "GML3" ) ); QVERIFY( !elemPoint.isNull() ); doc.appendChild( elemPoint ); xmlElem = comparableElement( QStringLiteral( "111 222" ) ); ogcElem = comparableElement( doc.toString( -1 ) ); QVERIFY( compareElements( xmlElem, ogcElem ) ); doc.removeChild( elemPoint ); elemLine = QgsOgcUtils::geometryToGML( geomLine, doc, QStringLiteral( "GML3" ) ); QVERIFY( !elemLine.isNull() ); doc.appendChild( elemLine ); xmlElem = comparableElement( QStringLiteral( "111 222 222 222" ) ); ogcElem = comparableElement( doc.toString( -1 ) ); QVERIFY( compareElements( xmlElem, ogcElem ) ); doc.removeChild( elemLine ); } void TestQgsOgcUtils::testExpressionFromOgcFilter_data() { QTest::addColumn( "xmlText" ); QTest::addColumn( "dumpText" ); QTest::newRow( "=" ) << QString( "" "NAME" "New York" "" ) << QStringLiteral( "NAME = 'New York'" ); QTest::newRow( ">" ) << QString( "" "COUNT" "3" "" ) << QStringLiteral( "COUNT > 3" ); QTest::newRow( "AND" ) << QString( "" "" "" "pop" "50000" "" "" "pop" "100000" "" "" "" ) << QStringLiteral( "pop >= 50000 AND pop < 100000" ); // TODO: should work also without tags in Lower/Upper-Boundary tags? QTest::newRow( "between" ) << QString( "" "POPULATION" "100" "200" "" ) << QStringLiteral( "POPULATION >= 100 AND POPULATION <= 200" ); // handle different wildcards, single chars, escape chars QTest::newRow( "like" ) << QString( "" "" "NAME*QGIS*" "" ) << QStringLiteral( "NAME LIKE '*QGIS*'" ); QTest::newRow( "ilike" ) << QString( "" "" "NAME*QGIS*" "" ) << QStringLiteral( "NAME ILIKE '*QGIS*'" ); // different wildCards QTest::newRow( "like wildCard" ) << QString( "" "" "NAME*%QGIS*\\*" "" ) << QStringLiteral( "NAME LIKE '%\\\\%QGIS%*'" ); // different single chars QTest::newRow( "like single char" ) << QString( "" "" "NAME._QGIS.\\." "" ) << QStringLiteral( "NAME LIKE '_\\\\_QGIS_.'" ); // different single chars QTest::newRow( "like escape char" ) << QString( "" "" "NAME_QGIS.!.!!%QGIS*!*" "" ) << QStringLiteral( "NAME LIKE '\\\\_QGIS_.!\\\\%QGIS%*'" ); QTest::newRow( "is null" ) << QString( "" "" "FIRST_NAME" "" "" ) << QStringLiteral( "FIRST_NAME IS NULL" ); QTest::newRow( "bbox with GML2 Box" ) << QString( "" "Name>NAME" "135.2239,34.4879 135.8578,34.8471" "" ) << QStringLiteral( "intersects_bbox($geometry, geom_from_gml('135.2239,34.4879 135.8578,34.8471'))" ); QTest::newRow( "Intersects" ) << QString( "" "" "GEOMETRY" "" "123,456" "" "" "" ) << QStringLiteral( "intersects($geometry, geom_from_gml('123,456'))" ); } void TestQgsOgcUtils::testExpressionFromOgcFilter() { QFETCH( QString, xmlText ); QFETCH( QString, dumpText ); QDomDocument doc; QVERIFY( doc.setContent( xmlText, true ) ); QDomElement rootElem = doc.documentElement(); std::shared_ptr expr( QgsOgcUtils::expressionFromOgcFilter( rootElem ) ); QVERIFY( expr.get() ); qDebug( "OGC XML : %s", xmlText.toAscii().data() ); qDebug( "EXPR-DUMP: %s", expr->expression().toAscii().data() ); if ( expr->hasParserError() ) qDebug( "ERROR: %s ", expr->parserErrorString().toAscii().data() ); QVERIFY( !expr->hasParserError() ); QCOMPARE( dumpText, expr->expression() ); } void TestQgsOgcUtils::testExpressionToOgcFilter() { QFETCH( QString, exprText ); QFETCH( QString, xmlText ); QgsExpression exp( exprText ); QVERIFY( !exp.hasParserError() ); QString errorMsg; QDomDocument doc; QDomElement filterElem = QgsOgcUtils::expressionToOgcFilter( exp, doc, &errorMsg ); if ( !errorMsg.isEmpty() ) qDebug( "ERROR: %s", errorMsg.toAscii().data() ); QVERIFY( !filterElem.isNull() ); doc.appendChild( filterElem ); qDebug( "EXPR: %s", exp.expression().toAscii().data() ); qDebug( "OGC : %s", doc.toString( -1 ).toAscii().data() ); QDomElement xmlElem = comparableElement( xmlText ); QDomElement ogcElem = comparableElement( doc.toString( -1 ) ); QVERIFY( compareElements( xmlElem, ogcElem ) ); } void TestQgsOgcUtils::testExpressionToOgcFilter_data() { QTest::addColumn( "exprText" ); QTest::addColumn( "xmlText" ); QTest::newRow( "=" ) << QStringLiteral( "NAME = 'New York'" ) << QString( "" "" "NAME" "New York" "" ); QTest::newRow( ">" ) << QStringLiteral( "\"COUNT\" > 3" ) << QString( "" "" "COUNT" "3" "" ); QTest::newRow( "and+or" ) << QStringLiteral( "(FIELD1 = 10 OR FIELD1 = 20) AND STATUS = 'VALID'" ) << QString( "" "" "" "" "FIELD1" "10" "" "" "FIELD1" "20" "" "" "" "STATUS" "VALID" "" "" "" ); QTest::newRow( "like" ) << QStringLiteral( "NAME LIKE '*QGIS*'" ) << QString( "" "" "NAME" "*QGIS*" "" "" ); QTest::newRow( "ilike" ) << QStringLiteral( "NAME ILIKE '*QGIS*'" ) << QString( "" "" "NAME" "*QGIS*" "" "" ); QTest::newRow( "is null" ) << QStringLiteral( "A IS NULL" ) << QString( "" "" "A" "" "" ); QTest::newRow( "is not null" ) << QStringLiteral( "A IS NOT NULL" ) << QString( "" "" "" "A" "" "" "" ); QTest::newRow( "in" ) << QStringLiteral( "A IN (10,20,30)" ) << QString( "" "" "" "A" "10" "" "" "A" "20" "" "" "A" "30" "" "" "" ); QTest::newRow( "not in" ) << QStringLiteral( "A NOT IN (10,20,30)" ) << QString( "" "" "" "" "A" "10" "" "" "A" "20" "" "" "A" "30" "" "" "" "" ); QTest::newRow( "intersects_bbox" ) << QStringLiteral( "intersects_bbox($geometry, geomFromWKT('POINT (5 6)'))" ) << QString( "" "" "geometry" "5,6 5,6" "" "" ); QTest::newRow( "intersects + wkt" ) << QStringLiteral( "intersects($geometry, geomFromWKT('POINT (5 6)'))" ) << QString( "" "" "geometry" "5,6" "" "" ); QTest::newRow( "contains + gml" ) << QStringLiteral( "contains($geometry, geomFromGML('5,6'))" ) << QString( "" "" "geometry" "5,6" "" "" ); } void TestQgsOgcUtils::testExpressionToOgcFilterWFS11() { QFETCH( QString, exprText ); QFETCH( QString, srsName ); QFETCH( QString, xmlText ); QgsExpression exp( exprText ); QVERIFY( !exp.hasParserError() ); QString errorMsg; QDomDocument doc; QDomElement filterElem = QgsOgcUtils::expressionToOgcFilter( exp, doc, QgsOgcUtils::GML_3_1_0, QgsOgcUtils::FILTER_OGC_1_1, QStringLiteral( "my_geometry_name" ), srsName, true, false, &errorMsg ); if ( !errorMsg.isEmpty() ) qDebug( "ERROR: %s", errorMsg.toAscii().data() ); QVERIFY( !filterElem.isNull() ); doc.appendChild( filterElem ); qDebug( "EXPR: %s", exp.expression().toAscii().data() ); qDebug( "SRSNAME: %s", srsName.toAscii().data() ); qDebug( "OGC : %s", doc.toString( -1 ).toAscii().data() ); QDomElement xmlElem = comparableElement( xmlText ); QDomElement ogcElem = comparableElement( doc.toString( -1 ) ); QVERIFY( compareElements( xmlElem, ogcElem ) ); } void TestQgsOgcUtils::testExpressionToOgcFilterWFS11_data() { QTest::addColumn( "exprText" ); QTest::addColumn( "srsName" ); QTest::addColumn( "xmlText" ); QTest::newRow( "bbox" ) << QStringLiteral( "intersects_bbox($geometry, geomFromWKT('POLYGON((2 49,2 50,3 50,3 49,2 49))'))" ) << QStringLiteral( "urn:ogc:def:crs:EPSG::4326" ) << QString( "" "" "my_geometry_name" "" "49 2" "50 3" "" "" "" ); } void TestQgsOgcUtils::testExpressionToOgcFilterWFS20() { QFETCH( QString, exprText ); QFETCH( QString, srsName ); QFETCH( QString, xmlText ); QgsExpression exp( exprText ); QVERIFY( !exp.hasParserError() ); QString errorMsg; QDomDocument doc; QDomElement filterElem = QgsOgcUtils::expressionToOgcFilter( exp, doc, QgsOgcUtils::GML_3_2_1, QgsOgcUtils::FILTER_FES_2_0, QStringLiteral( "my_geometry_name" ), srsName, true, false, &errorMsg ); if ( !errorMsg.isEmpty() ) qDebug( "ERROR: %s", errorMsg.toAscii().data() ); QVERIFY( !filterElem.isNull() ); doc.appendChild( filterElem ); qDebug( "EXPR: %s", exp.expression().toAscii().data() ); qDebug( "SRSNAME: %s", srsName.toAscii().data() ); qDebug( "OGC : %s", doc.toString( -1 ).toAscii().data() ); QDomElement xmlElem = comparableElement( xmlText ); QDomElement ogcElem = comparableElement( doc.toString( -1 ) ); QVERIFY( compareElements( xmlElem, ogcElem ) ); } void TestQgsOgcUtils::testExpressionToOgcFilterWFS20_data() { QTest::addColumn( "exprText" ); QTest::addColumn( "srsName" ); QTest::addColumn( "xmlText" ); QTest::newRow( "=" ) << QStringLiteral( "NAME = 'New York'" ) << QString() << QString( "" "" "NAME" "New York" "" ); QTest::newRow( "bbox" ) << QStringLiteral( "intersects_bbox($geometry, geomFromWKT('POLYGON((2 49,2 50,3 50,3 49,2 49))'))" ) << QStringLiteral( "urn:ogc:def:crs:EPSG::4326" ) << QString( "" "" "my_geometry_name" "" "49 2" "50 3" "" "" "" ); QTest::newRow( "intersects" ) << QStringLiteral( "intersects($geometry, geomFromWKT('POLYGON((2 49,2 50,3 50,3 49,2 49))'))" ) << QStringLiteral( "urn:ogc:def:crs:EPSG::4326" ) << QString( "" "" "my_geometry_name" "" "" "" "49 2 50 2 50 3 49 3 49 2" "" "" "" "" "" ); } Q_DECLARE_METATYPE( QgsOgcUtils::GMLVersion ) Q_DECLARE_METATYPE( QgsOgcUtils::FilterVersion ) Q_DECLARE_METATYPE( QList ) void TestQgsOgcUtils::testSQLStatementToOgcFilter() { QFETCH( QString, statementText ); QFETCH( QgsOgcUtils::GMLVersion, gmlVersion ); QFETCH( QgsOgcUtils::FilterVersion, filterVersion ); QFETCH( QList, layerProperties ); QFETCH( QString, xmlText ); QgsSQLStatement statement( statementText ); if ( !statement.hasParserError() ) { qDebug( "%s", statement.parserErrorString().toAscii().data() ); QVERIFY( !statement.hasParserError() ); } QString errorMsg; QDomDocument doc; //QgsOgcUtils::GMLVersion gmlVersion = QgsOgcUtils::GML_3_2_1; //QgsOgcUtils::FilterVersion filterVersion = QgsOgcUtils::FILTER_FES_2_0; bool honourAxisOrientation = true; bool invertAxisOrientation = false; //QList layerProperties; QDomElement filterElem = QgsOgcUtils::SQLStatementToOgcFilter( statement, doc, gmlVersion, filterVersion, layerProperties, honourAxisOrientation, invertAxisOrientation, QMap(), &errorMsg ); if ( !errorMsg.isEmpty() ) qDebug( "ERROR: %s", errorMsg.toAscii().data() ); QVERIFY( !filterElem.isNull() ); doc.appendChild( filterElem ); qDebug( "SQL: %s", statement.statement().toAscii().data() ); qDebug( "GML: %s", gmlVersion == QgsOgcUtils::GML_2_1_2 ? "2.1.2" : gmlVersion == QgsOgcUtils::GML_3_1_0 ? "3.1.0" : gmlVersion == QgsOgcUtils::GML_3_2_1 ? "3.2.1" : "unknown" ); qDebug( "FILTER: %s", filterVersion == QgsOgcUtils::FILTER_OGC_1_0 ? "OGC 1.0" : filterVersion == QgsOgcUtils::FILTER_OGC_1_1 ? "OGC 1.1" : filterVersion == QgsOgcUtils::FILTER_FES_2_0 ? "FES 2.0" : "unknown" ); qDebug( "OGC : %s", doc.toString( -1 ).toAscii().data() ); QDomElement xmlElem = comparableElement( xmlText ); QDomElement ogcElem = comparableElement( doc.toString( -1 ) ); QVERIFY( compareElements( xmlElem, ogcElem ) ); } void TestQgsOgcUtils::testSQLStatementToOgcFilter_data() { QList layerProperties; QTest::addColumn( "statementText" ); QTest::addColumn( "gmlVersion" ); QTest::addColumn( "filterVersion" ); QTest::addColumn< QList >( "layerProperties" ); QTest::addColumn( "xmlText" ); QTest::newRow( "= 1.0" ) << QStringLiteral( "SELECT * FROM t WHERE NAME = 'New York'" ) << QgsOgcUtils::GML_2_1_2 << QgsOgcUtils::FILTER_OGC_1_0 << layerProperties << QString( "" "" "NAME" "New York" "" "" ); QTest::newRow( "= 2.0" ) << QStringLiteral( "SELECT * FROM t WHERE NAME = 'New York'" ) << QgsOgcUtils::GML_3_2_1 << QgsOgcUtils::FILTER_FES_2_0 << layerProperties << QString( "" "" "NAME" "New York" "" "" ); QTest::newRow( ">" ) << QStringLiteral( "SELECT * FROM t WHERE COUNT > 3" ) << QgsOgcUtils::GML_2_1_2 << QgsOgcUtils::FILTER_OGC_1_0 << layerProperties << QString( "" "" "COUNT" "3" "" ); QTest::newRow( "and+or" ) << QStringLiteral( "SELECT * FROM t WHERE (FIELD1 <= 10 OR FIELD1 > 20) AND STATUS >= 1.5" ) << QgsOgcUtils::GML_2_1_2 << QgsOgcUtils::FILTER_OGC_1_0 << layerProperties << QString( "" "" "" "" "FIELD1" "10" "" "" "FIELD1" "20" "" "" "" "STATUS" "1.5" "" "" "" ); QTest::newRow( "is null" ) << QStringLiteral( "SELECT * FROM t WHERE A IS NULL" ) << QgsOgcUtils::GML_2_1_2 << QgsOgcUtils::FILTER_OGC_1_0 << layerProperties << QString( "" "" "A" "" "" ); QTest::newRow( "is not null" ) << QStringLiteral( "SELECT * FROM t WHERE A IS NOT NULL" ) << QgsOgcUtils::GML_2_1_2 << QgsOgcUtils::FILTER_OGC_1_0 << layerProperties << QString( "" "" "" "A" "" "" "" ); QTest::newRow( "in" ) << QStringLiteral( "SELECT * FROM t WHERE A IN (10,20,30)" ) << QgsOgcUtils::GML_2_1_2 << QgsOgcUtils::FILTER_OGC_1_0 << layerProperties << QString( "" "" "" "A" "10" "" "" "A" "20" "" "" "A" "30" "" "" "" ); QTest::newRow( "not in" ) << QStringLiteral( "SELECT * FROM t WHERE A NOT IN (10,20,30)" ) << QgsOgcUtils::GML_2_1_2 << QgsOgcUtils::FILTER_OGC_1_0 << layerProperties << QString( "" "" "" "" "A" "10" "" "" "A" "20" "" "" "A" "30" "" "" "" "" ); QTest::newRow( "between" ) << QStringLiteral( "SELECT * FROM t WHERE A BETWEEN 1 AND 2" ) << QgsOgcUtils::GML_2_1_2 << QgsOgcUtils::FILTER_OGC_1_0 << layerProperties << QString( "" "" "A" "1" "2" "" "" ); QTest::newRow( "not between" ) << QStringLiteral( "SELECT * FROM t WHERE A NOT BETWEEN 1 AND 2" ) << QgsOgcUtils::GML_2_1_2 << QgsOgcUtils::FILTER_OGC_1_0 << layerProperties << QString( "" "" "" "A" "1" "2" "" "" "" ); QTest::newRow( "intersects + wkt" ) << QStringLiteral( "SELECT * FROM t WHERE ST_Intersects(geom, ST_GeometryFromText('POINT (5 6)'))" ) << QgsOgcUtils::GML_2_1_2 << QgsOgcUtils::FILTER_OGC_1_0 << layerProperties << QString( "" "" "geom" "5,6" "" "" ); QTest::newRow( "contains + gml" ) << QStringLiteral( "SELECT * FROM t WHERE ST_Contains(geom, ST_GeomFromGML('5,6'))" ) << QgsOgcUtils::GML_2_1_2 << QgsOgcUtils::FILTER_OGC_1_0 << layerProperties << QString( "" "" "geom" "5,6" "" "" ); QTest::newRow( "abs" ) << QStringLiteral( "SELECT * FROM t WHERE ABS(x) < 5" ) << QgsOgcUtils::GML_2_1_2 << QgsOgcUtils::FILTER_OGC_1_0 << layerProperties << QString( "" "" "" "x" "" "5" "" "" ); QTest::newRow( "bbox + wkt + explicit srs" ) << QStringLiteral( "SELECT * FROM t WHERE BBOX(geom, ST_MakeEnvelope(2.2, 49, 3, 50, 4326))" ) << QgsOgcUtils::GML_3_1_0 << QgsOgcUtils::FILTER_OGC_1_1 << layerProperties << QString( "" "" "geom" "" "49 2.2" "50 3" "" "" "" ); QTest::newRow( "intersects + wkt + explicit srs" ) << QStringLiteral( "SELECT * FROM t WHERE ST_Intersects(geom, ST_GeometryFromText('POINT (5 6)', 'urn:ogc:def:crs:EPSG::4326'))" ) << QgsOgcUtils::GML_3_2_1 << QgsOgcUtils::FILTER_FES_2_0 << layerProperties << QString( "" "" "geom" "" "6 5" "" "" "" ); QTest::newRow( "intersects + wkt + explicit srs int" ) << QStringLiteral( "SELECT * FROM t WHERE ST_Intersects(geom, ST_GeometryFromText('POINT (5 6)', 4326))" ) << QgsOgcUtils::GML_3_2_1 << QgsOgcUtils::FILTER_FES_2_0 << layerProperties << QString( "" "" "geom" "" "6 5" "" "" "" ); QTest::newRow( "dwithin + wkt" ) << QStringLiteral( "SELECT * FROM t WHERE ST_DWithin(geom, ST_GeometryFromText('POINT (5 6)', 'urn:ogc:def:crs:EPSG::4326'), '3 m')" ) << QgsOgcUtils::GML_3_2_1 << QgsOgcUtils::FILTER_FES_2_0 << layerProperties << QString( "" "" "geom" "" "6 5" "" "3" "" "" ); QList layerProperties4326_FES20; QgsOgcUtils::LayerProperties prop; prop.mSRSName = QStringLiteral( "urn:ogc:def:crs:EPSG::4326" ); prop.mGeometryAttribute = QStringLiteral( "geom" ); layerProperties4326_FES20.append( prop ); QTest::newRow( "intersects + wkt + implicit SRS" ) << QStringLiteral( "SELECT * FROM t WHERE ST_Intersects(geom, ST_GeometryFromText('POINT (5 6)'))" ) << QgsOgcUtils::GML_3_2_1 << QgsOgcUtils::FILTER_FES_2_0 << layerProperties4326_FES20 << QString( "" "" "geom" "" "6 5" "" "" "" ); QTest::newRow( "intersects join 2.0" ) << QStringLiteral( "SELECT * FROM t, t2 WHERE ST_Intersects(t.geom, t2.geom)" ) << QgsOgcUtils::GML_3_2_1 << QgsOgcUtils::FILTER_FES_2_0 << layerProperties << QString( "" "" "t/geom" "t2/geom" "" "" ); QTest::newRow( "attrib join USING 2.0" ) << QStringLiteral( "SELECT * FROM t JOIN t2 USING (a)" ) << QgsOgcUtils::GML_3_2_1 << QgsOgcUtils::FILTER_FES_2_0 << layerProperties << QString( "" "" "t/a" "t2/a" "" "" ); QTest::newRow( "attrib join multi USING 2.0" ) << QStringLiteral( "SELECT * FROM t JOIN t2 USING (a, b)" ) << QgsOgcUtils::GML_3_2_1 << QgsOgcUtils::FILTER_FES_2_0 << layerProperties << QString( "" "" "" "t/a" "t2/a" "" "" "t/b" "t2/b" "" "" "" ); QTest::newRow( "attrib join ON 2.0" ) << QStringLiteral( "SELECT * FROM t aliased_t JOIN t2 aliasted_t2 ON aliased_t.a = aliasted_t2.b" ) << QgsOgcUtils::GML_3_2_1 << QgsOgcUtils::FILTER_FES_2_0 << layerProperties << QString( "" "" "t/a" "t2/b" "" "" ); QTest::newRow( "attrib multi join 2.0" ) << QStringLiteral( "SELECT * FROM t aliased_t JOIN t2 aliasted_t2 ON aliased_t.a = aliasted_t2.b JOIN t3 USING (c)" ) << QgsOgcUtils::GML_3_2_1 << QgsOgcUtils::FILTER_FES_2_0 << layerProperties << QString( "" "" "" "t/a" "t2/b" "" "" "t2/c" "t3/c" "" "" "" ); } QGSTEST_MAIN( TestQgsOgcUtils ) #include "testqgsogcutils.moc"