Skip to content

Commit 9d4e995

Browse files
committed
[FEATURE] Add geometry relation DE-9IM expression function
1 parent f1633a1 commit 9d4e995

File tree

3 files changed

+33
-0
lines changed

3 files changed

+33
-0
lines changed

resources/function_help/json/relate

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "relate",
3+
"type": "function",
4+
"description": "Returns the Dimensional Extended 9 Intersection Model (DE-9IM) representation of the relationship between two geometries.",
5+
"arguments": [
6+
{"arg":"geometry","description":"a geometry"},
7+
{"arg":"geometry","description":"a geometry"}
8+
],
9+
"examples": [
10+
{ "expression":"relate( geom_from_wkt( 'LINESTRING(40 40,120 120)' ), geom_from_wkt( 'LINESTRING(40 40,60 120)' ) )", "returns":"'FF1F00102'"}
11+
]
12+
}

src/core/qgsexpression.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "qgsdistancearea.h"
2929
#include "qgsfeature.h"
3030
#include "qgsgeometry.h"
31+
#include "qgsgeometryengine.h"
3132
#include "qgslogger.h"
3233
#include "qgsmaplayerregistry.h"
3334
#include "qgsogcutils.h"
@@ -1474,6 +1475,21 @@ static QVariant fcnYMax( const QVariantList& values, const QgsExpressionContext*
14741475
return QVariant::fromValue( geom.boundingBox().yMaximum() );
14751476
}
14761477

1478+
static QVariant fcnRelate( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
1479+
{
1480+
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1481+
QgsGeometry sGeom = getGeometry( values.at( 1 ), parent );
1482+
1483+
if ( fGeom.isEmpty() || sGeom.isEmpty() )
1484+
return QVariant();
1485+
1486+
QgsGeometryEngine* engine = QgsGeometry::createGeometryEngine( fGeom.geometry() );
1487+
QString result = engine->relate( *sGeom.geometry() );
1488+
delete engine;
1489+
1490+
return QVariant::fromValue( result );
1491+
}
1492+
14771493
static QVariant fcnBbox( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
14781494
{
14791495
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
@@ -2171,6 +2187,7 @@ const QStringList& QgsExpression::BuiltinFunctions()
21712187
<< "y_min" << "ymin" << "y_max" << "ymax" << "geom_from_wkt" << "geomFromWKT"
21722188
<< "geom_from_gml" << "geomFromGML" << "intersects_bbox" << "bbox"
21732189
<< "disjoint" << "intersects" << "touches" << "crosses" << "contains"
2190+
<< "relate"
21742191
<< "overlaps" << "within" << "buffer" << "centroid" << "bounds"
21752192
<< "bounds_width" << "bounds_height" << "convex_hull" << "difference"
21762193
<< "distance" << "intersection" << "sym_difference" << "combine"
@@ -2292,6 +2309,7 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
22922309
<< new StaticFunction( "y_max", 1, fcnYMax, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "ymax" )
22932310
<< new StaticFunction( "geom_from_wkt", 1, fcnGeomFromWKT, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "geomFromWKT" )
22942311
<< new StaticFunction( "geom_from_gml", 1, fcnGeomFromGML, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "geomFromGML" )
2312+
<< new StaticFunction( "relate", 2, fcnRelate, "GeometryGroup" )
22952313
<< new StaticFunction( "intersects_bbox", 2, fcnBbox, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "bbox" )
22962314
<< new StaticFunction( "disjoint", 2, fcnDisjoint, "GeometryGroup" )
22972315
<< new StaticFunction( "intersects", 2, fcnIntersects, "GeometryGroup" )

tests/src/core/testqgsexpression.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,9 @@ class TestQgsExpression: public QObject
428428
QTest::newRow( "x line" ) << "y(geom_from_wkt('LINESTRING(2 0,2 2, 3 2, 3 0)'))" << false << QVariant( 1.2 );
429429
QTest::newRow( "x polygon" ) << "x(geom_from_wkt('POLYGON((2 0,2 2, 3 2, 3 0, 2 0))'))" << false << QVariant( 2.5 );
430430
QTest::newRow( "x polygon" ) << "y(geom_from_wkt('POLYGON((2 0,2 2, 3 2, 3 0, 2 0))'))" << false << QVariant( 1.0 );
431+
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" );
432+
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();
433+
QTest::newRow( "relate bad 2" ) << "relate(geom_from_wkt('POINT(110 120)'),geom_from_wkt(''))" << false << QVariant();
431434

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

0 commit comments

Comments
 (0)