mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-28 00:17:30 -05:00
Merge pull request #3863 from rldhont/postgres-compile-expression-functions
[Feature][PostgreSQL] Compile expression functions
This commit is contained in:
commit
f59acade4b
@ -314,11 +314,46 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
if ( rn != Complete && rn != Partial )
|
||||
return rn;
|
||||
|
||||
result = QStringLiteral( "%1 %2IN(%3)" ).arg( nd, n->isNotIn() ? "NOT " : "", list.join( QStringLiteral( "," ) ) );
|
||||
result = QStringLiteral( "%1 %2IN (%3)" ).arg( nd, n->isNotIn() ? "NOT " : "", list.join( QStringLiteral( "," ) ) );
|
||||
return ( inResult == Partial || rn == Partial ) ? Partial : Complete;
|
||||
}
|
||||
|
||||
case QgsExpression::ntFunction:
|
||||
{
|
||||
const QgsExpression::NodeFunction* n = static_cast<const QgsExpression::NodeFunction*>( node );
|
||||
QgsExpression::Function* fd = QgsExpression::Functions()[n->fnIndex()];
|
||||
|
||||
// get sql function to compile node expression
|
||||
QString nd = sqlFunctionFromFunctionName( fd->name() );
|
||||
// if no sql function the node can't be compiled
|
||||
if ( nd.isEmpty() )
|
||||
return Fail;
|
||||
|
||||
// compile arguments
|
||||
QStringList args;
|
||||
Result inResult = Complete;
|
||||
Q_FOREACH ( const QgsExpression::Node* ln, n->args()->list() )
|
||||
{
|
||||
QString s;
|
||||
Result r = compileNode( ln, s );
|
||||
if ( r == Complete || r == Partial )
|
||||
{
|
||||
args << s;
|
||||
if ( r == Partial )
|
||||
inResult = Partial;
|
||||
}
|
||||
else
|
||||
return r;
|
||||
}
|
||||
|
||||
// update arguments to be adapted to SQL function
|
||||
args = sqlArgumentsFromFunctionName( fd->name(), args );
|
||||
|
||||
// build result
|
||||
result = QStringLiteral( "%1(%2)" ).arg( nd, args.join( ',' ) );
|
||||
return inResult == Partial ? Partial : Complete;
|
||||
}
|
||||
|
||||
case QgsExpression::ntCondition:
|
||||
break;
|
||||
}
|
||||
@ -326,6 +361,18 @@ QgsSqlExpressionCompiler::Result QgsSqlExpressionCompiler::compileNode( const Qg
|
||||
return Fail;
|
||||
}
|
||||
|
||||
QString QgsSqlExpressionCompiler::sqlFunctionFromFunctionName( const QString& fnName ) const
|
||||
{
|
||||
Q_UNUSED( fnName );
|
||||
return QString();
|
||||
}
|
||||
|
||||
QStringList QgsSqlExpressionCompiler::sqlArgumentsFromFunctionName( const QString& fnName, const QStringList& fnArgs ) const
|
||||
{
|
||||
Q_UNUSED( fnName );
|
||||
return QStringList( fnArgs );
|
||||
}
|
||||
|
||||
bool QgsSqlExpressionCompiler::nodeIsNullLiteral( const QgsExpression::Node* node ) const
|
||||
{
|
||||
if ( node->nodeType() != QgsExpression::ntLiteral )
|
||||
|
@ -93,6 +93,21 @@ class CORE_EXPORT QgsSqlExpressionCompiler
|
||||
*/
|
||||
virtual Result compileNode( const QgsExpression::Node* node, QString& str );
|
||||
|
||||
/** Return the SQL function for the expression function.
|
||||
* Derived classes should override this to help compile functions
|
||||
* @param fnName expression function name
|
||||
* @returns the SQL function name
|
||||
*/
|
||||
virtual QString sqlFunctionFromFunctionName( const QString& fnName ) const;
|
||||
|
||||
/** Return the Arguments for SQL function for the expression function.
|
||||
* Derived classes should override this to help compile functions
|
||||
* @param fnName expression function name
|
||||
* @param fnArgs arguments from expression
|
||||
* @returns the arguments updated for SQL Function
|
||||
*/
|
||||
virtual QStringList sqlArgumentsFromFunctionName( const QString& fnName, const QStringList& fnArgs ) const;
|
||||
|
||||
QString mResult;
|
||||
QgsFields mFields;
|
||||
|
||||
|
@ -18,6 +18,12 @@
|
||||
|
||||
QgsPostgresExpressionCompiler::QgsPostgresExpressionCompiler( QgsPostgresFeatureSource* source )
|
||||
: QgsSqlExpressionCompiler( source->mFields )
|
||||
, mGeometryColumn( source->mGeometryColumn )
|
||||
, mSpatialColType( source->mSpatialColType )
|
||||
, mDetectedGeomType( source->mDetectedGeomType )
|
||||
, mRequestedGeomType( source->mRequestedGeomType )
|
||||
, mRequestedSrid( source->mRequestedSrid )
|
||||
, mDetectedSrid( source->mDetectedSrid )
|
||||
{
|
||||
}
|
||||
|
||||
@ -32,3 +38,150 @@ QString QgsPostgresExpressionCompiler::quotedValue( const QVariant& value, bool&
|
||||
return QgsPostgresConn::quotedValue( value );
|
||||
}
|
||||
|
||||
static const QMap<QString, QString>& functionNamesSqlFunctionsMap()
|
||||
{
|
||||
static QMap<QString, QString> fnNames;
|
||||
if ( fnNames.isEmpty() )
|
||||
{
|
||||
fnNames =
|
||||
{
|
||||
{ "sqrt", "sqrt" },
|
||||
{ "radians", "radians" },
|
||||
{ "degrees", "degrees" },
|
||||
{ "abs", "abs" },
|
||||
{ "cos", "cos" },
|
||||
{ "sin", "sin" },
|
||||
{ "tan", "tan" },
|
||||
{ "acos", "acos" },
|
||||
{ "asin", "asin" },
|
||||
{ "atan", "atan" },
|
||||
{ "atan2", "atan2" },
|
||||
{ "exp", "exp" },
|
||||
{ "ln", "ln" },
|
||||
{ "log", "log" },
|
||||
{ "log10", "log" },
|
||||
{ "round", "round" },
|
||||
{ "floor", "floor" },
|
||||
{ "ceil", "ceil" },
|
||||
{ "pi", "pi" },
|
||||
// geometry functions
|
||||
//{ "azimuth", "ST_Azimuth" },
|
||||
{ "x", "ST_X" },
|
||||
{ "y", "ST_Y" },
|
||||
//{ "z", "ST_Z" },
|
||||
//{ "m", "ST_M" },
|
||||
{ "x_min", "ST_XMin" },
|
||||
{ "y_min", "ST_YMin" },
|
||||
{ "x_max", "ST_XMax" },
|
||||
{ "y_max", "ST_YMax" },
|
||||
{ "area", "ST_Area" },
|
||||
{ "perimeter", "ST_Perimeter" },
|
||||
{ "relate", "ST_Relate" },
|
||||
{ "disjoint", "ST_Disjoint" },
|
||||
{ "intersects", "ST_Intersects" },
|
||||
//{ "touches", "ST_Touches" },
|
||||
{ "crosses", "ST_Crosses" },
|
||||
{ "contains", "ST_Contains" },
|
||||
{ "overlaps", "ST_Overlaps" },
|
||||
{ "within", "ST_Within" },
|
||||
{ "translate", "ST_Translate" },
|
||||
{ "buffer", "ST_Buffer" },
|
||||
{ "centroid", "ST_Centroid" },
|
||||
{ "point_on_surface", "ST_PointOnSurface" },
|
||||
//{ "reverse", "ST_Reverse" },
|
||||
//{ "is_closed", "ST_IsClosed" },
|
||||
//{ "convex_hull", "ST_ConvexHull" },
|
||||
//{ "difference", "ST_Difference" },
|
||||
{ "distance", "ST_Distance" },
|
||||
//{ "intersection", "ST_Intersection" },
|
||||
//{ "sym_difference", "ST_SymDifference" },
|
||||
//{ "combine", "ST_Union" },
|
||||
//{ "union", "ST_Union" },
|
||||
{ "geom_from_wkt", "ST_GeomFromText" },
|
||||
{ "geom_from_gml", "ST_GeomFromGML" }
|
||||
};
|
||||
}
|
||||
return fnNames;
|
||||
}
|
||||
|
||||
QString QgsPostgresExpressionCompiler::sqlFunctionFromFunctionName( const QString& fnName ) const
|
||||
{
|
||||
return functionNamesSqlFunctionsMap().value( fnName, QString() );
|
||||
}
|
||||
|
||||
QStringList QgsPostgresExpressionCompiler::sqlArgumentsFromFunctionName( const QString& fnName, const QStringList& fnArgs ) const
|
||||
{
|
||||
QStringList args( fnArgs );
|
||||
if ( fnName == "geom_from_wkt" )
|
||||
{
|
||||
args << ( mRequestedSrid.isEmpty() ? mDetectedSrid : mRequestedSrid );
|
||||
}
|
||||
else if ( fnName == "geom_from_gml" )
|
||||
{
|
||||
args << ( mRequestedSrid.isEmpty() ? mDetectedSrid : mRequestedSrid );
|
||||
}
|
||||
else if ( fnName == "x" || fnName == "y" )
|
||||
{
|
||||
args = QStringList( QStringLiteral( "ST_Centroid(%1)" ).arg( args[0] ) );
|
||||
}
|
||||
else if ( fnName == "buffer" && args.length() == 2 )
|
||||
{
|
||||
args << "8";
|
||||
}
|
||||
// x and y functions have to be adapted
|
||||
return args;
|
||||
}
|
||||
|
||||
QgsSqlExpressionCompiler::Result QgsPostgresExpressionCompiler::compileNode( const QgsExpression::Node* node, QString& result )
|
||||
{
|
||||
switch ( node->nodeType() )
|
||||
{
|
||||
case QgsExpression::ntFunction:
|
||||
{
|
||||
const QgsExpression::NodeFunction* n = static_cast<const QgsExpression::NodeFunction*>( node );
|
||||
|
||||
QgsExpression::Function* fd = QgsExpression::Functions()[n->fnIndex()];
|
||||
if ( fd->name() == "$geometry" )
|
||||
{
|
||||
result = quotedIdentifier( mGeometryColumn );
|
||||
return Complete;
|
||||
}
|
||||
/*
|
||||
* These methods are tricky
|
||||
* QGIS expression versions of these return ellipsoidal measurements
|
||||
* based on the project settings, and also convert the result to the
|
||||
* units specified in project properties.
|
||||
else if ( fd->name() == "$area" )
|
||||
{
|
||||
result = QStringLiteral( "ST_Area(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
|
||||
return Complete;
|
||||
}
|
||||
else if ( fd->name() == "$length" )
|
||||
{
|
||||
result = QStringLiteral( "ST_Length(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
|
||||
return Complete;
|
||||
}
|
||||
else if ( fd->name() == "$perimeter" )
|
||||
{
|
||||
result = QStringLiteral( "ST_Perimeter(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
|
||||
return Complete;
|
||||
}
|
||||
else if ( fd->name() == "$x" )
|
||||
{
|
||||
result = QStringLiteral( "ST_X(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
|
||||
return Complete;
|
||||
}
|
||||
else if ( fd->name() == "$y" )
|
||||
{
|
||||
result = QStringLiteral( "ST_Y(%1)" ).arg( quotedIdentifier( mGeometryColumn ) );
|
||||
return Complete;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
default:
|
||||
return QgsSqlExpressionCompiler::compileNode( node, result );
|
||||
}
|
||||
|
||||
return Fail;
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include "qgssqlexpressioncompiler.h"
|
||||
#include "qgsexpression.h"
|
||||
#include "qgspostgresconn.h"
|
||||
#include "qgspostgresfeatureiterator.h"
|
||||
|
||||
class QgsPostgresExpressionCompiler : public QgsSqlExpressionCompiler
|
||||
@ -30,6 +31,16 @@ class QgsPostgresExpressionCompiler : public QgsSqlExpressionCompiler
|
||||
|
||||
virtual QString quotedIdentifier( const QString& identifier ) override;
|
||||
virtual QString quotedValue( const QVariant& value, bool& ok ) override;
|
||||
virtual Result compileNode( const QgsExpression::Node* node, QString& str ) override;
|
||||
virtual QString sqlFunctionFromFunctionName( const QString& fnName ) const override;
|
||||
virtual QStringList sqlArgumentsFromFunctionName( const QString& fnName, const QStringList& fnArgs ) const override;
|
||||
|
||||
QString mGeometryColumn;
|
||||
QgsPostgresGeometryColumnType mSpatialColType;
|
||||
QgsWkbTypes::Type mDetectedGeomType;
|
||||
QgsWkbTypes::Type mRequestedGeomType;
|
||||
QString mRequestedSrid;
|
||||
QString mDetectedSrid;
|
||||
};
|
||||
|
||||
#endif // QGSPOSTGRESEXPRESSIONCOMPILER_H
|
||||
|
@ -222,8 +222,47 @@ class ProviderTestCase(object):
|
||||
# against numeric literals
|
||||
self.assert_query(provider, 'num_char IN (2, 4, 5)', [2, 4, 5])
|
||||
|
||||
#function
|
||||
self.assert_query(provider, 'sqrt(pk) >= 2', [4, 5])
|
||||
self.assert_query(provider, 'radians(cnt) < 2', [1, 5])
|
||||
self.assert_query(provider, 'degrees(pk) <= 200', [1, 2, 3])
|
||||
self.assert_query(provider, 'abs(cnt) <= 200', [1, 2, 5])
|
||||
self.assert_query(provider, 'cos(pk) < 0', [2, 3, 4])
|
||||
self.assert_query(provider, 'sin(pk) < 0', [4, 5])
|
||||
self.assert_query(provider, 'tan(pk) < 0', [2, 3, 5])
|
||||
self.assert_query(provider, 'acos(-1) < pk', [4, 5])
|
||||
self.assert_query(provider, 'asin(1) < pk', [2, 3, 4, 5])
|
||||
self.assert_query(provider, 'atan(3.14) < pk', [2, 3, 4, 5])
|
||||
self.assert_query(provider, 'atan2(3.14, pk) < 1', [3, 4, 5])
|
||||
self.assert_query(provider, 'exp(pk) < 10', [1, 2])
|
||||
self.assert_query(provider, 'ln(pk) <= 1', [1, 2])
|
||||
self.assert_query(provider, 'log(3, pk) <= 1', [1, 2, 3])
|
||||
self.assert_query(provider, 'log10(pk) < 0.5', [1, 2, 3])
|
||||
self.assert_query(provider, 'round(3.14) <= pk', [3, 4, 5])
|
||||
self.assert_query(provider, 'floor(3.14) <= pk', [3, 4, 5])
|
||||
self.assert_query(provider, 'ceil(3.14) <= pk', [4, 5])
|
||||
self.assert_query(provider, 'pk < pi()', [1, 2, 3])
|
||||
|
||||
self.assert_query(provider, 'round(cnt / 66.67) <= 2', [1, 5])
|
||||
self.assert_query(provider, 'floor(cnt / 66.67) <= 2', [1, 2, 5])
|
||||
self.assert_query(provider, 'ceil(cnt / 66.67) <= 2', [1, 5])
|
||||
self.assert_query(provider, 'pk < pi() / 2', [1])
|
||||
|
||||
# geometry
|
||||
# azimuth and touches tests are deactivated because they do not pass for WFS provider
|
||||
#self.assert_query(provider, 'azimuth($geometry,geom_from_wkt( \'Point (-70 70)\')) < pi()', [1, 5])
|
||||
self.assert_query(provider, 'x($geometry) < -70', [1, 5])
|
||||
self.assert_query(provider, 'y($geometry) > 70', [2, 4, 5])
|
||||
self.assert_query(provider, 'xmin($geometry) < -70', [1, 5])
|
||||
self.assert_query(provider, 'ymin($geometry) > 70', [2, 4, 5])
|
||||
self.assert_query(provider, 'xmax($geometry) < -70', [1, 5])
|
||||
self.assert_query(provider, 'ymax($geometry) > 70', [2, 4, 5])
|
||||
self.assert_query(provider, 'disjoint($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))', [4, 5])
|
||||
self.assert_query(provider, 'intersects($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))', [1, 2])
|
||||
#self.assert_query(provider, 'touches($geometry,geom_from_wkt( \'Polygon ((-70.332 66.33, -65.32 66.33, -65.32 78.3, -70.332 78.3, -70.332 66.33))\'))', [1, 4])
|
||||
self.assert_query(provider, 'contains(geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'),$geometry)', [1, 2])
|
||||
self.assert_query(provider, 'distance($geometry,geom_from_wkt( \'Point (-70 70)\')) > 7', [4, 5])
|
||||
self.assert_query(provider, 'intersects($geometry,geom_from_gml( \'<gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-72.2,66.1 -65.2,66.1 -65.2,72.0 -72.2,72.0 -72.2,66.1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>\'))', [1, 2])
|
||||
|
||||
# combination of an uncompilable expression and limit
|
||||
feature = next(self.vl.getFeatures('pk=4'))
|
||||
@ -240,6 +279,29 @@ class ProviderTestCase(object):
|
||||
values = [f['pk'] for f in self.vl.getFeatures(request)]
|
||||
self.assertEqual(values, [4])
|
||||
|
||||
def runPolyGetFeatureTests(self, provider):
|
||||
assert len([f for f in provider.getFeatures()]) == 4
|
||||
|
||||
# geometry
|
||||
self.assert_query(provider, 'x($geometry) < -70', [1])
|
||||
self.assert_query(provider, 'y($geometry) > 79', [1, 2])
|
||||
self.assert_query(provider, 'xmin($geometry) < -70', [1, 3])
|
||||
self.assert_query(provider, 'ymin($geometry) < 76', [3])
|
||||
self.assert_query(provider, 'xmax($geometry) > -68', [2, 3])
|
||||
self.assert_query(provider, 'ymax($geometry) > 80', [1, 2])
|
||||
self.assert_query(provider, 'area($geometry) > 10', [1])
|
||||
self.assert_query(provider, 'perimeter($geometry) < 12', [2, 3])
|
||||
self.assert_query(provider, 'relate($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\')) = \'FF2FF1212\'', [1, 3])
|
||||
self.assert_query(provider, 'relate($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\'), \'****F****\')', [1, 3])
|
||||
self.assert_query(provider, 'crosses($geometry,geom_from_wkt( \'Linestring (-68.2 82.1, -66.95 82.1, -66.95 79.05)\'))', [2])
|
||||
self.assert_query(provider, 'overlaps($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\'))', [2])
|
||||
self.assert_query(provider, 'within($geometry,geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))', [1])
|
||||
self.assert_query(provider, 'overlaps(translate($geometry,-1,-1),geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))', [1])
|
||||
self.assert_query(provider, 'overlaps(buffer($geometry,1),geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))', [1, 3])
|
||||
self.assert_query(provider, 'intersects(centroid($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))', [2])
|
||||
self.assert_query(provider, 'intersects(point_on_surface($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))', [1, 2])
|
||||
self.assert_query(provider, 'distance($geometry,geom_from_wkt( \'Point (-70 70)\')) > 7', [1, 2])
|
||||
|
||||
def testGetFeaturesUncompiled(self):
|
||||
self.compiled = False
|
||||
try:
|
||||
@ -247,12 +309,16 @@ class ProviderTestCase(object):
|
||||
except AttributeError:
|
||||
pass
|
||||
self.runGetFeatureTests(self.provider)
|
||||
if hasattr(self, 'poly_provider'):
|
||||
self.runPolyGetFeatureTests(self.poly_provider)
|
||||
|
||||
def testGetFeaturesCompiled(self):
|
||||
def testPolyGetFeaturesCompiled(self):
|
||||
try:
|
||||
self.enableCompiler()
|
||||
self.compiled = True
|
||||
self.runGetFeatureTests(self.provider)
|
||||
if hasattr(self, 'poly_provider'):
|
||||
self.runPolyGetFeatureTests(self.poly_provider)
|
||||
except AttributeError:
|
||||
print('Provider does not support compiling')
|
||||
|
||||
|
@ -74,7 +74,58 @@ class TestPyQgsOracleProvider(unittest.TestCase, ProviderTestCase):
|
||||
'NULL or true',
|
||||
'NULL or NULL',
|
||||
'not null',
|
||||
'intersects($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))'])
|
||||
'sqrt(pk) >= 2',
|
||||
'radians(cnt) < 2',
|
||||
'degrees(pk) <= 200',
|
||||
'abs(cnt) <= 200',
|
||||
'cos(pk) < 0',
|
||||
'sin(pk) < 0',
|
||||
'tan(pk) < 0',
|
||||
'acos(-1) < pk',
|
||||
'asin(1) < pk',
|
||||
'atan(3.14) < pk',
|
||||
'atan2(3.14, pk) < 1',
|
||||
'exp(pk) < 10',
|
||||
'ln(pk) <= 1',
|
||||
'log(3, pk) <= 1',
|
||||
'log10(pk) < 0.5',
|
||||
'round(3.14) <= pk',
|
||||
'floor(3.14) <= pk',
|
||||
'ceil(3.14) <= pk',
|
||||
'pk < pi()',
|
||||
'round(cnt / 66.67) <= 2',
|
||||
'floor(cnt / 66.67) <= 2',
|
||||
'ceil(cnt / 66.67) <= 2',
|
||||
'pk < pi() / 2',
|
||||
'x($geometry) < -70',
|
||||
'y($geometry) > 70',
|
||||
'xmin($geometry) < -70',
|
||||
'ymin($geometry) > 70',
|
||||
'xmax($geometry) < -70',
|
||||
'ymax($geometry) > 70',
|
||||
'disjoint($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))',
|
||||
'intersects($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))',
|
||||
'contains(geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'),$geometry)',
|
||||
'distance($geometry,geom_from_wkt( \'Point (-70 70)\')) > 7',
|
||||
'intersects($geometry,geom_from_gml( \'<gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-72.2,66.1 -65.2,66.1 -65.2,72.0 -72.2,72.0 -72.2,66.1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>\'))',
|
||||
'x($geometry) < -70',
|
||||
'y($geometry) > 79',
|
||||
'xmin($geometry) < -70',
|
||||
'ymin($geometry) < 76',
|
||||
'xmax($geometry) > -68',
|
||||
'ymax($geometry) > 80',
|
||||
'area($geometry) > 10',
|
||||
'perimeter($geometry) < 12',
|
||||
'relate($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\')) = \'FF2FF1212\'',
|
||||
'relate($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\'), \'****F****\')',
|
||||
'crosses($geometry,geom_from_wkt( \'Linestring (-68.2 82.1, -66.95 82.1, -66.95 79.05)\'))',
|
||||
'overlaps($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\'))',
|
||||
'within($geometry,geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))',
|
||||
'overlaps(translate($geometry,-1,-1),geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))',
|
||||
'overlaps(buffer($geometry,1),geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))',
|
||||
'intersects(centroid($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))',
|
||||
'intersects(point_on_surface($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))'
|
||||
])
|
||||
return filters
|
||||
|
||||
# HERE GO THE PROVIDER SPECIFIC TESTS
|
||||
|
@ -94,7 +94,12 @@ class TestPyQgsPostgresProvider(unittest.TestCase, ProviderTestCase):
|
||||
QSettings().setValue('/qgis/compileExpressions', False)
|
||||
|
||||
def uncompiledFilters(self):
|
||||
return set(['intersects($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))'])
|
||||
return set([
|
||||
'round(cnt / 66.67) <= 2',
|
||||
'floor(cnt / 66.67) <= 2',
|
||||
'ceil(cnt / 66.67) <= 2',
|
||||
'pk < pi() / 2'
|
||||
])
|
||||
|
||||
def partiallyCompiledFilters(self):
|
||||
return set([])
|
||||
@ -664,7 +669,12 @@ class TestPyQgsPostgresProviderCompoundKey(unittest.TestCase, ProviderTestCase):
|
||||
QSettings().setValue('/qgis/compileExpressions', False)
|
||||
|
||||
def uncompiledFilters(self):
|
||||
return set(['intersects($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))'])
|
||||
return set([
|
||||
'round(cnt / 66.67) <= 2',
|
||||
'floor(cnt / 66.67) <= 2',
|
||||
'ceil(cnt / 66.67) <= 2',
|
||||
'pk < pi() / 2'
|
||||
])
|
||||
|
||||
def partiallyCompiledFilters(self):
|
||||
return set([])
|
||||
|
@ -131,7 +131,58 @@ class TestPyQgsShapefileProvider(unittest.TestCase, ProviderTestCase):
|
||||
'-cnt - 1 = -101',
|
||||
'-(-cnt) = 100',
|
||||
'-(cnt) = -(100)',
|
||||
'intersects($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))'])
|
||||
'sqrt(pk) >= 2',
|
||||
'radians(cnt) < 2',
|
||||
'degrees(pk) <= 200',
|
||||
'abs(cnt) <= 200',
|
||||
'cos(pk) < 0',
|
||||
'sin(pk) < 0',
|
||||
'tan(pk) < 0',
|
||||
'acos(-1) < pk',
|
||||
'asin(1) < pk',
|
||||
'atan(3.14) < pk',
|
||||
'atan2(3.14, pk) < 1',
|
||||
'exp(pk) < 10',
|
||||
'ln(pk) <= 1',
|
||||
'log(3, pk) <= 1',
|
||||
'log10(pk) < 0.5',
|
||||
'round(3.14) <= pk',
|
||||
'floor(3.14) <= pk',
|
||||
'ceil(3.14) <= pk',
|
||||
'pk < pi()',
|
||||
'round(cnt / 66.67) <= 2',
|
||||
'floor(cnt / 66.67) <= 2',
|
||||
'ceil(cnt / 66.67) <= 2',
|
||||
'pk < pi() / 2',
|
||||
'x($geometry) < -70',
|
||||
'y($geometry) > 70',
|
||||
'xmin($geometry) < -70',
|
||||
'ymin($geometry) > 70',
|
||||
'xmax($geometry) < -70',
|
||||
'ymax($geometry) > 70',
|
||||
'disjoint($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))',
|
||||
'intersects($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))',
|
||||
'contains(geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'),$geometry)',
|
||||
'distance($geometry,geom_from_wkt( \'Point (-70 70)\')) > 7',
|
||||
'intersects($geometry,geom_from_gml( \'<gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-72.2,66.1 -65.2,66.1 -65.2,72.0 -72.2,72.0 -72.2,66.1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>\'))',
|
||||
'x($geometry) < -70',
|
||||
'y($geometry) > 79',
|
||||
'xmin($geometry) < -70',
|
||||
'ymin($geometry) < 76',
|
||||
'xmax($geometry) > -68',
|
||||
'ymax($geometry) > 80',
|
||||
'area($geometry) > 10',
|
||||
'perimeter($geometry) < 12',
|
||||
'relate($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\')) = \'FF2FF1212\'',
|
||||
'relate($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\'), \'****F****\')',
|
||||
'crosses($geometry,geom_from_wkt( \'Linestring (-68.2 82.1, -66.95 82.1, -66.95 79.05)\'))',
|
||||
'overlaps($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\'))',
|
||||
'within($geometry,geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))',
|
||||
'overlaps(translate($geometry,-1,-1),geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))',
|
||||
'overlaps(buffer($geometry,1),geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))',
|
||||
'intersects(centroid($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))',
|
||||
'intersects(point_on_surface($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))'
|
||||
])
|
||||
if int(osgeo.gdal.VersionInfo()[:1]) < 2:
|
||||
filters.insert('not null')
|
||||
return filters
|
||||
|
@ -194,7 +194,58 @@ class TestQgsSpatialiteProvider(unittest.TestCase, ProviderTestCase):
|
||||
def uncompiledFilters(self):
|
||||
return set(['cnt = 10 ^ 2',
|
||||
'"name" ~ \'[OP]ra[gne]+\'',
|
||||
'intersects($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))'])
|
||||
'sqrt(pk) >= 2',
|
||||
'radians(cnt) < 2',
|
||||
'degrees(pk) <= 200',
|
||||
'abs(cnt) <= 200',
|
||||
'cos(pk) < 0',
|
||||
'sin(pk) < 0',
|
||||
'tan(pk) < 0',
|
||||
'acos(-1) < pk',
|
||||
'asin(1) < pk',
|
||||
'atan(3.14) < pk',
|
||||
'atan2(3.14, pk) < 1',
|
||||
'exp(pk) < 10',
|
||||
'ln(pk) <= 1',
|
||||
'log(3, pk) <= 1',
|
||||
'log10(pk) < 0.5',
|
||||
'round(3.14) <= pk',
|
||||
'floor(3.14) <= pk',
|
||||
'ceil(3.14) <= pk',
|
||||
'pk < pi()',
|
||||
'round(cnt / 66.67) <= 2',
|
||||
'floor(cnt / 66.67) <= 2',
|
||||
'ceil(cnt / 66.67) <= 2',
|
||||
'pk < pi() / 2',
|
||||
'x($geometry) < -70',
|
||||
'y($geometry) > 70',
|
||||
'xmin($geometry) < -70',
|
||||
'ymin($geometry) > 70',
|
||||
'xmax($geometry) < -70',
|
||||
'ymax($geometry) > 70',
|
||||
'disjoint($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))',
|
||||
'intersects($geometry,geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'))',
|
||||
'contains(geom_from_wkt( \'Polygon ((-72.2 66.1, -65.2 66.1, -65.2 72.0, -72.2 72.0, -72.2 66.1))\'),$geometry)',
|
||||
'distance($geometry,geom_from_wkt( \'Point (-70 70)\')) > 7',
|
||||
'intersects($geometry,geom_from_gml( \'<gml:Polygon srsName="EPSG:4326"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-72.2,66.1 -65.2,66.1 -65.2,72.0 -72.2,72.0 -72.2,66.1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>\'))',
|
||||
'x($geometry) < -70',
|
||||
'y($geometry) > 79',
|
||||
'xmin($geometry) < -70',
|
||||
'ymin($geometry) < 76',
|
||||
'xmax($geometry) > -68',
|
||||
'ymax($geometry) > 80',
|
||||
'area($geometry) > 10',
|
||||
'perimeter($geometry) < 12',
|
||||
'relate($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\')) = \'FF2FF1212\'',
|
||||
'relate($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\'), \'****F****\')',
|
||||
'crosses($geometry,geom_from_wkt( \'Linestring (-68.2 82.1, -66.95 82.1, -66.95 79.05)\'))',
|
||||
'overlaps($geometry,geom_from_wkt( \'Polygon ((-68.2 82.1, -66.95 82.1, -66.95 79.05, -68.2 79.05, -68.2 82.1))\'))',
|
||||
'within($geometry,geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))',
|
||||
'overlaps(translate($geometry,-1,-1),geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))',
|
||||
'overlaps(buffer($geometry,1),geom_from_wkt( \'Polygon ((-75.1 76.1, -75.1 81.6, -68.8 81.6, -68.8 76.1, -75.1 76.1))\'))',
|
||||
'intersects(centroid($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))',
|
||||
'intersects(point_on_surface($geometry),geom_from_wkt( \'Polygon ((-74.4 78.2, -74.4 79.1, -66.8 79.1, -66.8 78.2, -74.4 78.2))\'))'
|
||||
])
|
||||
|
||||
def partiallyCompiledFilters(self):
|
||||
return set(['"name" NOT LIKE \'Ap%\'',
|
||||
|
Loading…
x
Reference in New Issue
Block a user