Skip to content

Commit ba47c9f

Browse files
committed
Fix #9520 (bbox filter doesn't work applied on a WFS datasource)
Currently the bbox must have syntax bbox($geometry, geomFromWKT('...'))
1 parent 1607759 commit ba47c9f

File tree

3 files changed

+57
-5
lines changed

3 files changed

+57
-5
lines changed

src/core/qgsogcutils.cpp

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2100,15 +2100,61 @@ static bool isGeometryColumn( const QgsExpression::Node* node )
21002100
return fd->name() == "$geometry";
21012101
}
21022102

2103+
static QgsGeometry* geometryFromConstExpr( const QgsExpression::Node* node )
2104+
{
2105+
// Right now we support only geomFromWKT(' ..... ')
2106+
// Ideally we should support any constant sub-expression (not dependant on feature's geometry or attributes)
2107+
2108+
if ( node->nodeType() == QgsExpression::ntFunction )
2109+
{
2110+
const QgsExpression::NodeFunction* fnNode = static_cast<const QgsExpression::NodeFunction*>( node );
2111+
QgsExpression::Function* fnDef = QgsExpression::Functions()[fnNode->fnIndex()];
2112+
if ( fnDef->name() == "geomFromWKT" )
2113+
{
2114+
const QList<QgsExpression::Node*>& args = fnNode->args()->list();
2115+
if ( args[0]->nodeType() == QgsExpression::ntLiteral )
2116+
{
2117+
QString wkt = static_cast<const QgsExpression::NodeLiteral*>( args[0] )->value().toString();
2118+
return QgsGeometry::fromWkt( wkt );
2119+
}
2120+
}
2121+
}
2122+
return 0;
2123+
}
2124+
21032125

21042126
QDomElement QgsOgcUtils::expressionFunctionToOgcFilter( const QgsExpression::NodeFunction* node, QDomDocument& doc, QString& errorMessage )
21052127
{
21062128
QgsExpression::Function* fd = QgsExpression::Functions()[node->fnIndex()];
21072129

21082130
if ( fd->name() == "bbox" )
21092131
{
2110-
errorMessage = QString( "<BBOX> is currently not supported." );
2111-
return QDomElement();
2132+
QList<QgsExpression::Node*> argNodes = node->args()->list();
2133+
Q_ASSERT( argNodes.count() == 2 ); // binary spatial ops must have two args
2134+
2135+
QgsGeometry* geom = geometryFromConstExpr( argNodes[1] );
2136+
if ( geom && isGeometryColumn( argNodes[0] ) )
2137+
{
2138+
QgsRectangle rect = geom->boundingBox();
2139+
delete geom;
2140+
2141+
QDomElement elemBox = rectangleToGMLBox( &rect, doc );
2142+
2143+
QDomElement geomProperty = doc.createElement( "ogc:PropertyName" );
2144+
geomProperty.appendChild( doc.createTextNode( "geometry" ) );
2145+
2146+
QDomElement funcElem = doc.createElement( "ogr:BBOX" );
2147+
funcElem.appendChild( geomProperty );
2148+
funcElem.appendChild( elemBox );
2149+
return funcElem;
2150+
}
2151+
else
2152+
{
2153+
delete geom;
2154+
2155+
errorMessage = QString( "<BBOX> is currently supported only in form: bbox($geometry, geomFromWKT('...'))" );
2156+
return QDomElement();
2157+
}
21122158
}
21132159

21142160
if ( isBinarySpatialOperator( fd->name() ) )

src/providers/wfs/qgswfscapabilities.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "qgswfscapabilities.h"
1616
#include "qgsexpression.h"
1717
#include "qgslogger.h"
18+
#include "qgsmessagelog.h"
1819
#include "qgsnetworkaccessmanager.h"
1920
#include "qgsogcutils.h"
2021
#include <QDomDocument>
@@ -104,7 +105,12 @@ QString QgsWFSCapabilities::uriGetFeature( QString typeName, QString crsString,
104105
{
105106
//if not, if must be a QGIS expression
106107
QgsExpression filterExpression( filter );
107-
QDomElement filterElem = QgsOgcUtils::expressionToOgcFilter( filterExpression, filterDoc );
108+
QString errorMsg;
109+
QDomElement filterElem = QgsOgcUtils::expressionToOgcFilter( filterExpression, filterDoc, &errorMsg );
110+
if ( !errorMsg.isEmpty() )
111+
{
112+
QgsMessageLog::logMessage( "Expression to OGC Filter error: " + errorMsg, "WFS" );
113+
}
108114
if ( !filterElem.isNull() )
109115
{
110116
filterDoc.appendChild( filterElem );

src/providers/wfs/qgswfsprovider.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ QgsWFSProvider::QgsWFSProvider( const QString& uri )
111111
setDataSourceUri( bkUri );
112112
}
113113

114-
if ( ! uri.contains( "BBOX" ) )
114+
if ( ! uri.contains( "BBOX=" ) )
115115
{ //"Cache Features" option; get all features in layer immediately
116116
reloadData();
117117
} //otherwise, defer feature retrieval until layer is first rendered
@@ -241,7 +241,7 @@ QgsFeatureIterator QgsWFSProvider::getFeatures( const QgsFeatureRequest& request
241241
//ctor cannot initialize because layer object not available then
242242
if ( ! mInitGro )
243243
{ //did user check "Cache Features" in WFS layer source selection?
244-
if ( dsURI.contains( "BBOX" ) )
244+
if ( dsURI.contains( "BBOX=" ) )
245245
{ //no: initialize incremental getFeature
246246
if ( initGetRenderedOnly( rect ) )
247247
{

0 commit comments

Comments
 (0)