diff --git a/python/core/qgsgeometry.sip b/python/core/qgsgeometry.sip
index c6c962c345c0..ac9e2729e256 100644
--- a/python/core/qgsgeometry.sip
+++ b/python/core/qgsgeometry.sip
@@ -41,6 +41,18 @@ class QgsGeometry
/** static method that creates geometry from Wkt */
static QgsGeometry* fromWkt( QString wkt ) /Factory/;
+ /** static method that creates geometry from GML2
+ @param XML representation of the geometry. GML elements are expected to be
+ in default namespace (...) or in "gml" namespace (...)
+ @note added in 1.9
+ */
+ static QgsGeometry* fromGML2( const QString& xmlString ) /Factory/;
+
+ /** static method that creates geometry from GML2
+ @note added in 1.9
+ */
+ static QgsGeometry* fromGML2( const QDomNode& geometryNode ) /Factory/;
+
/** construct geometry from a point */
static QgsGeometry* fromPoint( const QgsPoint& point ) /Factory/;
/** construct geometry from a multipoint */
diff --git a/src/core/qgsexpression.cpp b/src/core/qgsexpression.cpp
index 8d7599ac528c..eebb757b0eff 100644
--- a/src/core/qgsexpression.cpp
+++ b/src/core/qgsexpression.cpp
@@ -795,21 +795,8 @@ static QVariant fcnGeomFromWKT( const QVariantList& values, QgsFeature*, QgsExpr
}
static QVariant fcnGeomFromGML2( const QVariantList& values, QgsFeature*, QgsExpression* parent )
{
- QDomDocument doc;
- QString errorMsg;
QString gml = getStringValue( values.at( 0 ), parent );
- if ( !doc.setContent( gml, true, &errorMsg ) )
- return QVariant();
-
- QgsGeometry* geom = 0;
- QDomElement elem = doc.documentElement();
- if ( elem.tagName() == "Box" )
- {
- QgsRectangle* rect = new QgsRectangle( elem );
- geom = QgsGeometry::fromRect( *rect );
- }
- else
- geom = QgsGeometry::fromGML2( doc.documentElement() );
+ QgsGeometry* geom = QgsGeometry::fromGML2( gml );
if ( geom )
return QVariant::fromValue( *geom );
diff --git a/src/core/qgsgeometry.cpp b/src/core/qgsgeometry.cpp
index ca3a437f86ff..f027d97178c2 100644
--- a/src/core/qgsgeometry.cpp
+++ b/src/core/qgsgeometry.cpp
@@ -540,7 +540,7 @@ QgsGeometry* QgsGeometry::fromGML2( const QDomNode& geometryNode )
QDomElement geometryTypeElement = geometryNode.toElement();
QString geomType = geometryTypeElement.tagName();
- if ( !( geomType == "Point" || geomType == "LineString" || geomType == "Polygon" || geomType == "MultiPoint" || geomType == "MultiLineString" || geomType == "MultiPolygon" ) )
+ if ( !( geomType == "Point" || geomType == "LineString" || geomType == "Polygon" || geomType == "MultiPoint" || geomType == "MultiLineString" || geomType == "MultiPolygon" || geomType == "Box" ) )
{
QDomNode geometryChild = geometryNode.firstChild();
if ( geometryChild.isNull() )
@@ -551,7 +551,7 @@ QgsGeometry* QgsGeometry::fromGML2( const QDomNode& geometryNode )
geomType = geometryTypeElement.tagName();
}
- if ( !( geomType == "Point" || geomType == "LineString" || geomType == "Polygon" || geomType == "MultiPoint" || geomType == "MultiLineString" || geomType == "MultiPolygon" ) )
+ if ( !( geomType == "Point" || geomType == "LineString" || geomType == "Polygon" || geomType == "MultiPoint" || geomType == "MultiLineString" || geomType == "MultiPolygon" || geomType == "Box" ) )
return 0;
if ( geomType == "Point" && g->setFromGML2Point( geometryTypeElement ) )
@@ -578,12 +578,28 @@ QgsGeometry* QgsGeometry::fromGML2( const QDomNode& geometryNode )
{
return g;
}
+ else if ( geomType == "Box" )
+ {
+ return QgsGeometry::fromRect( QgsRectangle( geometryTypeElement ) );
+ }
else //unknown type
{
return 0;
}
}
+QgsGeometry* QgsGeometry::fromGML2( const QString& xmlString )
+{
+ // wrap the string into a root tag to have "gml" namespace (and also as a default namespace)
+ QString xml = QString( "%2").arg( GML_NAMESPACE ).arg( xmlString );
+ QDomDocument doc;
+ if ( !doc.setContent( xml, true ) )
+ return 0;
+
+ return fromGML2( doc.documentElement().firstChildElement() );
+}
+
+
bool QgsGeometry::setFromGML2Point( const QDomElement& geometryElement )
{
QDomNodeList coordList = geometryElement.elementsByTagNameNS( GML_NAMESPACE, "coordinates" );
diff --git a/src/core/qgsgeometry.h b/src/core/qgsgeometry.h
index e3806dec6ce0..f684cbbb9ecb 100644
--- a/src/core/qgsgeometry.h
+++ b/src/core/qgsgeometry.h
@@ -89,6 +89,13 @@ class CORE_EXPORT QgsGeometry
/** static method that creates geometry from Wkt */
static QgsGeometry* fromWkt( QString wkt );
+ /** static method that creates geometry from GML2
+ @param XML representation of the geometry. GML elements are expected to be
+ in default namespace (...) or in "gml" namespace (...)
+ @note added in 1.9
+ */
+ static QgsGeometry* fromGML2( const QString& xmlString );
+
/** static method that creates geometry from GML2
@note added in 1.9
*/
diff --git a/tests/src/core/testqgsexpression.cpp b/tests/src/core/testqgsexpression.cpp
index 8741b9222e58..ba6bcd193ad0 100644
--- a/tests/src/core/testqgsexpression.cpp
+++ b/tests/src/core/testqgsexpression.cpp
@@ -569,6 +569,20 @@ class TestQgsExpression: public QObject
QTest::newRow( "geomFromWKT Line" ) << "geomFromWKT('" + QgsGeometry::fromPolyline( line )->exportToWkt() + "')" << ( void* ) QgsGeometry::fromPolyline( line ) << false;
QTest::newRow( "geomFromWKT Polyline" ) << "geomFromWKT('" + QgsGeometry::fromPolyline( polyline )->exportToWkt() + "')" << ( void* ) QgsGeometry::fromPolyline( polyline ) << false;
QTest::newRow( "geomFromWKT Polygon" ) << "geomFromWKT('" + QgsGeometry::fromPolygon( polygon )->exportToWkt() + "')" << ( void* ) QgsGeometry::fromPolygon( polygon ) << false;
+
+ // GML Point
+ QTest::newRow( "GML Point (coordinates)" ) << "geomFromGML2('123,456')" << ( void * ) QgsGeometry::fromPoint( point ) << false;
+ // gml:pos if from GML3
+ //QTest::newRow( "GML Point (pos)" ) << "geomFromGML2('123 456')" << ( void * ) QgsGeometry::fromPoint( point ) << false;
+
+ // GML Box
+ QgsRectangle rect( 135.2239, 34.4879, 135.8578, 34.8471 );
+ QTest::newRow( "GML Box" ) << "geomFromGML2('135.2239,34.4879 135.8578,34.8471')" << ( void * ) QgsGeometry::fromRect( rect ) << false;
+ // Envelope is from GML3 ?
+ //QTest::newRow( "GML Envelope" ) << "geomFromGML2('"
+ // "135.2239 34.4879"
+ // "135.8578 34.8471"
+ // "')" << ( void * ) QgsGeometry::fromRect( rect ) << false;
}
void eval_geometry_constructor()
@@ -744,6 +758,113 @@ class TestQgsExpression: public QObject
QgsExpression::unsetSpecialColumn( "$var1" );
}
+
+ void test_from_ogc_filter_data()
+ {
+ QTest::addColumn( "xmlText" );
+ QTest::addColumn( "dumpText" );
+
+ QTest::newRow( "=" ) << QString(
+ ""
+ "NAME"
+ "New York"
+ "" )
+ << QString( "NAME = 'New York'" );
+
+ QTest::newRow( ">" ) << QString(
+ ""
+ "COUNT"
+ "3"
+ "" )
+ << QString( "COUNT > 3" );
+
+ QTest::newRow( "AND" ) << QString(
+ ""
+ ""
+ ""
+ "pop"
+ "50000"
+ ""
+ ""
+ "pop"
+ "100000"
+ ""
+ ""
+ "" )
+ << QString( "pop >= 50000 AND pop < 100000" );
+
+ // TODO: should work also without tags in Lower/Upper-Boundary tags?
+ QTest::newRow( "between" ) << QString(
+ ""
+ "POPULATION"
+ "100"
+ "200"
+ "" )
+ << QString( "POPULATION >= 100 AND POPULATION <= 200" );
+
+ // TODO: needs to handle different wildcards, single chars, escape chars
+ QTest::newRow( "like" ) << QString(
+ ""
+ ""
+ "NAME*QGIS*"
+ "" )
+ << QString( "NAME LIKE '*QGIS*'" );
+
+ QTest::newRow( "is null" ) << QString(
+ ""
+ ""
+ "FIRST_NAME"
+ ""
+ "" )
+ << QString( "FIRST_NAME IS NULL" );
+
+ QTest::newRow( "bbox" ) << QString(
+ ""
+ "Name>NAME"
+ "135.2239,34.4879 135.8578,34.8471"
+ "" )
+ << QString( "bbox($geometry, geomFromGML2('135.2239,34.4879 135.8578,34.8471'))" );
+
+ QTest::newRow( "Intersects" ) << QString(
+ ""
+ ""
+ "GEOMETRY"
+ ""
+ "123,456"
+ ""
+ ""
+ "" )
+ << QString( "intersects($geometry, geomFromGML2('123,456'))" );
+ }
+
+ void test_from_ogc_filter()
+ {
+ QFETCH( QString, xmlText );
+ QFETCH( QString, dumpText );
+
+ QDomDocument doc;
+ QVERIFY(doc.setContent(xmlText, true));
+ QDomElement rootElem = doc.documentElement();
+
+ QgsExpression* expr = QgsExpression::createFromOgcFilter( rootElem );
+ QVERIFY( expr );
+
+ qDebug("OGC XML : %s", xmlText.toAscii().data() );
+ qDebug("EXPR-DUMP: %s", expr->dump().toAscii().data() );
+
+ if ( expr->hasParserError() )
+ qDebug( "ERROR: %s ", expr->parserErrorString().toAscii().data() );
+ QVERIFY( !expr->hasParserError() );
+
+ QCOMPARE( dumpText, expr->dump() );
+
+ delete expr;
+ }
+
+ void test_to_ogc_filter()
+ {
+ // TODO
+ }
};
QTEST_MAIN( TestQgsExpression )
diff --git a/tests/src/core/testqgsgeometry.cpp b/tests/src/core/testqgsgeometry.cpp
index 7ddd39bdf9a1..d64221426bab 100644
--- a/tests/src/core/testqgsgeometry.cpp
+++ b/tests/src/core/testqgsgeometry.cpp
@@ -55,6 +55,9 @@ class TestQgsGeometry: public QObject
void differenceCheck1();
void differenceCheck2();
void bufferCheck();
+
+ void gmlTest();
+
private:
/** A helper method to do a render check to see if the geometry op is as expected */
bool renderCheck( QString theTestName, QString theComment = "" );
@@ -369,6 +372,19 @@ void TestQgsGeometry::dumpPolyline( QgsPolyline &thePolyline )
mpPainter->drawPolyline( myPoints );
}
+void TestQgsGeometry::gmlTest()
+{
+ QgsGeometry* geom = QgsGeometry::fromGML2( "123,456" );
+ QVERIFY( geom );
+ QVERIFY( geom->wkbType() == QGis::WKBPoint );
+ QVERIFY( geom->asPoint() == QgsPoint( 123, 456 ) );
+
+ QgsGeometry* geomBox = QgsGeometry::fromGML2( "135.2239,34.4879 135.8578,34.8471" );
+ QVERIFY( geomBox );
+ QVERIFY( geomBox->wkbType() == QGis::WKBPolygon );
+}
+
+
QTEST_MAIN( TestQgsGeometry )
#include "moc_testqgsgeometry.cxx"