Skip to content

Commit

Permalink
[FEATURE] Add geometry relation DE-9IM expression function
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Oct 26, 2015
1 parent f1633a1 commit 9d4e995
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 0 deletions.
12 changes: 12 additions & 0 deletions resources/function_help/json/relate
@@ -0,0 +1,12 @@
{
"name": "relate",
"type": "function",
"description": "Returns the Dimensional Extended 9 Intersection Model (DE-9IM) representation of the relationship between two geometries.",
"arguments": [
{"arg":"geometry","description":"a geometry"},
{"arg":"geometry","description":"a geometry"}
],
"examples": [
{ "expression":"relate( geom_from_wkt( 'LINESTRING(40 40,120 120)' ), geom_from_wkt( 'LINESTRING(40 40,60 120)' ) )", "returns":"'FF1F00102'"}
]
}
18 changes: 18 additions & 0 deletions src/core/qgsexpression.cpp
Expand Up @@ -28,6 +28,7 @@
#include "qgsdistancearea.h"
#include "qgsfeature.h"
#include "qgsgeometry.h"
#include "qgsgeometryengine.h"
#include "qgslogger.h"
#include "qgsmaplayerregistry.h"
#include "qgsogcutils.h"
Expand Down Expand Up @@ -1474,6 +1475,21 @@ static QVariant fcnYMax( const QVariantList& values, const QgsExpressionContext*
return QVariant::fromValue( geom.boundingBox().yMaximum() );
}

static QVariant fcnRelate( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
{
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );

if ( fGeom.isEmpty() || sGeom.isEmpty() )
return QVariant();

QgsGeometryEngine* engine = QgsGeometry::createGeometryEngine( fGeom.geometry() );
QString result = engine->relate( *sGeom.geometry() );
delete engine;

return QVariant::fromValue( result );
}

static QVariant fcnBbox( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
{
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
Expand Down Expand Up @@ -2171,6 +2187,7 @@ const QStringList& QgsExpression::BuiltinFunctions()
<< "y_min" << "ymin" << "y_max" << "ymax" << "geom_from_wkt" << "geomFromWKT"
<< "geom_from_gml" << "geomFromGML" << "intersects_bbox" << "bbox"
<< "disjoint" << "intersects" << "touches" << "crosses" << "contains"
<< "relate"
<< "overlaps" << "within" << "buffer" << "centroid" << "bounds"
<< "bounds_width" << "bounds_height" << "convex_hull" << "difference"
<< "distance" << "intersection" << "sym_difference" << "combine"
Expand Down Expand Up @@ -2292,6 +2309,7 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
<< new StaticFunction( "y_max", 1, fcnYMax, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "ymax" )
<< new StaticFunction( "geom_from_wkt", 1, fcnGeomFromWKT, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "geomFromWKT" )
<< new StaticFunction( "geom_from_gml", 1, fcnGeomFromGML, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "geomFromGML" )
<< new StaticFunction( "relate", 2, fcnRelate, "GeometryGroup" )
<< new StaticFunction( "intersects_bbox", 2, fcnBbox, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "bbox" )
<< new StaticFunction( "disjoint", 2, fcnDisjoint, "GeometryGroup" )
<< new StaticFunction( "intersects", 2, fcnIntersects, "GeometryGroup" )
Expand Down
3 changes: 3 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -428,6 +428,9 @@ class TestQgsExpression: public QObject
QTest::newRow( "x line" ) << "y(geom_from_wkt('LINESTRING(2 0,2 2, 3 2, 3 0)'))" << false << QVariant( 1.2 );
QTest::newRow( "x polygon" ) << "x(geom_from_wkt('POLYGON((2 0,2 2, 3 2, 3 0, 2 0))'))" << false << QVariant( 2.5 );
QTest::newRow( "x polygon" ) << "y(geom_from_wkt('POLYGON((2 0,2 2, 3 2, 3 0, 2 0))'))" << false << QVariant( 1.0 );
QTest::newRow( "relate valid" ) << "relate(geom_from_wkt('POINT(110 120)'),geom_from_wkt('POLYGON((60 120,60 40,160 40,160 120,60 120))'))" << false << QVariant( "F0FFFF212" );
QTest::newRow( "relate bad 1" ) << "relate(geom_from_wkt(''),geom_from_wkt('POLYGON((60 120,60 40,160 40,160 120,60 120))'))" << false << QVariant();
QTest::newRow( "relate bad 2" ) << "relate(geom_from_wkt('POINT(110 120)'),geom_from_wkt(''))" << false << QVariant();

// string functions
QTest::newRow( "lower" ) << "lower('HeLLo')" << false << QVariant( "hello" );
Expand Down

0 comments on commit 9d4e995

Please sign in to comment.