diff --git a/resources/function_help/bounds b/resources/function_help/bounds
new file mode 100644
index 00000000000..3dd42343bdc
--- /dev/null
+++ b/resources/function_help/bounds
@@ -0,0 +1,12 @@
+
bounds function
+Returns a geometry which represents the bounding box of an input geometry. Calculations are in the Spatial Reference System of this Geometry.
+
+Syntax
+bounds(geom)
+
+Arguments
+geom → a geometry
+
+Example
+ bounds($geometry) → returns bounding box of $geometry
+
diff --git a/resources/function_help/bounds_height b/resources/function_help/bounds_height
new file mode 100644
index 00000000000..86fe6af83ff
--- /dev/null
+++ b/resources/function_help/bounds_height
@@ -0,0 +1,12 @@
+bounds_height function
+Returns the height of the bounding box of a geometry. Calculations are in the Spatial Reference System of this Geometry.
+
+Syntax
+bounds_height(geom)
+
+Arguments
+geom → a geometry
+
+Example
+ bounds_height($geometry) → returns height of bounding box of $geometry
+
diff --git a/resources/function_help/bounds_width b/resources/function_help/bounds_width
new file mode 100644
index 00000000000..a053a115006
--- /dev/null
+++ b/resources/function_help/bounds_width
@@ -0,0 +1,12 @@
+bounds_width function
+Returns the width of the bounding box of a geometry. Calculations are in the Spatial Reference System of this Geometry.
+
+Syntax
+bounds_width(geom)
+
+Arguments
+geom → a geometry
+
+Example
+ bounds_width($geometry) → returns width of bounding box of $geometry
+
diff --git a/resources/function_help/xmax b/resources/function_help/xmax
new file mode 100644
index 00000000000..717a530a8e7
--- /dev/null
+++ b/resources/function_help/xmax
@@ -0,0 +1,12 @@
+xmax function
+Returns the maximum x coordinate of a geometry. Calculations are in the Spatial Reference System of this Geometry.
+
+Syntax
+xmax(geom)
+
+Arguments
+geom → a geometry
+
+Example
+ xmax($geometry) → returns maximum x coordinate of $geometry
+
diff --git a/resources/function_help/xmin b/resources/function_help/xmin
new file mode 100644
index 00000000000..e04c9076d18
--- /dev/null
+++ b/resources/function_help/xmin
@@ -0,0 +1,12 @@
+xmin function
+Returns the minimum x coordinate of a geometry. Calculations are in the Spatial Reference System of this Geometry.
+
+Syntax
+xmin(geom)
+
+Arguments
+geom → a geometry
+
+Example
+ xmin($geometry) → returns minimum x coordinate of $geometry
+
diff --git a/resources/function_help/ymax b/resources/function_help/ymax
new file mode 100644
index 00000000000..68d9a99bcd6
--- /dev/null
+++ b/resources/function_help/ymax
@@ -0,0 +1,12 @@
+ymax function
+Returns the maximum y coordinate of a geometry. Calculations are in the Spatial Reference System of this Geometry.
+
+Syntax
+ymax(geom)
+
+Arguments
+geom → a geometry
+
+Example
+ ymax($geometry) → returns maximum y coordinate of $geometry
+
diff --git a/resources/function_help/ymin b/resources/function_help/ymin
new file mode 100644
index 00000000000..e860a053136
--- /dev/null
+++ b/resources/function_help/ymin
@@ -0,0 +1,12 @@
+ymin function
+Returns the minimum y coordinate of a geometry. Calculations are in the Spatial Reference System of this Geometry.
+
+Syntax
+ymin(geom)
+
+Arguments
+geom → a geometry
+
+Example
+ ymin($geometry) → returns minimum y coordinate of $geometry
+
diff --git a/src/core/qgsexpression.cpp b/src/core/qgsexpression.cpp
index 041c56d37b4..66b4fbd4164 100644
--- a/src/core/qgsexpression.cpp
+++ b/src/core/qgsexpression.cpp
@@ -1087,6 +1087,56 @@ static QVariant fcnGeomPerimeter( const QVariantList& , const QgsFeature* f, Qgs
return QVariant( calc->measurePerimeter( f->geometry() ) );
}
+static QVariant fcnBounds( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
+{
+ QgsGeometry geom = getGeometry( values.at( 0 ), parent );
+ QgsGeometry* geomBounds = QgsGeometry::fromRect( geom.boundingBox() );
+ if ( geomBounds )
+ {
+ return QVariant::fromValue( *geomBounds );
+ }
+ else
+ {
+ return QVariant();
+ }
+}
+
+static QVariant fcnBoundsWidth( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
+{
+ QgsGeometry geom = getGeometry( values.at( 0 ), parent );
+ return QVariant::fromValue( geom.boundingBox().width() );
+}
+
+static QVariant fcnBoundsHeight( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
+{
+ QgsGeometry geom = getGeometry( values.at( 0 ), parent );
+ return QVariant::fromValue( geom.boundingBox().height() );
+}
+
+static QVariant fcnXMin( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
+{
+ QgsGeometry geom = getGeometry( values.at( 0 ), parent );
+ return QVariant::fromValue( geom.boundingBox().xMinimum() );
+}
+
+static QVariant fcnXMax( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
+{
+ QgsGeometry geom = getGeometry( values.at( 0 ), parent );
+ return QVariant::fromValue( geom.boundingBox().xMaximum() );
+}
+
+static QVariant fcnYMin( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
+{
+ QgsGeometry geom = getGeometry( values.at( 0 ), parent );
+ return QVariant::fromValue( geom.boundingBox().yMinimum() );
+}
+
+static QVariant fcnYMax( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
+{
+ QgsGeometry geom = getGeometry( values.at( 0 ), parent );
+ return QVariant::fromValue( geom.boundingBox().yMaximum() );
+}
+
static QVariant fcnBbox( const QVariantList& values, const QgsFeature* , QgsExpression* parent )
{
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
@@ -1574,14 +1624,18 @@ const QList &QgsExpression::Functions()
<< new StaticFunction( "color_hsva", 4, fncColorHsva, "Color" )
<< new StaticFunction( "color_cmyk", 4, fcnColorCmyk, "Color" )
<< new StaticFunction( "color_cmyka", 5, fncColorCmyka, "Color" )
- << new StaticFunction( "xat", 1, fcnXat, "Geometry", "", true )
- << new StaticFunction( "yat", 1, fcnYat, "Geometry", "", true )
+ << new StaticFunction( "$geometry", 0, fcnGeometry, "Geometry", "" , true )
<< new StaticFunction( "$area", 0, fcnGeomArea, "Geometry", "", true )
<< new StaticFunction( "$length", 0, fcnGeomLength, "Geometry", "", true )
<< new StaticFunction( "$perimeter", 0, fcnGeomPerimeter, "Geometry", "", true )
<< new StaticFunction( "$x", 0, fcnX, "Geometry", "", true )
<< new StaticFunction( "$y", 0, fcnY, "Geometry", "" , true )
- << new StaticFunction( "$geometry", 0, fcnGeometry, "Geometry", "" , true )
+ << new StaticFunction( "xat", 1, fcnXat, "Geometry", "", true )
+ << new StaticFunction( "yat", 1, fcnYat, "Geometry", "", true )
+ << new StaticFunction( "xmin", 1, fcnXMin, "Geometry", "", true )
+ << new StaticFunction( "xmax", 1, fcnXMax, "Geometry", "", true )
+ << new StaticFunction( "ymin", 1, fcnYMin, "Geometry", "", true )
+ << new StaticFunction( "ymax", 1, fcnYMax, "Geometry", "", true )
<< new StaticFunction( "geomFromWKT", 1, fcnGeomFromWKT, "Geometry" )
<< new StaticFunction( "geomFromGML", 1, fcnGeomFromGML, "Geometry" )
<< new StaticFunction( "bbox", 2, fcnBbox, "Geometry" )
@@ -1594,6 +1648,9 @@ const QList &QgsExpression::Functions()
<< new StaticFunction( "within", 2, fcnWithin, "Geometry" )
<< new StaticFunction( "buffer", -1, fcnBuffer, "Geometry" )
<< new StaticFunction( "centroid", 1, fcnCentroid, "Geometry" )
+ << new StaticFunction( "bounds", 1, fcnBounds, "Geometry", "", true )
+ << new StaticFunction( "bounds_width", 1, fcnBoundsWidth, "Geometry", "", true )
+ << new StaticFunction( "bounds_height", 1, fcnBoundsHeight, "Geometry", "", true )
<< new StaticFunction( "convexHull", 1, fcnConvexHull, "Geometry" )
<< new StaticFunction( "difference", 2, fcnDifference, "Geometry" )
<< new StaticFunction( "distance", 2, fcnDistance, "Geometry" )
diff --git a/tests/src/core/testqgsexpression.cpp b/tests/src/core/testqgsexpression.cpp
index d81d8002bd3..1311e380606 100644
--- a/tests/src/core/testqgsexpression.cpp
+++ b/tests/src/core/testqgsexpression.cpp
@@ -627,7 +627,7 @@ class TestQgsExpression: public QObject
{
QgsPolyline polyline, polygon_ring;
polyline << QgsPoint( 0, 0 ) << QgsPoint( 10, 0 );
- polygon_ring << QgsPoint( 1, 1 ) << QgsPoint( 6, 1 ) << QgsPoint( 6, 6 ) << QgsPoint( 1, 6 ) << QgsPoint( 1, 1 );
+ polygon_ring << QgsPoint( 2, 1 ) << QgsPoint( 10, 1 ) << QgsPoint( 10, 6 ) << QgsPoint( 2, 6 ) << QgsPoint( 2, 1 );
QgsPolygon polygon;
polygon << polygon_ring;
QgsFeature fPolygon, fPolyline;
@@ -636,7 +636,7 @@ class TestQgsExpression: public QObject
QgsExpression exp1( "$area" );
QVariant vArea = exp1.evaluate( &fPolygon );
- QCOMPARE( vArea.toDouble(), 25. );
+ QCOMPARE( vArea.toDouble(), 40. );
QgsExpression exp2( "$length" );
QVariant vLength = exp2.evaluate( &fPolyline );
@@ -644,7 +644,31 @@ class TestQgsExpression: public QObject
QgsExpression exp3( "$perimeter" );
QVariant vPerimeter = exp3.evaluate( &fPolygon );
- QCOMPARE( vPerimeter.toDouble(), 20. );
+ QCOMPARE( vPerimeter.toDouble(), 26. );
+
+ QgsExpression exp4( "bounds_width($geometry)" );
+ QVariant vBoundsWidth = exp4.evaluate( &fPolygon );
+ QCOMPARE( vBoundsWidth.toDouble(), 8.0 );
+
+ QgsExpression exp5( "bounds_height($geometry)" );
+ QVariant vBoundsHeight = exp5.evaluate( &fPolygon );
+ QCOMPARE( vBoundsHeight.toDouble(), 5.0 );
+
+ QgsExpression exp6( "xmin($geometry)" );
+ QVariant vXMin = exp6.evaluate( &fPolygon );
+ QCOMPARE( vXMin.toDouble(), 2.0 );
+
+ QgsExpression exp7( "xmax($geometry)" );
+ QVariant vXMax = exp7.evaluate( &fPolygon );
+ QCOMPARE( vXMax.toDouble(), 10.0 );
+
+ QgsExpression exp8( "ymin($geometry)" );
+ QVariant vYMin = exp8.evaluate( &fPolygon );
+ QCOMPARE( vYMin.toDouble(), 1.0 );
+
+ QgsExpression exp9( "ymax($geometry)" );
+ QVariant vYMax = exp9.evaluate( &fPolygon );
+ QCOMPARE( vYMax.toDouble(), 6.0 );
}
void eval_geometry_constructor_data()
@@ -803,6 +827,8 @@ class TestQgsExpression: public QObject
QTest::newRow( "convexHull simple" ) << "convexHull( $geometry )" << ( void* ) geom << false << true << ( void* ) geom->convexHull();
geom = QgsGeometry::fromPolygon( polygon );
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))" );
+ geom = QgsGeometry::fromPolygon( polygon );
+ QTest::newRow( "bounds" ) << "bounds( $geometry )" << ( void* ) geom << false << true << ( void* ) QgsGeometry::fromRect( geom->boundingBox() );
}
void eval_geometry_method()