@@ -1600,6 +1600,11 @@ QColor QgsOgcUtils::colorFromOgcFill( const QDomElement &fillElement )
1600
1600
1601
1601
1602
1602
QgsExpression *QgsOgcUtils::expressionFromOgcFilter ( const QDomElement &element, QgsVectorLayer *layer )
1603
+ {
1604
+ return expressionFromOgcFilter ( element, QgsOgcUtils::FILTER_OGC_1_0, layer );
1605
+ }
1606
+
1607
+ QgsExpression *QgsOgcUtils::expressionFromOgcFilter ( const QDomElement &element, const FilterVersion version, QgsVectorLayer *layer )
1603
1608
{
1604
1609
if ( element.isNull () || !element.hasChildNodes () )
1605
1610
return nullptr ;
@@ -1614,17 +1619,19 @@ QgsExpression *QgsOgcUtils::expressionFromOgcFilter( const QDomElement &element,
1614
1619
return expr;
1615
1620
}
1616
1621
1622
+ QgsOgcUtilsExprFromFilter utils ( version, layer );
1623
+
1617
1624
// then check OGC DOM elements that contain OGC tags specifying
1618
1625
// OGC operators.
1619
1626
QDomElement childElem = element.firstChildElement ();
1620
1627
while ( !childElem.isNull () )
1621
1628
{
1622
- QString errorMsg ;
1623
- QgsExpressionNode *node = nodeFromOgcFilter ( childElem, errorMsg, layer );
1629
+ QgsExpressionNode *node = utils. nodeFromOgcFilter ( childElem ) ;
1630
+
1624
1631
if ( !node )
1625
1632
{
1626
1633
// invalid expression, parser error
1627
- expr->d ->mParserErrorString = errorMsg ;
1634
+ expr->d ->mParserErrorString = utils. errorMessage () ;
1628
1635
return expr;
1629
1636
}
1630
1637
@@ -1647,7 +1654,6 @@ QgsExpression *QgsOgcUtils::expressionFromOgcFilter( const QDomElement &element,
1647
1654
return expr;
1648
1655
}
1649
1656
1650
-
1651
1657
static const QMap<QString, int > BINARY_OPERATORS_TAG_NAMES_MAP
1652
1658
{
1653
1659
// logical
@@ -1701,173 +1707,22 @@ static bool isSpatialOperator( const QString &tagName )
1701
1707
return spatialOps.contains ( tagName );
1702
1708
}
1703
1709
1704
-
1705
-
1706
1710
QgsExpressionNode *QgsOgcUtils::nodeFromOgcFilter ( QDomElement &element, QString &errorMessage, QgsVectorLayer *layer )
1707
1711
{
1708
- if ( element.isNull () )
1709
- return nullptr ;
1710
-
1711
- // check for binary operators
1712
- if ( isBinaryOperator ( element.tagName () ) )
1713
- {
1714
- return nodeBinaryOperatorFromOgcFilter ( element, errorMessage, layer );
1715
- }
1716
-
1717
- // check for spatial operators
1718
- if ( isSpatialOperator ( element.tagName () ) )
1719
- {
1720
- return nodeSpatialOperatorFromOgcFilter ( element, errorMessage );
1721
- }
1722
-
1723
- // check for other OGC operators, convert them to expressions
1724
-
1725
- if ( element.tagName () == QLatin1String ( " Not" ) )
1726
- {
1727
- return nodeNotFromOgcFilter ( element, errorMessage );
1728
- }
1729
- else if ( element.tagName () == QLatin1String ( " PropertyIsNull" ) )
1730
- {
1731
- return nodePropertyIsNullFromOgcFilter ( element, errorMessage );
1732
- }
1733
- else if ( element.tagName () == QLatin1String ( " Literal" ) )
1734
- {
1735
- return nodeLiteralFromOgcFilter ( element, errorMessage, layer );
1736
- }
1737
- else if ( element.tagName () == QLatin1String ( " Function" ) )
1738
- {
1739
- return nodeFunctionFromOgcFilter ( element, errorMessage );
1740
- }
1741
- else if ( element.tagName () == QLatin1String ( " PropertyName" ) )
1742
- {
1743
- return nodeColumnRefFromOgcFilter ( element, errorMessage );
1744
- }
1745
- else if ( element.tagName () == QLatin1String ( " PropertyIsBetween" ) )
1746
- {
1747
- return nodeIsBetweenFromOgcFilter ( element, errorMessage );
1748
- }
1749
-
1750
- errorMessage += QObject::tr ( " unable to convert '%1' element to a valid expression: it is not supported yet or it has invalid arguments" ).arg ( element.tagName () );
1751
- return nullptr ;
1712
+ QgsOgcUtilsExprFromFilter utils ( QgsOgcUtils::FILTER_OGC_1_0, layer );
1713
+ QgsExpressionNode *node = utils.nodeFromOgcFilter ( element );
1714
+ errorMessage = utils.errorMessage ();
1715
+ return node;
1752
1716
}
1753
1717
1754
-
1755
-
1756
1718
QgsExpressionNodeBinaryOperator *QgsOgcUtils::nodeBinaryOperatorFromOgcFilter ( QDomElement &element, QString &errorMessage, QgsVectorLayer *layer )
1757
1719
{
1758
- if ( element.isNull () )
1759
- return nullptr ;
1760
-
1761
- int op = binaryOperatorFromTagName ( element.tagName () );
1762
- if ( op < 0 )
1763
- {
1764
- if ( errorMessage.isEmpty () )
1765
- errorMessage = QObject::tr ( " '%1' binary operator not supported." ).arg ( element.tagName () );
1766
- return nullptr ;
1767
- }
1768
-
1769
- if ( op == QgsExpressionNodeBinaryOperator::boLike && element.hasAttribute ( QStringLiteral ( " matchCase" ) ) && element.attribute ( QStringLiteral ( " matchCase" ) ) == QLatin1String ( " false" ) )
1770
- {
1771
- op = QgsExpressionNodeBinaryOperator::boILike;
1772
- }
1773
-
1774
- QDomElement operandElem = element.firstChildElement ();
1775
- QgsExpressionNode *expr = nodeFromOgcFilter ( operandElem, errorMessage, layer ), *leftOp = expr;
1776
- if ( !expr )
1777
- {
1778
- if ( errorMessage.isEmpty () )
1779
- errorMessage = QObject::tr ( " invalid left operand for '%1' binary operator" ).arg ( element.tagName () );
1780
- return nullptr ;
1781
- }
1782
-
1783
- for ( operandElem = operandElem.nextSiblingElement (); !operandElem.isNull (); operandElem = operandElem.nextSiblingElement () )
1784
- {
1785
- QgsExpressionNode *opRight = nodeFromOgcFilter ( operandElem, errorMessage, layer );
1786
- if ( !opRight )
1787
- {
1788
- if ( errorMessage.isEmpty () )
1789
- errorMessage = QObject::tr ( " invalid right operand for '%1' binary operator" ).arg ( element.tagName () );
1790
- delete expr;
1791
- return nullptr ;
1792
- }
1793
-
1794
- if ( op == QgsExpressionNodeBinaryOperator::boLike || op == QgsExpressionNodeBinaryOperator::boILike )
1795
- {
1796
- QString wildCard;
1797
- if ( element.hasAttribute ( QStringLiteral ( " wildCard" ) ) )
1798
- {
1799
- wildCard = element.attribute ( QStringLiteral ( " wildCard" ) );
1800
- }
1801
- QString singleChar;
1802
- if ( element.hasAttribute ( QStringLiteral ( " singleChar" ) ) )
1803
- {
1804
- singleChar = element.attribute ( QStringLiteral ( " singleChar" ) );
1805
- }
1806
- QString escape = QStringLiteral ( " \\ " );
1807
- if ( element.hasAttribute ( QStringLiteral ( " escape" ) ) )
1808
- {
1809
- escape = element.attribute ( QStringLiteral ( " escape" ) );
1810
- }
1811
- // replace
1812
- QString oprValue = static_cast <const QgsExpressionNodeLiteral *>( opRight )->value ().toString ();
1813
- if ( !wildCard.isEmpty () && wildCard != QLatin1String ( " %" ) )
1814
- {
1815
- oprValue.replace ( ' %' , QLatin1String ( " \\ %" ) );
1816
- if ( oprValue.startsWith ( wildCard ) )
1817
- {
1818
- oprValue.replace ( 0 , 1 , QStringLiteral ( " %" ) );
1819
- }
1820
- QRegExp rx ( " [^" + QRegExp::escape ( escape ) + " ](" + QRegExp::escape ( wildCard ) + " )" );
1821
- int pos = 0 ;
1822
- while ( ( pos = rx.indexIn ( oprValue, pos ) ) != -1 )
1823
- {
1824
- oprValue.replace ( pos + 1 , 1 , QStringLiteral ( " %" ) );
1825
- pos += 1 ;
1826
- }
1827
- oprValue.replace ( escape + wildCard, wildCard );
1828
- }
1829
- if ( !singleChar.isEmpty () && singleChar != QLatin1String ( " _" ) )
1830
- {
1831
- oprValue.replace ( ' _' , QLatin1String ( " \\ _" ) );
1832
- if ( oprValue.startsWith ( singleChar ) )
1833
- {
1834
- oprValue.replace ( 0 , 1 , QStringLiteral ( " _" ) );
1835
- }
1836
- QRegExp rx ( " [^" + QRegExp::escape ( escape ) + " ](" + QRegExp::escape ( singleChar ) + " )" );
1837
- int pos = 0 ;
1838
- while ( ( pos = rx.indexIn ( oprValue, pos ) ) != -1 )
1839
- {
1840
- oprValue.replace ( pos + 1 , 1 , QStringLiteral ( " _" ) );
1841
- pos += 1 ;
1842
- }
1843
- oprValue.replace ( escape + singleChar, singleChar );
1844
- }
1845
- if ( !escape.isEmpty () && escape != QLatin1String ( " \\ " ) )
1846
- {
1847
- oprValue.replace ( escape + escape, escape );
1848
- }
1849
- opRight = new QgsExpressionNodeLiteral ( oprValue );
1850
- }
1851
-
1852
- expr = new QgsExpressionNodeBinaryOperator ( static_cast < QgsExpressionNodeBinaryOperator::BinaryOperator >( op ), expr, opRight );
1853
- }
1854
-
1855
- if ( expr == leftOp )
1856
- {
1857
- if ( errorMessage.isEmpty () )
1858
- errorMessage = QObject::tr ( " only one operand for '%1' binary operator" ).arg ( element.tagName () );
1859
- delete expr;
1860
- return nullptr ;
1861
- }
1862
-
1863
- QgsExpressionNodeBinaryOperator *ret = dynamic_cast < QgsExpressionNodeBinaryOperator * >( expr );
1864
- if ( !ret )
1865
- delete expr;
1866
-
1867
- return ret;
1720
+ QgsOgcUtilsExprFromFilter utils ( QgsOgcUtils::FILTER_OGC_1_0, layer );
1721
+ QgsExpressionNode *node = utils.nodeBinaryOperatorFromOgcFilter ( element );
1722
+ errorMessage = utils.errorMessage ();
1723
+ retur node;
1868
1724
}
1869
1725
1870
-
1871
1726
QgsExpressionNodeFunction *QgsOgcUtils::nodeSpatialOperatorFromOgcFilter ( QDomElement &element, QString &errorMessage )
1872
1727
{
1873
1728
// we are exploiting the fact that our function names are the same as the XML tag names
@@ -1963,103 +1818,19 @@ QgsExpressionNodeFunction *QgsOgcUtils::nodeFunctionFromOgcFilter( QDomElement &
1963
1818
1964
1819
QgsExpressionNode *QgsOgcUtils::nodeLiteralFromOgcFilter ( QDomElement &element, QString &errorMessage, QgsVectorLayer *layer )
1965
1820
{
1966
- if ( element.isNull () || element.tagName () != QLatin1String ( " Literal" ) )
1967
- {
1968
- errorMessage = QObject::tr ( " ogc:Literal expected, got %1" ).arg ( element.tagName () );
1969
- return nullptr ;
1970
- }
1971
-
1972
- QgsExpressionNode *root = nullptr ;
1973
-
1974
- // the literal content can have more children (e.g. CDATA section, text, ...)
1975
- QDomNode childNode = element.firstChild ();
1976
- while ( !childNode.isNull () )
1977
- {
1978
- QgsExpressionNode *operand = nullptr ;
1979
-
1980
- if ( childNode.nodeType () == QDomNode::ElementNode )
1981
- {
1982
- // found a element node (e.g. PropertyName), convert it
1983
- QDomElement operandElem = childNode.toElement ();
1984
- operand = nodeFromOgcFilter ( operandElem, errorMessage, layer );
1985
- if ( !operand )
1986
- {
1987
- delete root;
1988
-
1989
- errorMessage = QObject::tr ( " '%1' is an invalid or not supported content for ogc:Literal" ).arg ( operandElem.tagName () );
1990
- return nullptr ;
1991
- }
1992
- }
1993
- else
1994
- {
1995
- // probably a text/CDATA node
1996
- QVariant value = childNode.nodeValue ();
1997
-
1998
- bool converted = false ;
1999
-
2000
- // try to convert the node content to corresponding field type if possible
2001
- if ( layer != nullptr )
2002
- {
2003
- QDomElement propertyNameElement = element.previousSiblingElement ( QLatin1String ( " PropertyName" ) );
2004
- if ( propertyNameElement.isNull () || propertyNameElement.tagName () != QLatin1String ( " PropertyName" ) )
2005
- {
2006
- propertyNameElement = element.nextSiblingElement ( QLatin1String ( " PropertyName" ) );
2007
- }
2008
- if ( !propertyNameElement.isNull () || propertyNameElement.tagName () == QLatin1String ( " PropertyName" ) )
2009
- {
2010
- int fieldIndex = layer->fields ().indexOf ( propertyNameElement.firstChild ().nodeValue () );
2011
- if ( fieldIndex != -1 )
2012
- {
2013
- QgsField field = layer->fields ().field ( propertyNameElement.firstChild ().nodeValue () );
2014
- field.convertCompatible ( value );
2015
- converted = true ;
2016
- }
2017
- }
2018
- }
2019
- if ( !converted )
2020
- {
2021
- // try to convert the node content to number if possible,
2022
- // otherwise let's use it as string
2023
- bool ok;
2024
- double d = value.toDouble ( &ok );
2025
- if ( ok )
2026
- value = d;
2027
- }
2028
-
2029
- operand = new QgsExpressionNodeLiteral ( value );
2030
- if ( !operand )
2031
- continue ;
2032
- }
2033
-
2034
- // use the concat operator to merge the ogc:Literal children
2035
- if ( !root )
2036
- {
2037
- root = operand;
2038
- }
2039
- else
2040
- {
2041
- root = new QgsExpressionNodeBinaryOperator ( QgsExpressionNodeBinaryOperator::boConcat, root, operand );
2042
- }
2043
-
2044
- childNode = childNode.nextSibling ();
2045
- }
2046
-
2047
- if ( root )
2048
- return root;
2049
-
2050
- return nullptr ;
1821
+ QgsOgcUtilsExprFromFilter utils ( QgsOgcUtils::FILTER_OGC_1_0, layer );
1822
+ QgsExpressionNode *node = utils.nodeLiteralFromOgcFilter ( element );
1823
+ errorMessage = utils.errorMessage ();
1824
+ return node;
2051
1825
}
2052
1826
2053
1827
2054
1828
QgsExpressionNodeColumnRef *QgsOgcUtils::nodeColumnRefFromOgcFilter ( QDomElement &element, QString &errorMessage )
2055
1829
{
2056
- if ( element.isNull () || element.tagName () != QLatin1String ( " PropertyName" ) )
2057
- {
2058
- errorMessage = QObject::tr ( " ogc:PropertyName expected, got %1" ).arg ( element.tagName () );
2059
- return nullptr ;
2060
- }
2061
-
2062
- return new QgsExpressionNodeColumnRef ( element.firstChild ().nodeValue () );
1830
+ QgsOgcUtilsExprFromFilter utils ( QgsOgcUtils::FILTER_OGC_1_0 );
1831
+ QgsExpressionNode *node = utils.nodeColumnRefFromOgcFilter ( element );
1832
+ errorMessage = utils.errorMessage ();
1833
+ return node;
2063
1834
}
2064
1835
2065
1836
@@ -3443,3 +3214,312 @@ QDomElement QgsOgcUtilsSQLStatementToFilter::toOgcFilter( const QgsSQLStatement:
3443
3214
3444
3215
return QDomElement ();
3445
3216
}
3217
+
3218
+ QgsOgcUtilsExprFromFilter::QgsOgcUtilsExprFromFilter ( const QgsOgcUtils::FilterVersion version, QgsVectorLayer *layer )
3219
+ : mVersion( version )
3220
+ , mLayer( layer )
3221
+ {
3222
+ mPropertyName = QStringLiteral ( " PropertyName" );
3223
+
3224
+ if ( version == QgsOgcUtils::FILTER_FES_2_0 )
3225
+ mPropertyName = QStringLiteral ( " ValueReference" );
3226
+ }
3227
+
3228
+ QgsExpressionNode *QgsOgcUtilsExprFromFilter::nodeFromOgcFilter ( const QDomElement &element )
3229
+ {
3230
+ if ( element.isNull () )
3231
+ return nullptr ;
3232
+
3233
+ // check for binary operators
3234
+ if ( isBinaryOperator ( element.tagName () ) )
3235
+ {
3236
+ return nodeBinaryOperatorFromOgcFilter ( element );
3237
+ }
3238
+
3239
+ // check for spatial operators
3240
+ if ( isSpatialOperator ( element.tagName () ) )
3241
+ {
3242
+ return nodeSpatialOperatorFromOgcFilter ( element );
3243
+ }
3244
+
3245
+ // check for other OGC operators, convert them to expressions
3246
+
3247
+ if ( element.tagName () == QLatin1String ( " Not" ) )
3248
+ {
3249
+ // return nodeNotFromOgcFilter( element, errorMessage );
3250
+ }
3251
+ else if ( element.tagName () == QLatin1String ( " PropertyIsNull" ) )
3252
+ {
3253
+ // return nodePropertyIsNullFromOgcFilter( element, errorMessage );
3254
+ }
3255
+ else if ( element.tagName () == QLatin1String ( " Literal" ) )
3256
+ {
3257
+ return nodeLiteralFromOgcFilter ( element );
3258
+ }
3259
+ else if ( element.tagName () == QLatin1String ( " Function" ) )
3260
+ {
3261
+ // return nodeFunctionFromOgcFilter( element, errorMessage );
3262
+ }
3263
+ else if ( element.tagName () == mPropertyName )
3264
+ {
3265
+ return nodeColumnRefFromOgcFilter ( element );
3266
+ }
3267
+ else if ( element.tagName () == QLatin1String ( " PropertyIsBetween" ) )
3268
+ {
3269
+ // return nodeIsBetweenFromOgcFilter( element, errorMessage );
3270
+ }
3271
+
3272
+ mErrorMessage += QObject::tr ( " unable to convert '%1' element to a valid expression: it is not supported yet or it has invalid arguments" ).arg ( element.tagName () );
3273
+ return nullptr ;
3274
+ }
3275
+
3276
+ QgsExpressionNodeBinaryOperator *QgsOgcUtilsExprFromFilter::nodeBinaryOperatorFromOgcFilter ( const QDomElement &element )
3277
+ {
3278
+ if ( element.isNull () )
3279
+ return nullptr ;
3280
+
3281
+ int op = binaryOperatorFromTagName ( element.tagName () );
3282
+ if ( op < 0 )
3283
+ {
3284
+ mErrorMessage = QObject::tr ( " '%1' binary operator not supported." ).arg ( element.tagName () );
3285
+ return nullptr ;
3286
+ }
3287
+
3288
+ if ( op == QgsExpressionNodeBinaryOperator::boLike && element.hasAttribute ( QStringLiteral ( " matchCase" ) ) && element.attribute ( QStringLiteral ( " matchCase" ) ) == QLatin1String ( " false" ) )
3289
+ {
3290
+ op = QgsExpressionNodeBinaryOperator::boILike;
3291
+ }
3292
+
3293
+ QDomElement operandElem = element.firstChildElement ();
3294
+ QgsExpressionNode *expr = nodeFromOgcFilter ( operandElem ), *leftOp = expr;
3295
+ if ( !expr )
3296
+ {
3297
+ mErrorMessage = QObject::tr ( " invalid left operand for '%1' binary operator" ).arg ( element.tagName () );
3298
+ return nullptr ;
3299
+ }
3300
+
3301
+ for ( operandElem = operandElem.nextSiblingElement (); !operandElem.isNull (); operandElem = operandElem.nextSiblingElement () )
3302
+ {
3303
+ QgsExpressionNode *opRight = nodeFromOgcFilter ( operandElem );
3304
+ if ( !opRight )
3305
+ {
3306
+ mErrorMessage = QObject::tr ( " invalid right operand for '%1' binary operator" ).arg ( element.tagName () );
3307
+ delete expr;
3308
+ return nullptr ;
3309
+ }
3310
+
3311
+ if ( op == QgsExpressionNodeBinaryOperator::boLike || op == QgsExpressionNodeBinaryOperator::boILike )
3312
+ {
3313
+ QString wildCard;
3314
+ if ( element.hasAttribute ( QStringLiteral ( " wildCard" ) ) )
3315
+ {
3316
+ wildCard = element.attribute ( QStringLiteral ( " wildCard" ) );
3317
+ }
3318
+ QString singleChar;
3319
+ if ( element.hasAttribute ( QStringLiteral ( " singleChar" ) ) )
3320
+ {
3321
+ singleChar = element.attribute ( QStringLiteral ( " singleChar" ) );
3322
+ }
3323
+ QString escape = QStringLiteral ( " \\ " );
3324
+ if ( element.hasAttribute ( QStringLiteral ( " escape" ) ) )
3325
+ {
3326
+ escape = element.attribute ( QStringLiteral ( " escape" ) );
3327
+ }
3328
+ // replace
3329
+ QString oprValue = static_cast <const QgsExpressionNodeLiteral *>( opRight )->value ().toString ();
3330
+ if ( !wildCard.isEmpty () && wildCard != QLatin1String ( " %" ) )
3331
+ {
3332
+ oprValue.replace ( ' %' , QLatin1String ( " \\ %" ) );
3333
+ if ( oprValue.startsWith ( wildCard ) )
3334
+ {
3335
+ oprValue.replace ( 0 , 1 , QStringLiteral ( " %" ) );
3336
+ }
3337
+ QRegExp rx ( " [^" + QRegExp::escape ( escape ) + " ](" + QRegExp::escape ( wildCard ) + " )" );
3338
+ int pos = 0 ;
3339
+ while ( ( pos = rx.indexIn ( oprValue, pos ) ) != -1 )
3340
+ {
3341
+ oprValue.replace ( pos + 1 , 1 , QStringLiteral ( " %" ) );
3342
+ pos += 1 ;
3343
+ }
3344
+ oprValue.replace ( escape + wildCard, wildCard );
3345
+ }
3346
+ if ( !singleChar.isEmpty () && singleChar != QLatin1String ( " _" ) )
3347
+ {
3348
+ oprValue.replace ( ' _' , QLatin1String ( " \\ _" ) );
3349
+ if ( oprValue.startsWith ( singleChar ) )
3350
+ {
3351
+ oprValue.replace ( 0 , 1 , QStringLiteral ( " _" ) );
3352
+ }
3353
+ QRegExp rx ( " [^" + QRegExp::escape ( escape ) + " ](" + QRegExp::escape ( singleChar ) + " )" );
3354
+ int pos = 0 ;
3355
+ while ( ( pos = rx.indexIn ( oprValue, pos ) ) != -1 )
3356
+ {
3357
+ oprValue.replace ( pos + 1 , 1 , QStringLiteral ( " _" ) );
3358
+ pos += 1 ;
3359
+ }
3360
+ oprValue.replace ( escape + singleChar, singleChar );
3361
+ }
3362
+ if ( !escape.isEmpty () && escape != QLatin1String ( " \\ " ) )
3363
+ {
3364
+ oprValue.replace ( escape + escape, escape );
3365
+ }
3366
+ opRight = new QgsExpressionNodeLiteral ( oprValue );
3367
+ }
3368
+
3369
+ expr = new QgsExpressionNodeBinaryOperator ( static_cast < QgsExpressionNodeBinaryOperator::BinaryOperator >( op ), expr, opRight );
3370
+ }
3371
+
3372
+ if ( expr == leftOp )
3373
+ {
3374
+ mErrorMessage = QObject::tr ( " only one operand for '%1' binary operator" ).arg ( element.tagName () );
3375
+ delete expr;
3376
+ return nullptr ;
3377
+ }
3378
+
3379
+ QgsExpressionNodeBinaryOperator *ret = dynamic_cast < QgsExpressionNodeBinaryOperator * >( expr );
3380
+ if ( !ret )
3381
+ delete expr;
3382
+
3383
+ return ret;
3384
+ }
3385
+
3386
+
3387
+ QgsExpressionNodeFunction *QgsOgcUtilsExprFromFilter::nodeSpatialOperatorFromOgcFilter ( const QDomElement &element )
3388
+ {
3389
+ // we are exploiting the fact that our function names are the same as the XML tag names
3390
+ int opIdx = QgsExpression::functionIndex ( element.tagName ().toLower () );
3391
+
3392
+ QgsExpressionNode::NodeList *gml2Args = new QgsExpressionNode::NodeList ();
3393
+ QDomElement childElem = element.firstChildElement ();
3394
+ QString gml2Str;
3395
+ while ( !childElem.isNull () && gml2Str.isEmpty () )
3396
+ {
3397
+ if ( childElem.tagName () != mPropertyName )
3398
+ {
3399
+ QTextStream gml2Stream ( &gml2Str );
3400
+ childElem.save ( gml2Stream, 0 );
3401
+ }
3402
+ childElem = childElem.nextSiblingElement ();
3403
+ }
3404
+ if ( !gml2Str.isEmpty () )
3405
+ {
3406
+ gml2Args->append ( new QgsExpressionNodeLiteral ( QVariant ( gml2Str.remove ( ' \n ' ) ) ) );
3407
+ }
3408
+ else
3409
+ {
3410
+ mErrorMessage = QObject::tr ( " No OGC Geometry found" );
3411
+ delete gml2Args;
3412
+ return nullptr ;
3413
+ }
3414
+
3415
+ QgsExpressionNode::NodeList *opArgs = new QgsExpressionNode::NodeList ();
3416
+ opArgs->append ( new QgsExpressionNodeFunction ( QgsExpression::functionIndex ( QStringLiteral ( " $geometry" ) ), new QgsExpressionNode::NodeList () ) );
3417
+ opArgs->append ( new QgsExpressionNodeFunction ( QgsExpression::functionIndex ( QStringLiteral ( " geomFromGML" ) ), gml2Args ) );
3418
+
3419
+ return new QgsExpressionNodeFunction ( opIdx, opArgs );
3420
+ }
3421
+
3422
+ QgsExpressionNodeColumnRef *QgsOgcUtilsExprFromFilter::nodeColumnRefFromOgcFilter ( const QDomElement &element )
3423
+ {
3424
+ if ( element.isNull () || element.tagName () != mPropertyName )
3425
+ {
3426
+ mErrorMessage = QObject::tr ( " ogc:PropertyName expected, got %1" ).arg ( element.tagName () );
3427
+ return nullptr ;
3428
+ }
3429
+
3430
+ return new QgsExpressionNodeColumnRef ( element.firstChild ().nodeValue () );
3431
+ }
3432
+
3433
+ QgsExpressionNode *QgsOgcUtilsExprFromFilter::nodeLiteralFromOgcFilter ( const QDomElement &element )
3434
+ {
3435
+ if ( element.isNull () || element.tagName () != QLatin1String ( " Literal" ) )
3436
+ {
3437
+ mErrorMessage = QObject::tr ( " ogc:Literal expected, got %1" ).arg ( element.tagName () );
3438
+ return nullptr ;
3439
+ }
3440
+
3441
+ QgsExpressionNode *root = nullptr ;
3442
+
3443
+ // the literal content can have more children (e.g. CDATA section, text, ...)
3444
+ QDomNode childNode = element.firstChild ();
3445
+ while ( !childNode.isNull () )
3446
+ {
3447
+ QgsExpressionNode *operand = nullptr ;
3448
+
3449
+ if ( childNode.nodeType () == QDomNode::ElementNode )
3450
+ {
3451
+ // found a element node (e.g. PropertyName), convert it
3452
+ QDomElement operandElem = childNode.toElement ();
3453
+ operand = nodeFromOgcFilter ( operandElem );
3454
+ if ( !operand )
3455
+ {
3456
+ delete root;
3457
+
3458
+ mErrorMessage = QObject::tr ( " '%1' is an invalid or not supported content for ogc:Literal" ).arg ( operandElem.tagName () );
3459
+ return nullptr ;
3460
+ }
3461
+ }
3462
+ else
3463
+ {
3464
+ // probably a text/CDATA node
3465
+ QVariant value = childNode.nodeValue ();
3466
+
3467
+ bool converted = false ;
3468
+
3469
+ // try to convert the node content to corresponding field type if possible
3470
+ if ( mLayer )
3471
+ {
3472
+ QDomElement propertyNameElement = element.previousSiblingElement ( mPropertyName );
3473
+ if ( propertyNameElement.isNull () || propertyNameElement.tagName () != mPropertyName )
3474
+ {
3475
+ propertyNameElement = element.nextSiblingElement ( mPropertyName );
3476
+ }
3477
+ if ( !propertyNameElement.isNull () || propertyNameElement.tagName () == mPropertyName )
3478
+ {
3479
+ int fieldIndex = mLayer ->fields ().indexOf ( propertyNameElement.firstChild ().nodeValue () );
3480
+ if ( fieldIndex != -1 )
3481
+ {
3482
+ QgsField field = mLayer ->fields ().field ( propertyNameElement.firstChild ().nodeValue () );
3483
+ field.convertCompatible ( value );
3484
+ converted = true ;
3485
+ }
3486
+ }
3487
+ }
3488
+ if ( !converted )
3489
+ {
3490
+ // try to convert the node content to number if possible,
3491
+ // otherwise let's use it as string
3492
+ bool ok;
3493
+ double d = value.toDouble ( &ok );
3494
+ if ( ok )
3495
+ value = d;
3496
+ }
3497
+
3498
+ operand = new QgsExpressionNodeLiteral ( value );
3499
+ if ( !operand )
3500
+ continue ;
3501
+ }
3502
+
3503
+ // use the concat operator to merge the ogc:Literal children
3504
+ if ( !root )
3505
+ {
3506
+ root = operand;
3507
+ }
3508
+ else
3509
+ {
3510
+ root = new QgsExpressionNodeBinaryOperator ( QgsExpressionNodeBinaryOperator::boConcat, root, operand );
3511
+ }
3512
+
3513
+ childNode = childNode.nextSibling ();
3514
+ }
3515
+
3516
+ if ( root )
3517
+ return root;
3518
+
3519
+ return nullptr ;
3520
+ }
3521
+
3522
+ QString QgsOgcUtilsExprFromFilter::errorMessage () const
3523
+ {
3524
+ return mErrorMessage ;
3525
+ }
0 commit comments