add function $z for expression (#44776)

[feature] [expression] add function $z for expression
This commit is contained in:
Vincent Cloarec 2021-09-01 03:08:36 -04:00 committed by GitHub
parent 553bb27bc9
commit c2e607cbd7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 3 deletions

View File

@ -0,0 +1,8 @@
{
"name": "$z",
"type": "function",
"groups": ["GeometryGroup"],
"description": "Returns the z value of the current point feature if it is 3D. If the feature is a multipoint feature, then the z value of the first point will be returned.",
"examples": [ { "expression":"$z", "returns":"123"}
]
}

View File

@ -2426,6 +2426,40 @@ static QVariant fcnY( const QVariantList &, const QgsExpressionContext *context,
}
}
static QVariant fcnZ( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * )
{
FEAT_FROM_CONTEXT( context, f )
ENSURE_GEOM_TYPE( f, g, QgsWkbTypes::PointGeometry )
if ( g.isEmpty() )
return QVariant();
const QgsAbstractGeometry *abGeom = g.constGet();
if ( g.isEmpty() || !abGeom->is3D() )
return QVariant();
if ( g.type() == QgsWkbTypes::PointGeometry && !g.isMultipart() )
{
const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( g.constGet() );
if ( point )
return point->z();
}
else if ( g.type() == QgsWkbTypes::PointGeometry && g.isMultipart() )
{
if ( const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection * >( g.constGet() ) )
{
if ( collection->numGeometries() > 0 )
{
if ( const QgsPoint *point = qgsgeometry_cast< const QgsPoint * >( collection->geometryN( 0 ) ) )
return point->z();
}
}
}
return QVariant();
}
static QVariant fcnGeomIsValid( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
{
QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
@ -6794,6 +6828,10 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
yFunc->setIsStatic( false );
functions << yFunc;
QgsStaticExpressionFunction *zFunc = new QgsStaticExpressionFunction( QStringLiteral( "$z" ), 0, fcnZ, QStringLiteral( "GeometryGroup" ), QString(), true );
zFunc->setIsStatic( false );
functions << zFunc;
QMap< QString, QgsExpressionFunction::FcnEval > geometry_overlay_definitions
{
{ QStringLiteral( "overlay_intersects" ), fcnGeomOverlayIntersects },

View File

@ -2826,12 +2826,13 @@ class TestQgsExpression: public QObject
QTest::addColumn<bool>( "evalError" );
QTest::addColumn<QVariant>( "result" );
QgsPointXY point( 123, 456 );
QgsPoint point( 123, 456, 789 );
QgsPolylineXY line;
line << QgsPointXY( 1, 1 ) << QgsPointXY( 4, 2 ) << QgsPointXY( 3, 1 );
QTest::newRow( "geom x" ) << "$x" << QgsGeometry::fromPointXY( point ) << false << QVariant( 123. );
QTest::newRow( "geom y" ) << "$y" << QgsGeometry::fromPointXY( point ) << false << QVariant( 456. );
QTest::newRow( "geom x" ) << "$x" << QgsGeometry( std::make_unique<QgsPoint>( point ) ) << false << QVariant( 123. );
QTest::newRow( "geom y" ) << "$y" << QgsGeometry( std::make_unique<QgsPoint>( point ) ) << false << QVariant( 456. );
QTest::newRow( "geom z" ) << "$z" << QgsGeometry( std::make_unique<QgsPoint>( point ) ) << false << QVariant( 789. );
QTest::newRow( "geom xat" ) << "xat(-1)" << QgsGeometry::fromPolylineXY( line ) << false << QVariant( 3. );
QTest::newRow( "geom yat" ) << "yat(1)" << QgsGeometry::fromPolylineXY( line ) << false << QVariant( 2. );
QTest::newRow( "null geometry" ) << "$geometry" << QgsGeometry() << false << QVariant();