@@ -1666,6 +1666,10 @@ static int binaryOperatorFromTagName( const QString& tagName )
16661666
16671667static QString binaryOperatorToTagName ( QgsExpression::BinaryOperator op )
16681668{
1669+ if ( op == QgsExpression::boILike )
1670+ {
1671+ return " PropertyIsLike" ;
1672+ }
16691673 return binaryOperatorsTagNamesMap ().key ( op, QString () );
16701674}
16711675
@@ -1752,6 +1756,11 @@ QgsExpression::NodeBinaryOperator* QgsOgcUtils::nodeBinaryOperatorFromOgcFilter(
17521756 return nullptr ;
17531757 }
17541758
1759+ if ( op == QgsExpression::boLike && element.hasAttribute ( " matchCase" ) && element.attribute ( " matchCase" ) == " false" )
1760+ {
1761+ op = QgsExpression::boILike;
1762+ }
1763+
17551764 QDomElement operandElem = element.firstChildElement ();
17561765 QgsExpression::Node *expr = nodeFromOgcFilter ( operandElem, errorMessage ), *leftOp = expr;
17571766 if ( !expr )
@@ -1772,6 +1781,64 @@ QgsExpression::NodeBinaryOperator* QgsOgcUtils::nodeBinaryOperatorFromOgcFilter(
17721781 return nullptr ;
17731782 }
17741783
1784+ if ( op == QgsExpression::boLike || op == QgsExpression::boILike )
1785+ {
1786+ QString wildCard;
1787+ if ( element.hasAttribute ( " wildCard" ) )
1788+ {
1789+ wildCard = element.attribute ( " wildCard" );
1790+ }
1791+ QString singleChar;
1792+ if ( element.hasAttribute ( " singleChar" ) )
1793+ {
1794+ singleChar = element.attribute ( " singleChar" );
1795+ }
1796+ QString escape = " \\ " ;
1797+ if ( element.hasAttribute ( " escape" ) )
1798+ {
1799+ escape = element.attribute ( " escape" );
1800+ }
1801+ // replace
1802+ QString oprValue = static_cast <const QgsExpression::NodeLiteral*>( opRight )->value ().toString ();
1803+ if ( !wildCard.isEmpty () && wildCard != " %" )
1804+ {
1805+ oprValue.replace ( ' %' , " \\ %" );
1806+ if ( oprValue.startsWith ( wildCard ) )
1807+ {
1808+ oprValue.replace ( 0 , 1 , " %" );
1809+ }
1810+ QRegExp rx ( " [^" + QRegExp::escape ( escape ) + " ](" + QRegExp::escape ( wildCard ) + " )" );
1811+ int pos = 0 ;
1812+ while (( pos = rx.indexIn ( oprValue, pos ) ) != -1 )
1813+ {
1814+ oprValue.replace ( pos + 1 , 1 , " %" );
1815+ pos += 1 ;
1816+ }
1817+ oprValue.replace ( escape + wildCard, wildCard );
1818+ }
1819+ if ( !singleChar.isEmpty () && singleChar != " _" )
1820+ {
1821+ oprValue.replace ( ' _' , " \\ _" );
1822+ if ( oprValue.startsWith ( singleChar ) )
1823+ {
1824+ oprValue.replace ( 0 , 1 , " _" );
1825+ }
1826+ QRegExp rx ( " [^" + QRegExp::escape ( escape ) + " ](" + QRegExp::escape ( singleChar ) + " )" );
1827+ int pos = 0 ;
1828+ while (( pos = rx.indexIn ( oprValue, pos ) ) != -1 )
1829+ {
1830+ oprValue.replace ( pos + 1 , 1 , " _" );
1831+ pos += 1 ;
1832+ }
1833+ oprValue.replace ( escape + singleChar, singleChar );
1834+ }
1835+ if ( !escape.isEmpty () && escape != " \\ " )
1836+ {
1837+ oprValue.replace ( escape + escape, escape );
1838+ }
1839+ opRight = new QgsExpression::NodeLiteral ( oprValue );
1840+ }
1841+
17751842 expr = new QgsExpression::NodeBinaryOperator ( static_cast < QgsExpression::BinaryOperator >( op ), expr, opRight );
17761843 }
17771844
@@ -2289,13 +2356,13 @@ QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const
22892356 if ( op == QgsExpression::boILike )
22902357 boElem.setAttribute ( " matchCase" , " false" );
22912358
2292- // setup wildcards to <ogc:PropertyIsLike>
2359+ // setup wildCards to <ogc:PropertyIsLike>
22932360 boElem.setAttribute ( " wildCard" , " %" );
2294- boElem.setAttribute ( " singleChar" , " ? " );
2361+ boElem.setAttribute ( " singleChar" , " _ " );
22952362 if ( mFilterVersion == QgsOgcUtils::FILTER_OGC_1_0 )
2296- boElem.setAttribute ( " escape" , " ! " );
2363+ boElem.setAttribute ( " escape" , " \\ " );
22972364 else
2298- boElem.setAttribute ( " escapeChar" , " ! " );
2365+ boElem.setAttribute ( " escapeChar" , " \\ " );
22992366 }
23002367
23012368 boElem.appendChild ( leftElem );
@@ -2712,6 +2779,8 @@ QDomElement QgsOgcUtilsSQLStatementToFilter::toOgcFilter( const QgsSQLStatement:
27122779 opText = " PropertyIsGreaterThan" ;
27132780 else if ( op == QgsSQLStatement::boLike )
27142781 opText = " PropertyIsLike" ;
2782+ else if ( op == QgsSQLStatement::boILike )
2783+ opText = " PropertyIsLike" ;
27152784
27162785 if ( opText.isEmpty () )
27172786 {
@@ -2727,13 +2796,13 @@ QDomElement QgsOgcUtilsSQLStatementToFilter::toOgcFilter( const QgsSQLStatement:
27272796 if ( op == QgsSQLStatement::boILike )
27282797 boElem.setAttribute ( " matchCase" , " false" );
27292798
2730- // setup wildcards to <ogc:PropertyIsLike>
2799+ // setup wildCards to <ogc:PropertyIsLike>
27312800 boElem.setAttribute ( " wildCard" , " %" );
2732- boElem.setAttribute ( " singleChar" , " ? " );
2801+ boElem.setAttribute ( " singleChar" , " _ " );
27332802 if ( mFilterVersion == QgsOgcUtils::FILTER_OGC_1_0 )
2734- boElem.setAttribute ( " escape" , " ! " );
2803+ boElem.setAttribute ( " escape" , " \\ " );
27352804 else
2736- boElem.setAttribute ( " escapeChar" , " ! " );
2805+ boElem.setAttribute ( " escapeChar" , " \\ " );
27372806 }
27382807
27392808 boElem.appendChild ( leftElem );
0 commit comments