From 35fea9c98613c48b12d6267fd39f9347657346ab Mon Sep 17 00:00:00 2001 From: nirvn Date: Fri, 11 Dec 2015 09:33:00 +0700 Subject: [PATCH] [expression] add point_on_surface function --- resources/function_help/json/point_on_surface | 7 +++++++ src/core/qgsexpression.cpp | 9 +++++++++ tests/src/core/testqgsexpression.cpp | 16 ++++++++++++---- 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 resources/function_help/json/point_on_surface diff --git a/resources/function_help/json/point_on_surface b/resources/function_help/json/point_on_surface new file mode 100644 index 00000000000..68d9c8dcde4 --- /dev/null +++ b/resources/function_help/json/point_on_surface @@ -0,0 +1,7 @@ +{ + "name": "point_on_surface", + "type": "function", + "description": "Returns a point guaranteed to lie on the surface of a geometry.", + "arguments": [ {"arg":"geom","description":"a geometry"}], + "examples": [ { "expression":"point_on_surface($geometry)", "returns":"a point geometry"}] +} diff --git a/src/core/qgsexpression.cpp b/src/core/qgsexpression.cpp index 9a40fcc8043..547ff0752ba 100644 --- a/src/core/qgsexpression.cpp +++ b/src/core/qgsexpression.cpp @@ -1736,6 +1736,14 @@ static QVariant fcnCentroid( const QVariantList& values, const QgsExpressionCont delete geom; return result; } +static QVariant fcnPointOnSurface( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent ) +{ + QgsGeometry fGeom = getGeometry( values.at( 0 ), parent ); + QgsGeometry* geom = fGeom.pointOnSurface(); + QVariant result = geom ? QVariant::fromValue( *geom ) : QVariant(); + delete geom; + return result; +} static QVariant fcnConvexHull( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent ) { QgsGeometry fGeom = getGeometry( values.at( 0 ), parent ); @@ -2548,6 +2556,7 @@ const QList& QgsExpression::Functions() << new StaticFunction( "translate", 3, fcnTranslate, "GeometryGroup" ) << new StaticFunction( "buffer", -1, fcnBuffer, "GeometryGroup" ) << new StaticFunction( "centroid", 1, fcnCentroid, "GeometryGroup" ) + << new StaticFunction( "point_on_surface", 1, fcnPointOnSurface, "GeometryGroup" ) << new StaticFunction( "reverse", 1, fcnReverse, "GeometryGroup" ) << new StaticFunction( "bounds", 1, fcnBounds, "GeometryGroup" ) << new StaticFunction( "num_points", 1, fcnGeomNumPoints, "GeometryGroup" ) diff --git a/tests/src/core/testqgsexpression.cpp b/tests/src/core/testqgsexpression.cpp index 020ca370dbf..a5e846655e5 100644 --- a/tests/src/core/testqgsexpression.cpp +++ b/tests/src/core/testqgsexpression.cpp @@ -449,6 +449,18 @@ class TestQgsExpression: public QObject QTest::newRow( "reverse point" ) << "reverse(geom_from_wkt('POINT(1 2)'))" << false << QVariant(); QTest::newRow( "reverse polygon" ) << "reverse(geom_from_wkt('POLYGON((-1 -1, 4 0, 4 2, 0 2, -1 -1))'))" << false << QVariant(); QTest::newRow( "reverse line" ) << "geom_to_wkt(reverse(geom_from_wkt('LINESTRING(0 0, 1 1, 2 2)')))" << false << QVariant( "LineString (2 2, 1 1, 0 0)" ); + QTest::newRow( "centroid polygon" ) << "geom_to_wkt(centroid( geomFromWKT('POLYGON((0 0,0 9,9 0,0 0))')))" << false << QVariant( "Point (3 3)" ); + QTest::newRow( "centroid multi polygon" ) << "geom_to_wkt(centroid( geomFromWKT('MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0)),((2 0,2 1,3 1,3 0,2 0)))') ))" << false << QVariant( "Point (1.5 0.5)" ); + QTest::newRow( "centroid point" ) << "geom_to_wkt(centroid( geomFromWKT('POINT (1.5 0.5)') ))" << false << QVariant( "Point (1.5 0.5)" ); + QTest::newRow( "centroid line" ) << "geom_to_wkt(centroid( geomFromWKT('LINESTRING (-1 2, 9 12)') ))" << false << QVariant( "Point (4 7)" ); + QTest::newRow( "centroid not geom" ) << "centroid('g')" << true << QVariant(); + QTest::newRow( "centroid null" ) << "centroid(NULL)" << false << QVariant(); + QTest::newRow( "point on surface polygon" ) << "geom_to_wkt(point_on_surface( geomFromWKT('POLYGON((0 0,0 9,9 0,0 0))')))" << false << QVariant( "Point (2.25 4.5)" ); + QTest::newRow( "point on surface multi polygon" ) << "geom_to_wkt(point_on_surface( geomFromWKT('MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0)),((2 0,2 1,3 1,3 0,2 0)))') ))" << false << QVariant( "Point (0.5 0.5)" ); + QTest::newRow( "point on surface point" ) << "geom_to_wkt(point_on_surface( geomFromWKT('POINT (1.5 0.5)') ))" << false << QVariant( "Point (1.5 0.5)" ); + QTest::newRow( "point on surface line" ) << "geom_to_wkt(point_on_surface( geomFromWKT('LINESTRING (-1 2, 9 12)') ))" << false << QVariant( "Point (-1 2)" ); + QTest::newRow( "point on surface not geom" ) << "point_on_surface('g')" << true << QVariant(); + QTest::newRow( "point on surface null" ) << "point_on_surface(NULL)" << false << QVariant(); QTest::newRow( "make_point" ) << "geom_to_wkt(make_point(2.2,4.4))" << false << QVariant( "Point (2.2 4.4)" ); QTest::newRow( "make_point z" ) << "geom_to_wkt(make_point(2.2,4.4,5.5))" << false << QVariant( "PointZ (2.2 4.4 5.5)" ); QTest::newRow( "make_point zm" ) << "geom_to_wkt(make_point(2.2,4.4,5.5,6.6))" << false << QVariant( "PointZM (2.2 4.4 5.5 6.6)" ); @@ -1459,10 +1471,6 @@ class TestQgsExpression: public QObject geom = QgsGeometry::fromPolygon( polygon ); QTest::newRow( "symDifference" ) << "symDifference( $geometry, geomFromWKT('POLYGON((0 0, 0 10, 10 0, 0 0))') )" << ( void* ) geom << false << true << ( void* ) QgsGeometry::fromWkt( "MULTIPOLYGON(((5 5,0 0,0 10,5 5)),((5 5,10 10,10 0,5 5)))" ); - geom = QgsGeometry::fromPolygon( polygon ); - QTest::newRow( "centroid polygon" ) << "centroid( $geometry )" << ( void* ) geom << false << true << ( void* ) geom->centroid(); - geom = QgsGeometry::fromPolygon( polygon ); - QTest::newRow( "centroid multi polygon" ) << "centroid( geomFromWKT('MULTIPOLYGON(((0 0,0 1,1 1,1 0,0 0)),((2 0,2 1,3 1,3 0,2 0)))') )" << ( void* ) geom << false << false << ( void* ) QgsGeometry::fromWkt( "POINT (1.5 0.5)" ); geom = QgsGeometry::fromPolygon( polygon ); QTest::newRow( "convexHull simple" ) << "convexHull( $geometry )" << ( void* ) geom << false << true << ( void* ) geom->convexHull(); geom = QgsGeometry::fromPolygon( polygon );