Skip to content

Commit

Permalink
Fix #9520 (bbox filter doesn't work applied on a WFS datasource)
Browse files Browse the repository at this point in the history
Currently the bbox must have syntax bbox($geometry, geomFromWKT('...'))
  • Loading branch information
wonder-sk committed Feb 16, 2014
1 parent 1607759 commit ba47c9f
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 5 deletions.
50 changes: 48 additions & 2 deletions src/core/qgsogcutils.cpp
Expand Up @@ -2100,15 +2100,61 @@ static bool isGeometryColumn( const QgsExpression::Node* node )
return fd->name() == "$geometry";
}

static QgsGeometry* geometryFromConstExpr( const QgsExpression::Node* node )
{
// Right now we support only geomFromWKT(' ..... ')
// Ideally we should support any constant sub-expression (not dependant on feature's geometry or attributes)

if ( node->nodeType() == QgsExpression::ntFunction )
{
const QgsExpression::NodeFunction* fnNode = static_cast<const QgsExpression::NodeFunction*>( node );
QgsExpression::Function* fnDef = QgsExpression::Functions()[fnNode->fnIndex()];
if ( fnDef->name() == "geomFromWKT" )
{
const QList<QgsExpression::Node*>& args = fnNode->args()->list();
if ( args[0]->nodeType() == QgsExpression::ntLiteral )
{
QString wkt = static_cast<const QgsExpression::NodeLiteral*>( args[0] )->value().toString();
return QgsGeometry::fromWkt( wkt );
}
}
}
return 0;
}


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

if ( fd->name() == "bbox" )
{
errorMessage = QString( "<BBOX> is currently not supported." );
return QDomElement();
QList<QgsExpression::Node*> argNodes = node->args()->list();
Q_ASSERT( argNodes.count() == 2 ); // binary spatial ops must have two args

QgsGeometry* geom = geometryFromConstExpr( argNodes[1] );
if ( geom && isGeometryColumn( argNodes[0] ) )
{
QgsRectangle rect = geom->boundingBox();
delete geom;

QDomElement elemBox = rectangleToGMLBox( &rect, doc );

QDomElement geomProperty = doc.createElement( "ogc:PropertyName" );
geomProperty.appendChild( doc.createTextNode( "geometry" ) );

QDomElement funcElem = doc.createElement( "ogr:BBOX" );
funcElem.appendChild( geomProperty );
funcElem.appendChild( elemBox );
return funcElem;
}
else
{
delete geom;

errorMessage = QString( "<BBOX> is currently supported only in form: bbox($geometry, geomFromWKT('...'))" );
return QDomElement();
}
}

if ( isBinarySpatialOperator( fd->name() ) )
Expand Down
8 changes: 7 additions & 1 deletion src/providers/wfs/qgswfscapabilities.cpp
Expand Up @@ -15,6 +15,7 @@
#include "qgswfscapabilities.h"
#include "qgsexpression.h"
#include "qgslogger.h"
#include "qgsmessagelog.h"
#include "qgsnetworkaccessmanager.h"
#include "qgsogcutils.h"
#include <QDomDocument>
Expand Down Expand Up @@ -104,7 +105,12 @@ QString QgsWFSCapabilities::uriGetFeature( QString typeName, QString crsString,
{
//if not, if must be a QGIS expression
QgsExpression filterExpression( filter );
QDomElement filterElem = QgsOgcUtils::expressionToOgcFilter( filterExpression, filterDoc );
QString errorMsg;
QDomElement filterElem = QgsOgcUtils::expressionToOgcFilter( filterExpression, filterDoc, &errorMsg );
if ( !errorMsg.isEmpty() )
{
QgsMessageLog::logMessage( "Expression to OGC Filter error: " + errorMsg, "WFS" );
}
if ( !filterElem.isNull() )
{
filterDoc.appendChild( filterElem );
Expand Down
4 changes: 2 additions & 2 deletions src/providers/wfs/qgswfsprovider.cpp
Expand Up @@ -111,7 +111,7 @@ QgsWFSProvider::QgsWFSProvider( const QString& uri )
setDataSourceUri( bkUri );
}

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

0 comments on commit ba47c9f

Please sign in to comment.