Skip to content

Commit 2ce7416

Browse files
committed
Add expression functions for bounding box (bounds), bounding box width & height (bounds_width/bounds_height), and min/max x/y coordinates (xmin/xmax/ymin/ymax)
1 parent c305c2f commit 2ce7416

9 files changed

Lines changed: 173 additions & 6 deletions

File tree

‎resources/function_help/bounds‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<h3>bounds function</h3>
2+
Returns a geometry which represents the bounding box of an input geometry. Calculations are in the Spatial Reference System of this Geometry.
3+
4+
<h4>Syntax</h4>
5+
<pre>bounds(geom)</pre>
6+
7+
<h4>Arguments</h4>
8+
geom &rarr; a geometry
9+
10+
<h4>Example</h4>
11+
<pre> bounds($geometry) &rarr; returns bounding box of $geometry</pre>
12+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<h3>bounds_height function</h3>
2+
Returns the height of the bounding box of a geometry. Calculations are in the Spatial Reference System of this Geometry.
3+
4+
<h4>Syntax</h4>
5+
<pre>bounds_height(geom)</pre>
6+
7+
<h4>Arguments</h4>
8+
geom &rarr; a geometry
9+
10+
<h4>Example</h4>
11+
<pre> bounds_height($geometry) &rarr; returns height of bounding box of $geometry</pre>
12+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<h3>bounds_width function</h3>
2+
Returns the width of the bounding box of a geometry. Calculations are in the Spatial Reference System of this Geometry.
3+
4+
<h4>Syntax</h4>
5+
<pre>bounds_width(geom)</pre>
6+
7+
<h4>Arguments</h4>
8+
geom &rarr; a geometry
9+
10+
<h4>Example</h4>
11+
<pre> bounds_width($geometry) &rarr; returns width of bounding box of $geometry</pre>
12+

‎resources/function_help/xmax‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<h3>xmax function</h3>
2+
Returns the maximum x coordinate of a geometry. Calculations are in the Spatial Reference System of this Geometry.
3+
4+
<h4>Syntax</h4>
5+
<pre>xmax(geom)</pre>
6+
7+
<h4>Arguments</h4>
8+
geom &rarr; a geometry
9+
10+
<h4>Example</h4>
11+
<pre> xmax($geometry) &rarr; returns maximum x coordinate of $geometry</pre>
12+

‎resources/function_help/xmin‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<h3>xmin function</h3>
2+
Returns the minimum x coordinate of a geometry. Calculations are in the Spatial Reference System of this Geometry.
3+
4+
<h4>Syntax</h4>
5+
<pre>xmin(geom)</pre>
6+
7+
<h4>Arguments</h4>
8+
geom &rarr; a geometry
9+
10+
<h4>Example</h4>
11+
<pre> xmin($geometry) &rarr; returns minimum x coordinate of $geometry</pre>
12+

‎resources/function_help/ymax‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<h3>ymax function</h3>
2+
Returns the maximum y coordinate of a geometry. Calculations are in the Spatial Reference System of this Geometry.
3+
4+
<h4>Syntax</h4>
5+
<pre>ymax(geom)</pre>
6+
7+
<h4>Arguments</h4>
8+
geom &rarr; a geometry
9+
10+
<h4>Example</h4>
11+
<pre> ymax($geometry) &rarr; returns maximum y coordinate of $geometry</pre>
12+

‎resources/function_help/ymin‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<h3>ymin function</h3>
2+
Returns the minimum y coordinate of a geometry. Calculations are in the Spatial Reference System of this Geometry.
3+
4+
<h4>Syntax</h4>
5+
<pre>ymin(geom)</pre>
6+
7+
<h4>Arguments</h4>
8+
geom &rarr; a geometry
9+
10+
<h4>Example</h4>
11+
<pre> ymin($geometry) &rarr; returns minimum y coordinate of $geometry</pre>
12+

‎src/core/qgsexpression.cpp‎

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,56 @@ static QVariant fcnGeomPerimeter( const QVariantList& , const QgsFeature* f, Qgs
10871087
return QVariant( calc->measurePerimeter( f->geometry() ) );
10881088
}
10891089

