mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-06 00:07:29 -04:00
[feature][expressions] Add "length3D" function to return the 3D length
of a LineGeometry type geometry using QgsLineString::length3D(). If the geometry is not a 3D line string, it returns its 2D length.
This commit is contained in:
parent
4b8baddee2
commit
d7167e48d0
8
resources/function_help/json/length3D
Normal file
8
resources/function_help/json/length3D
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "length3D",
|
||||
"type": "function",
|
||||
"groups": ["GeometryGroup"],
|
||||
"description": "Calculates the 3D length of a geometry line object. If the geometry is not a 3D line object, it returns its 2D length. Calculations are always planimetric in the Spatial Reference System (SRS) of this geometry, and the units of the returned length will match the units for the SRS. This differs from the calculations performed by the $length function, which will perform ellipsoidal calculations based on the project's ellipsoid and distance unit settings.",
|
||||
"arguments": [ {"arg":"geometry","description":"line geometry object"}],
|
||||
"examples": [ { "expression":"length3D(geom_from_wkt('LINESTRINGZ(0 0 0, 3 0 4)'))", "returns":"5.0"}]
|
||||
}
|
@ -1357,6 +1357,16 @@ static QVariant fcnLength( const QVariantList &values, const QgsExpressionContex
|
||||
return QVariant( str.length() );
|
||||
}
|
||||
|
||||
static QVariant fcnLength3D( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
|
||||
|
||||
if ( geom.type() != QgsWkbTypes::LineGeometry )
|
||||
return QVariant();
|
||||
|
||||
return QVariant( qgsgeometry_cast< const QgsLineString * >( geom.constGet() )->length3D() );
|
||||
}
|
||||
|
||||
static QVariant fcnReplace( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
if ( values.count() == 2 && values.at( 1 ).type() == QVariant::Map )
|
||||
@ -6428,6 +6438,7 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "ascii" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "string" ) ), fcnAscii, QStringLiteral( "String" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "wordwrap" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "text" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "length" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "delimiter" ), true, "" ), fcnWordwrap, QStringLiteral( "String" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "length" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "text" ), true, "" ), fcnLength, QStringList() << QStringLiteral( "String" ) << QStringLiteral( "GeometryGroup" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "length3D" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) ), fcnLength3D, QStringLiteral( "GeometryGroup" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "replace" ), -1, fcnReplace, QStringLiteral( "String" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "regexp_replace" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "input_string" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "regex" ) )
|
||||
<< QgsExpressionFunction::Parameter( QStringLiteral( "replacement" ) ), fcnRegexpReplace, QStringLiteral( "String" ) )
|
||||
|
@ -941,6 +941,10 @@ class TestQgsExpression: public QObject
|
||||
QTest::newRow( "length line" ) << "length(geom_from_wkt('LINESTRING(0 0, 4 0)'))" << false << QVariant( 4.0 );
|
||||
QTest::newRow( "length polygon" ) << "length(geom_from_wkt('POLYGON((0 0, 4 0, 4 2, 0 2, 0 0))'))" << false << QVariant();
|
||||
QTest::newRow( "length point" ) << "length(geom_from_wkt('POINT(0 0)'))" << false << QVariant();
|
||||
QTest::newRow( "length3D lineZ" ) << "length3D(geom_from_wkt('LINESTRINGZ(0 0 0, 3 0 4)'))" << false << QVariant( 5.0 );
|
||||
QTest::newRow( "length3D line" ) << "length3D(geom_from_wkt('LINESTRING(0 0, 4 0)'))" << false << QVariant( 4.0 );
|
||||
QTest::newRow( "length3D polygon" ) << "length3D(geom_from_wkt('POLYGON((0 0, 4 0, 4 2, 0 2, 0 0))'))" << false << QVariant();
|
||||
QTest::newRow( "length3D point" ) << "length3D(geom_from_wkt('POINT(0 0)'))" << false << QVariant();
|
||||
QTest::newRow( "area polygon" ) << "area(geom_from_wkt('POLYGON((0 0, 4 0, 4 2, 0 2, 0 0))'))" << false << QVariant( 8.0 );
|
||||
QTest::newRow( "area line" ) << "area(geom_from_wkt('LINESTRING(0 0, 4 0)'))" << false << QVariant();
|
||||
QTest::newRow( "area point" ) << "area(geom_from_wkt('POINT(0 0)'))" << false << QVariant();
|
||||
@ -2775,13 +2779,17 @@ class TestQgsExpression: public QObject
|
||||
void eval_geometry_calc()
|
||||
{
|
||||
QgsPolylineXY polyline, polygon_ring;
|
||||
QgsPolyline polylineZ;
|
||||
polyline << QgsPointXY( 0, 0 ) << QgsPointXY( 10, 0 );
|
||||
polylineZ << QgsPoint( 0, 0, 0 ) << QgsPoint( 3, 0, 4 );
|
||||
polygon_ring << QgsPointXY( 2, 1 ) << QgsPointXY( 10, 1 ) << QgsPointXY( 10, 6 ) << QgsPointXY( 2, 6 ) << QgsPointXY( 2, 1 );
|
||||
QgsPolygonXY polygon;
|
||||
polygon << polygon_ring;
|
||||
QgsFeature fPolygon, fPolyline;
|
||||
QgsFeature fPolygon, fPolyline, fPolylineZ;
|
||||
QgsGeometry polylineGeom = QgsGeometry::fromPolylineXY( polyline );
|
||||
fPolyline.setGeometry( polylineGeom );
|
||||
QgsGeometry polylineZGeom = QgsGeometry::fromPolyline( polylineZ );
|
||||
fPolylineZ.setGeometry( polylineZGeom );
|
||||
QgsGeometry polygonGeom = QgsGeometry::fromPolygonXY( polygon );
|
||||
fPolygon.setGeometry( polygonGeom );
|
||||
|
||||
@ -2898,6 +2906,11 @@ class TestQgsExpression: public QObject
|
||||
QgsExpression exp13( QStringLiteral( "perimeter($geometry)" ) );
|
||||
QVariant vPerimeterPoly = exp13.evaluate( &context );
|
||||
QCOMPARE( vPerimeterPoly.toDouble(), 26.0 );
|
||||
|
||||
context.setFeature( fPolylineZ );
|
||||
QgsExpression exp14( QStringLiteral( "length3D($geometry)" ) );
|
||||
QVariant vLengthLineZ = exp14.evaluate( &context );
|
||||
QCOMPARE( vLengthLineZ.toDouble(), 5.0 );
|
||||
}
|
||||
|
||||
void geom_calculator()
|
||||
|
Loading…
x
Reference in New Issue
Block a user