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()