Skip to content

Commit

Permalink
Support for static expression functions in WFS filters
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kuhn committed Aug 24, 2018
1 parent c709f18 commit 9abd6d3
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 34 deletions.
73 changes: 46 additions & 27 deletions src/core/qgsogcutils.cpp
Expand Up @@ -22,6 +22,7 @@
#include "qgswkbptr.h"
#include "qgscoordinatereferencesystem.h"
#include "qgsrectangle.h"
#include "qgsproject.h"

#include <QColor>
#include <QStringList>
Expand Down Expand Up @@ -2145,7 +2146,7 @@ QDomElement QgsOgcUtils::expressionToOgcExpression( const QgsExpression &exp, QD
QStringLiteral( "geometry" ), QString(), false, false, errorMessage );
}

QDomElement QgsOgcUtils::expressionToOgcFilter( const QgsExpression &exp,
QDomElement QgsOgcUtils::expressionToOgcFilter( const QgsExpression &expression,
QDomDocument &doc,
GMLVersion gmlVersion,
FilterVersion filterVersion,
Expand All @@ -2155,11 +2156,15 @@ QDomElement QgsOgcUtils::expressionToOgcFilter( const QgsExpression &exp,
bool invertAxisOrientation,
QString *errorMessage )
{
if ( !exp.rootNode() )
if ( !expression.rootNode() )
return QDomElement();

QgsExpression exp = expression;

QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope() << QgsExpressionContextUtils::projectScope( QgsProject::instance() );
QgsOgcUtilsExprToFilter utils( doc, gmlVersion, filterVersion, geometryName, srsName, honourAxisOrientation, invertAxisOrientation );
QDomElement exprRootElem = utils.expressionNodeToOgcFilter( exp.rootNode() );
QDomElement exprRootElem = utils.expressionNodeToOgcFilter( exp.rootNode(), &exp, &context );
if ( errorMessage )
*errorMessage = utils.errorMessage();
if ( exprRootElem.isNull() )
Expand All @@ -2182,7 +2187,7 @@ QDomElement QgsOgcUtils::expressionToOgcFilter( const QgsExpression &exp,
return filterElem;
}

QDomElement QgsOgcUtils::expressionToOgcExpression( const QgsExpression &exp,
QDomElement QgsOgcUtils::expressionToOgcExpression( const QgsExpression &expression,
QDomDocument &doc,
GMLVersion gmlVersion,
FilterVersion filterVersion,
Expand All @@ -2192,6 +2197,11 @@ QDomElement QgsOgcUtils::expressionToOgcExpression( const QgsExpression &exp,
bool invertAxisOrientation,
QString *errorMessage )
{
QgsExpressionContext context;
context << QgsExpressionContextUtils::globalScope() << QgsExpressionContextUtils::projectScope( QgsProject::instance() );

QgsExpression exp = expression;

const QgsExpressionNode *node = exp.rootNode();
if ( !node )
return QDomElement();
Expand All @@ -2203,7 +2213,7 @@ QDomElement QgsOgcUtils::expressionToOgcExpression( const QgsExpression &exp,
case QgsExpressionNode::ntColumnRef:
{
QgsOgcUtilsExprToFilter utils( doc, gmlVersion, filterVersion, geometryName, srsName, honourAxisOrientation, invertAxisOrientation );
QDomElement exprRootElem = utils.expressionNodeToOgcFilter( node );
QDomElement exprRootElem = utils.expressionNodeToOgcFilter( node, &exp, &context );

if ( errorMessage )
*errorMessage = utils.errorMessage();
Expand Down Expand Up @@ -2266,34 +2276,32 @@ QDomElement QgsOgcUtils::SQLStatementToOgcFilter( const QgsSQLStatement &stateme
//


QDomElement QgsOgcUtilsExprToFilter::expressionNodeToOgcFilter( const QgsExpressionNode *node )
QDomElement QgsOgcUtilsExprToFilter::expressionNodeToOgcFilter( const QgsExpressionNode *node, QgsExpression *expression, const QgsExpressionContext *context )
{
switch ( node->nodeType() )
{
case QgsExpressionNode::ntUnaryOperator:
return expressionUnaryOperatorToOgcFilter( static_cast<const QgsExpressionNodeUnaryOperator *>( node ) );
return expressionUnaryOperatorToOgcFilter( static_cast<const QgsExpressionNodeUnaryOperator *>( node ), expression, context );
case QgsExpressionNode::ntBinaryOperator:
return expressionBinaryOperatorToOgcFilter( static_cast<const QgsExpressionNodeBinaryOperator *>( node ) );
return expressionBinaryOperatorToOgcFilter( static_cast<const QgsExpressionNodeBinaryOperator *>( node ), expression, context );
case QgsExpressionNode::ntInOperator:
return expressionInOperatorToOgcFilter( static_cast<const QgsExpressionNodeInOperator *>( node ) );
return expressionInOperatorToOgcFilter( static_cast<const QgsExpressionNodeInOperator *>( node ), expression, context );
case QgsExpressionNode::ntFunction:
return expressionFunctionToOgcFilter( static_cast<const QgsExpressionNodeFunction *>( node ) );
return expressionFunctionToOgcFilter( static_cast<const QgsExpressionNodeFunction *>( node ), expression, context );
case QgsExpressionNode::ntLiteral:
return expressionLiteralToOgcFilter( static_cast<const QgsExpressionNodeLiteral *>( node ) );
return expressionLiteralToOgcFilter( static_cast<const QgsExpressionNodeLiteral *>( node ), expression, context );
case QgsExpressionNode::ntColumnRef:
return expressionColumnRefToOgcFilter( static_cast<const QgsExpressionNodeColumnRef *>( node ) );
return expressionColumnRefToOgcFilter( static_cast<const QgsExpressionNodeColumnRef *>( node ), expression, context );

default:
mErrorMessage = QObject::tr( "Node type not supported: %1" ).arg( node->nodeType() );
return QDomElement();
}
}


QDomElement QgsOgcUtilsExprToFilter::expressionUnaryOperatorToOgcFilter( const QgsExpressionNodeUnaryOperator *node )
QDomElement QgsOgcUtilsExprToFilter::expressionUnaryOperatorToOgcFilter( const QgsExpressionNodeUnaryOperator *node, QgsExpression *expression, const QgsExpressionContext *context )
{

QDomElement operandElem = expressionNodeToOgcFilter( node->operand() );
QDomElement operandElem = expressionNodeToOgcFilter( node->operand(), expression, context );
if ( !mErrorMessage.isEmpty() )
return QDomElement();

Expand Down Expand Up @@ -2329,9 +2337,9 @@ QDomElement QgsOgcUtilsExprToFilter::expressionUnaryOperatorToOgcFilter( const Q
}


QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const QgsExpressionNodeBinaryOperator *node )
QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const QgsExpressionNodeBinaryOperator *node, QgsExpression *expression, const QgsExpressionContext *context )
{
QDomElement leftElem = expressionNodeToOgcFilter( node->opLeft() );
QDomElement leftElem = expressionNodeToOgcFilter( node->opLeft(), expression, context );
if ( !mErrorMessage.isEmpty() )
return QDomElement();

Expand Down Expand Up @@ -2365,7 +2373,7 @@ QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const

}

QDomElement rightElem = expressionNodeToOgcFilter( node->opRight() );
QDomElement rightElem = expressionNodeToOgcFilter( node->opRight(), expression, context );
if ( !mErrorMessage.isEmpty() )
return QDomElement();

Expand Down Expand Up @@ -2401,8 +2409,10 @@ QDomElement QgsOgcUtilsExprToFilter::expressionBinaryOperatorToOgcFilter( const
}


QDomElement QgsOgcUtilsExprToFilter::expressionLiteralToOgcFilter( const QgsExpressionNodeLiteral *node )
QDomElement QgsOgcUtilsExprToFilter::expressionLiteralToOgcFilter( const QgsExpressionNodeLiteral *node, QgsExpression *expression, const QgsExpressionContext *context )
{
Q_UNUSED( expression )
Q_UNUSED( context )
QString value;
switch ( node->value().type() )
{
Expand Down Expand Up @@ -2433,26 +2443,28 @@ QDomElement QgsOgcUtilsExprToFilter::expressionLiteralToOgcFilter( const QgsExpr
}


QDomElement QgsOgcUtilsExprToFilter::expressionColumnRefToOgcFilter( const QgsExpressionNodeColumnRef *node )
QDomElement QgsOgcUtilsExprToFilter::expressionColumnRefToOgcFilter( const QgsExpressionNodeColumnRef *node, QgsExpression *expression, const QgsExpressionContext *context )
{
Q_UNUSED( expression )
Q_UNUSED( context )
QDomElement propElem = mDoc.createElement( mFilterPrefix + ":" + mPropertyName );
propElem.appendChild( mDoc.createTextNode( node->name() ) );
return propElem;
}



QDomElement QgsOgcUtilsExprToFilter::expressionInOperatorToOgcFilter( const QgsExpressionNodeInOperator *node )
QDomElement QgsOgcUtilsExprToFilter::expressionInOperatorToOgcFilter( const QgsExpressionNodeInOperator *node, QgsExpression *expression, const QgsExpressionContext *context )
{
if ( node->list()->list().size() == 1 )
return expressionNodeToOgcFilter( node->list()->list()[0] );
return expressionNodeToOgcFilter( node->list()->list()[0], expression, context );

QDomElement orElem = mDoc.createElement( mFilterPrefix + ":Or" );
QDomElement leftNode = expressionNodeToOgcFilter( node->node() );
QDomElement leftNode = expressionNodeToOgcFilter( node->node(), expression, context );

Q_FOREACH ( QgsExpressionNode *n, node->list()->list() )
{
QDomElement listNode = expressionNodeToOgcFilter( n );
QDomElement listNode = expressionNodeToOgcFilter( n, expression, context );
if ( !mErrorMessage.isEmpty() )
return QDomElement();

Expand Down Expand Up @@ -2527,7 +2539,7 @@ static QgsGeometry geometryFromConstExpr( const QgsExpressionNode *node )
}


QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExpressionNodeFunction *node )
QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExpressionNodeFunction *node, QgsExpression *expression, const QgsExpressionContext *context )
{
QgsExpressionFunction *fd = QgsExpression::Functions()[node->fnIndex()];

Expand Down Expand Up @@ -2639,6 +2651,13 @@ QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExp
return funcElem;
}

if ( fd->isStatic( node, expression, context ) )
{
QVariant result = fd->run( node->args(), context, expression, node );
QgsExpressionNodeLiteral literal( result );
return expressionLiteralToOgcFilter( &literal, expression, context );
}

if ( fd->params() == 0 )
{
mErrorMessage = QObject::tr( "Special columns/constants are not supported." );
Expand All @@ -2650,7 +2669,7 @@ QDomElement QgsOgcUtilsExprToFilter::expressionFunctionToOgcFilter( const QgsExp
funcElem.setAttribute( QStringLiteral( "name" ), fd->name() );
Q_FOREACH ( QgsExpressionNode *n, node->args()->list() )
{
QDomElement childElem = expressionNodeToOgcFilter( n );
QDomElement childElem = expressionNodeToOgcFilter( n, expression, context );
if ( !mErrorMessage.isEmpty() )
return QDomElement();

Expand Down
14 changes: 7 additions & 7 deletions src/core/qgsogcutils.h
Expand Up @@ -338,7 +338,7 @@ class QgsOgcUtilsExprToFilter
bool invertAxisOrientation );

//! Convert an expression to a OGC filter
QDomElement expressionNodeToOgcFilter( const QgsExpressionNode *node );
QDomElement expressionNodeToOgcFilter( const QgsExpressionNode *node, QgsExpression *expression, const QgsExpressionContext *context );

//! Returns whether the gml: namespace is used
bool GMLNamespaceUsed() const { return mGMLUsed; }
Expand All @@ -359,12 +359,12 @@ class QgsOgcUtilsExprToFilter
QString mPropertyName;
int mGeomId;

QDomElement expressionUnaryOperatorToOgcFilter( const QgsExpressionNodeUnaryOperator *node );
QDomElement expressionBinaryOperatorToOgcFilter( const QgsExpressionNodeBinaryOperator *node );
QDomElement expressionLiteralToOgcFilter( const QgsExpressionNodeLiteral *node );
QDomElement expressionColumnRefToOgcFilter( const QgsExpressionNodeColumnRef *node );
QDomElement expressionInOperatorToOgcFilter( const QgsExpressionNodeInOperator *node );
QDomElement expressionFunctionToOgcFilter( const QgsExpressionNodeFunction *node );
QDomElement expressionUnaryOperatorToOgcFilter( const QgsExpressionNodeUnaryOperator *node, QgsExpression *expression, const QgsExpressionContext *context );
QDomElement expressionBinaryOperatorToOgcFilter( const QgsExpressionNodeBinaryOperator *node, QgsExpression *expression, const QgsExpressionContext *context );
QDomElement expressionLiteralToOgcFilter( const QgsExpressionNodeLiteral *node, QgsExpression *expression, const QgsExpressionContext *context );
QDomElement expressionColumnRefToOgcFilter( const QgsExpressionNodeColumnRef *node, QgsExpression *expression, const QgsExpressionContext *context );
QDomElement expressionInOperatorToOgcFilter( const QgsExpressionNodeInOperator *node, QgsExpression *expression, const QgsExpressionContext *context );
QDomElement expressionFunctionToOgcFilter( const QgsExpressionNodeFunction *node, QgsExpression *expression, const QgsExpressionContext *context );
};

/**
Expand Down

0 comments on commit 9abd6d3

Please sign in to comment.