1090+
static QVariant fcnBounds( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1091+
{
1092+
QgsGeometry geom = getGeometry( values.at( 0 ), parent );
1093+
QgsGeometry* geomBounds = QgsGeometry::fromRect( geom.boundingBox() );
1094+
if ( geomBounds )
1095+
{
1096+
return QVariant::fromValue( *geomBounds );
1097+
}
1098+
else
1099+
{
1100+
return QVariant();
1101+
}
1102+
}
1103+
1104+
static QVariant fcnBoundsWidth( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1105+
{
1106+
QgsGeometry geom = getGeometry( values.at( 0 ), parent );
1107+
return QVariant::fromValue( geom.boundingBox().width() );
1108+
}
1109+
1110+
static QVariant fcnBoundsHeight( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1111+
{
1112+
QgsGeometry geom = getGeometry( values.at( 0 ), parent );
1113+
return QVariant::fromValue( geom.boundingBox().height() );
1114+
}
1115+
1116+
static QVariant fcnXMin( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1117+
{
1118+
QgsGeometry geom = getGeometry( values.at( 0 ), parent );
1119+
return QVariant::fromValue( geom.boundingBox().xMinimum() );
1120+
}
1121+
1122+
static QVariant fcnXMax( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1123+
{
1124+
QgsGeometry geom = getGeometry( values.at( 0 ), parent );
1125+
return QVariant::fromValue( geom.boundingBox().xMaximum() );
1126+
}
1127+
1128+
static QVariant fcnYMin( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1129+
{
1130+
QgsGeometry geom = getGeometry( values.at( 0 ), parent );
1131+
return QVariant::fromValue( geom.boundingBox().yMinimum() );
1132+
}
1133+
1134+
static QVariant fcnYMax( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
1135+
{
1136+
QgsGeometry geom = getGeometry( values.at( 0 ), parent );
1137+
return QVariant::fromValue( geom.boundingBox().yMaximum() );
1138+
}
1139+
10901140
static QVariant fcnBbox( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
10911141
{
10921142
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
@@ -1574,14 +1624,18 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
15741624
<< new StaticFunction( "color_hsva", 4, fncColorHsva, "Color" )
15751625
<< new StaticFunction( "color_cmyk", 4, fcnColorCmyk, "Color" )
15761626
<< new StaticFunction( "color_cmyka", 5, fncColorCmyka, "Color" )
1577-
<< new StaticFunction( "xat", 1, fcnXat, "Geometry", "", true )
1578-
<< new StaticFunction( "yat", 1, fcnYat, "Geometry", "", true )
1627+
<< new StaticFunction( "$geometry", 0, fcnGeometry, "Geometry", "" , true )
15791628
<< new StaticFunction( "$area", 0, fcnGeomArea, "Geometry", "", true )
15801629
<< new StaticFunction( "$length", 0, fcnGeomLength, "Geometry", "", true )
15811630
<< new StaticFunction( "$perimeter", 0, fcnGeomPerimeter, "Geometry", "", true )
15821631
<< new StaticFunction( "$x", 0, fcnX, "Geometry", "", true )
15831632
<< new StaticFunction( "$y", 0, fcnY, "Geometry", "" , true )
1584-
<< new StaticFunction( "$geometry", 0, fcnGeometry, "Geometry", "" , true )
1633+
<< new StaticFunction( "xat", 1, fcnXat, "Geometry", "", true )
1634+
<< new StaticFunction( "yat", 1, fcnYat, "Geometry", "", true )
1635+
<< new StaticFunction( "xmin", 1, fcnXMin, "Geometry", "", true )
1636+
<< new StaticFunction( "xmax", 1, fcnXMax, "Geometry", "", true )
1637+
<< new StaticFunction( "ymin", 1, fcnYMin, "Geometry", "", true )
1638+
<< new StaticFunction( "ymax", 1, fcnYMax, "Geometry", "", true )
15851639
<< new StaticFunction( "geomFromWKT", 1, fcnGeomFromWKT, "Geometry" )
15861640
<< new StaticFunction( "geomFromGML", 1, fcnGeomFromGML, "Geometry" )
15871641
<< new StaticFunction( "bbox", 2, fcnBbox, "Geometry" )
@@ -1594,6 +1648,9 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
15941648
<< new StaticFunction( "within", 2, fcnWithin, "Geometry" )
15951649
<< new StaticFunction( "buffer", -1, fcnBuffer, "Geometry" )
15961650
<< new StaticFunction( "centroid", 1, fcnCentroid, "Geometry" )
1651+
<< new StaticFunction( "bounds", 1, fcnBounds, "Geometry", "", true )
1652+
<< new StaticFunction( "bounds_width", 1, fcnBoundsWidth, "Geometry", "", true )
1653+
<< new StaticFunction( "bounds_height", 1, fcnBoundsHeight, "Geometry", "", true )
15971654
<< new StaticFunction( "convexHull", 1, fcnConvexHull, "Geometry" )
15981655
<< new StaticFunction( "difference", 2, fcnDifference, "Geometry" )
15991656
<< new StaticFunction( "distance", 2, fcnDistance, "Geometry" )

‎tests/src/core/testqgsexpression.cpp‎

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ class TestQgsExpression: public QObject
627627
{
628628
QgsPolyline polyline, polygon_ring;
629629
polyline << QgsPoint( 0, 0 ) << QgsPoint( 10, 0 );
630-
polygon_ring << QgsPoint( 1, 1 ) << QgsPoint( 6, 1 ) << QgsPoint( 6, 6 ) << QgsPoint( 1, 6 ) << QgsPoint( 1, 1 );
630+
polygon_ring << QgsPoint( 2, 1 ) << QgsPoint( 10, 1 ) << QgsPoint( 10, 6 ) << QgsPoint( 2, 6 ) << QgsPoint( 2, 1 );
631631
QgsPolygon polygon;
632632
polygon << polygon_ring;
633633
QgsFeature fPolygon, fPolyline;
@@ -636,15 +636,39 @@ class TestQgsExpression: public QObject
636636

637637
QgsExpression exp1( "$area" );
638638
QVariant vArea = exp1.evaluate( &fPolygon );
639-
QCOMPARE( vArea.toDouble(), 25. );
639+
QCOMPARE( vArea.toDouble(), 40. );
640640

641641
QgsExpression exp2( "$length" );
642642
QVariant vLength = exp2.evaluate( &fPolyline );
643643
QCOMPARE( vLength.toDouble(), 10. );
644644

645645
QgsExpression exp3( "$perimeter" );
646646
QVariant vPerimeter = exp3.evaluate( &fPolygon );
647-
QCOMPARE( vPerimeter.toDouble(), 20. );
647+
QCOMPARE( vPerimeter.toDouble(), 26. );
648+
649+
QgsExpression exp4( "bounds_width($geometry)" );
650+
QVariant vBoundsWidth = exp4.evaluate( &fPolygon );
651+
QCOMPARE( vBoundsWidth.toDouble(), 8.0 );
652+
653+
QgsExpression exp5( "bounds_height($geometry)" );
654+
QVariant vBoundsHeight = exp5.evaluate( &fPolygon );
655+
QCOMPARE( vBoundsHeight.toDouble(), 5.0 );
656+
657+
QgsExpression exp6( "xmin($geometry)" );
658+
QVariant vXMin = exp6.evaluate( &fPolygon );
659+
QCOMPARE( vXMin.toDouble(), 2.0 );
660+
661+
QgsExpression exp7( "xmax($geometry)" );
662+
QVariant vXMax = exp7.evaluate( &fPolygon );
663+
QCOMPARE( vXMax.toDouble(), 10.0 );
664+
665+
QgsExpression exp8( "ymin($geometry)" );
666+
QVariant vYMin = exp8.evaluate( &fPolygon );
667+
QCOMPARE( vYMin.toDouble(), 1.0 );
668+
669+
QgsExpression exp9( "ymax($geometry)" );
670+
QVariant vYMax = exp9.evaluate( &fPolygon );
671+
QCOMPARE( vYMax.toDouble(), 6.0 );
648672
}
649673

650674
void eval_geometry_constructor_data()
@@ -803,6 +827,8 @@ class TestQgsExpression: public QObject
803827
QTest::newRow( "convexHull simple" ) << "convexHull( $geometry )" << ( void* ) geom << false << true << ( void* ) geom->convexHull();
804828
geom = QgsGeometry::fromPolygon( polygon );
805829
QTest::newRow( "convexHull multi" ) << "convexHull( geomFromWKT('GEOMETRYCOLLECTION(POINT(0 1), POINT(0 0), POINT(1 0), POINT(1 1))') )" << ( void* ) geom << false << false << ( void* ) QgsGeometry::fromWkt( "POLYGON ((0 0,0 1,1 1,1 0,0 0))" );
830+
geom = QgsGeometry::fromPolygon( polygon );
831+
QTest::newRow( "bounds" ) << "bounds( $geometry )" << ( void* ) geom << false << true << ( void* ) QgsGeometry::fromRect( geom->boundingBox() );
806832
}
807833

808834
void eval_geometry_method()

0 commit comments

Comments
 (0)