@@ -226,6 +226,15 @@ const char* QgsExpression::UnaryOgcOperatorText[] =
226
226
" Not" , " "
227
227
};
228
228
229
+ const char * QgsExpression::SpatialOgcOperatorText[] =
230
+ {
231
+ " BBOX" , " Intersects" ,
232
+ " Contians" , " Crosses" ,
233
+ " Equals" , " Disjoint" ,
234
+ " Overlaps" , " Touches" ,
235
+ " Within"
236
+ };
237
+
229
238
// /////////////////////////////////////////////
230
239
// functions
231
240
@@ -1250,7 +1259,7 @@ QgsExpression::Node* QgsExpression::Node::createFromOgcFilter( QDomElement &elem
1250
1259
if ( ogcOperatorName.isEmpty () )
1251
1260
continue ;
1252
1261
1253
- if ( element.localName () == ogcOperatorName )
1262
+ if ( element.tagName () == ogcOperatorName )
1254
1263
{
1255
1264
QgsExpression::Node *node = QgsExpression::NodeUnaryOperator::createFromOgcFilter ( element, errorMessage );
1256
1265
if ( node )
@@ -1268,7 +1277,7 @@ QgsExpression::Node* QgsExpression::Node::createFromOgcFilter( QDomElement &elem
1268
1277
if ( ogcOperatorName.isEmpty () )
1269
1278
continue ;
1270
1279
1271
- if ( element.localName () == ogcOperatorName )
1280
+ if ( element.tagName () == ogcOperatorName )
1272
1281
{
1273
1282
QgsExpression::Node *node = QgsExpression::NodeBinaryOperator::createFromOgcFilter ( element, errorMessage );
1274
1283
if ( node )
@@ -1278,25 +1287,43 @@ QgsExpression::Node* QgsExpression::Node::createFromOgcFilter( QDomElement &elem
1278
1287
}
1279
1288
}
1280
1289
1290
+ // check for spatial operators
1291
+ int spatialOpCount = sizeof ( SpatialOgcOperatorText ) / sizeof ( SpatialOgcOperatorText[0 ] );
1292
+ for ( int i = 0 ; i < spatialOpCount; i++ )
1293
+ {
1294
+ QString ogcOperatorName = SpatialOgcOperatorText[ i ];
1295
+ if ( ogcOperatorName.isEmpty () )
1296
+ continue ;
1297
+
1298
+ if ( element.tagName () == ogcOperatorName )
1299
+ {
1300
+ QgsExpression::Node *node = QgsExpression::NodeSpatialOperator::createFromOgcFilter ( element, errorMessage );
1301
+ if ( node )
1302
+ return node;
1303
+
1304
+ return NULL ;
1305
+ }
1306
+ }
1307
+
1281
1308
// check for other OGC operators, convert them to expressions
1282
1309
1283
- if ( element.localName () == " PropertyIsNull" )
1310
+ if ( element.tagName () == " PropertyIsNull" )
1284
1311
{
1285
1312
return QgsExpression::NodeBinaryOperator::createFromOgcFilter ( element, errorMessage );
1286
1313
}
1287
- else if ( element.localName () == " Literal" )
1314
+ else if ( element.tagName () == " Literal" )
1288
1315
{
1289
1316
return QgsExpression::NodeLiteral::createFromOgcFilter ( element, errorMessage );
1290
1317
}
1291
- else if ( element.localName () == " Function" )
1318
+ else if ( element.tagName () == " Function" )
1292
1319
{
1293
1320
return QgsExpression::NodeFunction::createFromOgcFilter ( element, errorMessage );
1294
1321
}
1295
- else if ( element.localName () == " PropertyName" )
1322
+ else if ( element.tagName () == " PropertyName" )
1296
1323
{
1297
1324
return QgsExpression::NodeColumnRef::createFromOgcFilter ( element, errorMessage );
1298
1325
}
1299
- else if ( element.localName () == " PropertyIsBetween" )
1326
+ else if ( element.tagName () == " PropertyIsBetween" )
1300
1327
{
1301
1328
// <ogc:PropertyIsBetween> encode a Range check
1302
1329
QgsExpression::Node *operand = 0 , *lowerBound = 0 ;
@@ -1305,12 +1332,12 @@ QgsExpression::Node* QgsExpression::Node::createFromOgcFilter( QDomElement &elem
1305
1332
QDomElement operandElem = element.firstChildElement ();
1306
1333
while ( !operandElem.isNull () )
1307
1334
{
1308
- if ( operandElem.localName () == " LowerBoundary" )
1335
+ if ( operandElem.tagName () == " LowerBoundary" )
1309
1336
{
1310
1337
QDomElement lowerBoundElem = operandElem.firstChildElement ();
1311
1338
lowerBound = createFromOgcFilter ( lowerBoundElem, errorMessage );
1312
1339
}
1313
- else if ( operandElem.localName () == " UpperBoundary" )
1340
+ else if ( operandElem.tagName () == " UpperBoundary" )
1314
1341
{
1315
1342
QDomElement upperBoundElem = operandElem.firstChildElement ();
1316
1343
upperBound = createFromOgcFilter ( upperBoundElem, errorMessage );
@@ -1449,7 +1476,7 @@ QgsExpression::Node* QgsExpression::NodeUnaryOperator::createFromOgcFilter( QDom
1449
1476
if ( ogcOperatorName.isEmpty () )
1450
1477
continue ;
1451
1478
1452
- if ( element.localName () != ogcOperatorName )
1479
+ if ( element.tagName () != ogcOperatorName )
1453
1480
continue ;
1454
1481
1455
1482
QDomElement operandElem = element.firstChildElement ();
@@ -1811,7 +1838,7 @@ QgsExpression::Node* QgsExpression::NodeBinaryOperator::createFromOgcFilter( QDo
1811
1838
QgsExpression::Node* opRight = 0 ;
1812
1839
1813
1840
// convert ogc:PropertyIsNull to IS operator with NULL right operand
1814
- if ( element.localName () == " PropertyIsNull" )
1841
+ if ( element.tagName () == " PropertyIsNull" )
1815
1842
{
1816
1843
QDomElement operandElem = element.firstChildElement ();
1817
1844
opLeft = QgsExpression::Node::createFromOgcFilter ( operandElem, errorMessage );
@@ -1830,7 +1857,7 @@ QgsExpression::Node* QgsExpression::NodeBinaryOperator::createFromOgcFilter( QDo
1830
1857
if ( ogcOperatorName.isEmpty () )
1831
1858
continue ;
1832
1859
1833
- if ( element.localName () != ogcOperatorName )
1860
+ if ( element.tagName () != ogcOperatorName )
1834
1861
continue ;
1835
1862
1836
1863
QDomElement operandElem = element.firstChildElement ();
@@ -1871,6 +1898,167 @@ QgsExpression::Node* QgsExpression::NodeBinaryOperator::createFromOgcFilter( QDo
1871
1898
1872
1899
//
1873
1900
1901
+ QVariant QgsExpression::NodeSpatialOperator::eval ( QgsExpression* parent, QgsFeature* f )
1902
+ {
1903
+ QgsGeometry* geom = f->geometry ();
1904
+
1905
+ switch ( mOp )
1906
+ {
1907
+ case soBbox:
1908
+ return geom->intersects ( mOpGeometry ->boundingBox () ) ? TVL_True : TVL_False;
1909
+ case soIntersects:
1910
+ return geom->intersects ( mOpGeometry ) ? TVL_True : TVL_False;
1911
+ case soContains:
1912
+ return geom->contains ( mOpGeometry ) ? TVL_True : TVL_False;
1913
+ case soCrosses:
1914
+ return geom->crosses ( mOpGeometry ) ? TVL_True : TVL_False;
1915
+ case soEquals:
1916
+ return geom->equals ( mOpGeometry ) ? TVL_True : TVL_False;
1917
+ case soDisjoint:
1918
+ return geom->disjoint ( mOpGeometry ) ? TVL_True : TVL_False;
1919
+ case soOverlaps:
1920
+ return geom->overlaps ( mOpGeometry ) ? TVL_True : TVL_False;
1921
+ case soTouches:
1922
+ return geom->touches ( mOpGeometry ) ? TVL_True : TVL_False;
1923
+ case soWithin:
1924
+ return geom->within ( mOpGeometry ) ? TVL_True : TVL_False;
1925
+ }
1926
+ return TVL_False;
1927
+ }
1928
+
1929
+ bool QgsExpression::NodeSpatialOperator::prepare ( QgsExpression* /* parent*/ , const QgsFieldMap& /* fields*/ )
1930
+ {
1931
+ return true ;
1932
+ }
1933
+
1934
+ QString QgsExpression::NodeSpatialOperator::dump () const
1935
+ {
1936
+ switch ( mOp )
1937
+ {
1938
+ case soBbox:
1939
+ return QString ( " Intersects('%1')" ).arg ( mOpGeometry ->boundingBox ().asWktPolygon () );
1940
+ case soIntersects:
1941
+ return QString ( " Intersects('%1')" ).arg ( mOpGeometry ->exportToWkt () );
1942
+ }
1943
+ return " " ;
1944
+ }
1945
+
1946
+ QgsExpression::Node* QgsExpression::NodeSpatialOperator::createFromOgcFilter ( QDomElement &element, QString &errorMessage )
1947
+ {
1948
+ if ( element.isNull () )
1949
+ return NULL ;
1950
+
1951
+ bool geomOk = false ;
1952
+ QgsGeometry* geom = new QgsGeometry ();
1953
+
1954
+ QDomNodeList bNodes = element.elementsByTagName ( " Box" );
1955
+ if ( bNodes.size () > 0 ) {
1956
+ QDomElement bElem = bNodes.at ( 0 ).toElement ().firstChild ().toElement ();
1957
+ QString coordSeparator = " ," ;
1958
+ QString tupelSeparator = " " ;
1959
+ if ( bElem.hasAttribute ( " cs" ) )
1960
+ {
1961
+ coordSeparator = bElem.attribute ( " cs" );
1962
+ }
1963
+ if ( bElem.hasAttribute ( " ts" ) )
1964
+ {
1965
+ tupelSeparator = bElem.attribute ( " ts" );
1966
+ }
1967
+
1968
+ QString bString = bElem.text ();
1969
+ bool conversionSuccess;
1970
+ double minx = bString.section ( tupelSeparator, 0 , 0 ).section ( coordSeparator, 0 , 0 ).toDouble ( &conversionSuccess );
1971
+ double miny = bString.section ( tupelSeparator, 0 , 0 ).section ( coordSeparator, 1 , 1 ).toDouble ( &conversionSuccess );
1972
+ double maxx = bString.section ( tupelSeparator, 1 , 1 ).section ( coordSeparator, 0 , 0 ).toDouble ( &conversionSuccess );
1973
+ double maxy = bString.section ( tupelSeparator, 1 , 1 ).section ( coordSeparator, 1 , 1 ).toDouble ( &conversionSuccess );
1974
+ QgsRectangle* rect = new QgsRectangle ( minx, miny, maxx, maxy );
1975
+ geom = QgsGeometry::fromRect ( *rect );
1976
+ geomOk = true ;
1977
+ }
1978
+
1979
+ if ( !geomOk )
1980
+ {
1981
+ QDomNodeList gNodes = element.elementsByTagName ( " MultiPolygon" );
1982
+ if ( gNodes .size () > 0 ) {
1983
+ QDomElement gElem = gNodes .at ( 0 ).toElement ();
1984
+ geom = QgsGeometry::fromGML2 ( gElem );
1985
+ geomOk = true ;
1986
+ }
1987
+ }
1988
+
1989
+ if ( !geomOk )
1990
+ {
1991
+ QDomNodeList gNodes = element.elementsByTagName ( " MultiLineString" );
1992
+ if ( gNodes .size () > 0 ) {
1993
+ QDomElement gElem = gNodes .at ( 0 ).toElement ();
1994
+ geom = QgsGeometry::fromGML2 ( gElem );
1995
+ geomOk = true ;
1996
+ }
1997
+ }
1998
+
1999
+ if ( !geomOk )
2000
+ {
2001
+ QDomNodeList gNodes = element.elementsByTagName ( " MultiPoint" );
2002
+ if ( gNodes .size () > 0 ) {
2003
+ QDomElement gElem = gNodes .at ( 0 ).toElement ();
2004
+ geom = QgsGeometry::fromGML2 ( gElem );
2005
+ geomOk = true ;
2006
+ }
2007
+ }
2008
+
2009
+ if ( !geomOk )
2010
+ {
2011
+ QDomNodeList gNodes = element.elementsByTagName ( " Polygon" );
2012
+ if ( gNodes .size () > 0 ) {
2013
+ QDomElement gElem = gNodes .at ( 0 ).toElement ();
2014
+ geom = QgsGeometry::fromGML2 ( gElem );
2015
+ geomOk = true ;
2016
+ }
2017
+ }
2018
+
2019
+ if ( !geomOk )
2020
+ {
2021
+ QDomNodeList gNodes = element.elementsByTagName ( " LineString" );
2022
+ if ( gNodes .size () > 0 ) {
2023
+ QDomElement gElem = gNodes .at ( 0 ).toElement ();
2024
+ geom = QgsGeometry::fromGML2 ( gElem );
2025
+ geomOk = true ;
2026
+ }
2027
+ }
2028
+
2029
+ if ( !geomOk )
2030
+ {
2031
+ QDomNodeList gNodes = element.elementsByTagName ( " Point" );
2032
+ if ( gNodes .size () > 0 ) {
2033
+ QDomElement gElem = gNodes .at ( 0 ).toElement ();
2034
+ geom = QgsGeometry::fromGML2 ( gElem );
2035
+ geomOk = true ;
2036
+ }
2037
+ }
2038
+
2039
+ if ( !geomOk )
2040
+ {
2041
+ errorMessage = QString ( " invalid geometry" );
2042
+ return NULL ;
2043
+ }
2044
+
2045
+ int spatialOpCount = sizeof ( SpatialOgcOperatorText ) / sizeof ( SpatialOgcOperatorText[0 ] );
2046
+ for ( int i = 0 ; i < spatialOpCount; i++ )
2047
+ {
2048
+ QString ogcOperatorName = SpatialOgcOperatorText[ i ];
2049
+ if ( ogcOperatorName.isEmpty () )
2050
+ continue ;
2051
+
2052
+ if ( element.tagName () != ogcOperatorName )
2053
+ continue ;
2054
+
2055
+ return new QgsExpression::NodeSpatialOperator (( SpatialOperator ) i, geom );
2056
+ }
2057
+ return NULL ;
2058
+ }
2059
+
2060
+ //
2061
+
1874
2062
QVariant QgsExpression::NodeInOperator::eval ( QgsExpression* parent, QgsFeature* f )
1875
2063
{
1876
2064
if ( mList ->count () == 0 )
@@ -2024,7 +2212,7 @@ QgsExpression::Node* QgsExpression::NodeFunction::createFromOgcFilter( QDomEleme
2024
2212
if ( element.isNull () )
2025
2213
return NULL ;
2026
2214
2027
- if ( element.localName () != " Function" )
2215
+ if ( element.tagName () != " Function" )
2028
2216
{
2029
2217
errorMessage = QString ( " ogc:Function expected, got %1" ).arg ( element.tagName () );
2030
2218
return NULL ;
@@ -2116,7 +2304,7 @@ QgsExpression::Node* QgsExpression::NodeLiteral::createFromOgcFilter( QDomElemen
2116
2304
if ( element.isNull () )
2117
2305
return NULL ;
2118
2306
2119
- if ( element.localName () != " Literal" )
2307
+ if ( element.tagName () != " Literal" )
2120
2308
{
2121
2309
errorMessage = QString ( " ogc:Literal expected, got %1" ).arg ( element.tagName () );
2122
2310
return NULL ;
@@ -2223,7 +2411,7 @@ QgsExpression::Node* QgsExpression::NodeColumnRef::createFromOgcFilter( QDomElem
2223
2411
if ( element.isNull () )
2224
2412
return NULL ;
2225
2413
2226
- if ( element.localName () != " PropertyName" )
2414
+ if ( element.tagName () != " PropertyName" )
2227
2415
{
2228
2416
errorMessage = QString ( " ogc:PropertyName expected, got %1" ).arg ( element.tagName () );
2229
2417
return NULL ;
0 commit comments