Skip to content

Commit

Permalink
[FEATURE] is_closed function for expressions
Browse files Browse the repository at this point in the history
Returns whether a linestring is closed
  • Loading branch information
nyalldawson committed Dec 13, 2015
1 parent 2d9f361 commit ceddb7e
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 1 deletion.
8 changes: 8 additions & 0 deletions resources/function_help/json/is_closed
@@ -0,0 +1,8 @@
{
"name": "is_closed",
"type": "function",
"description": "Returns true if a line string is closed (start and end points are coincident), or false if a line string is not closed. If the geometry is not a line string then the result will be null.",
"arguments": [ {"arg":"geom","description":"a line string geometry"}],
"examples": [ { "expression":"is_closed(geom_from_wkt('LINESTRING(0 0, 1 1, 2 2)'))", "returns":"false"},
{ "expression":"is_closed(geom_from_wkt('LINESTRING(0 0, 1 1, 2 2, 0 0)'))", "returns":"true"}]
}
16 changes: 15 additions & 1 deletion src/core/qgsexpression.cpp
Expand Up @@ -1628,6 +1628,19 @@ static QVariant fcnYMax( const QVariantList& values, const QgsExpressionContext*
return QVariant::fromValue( geom.boundingBox().yMaximum() );
}

static QVariant fcnIsClosed( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
{
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
if ( fGeom.isEmpty() )
return QVariant();

QgsCurveV2* curve = dynamic_cast< QgsCurveV2* >( fGeom.geometry() );
if ( !curve )
return QVariant();

return QVariant::fromValue( curve->isClosed() );
}

static QVariant fcnRelate( const QVariantList& values, const QgsExpressionContext*, QgsExpression* parent )
{
if ( values.length() < 2 || values.length() > 3 )
Expand Down Expand Up @@ -2430,7 +2443,7 @@ const QStringList& QgsExpression::BuiltinFunctions()
<< "disjoint" << "intersects" << "touches" << "crosses" << "contains"
<< "relate"
<< "overlaps" << "within" << "buffer" << "centroid" << "bounds" << "reverse" << "exterior_ring"
<< "bounds_width" << "bounds_height" << "convex_hull" << "difference"
<< "bounds_width" << "bounds_height" << "is_closed" << "convex_hull" << "difference"
<< "distance" << "intersection" << "sym_difference" << "combine"
<< "union" << "geom_to_wkt" << "geomToWKT" << "geometry"
<< "transform" << "get_feature" << "getFeature"
Expand Down Expand Up @@ -2578,6 +2591,7 @@ const QList<QgsExpression::Function*>& QgsExpression::Functions()
<< new StaticFunction( "num_points", 1, fcnGeomNumPoints, "GeometryGroup" )
<< new StaticFunction( "bounds_width", 1, fcnBoundsWidth, "GeometryGroup" )
<< new StaticFunction( "bounds_height", 1, fcnBoundsHeight, "GeometryGroup" )
<< new StaticFunction( "is_closed", 1, fcnIsClosed, "GeometryGroup" )
<< new StaticFunction( "convex_hull", 1, fcnConvexHull, "GeometryGroup", QString(), false, QStringList(), false, QStringList() << "convexHull" )
<< new StaticFunction( "difference", 2, fcnDifference, "GeometryGroup" )
<< new StaticFunction( "distance", 2, fcnDistance, "GeometryGroup" )
Expand Down
6 changes: 6 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -466,6 +466,12 @@ class TestQgsExpression: public QObject
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( "is_closed not geom" ) << "is_closed('g')" << true << QVariant();
QTest::newRow( "is_closed null" ) << "is_closed(NULL)" << false << QVariant();
QTest::newRow( "is_closed point" ) << "is_closed(geom_from_wkt('POINT(1 2)'))" << false << QVariant();
QTest::newRow( "is_closed polygon" ) << "is_closed(geom_from_wkt('POLYGON((-1 -1, 4 0, 4 2, 0 2, -1 -1))'))" << false << QVariant();
QTest::newRow( "is_closed not closed" ) << "is_closed(geom_from_wkt('LINESTRING(0 0, 1 1, 2 2)'))" << false << QVariant( false );
QTest::newRow( "is_closed closed" ) << "is_closed(geom_from_wkt('LINESTRING(0 0, 1 1, 2 2, 0 0)'))" << false << QVariant( true );
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)" );
Expand Down

0 comments on commit ceddb7e

Please sign in to comment.