mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-15 00:07:25 -05:00
feature: add x_at, y_at, z_at and m_at expressions
This commit is contained in:
parent
ec689c52f1
commit
d8131a0791
18
resources/function_help/json/m_at
Normal file
18
resources/function_help/json/m_at
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "m_at",
|
||||
"type": "function",
|
||||
"groups": ["GeometryGroup"],
|
||||
"description": "Retrieves a m coordinate of the geometry, or NULL if the geometry has no m value.",
|
||||
"arguments": [{
|
||||
"arg": "geometry",
|
||||
"description": "geometry object"
|
||||
}, {
|
||||
"arg": "i",
|
||||
"description": "index of the vertex of the geometry (indices start at 0; negative values apply from the last index, starting at -1)"
|
||||
}],
|
||||
"examples": [{
|
||||
"expression": "m_at(geom_from_wkt('LineStringZM(0 0 0 0, 10 10 0 5, 10 10 0 0)'), 1)",
|
||||
"returns": "5"
|
||||
}],
|
||||
"tags": ["retrieves", "coordinate", "measure"]
|
||||
}
|
||||
18
resources/function_help/json/x_at
Normal file
18
resources/function_help/json/x_at
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "x_at",
|
||||
"type": "function",
|
||||
"groups": ["GeometryGroup"],
|
||||
"description": "Retrieves a x coordinate of the geometry.",
|
||||
"arguments": [{
|
||||
"arg": "geometry",
|
||||
"description": "geometry object"
|
||||
}, {
|
||||
"arg": "i",
|
||||
"description": "index of the vertex of the geometry (indices start at 0; negative values apply from the last index, starting at -1)"
|
||||
}],
|
||||
"examples": [{
|
||||
"expression": "x_at( geom_from_wkt( 'POINT(4 5)' ), 0 )",
|
||||
"returns": "4"
|
||||
}],
|
||||
"tags": ["retrieves", "coordinate"]
|
||||
}
|
||||
18
resources/function_help/json/y_at
Normal file
18
resources/function_help/json/y_at
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "y_at",
|
||||
"type": "function",
|
||||
"groups": ["GeometryGroup"],
|
||||
"description": "Retrieves a y coordinate of the geometry.",
|
||||
"arguments": [{
|
||||
"arg": "geometry",
|
||||
"description": "geometry object"
|
||||
}, {
|
||||
"arg": "i",
|
||||
"description": "index of the vertex of the geometry (indices start at 0; negative values apply from the last index, starting at -1)"
|
||||
}],
|
||||
"examples": [{
|
||||
"expression": "y_at( geom_from_wkt( 'POINT(4 5)' ), 0 )",
|
||||
"returns": "5"
|
||||
}],
|
||||
"tags": ["retrieves", "coordinate"]
|
||||
}
|
||||
18
resources/function_help/json/z_at
Normal file
18
resources/function_help/json/z_at
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "z_at",
|
||||
"type": "function",
|
||||
"groups": ["GeometryGroup"],
|
||||
"description": "Retrieves a z coordinate of the geometry, or NULL if the geometry has no z value.",
|
||||
"arguments": [{
|
||||
"arg": "geometry",
|
||||
"description": "geometry object"
|
||||
}, {
|
||||
"arg": "i",
|
||||
"description": "index of the vertex of the geometry (indices start at 0; negative values apply from the last index, starting at -1)"
|
||||
}],
|
||||
"examples": [{
|
||||
"expression": "z_at(geom_from_wkt('LineStringZ(0 0 0, 10 10 5, 10 10 0)'), 1)",
|
||||
"returns": "5"
|
||||
}],
|
||||
"tags": ["retrieves", "coordinate", "3D"]
|
||||
}
|
||||
@ -3778,44 +3778,134 @@ static QVariant fcnMakeRectangleFrom3Points( const QVariantList &values, const Q
|
||||
return QVariant::fromValue( QgsGeometry( rect.toPolygon() ) );
|
||||
}
|
||||
|
||||
static QVariant pointAt( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent ) // helper function
|
||||
static QVariant pointAt( const QgsGeometry &geom, int idx, QgsExpression *parent ) // helper function
|
||||
{
|
||||
FEAT_FROM_CONTEXT( context, f )
|
||||
int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
|
||||
QgsGeometry g = f.geometry();
|
||||
if ( g.isNull() )
|
||||
if ( geom.isNull() )
|
||||
return QVariant();
|
||||
|
||||
if ( idx < 0 )
|
||||
{
|
||||
idx += g.constGet()->nCoordinates();
|
||||
idx += geom.constGet()->nCoordinates();
|
||||
}
|
||||
if ( idx < 0 || idx >= g.constGet()->nCoordinates() )
|
||||
if ( idx < 0 || idx >= geom.constGet()->nCoordinates() )
|
||||
{
|
||||
parent->setEvalErrorString( QObject::tr( "Index is out of range" ) );
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QgsPointXY p = g.vertexAt( idx );
|
||||
return QVariant( QPointF( p.x(), p.y() ) );
|
||||
return QVariant::fromValue( geom.vertexAt( idx ) );
|
||||
}
|
||||
|
||||
static QVariant fcnXat( const QVariantList &values, const QgsExpressionContext *f, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
// function used for the old $ style
|
||||
static QVariant fcnOldXat( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
QVariant v = pointAt( values, f, parent );
|
||||
if ( v.type() == QVariant::PointF )
|
||||
return QVariant( v.toPointF().x() );
|
||||
FEAT_FROM_CONTEXT( context, feature )
|
||||
const QgsGeometry geom = feature.geometry();
|
||||
int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
|
||||
|
||||
QVariant v = pointAt( geom, idx, parent );
|
||||
|
||||
if ( !v.isNull() )
|
||||
return QVariant( v.value<QgsPoint>().x() );
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
static QVariant fcnYat( const QVariantList &values, const QgsExpressionContext *f, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
static QVariant fcnXat( const QVariantList &values, const QgsExpressionContext *f, QgsExpression *parent, const QgsExpressionNodeFunction *node )
|
||||
{
|
||||
QVariant v = pointAt( values, f, parent );
|
||||
if ( v.type() == QVariant::PointF )
|
||||
return QVariant( v.toPointF().y() );
|
||||
if ( values.at( 1 ).isNull() || values.at( 0 ).isNull() ) // the case where the alias x_at function is called like a $ function (x_at(i))
|
||||
{
|
||||
return fcnOldXat( values, f, parent, node );
|
||||
}
|
||||
else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() ) // same as above with x_at(i:=0) (this values is at the second position)
|
||||
{
|
||||
return fcnOldXat( QVariantList() << values[1], f, parent, node );
|
||||
}
|
||||
|
||||
QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
|
||||
int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent ); // Should be one or 0 ???
|
||||
if ( geom.isNull() )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant v = pointAt( geom, vertexNumber, parent );
|
||||
if ( !v.isNull() )
|
||||
return QVariant( v.value<QgsPoint>().x() );
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
// function used for the old $ style
|
||||
static QVariant fcnOldYat( const QVariantList &values, const QgsExpressionContext *context, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
FEAT_FROM_CONTEXT( context, feature )
|
||||
const QgsGeometry geom = feature.geometry();
|
||||
int idx = QgsExpressionUtils::getNativeIntValue( values.at( 0 ), parent );
|
||||
|
||||
QVariant v = pointAt( geom, idx, parent );
|
||||
|
||||
if ( !v.isNull() )
|
||||
return QVariant( v.value<QgsPoint>().y() );
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
static QVariant fcnYat( const QVariantList &values, const QgsExpressionContext *f, QgsExpression *parent, const QgsExpressionNodeFunction *node )
|
||||
{
|
||||
if ( values.at( 1 ).isNull() ) // the case where the alias y_at function is called like a $ function (y_at(i))
|
||||
{
|
||||
return fcnOldYat( values, f, parent, node );
|
||||
}
|
||||
else if ( values.at( 0 ).isNull() && !values.at( 1 ).isNull() ) // same as above with x_at(i:=0) (this values is at the second position)
|
||||
{
|
||||
return fcnOldYat( QVariantList() << values[1], f, parent, node );
|
||||
}
|
||||
|
||||
QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
|
||||
int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
|
||||
if ( geom.isNull() )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant v = pointAt( geom, vertexNumber, parent );
|
||||
if ( !v.isNull() )
|
||||
return QVariant( v.value<QgsPoint>().y() );
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
static QVariant fcnZat( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
|
||||
int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
|
||||
if ( geom.isNull() )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant v = pointAt( geom, vertexNumber, parent );
|
||||
if ( !v.isNull() && v.value<QgsPoint>().is3D() )
|
||||
return QVariant( v.value<QgsPoint>().z() );
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
static QVariant fcnMat( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
QgsGeometry geom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
|
||||
int vertexNumber = QgsExpressionUtils::getNativeIntValue( values.at( 1 ), parent );
|
||||
if ( geom.isNull() )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QVariant v = pointAt( geom, vertexNumber, parent );
|
||||
if ( !v.isNull() && v.value<QgsPoint>().isMeasure() )
|
||||
return QVariant( v.value<QgsPoint>().m() );
|
||||
else
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
|
||||
static QVariant fcnGeometry( const QVariantList &, const QgsExpressionContext *context, QgsExpression *, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
if ( !context )
|
||||
@ -8022,11 +8112,18 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
|
||||
#endif
|
||||
QgsExpressionFunction::Parameter( QStringLiteral( "keep_collapsed" ), true, false )
|
||||
}, fcnGeomMakeValid, QStringLiteral( "GeometryGroup" ) );
|
||||
QgsStaticExpressionFunction *xAtFunc = new QgsStaticExpressionFunction( QStringLiteral( "$x_at" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "i" ) ), fcnXat, QStringLiteral( "GeometryGroup" ), QString(), true, QSet<QString>(), false, QStringList() << QStringLiteral( "xat" ) << QStringLiteral( "x_at" ) );
|
||||
|
||||
functions << new QgsStaticExpressionFunction( QStringLiteral( "x_at" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ), true ) << QgsExpressionFunction::Parameter( QStringLiteral( "i" ), true ), fcnXat, QStringLiteral( "GeometryGroup" ) );
|
||||
functions << new QgsStaticExpressionFunction( QStringLiteral( "y_at" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ), true ) << QgsExpressionFunction::Parameter( QStringLiteral( "i" ), true ), fcnYat, QStringLiteral( "GeometryGroup" ) );
|
||||
functions << new QgsStaticExpressionFunction( QStringLiteral( "z_at" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "i" ), true ), fcnZat, QStringLiteral( "GeometryGroup" ) );
|
||||
functions << new QgsStaticExpressionFunction( QStringLiteral( "m_at" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) ) << QgsExpressionFunction::Parameter( QStringLiteral( "i" ), true ), fcnMat, QStringLiteral( "GeometryGroup" ) );
|
||||
|
||||
QgsStaticExpressionFunction *xAtFunc = new QgsStaticExpressionFunction( QStringLiteral( "$x_at" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "i" ) ), fcnOldXat, QStringLiteral( "GeometryGroup" ), QString(), true, QSet<QString>(), false, QStringList() << QStringLiteral( "xat" ) );
|
||||
xAtFunc->setIsStatic( false );
|
||||
functions << xAtFunc;
|
||||
|
||||
QgsStaticExpressionFunction *yAtFunc = new QgsStaticExpressionFunction( QStringLiteral( "$y_at" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "i" ) ), fcnYat, QStringLiteral( "GeometryGroup" ), QString(), true, QSet<QString>(), false, QStringList() << QStringLiteral( "yat" ) << QStringLiteral( "y_at" ) );
|
||||
|
||||
QgsStaticExpressionFunction *yAtFunc = new QgsStaticExpressionFunction( QStringLiteral( "$y_at" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "i" ) ), fcnOldYat, QStringLiteral( "GeometryGroup" ), QString(), true, QSet<QString>(), false, QStringList() << QStringLiteral( "yat" ) );
|
||||
yAtFunc->setIsStatic( false );
|
||||
functions << yAtFunc;
|
||||
|
||||
|
||||
@ -3233,21 +3233,51 @@ 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 );
|
||||
QgsPolylineXY polygon_ring;
|
||||
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, fPolylineZ;
|
||||
QgsGeometry polylineGeom = QgsGeometry::fromPolylineXY( polyline );
|
||||
fPolyline.setGeometry( polylineGeom );
|
||||
QgsGeometry polylineZGeom = QgsGeometry::fromPolyline( polylineZ );
|
||||
fPolylineZ.setGeometry( polylineZGeom );
|
||||
QgsGeometry polygonGeom = QgsGeometry::fromPolygonXY( polygon );
|
||||
QgsPolygonXY polygonXY;
|
||||
polygonXY << polygon_ring;
|
||||
QgsGeometry polygonGeom = QgsGeometry::fromPolygonXY( polygonXY );
|
||||
QgsFeature fPolygon;
|
||||
fPolygon.setGeometry( polygonGeom );
|
||||
|
||||
QgsPolylineXY polyline;
|
||||
polyline << QgsPointXY( 0, 0 ) << QgsPointXY( 10, 0 );
|
||||
QgsGeometry polylineGeom = QgsGeometry::fromPolylineXY( polyline );
|
||||
QgsFeature fPolyline;
|
||||
fPolyline.setGeometry( polylineGeom );
|
||||
|
||||
QgsPolyline polylineZ;
|
||||
polylineZ << QgsPoint( 0, 0, 0 ) << QgsPoint( 3, 0, 4 );
|
||||
QgsGeometry polylineZGeom = QgsGeometry::fromPolyline( polylineZ );
|
||||
QgsFeature fPolylineZ;
|
||||
fPolylineZ.setGeometry( polylineZGeom );
|
||||
|
||||
QgsPolyline polylineM;
|
||||
polylineM << QgsPoint( QgsWkbTypes::PointM, 0, 0, 0, 0 ) << QgsPoint( QgsWkbTypes::PointM, 3, 0, 0, 8 );
|
||||
QgsGeometry polylineMGeom = QgsGeometry::fromPolyline( polylineM );
|
||||
QgsFeature fPolylineM;
|
||||
fPolylineM.setGeometry( polylineMGeom );
|
||||
|
||||
QgsPolyline polylineZM;
|
||||
polylineZM << QgsPoint( QgsWkbTypes::PointZM, 0, 0, 0, 0 ) << QgsPoint( QgsWkbTypes::PointZM, 3, 0, 4, 8 );
|
||||
QgsGeometry polylineZMGeom = QgsGeometry::fromPolyline( polylineZM );
|
||||
QgsFeature fPolylineZM;
|
||||
fPolylineZM.setGeometry( polylineZMGeom );
|
||||
|
||||
QgsMultiLineString mls;
|
||||
QgsLineString part;
|
||||
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 10, 10, 10, 10 )
|
||||
<< QgsPoint( QgsWkbTypes::PointZM, 20, 20, 20, 20 ) );
|
||||
mls.addGeometry( part.clone() );
|
||||
part.setPoints( QgsPointSequence() << QgsPoint( QgsWkbTypes::PointZM, 30, 30, 30, 30 )
|
||||
<< QgsPoint( QgsWkbTypes::PointZM, 40, 40, 40, 40 ) );
|
||||
mls.addGeometry( part.clone() );
|
||||
QgsGeometry multiStringZMGeom;
|
||||
multiStringZMGeom.set( mls.clone() );
|
||||
QgsFeature fMultiLineStringZM;
|
||||
fMultiLineStringZM.setGeometry( multiStringZMGeom );
|
||||
|
||||
QgsExpressionContext context;
|
||||
|
||||
QgsExpression exp1( QStringLiteral( "$area" ) );
|
||||
@ -3266,59 +3296,174 @@ class TestQgsExpression: public QObject
|
||||
QCOMPARE( vPerimeter.toDouble(), 26. );
|
||||
|
||||
QgsExpression deprecatedExpXAt( QStringLiteral( "$x_at(1)" ) );
|
||||
QgsExpression expXAt( QStringLiteral( "x_at(@geometry, 1)" ) );
|
||||
context.setFeature( fPolygon );
|
||||
QVariant xAt = deprecatedExpXAt.evaluate( &context );
|
||||
QCOMPARE( xAt.toDouble(), 10.0 );
|
||||
xAt = expXAt.evaluate( &context );
|
||||
QCOMPARE( xAt.toDouble(), 10.0 );
|
||||
context.setFeature( fPolyline );
|
||||
xAt = deprecatedExpXAt.evaluate( &context );
|
||||
QCOMPARE( xAt.toDouble(), 10.0 );
|
||||
xAt = expXAt.evaluate( &context );
|
||||
QCOMPARE( xAt.toDouble(), 10.0 );
|
||||
|
||||
QgsExpression deprecatedExpXAtNeg( QStringLiteral( "$x_at(-2)" ) );
|
||||
QgsExpression expXAtNeg( QStringLiteral( "x_at(@geometry, -2)" ) );
|
||||
context.setFeature( fPolygon );
|
||||
xAt = deprecatedExpXAtNeg.evaluate( &context );
|
||||
QCOMPARE( xAt.toDouble(), 2.0 );
|
||||
xAt = expXAtNeg.evaluate( &context );
|
||||
QCOMPARE( xAt.toDouble(), 2.0 );
|
||||
|
||||
QgsExpression deprecatedExpYAt( QStringLiteral( "$y_at(2)" ) );
|
||||
QgsExpression expYAt( QStringLiteral( "y_at(@geometry, 2)" ) );
|
||||
context.setFeature( fPolygon );
|
||||
QVariant yAt = deprecatedExpYAt.evaluate( &context );
|
||||
QCOMPARE( yAt.toDouble(), 6.0 );
|
||||
yAt = expYAt.evaluate( &context );
|
||||
QCOMPARE( yAt.toDouble(), 6.0 );
|
||||
QgsExpression deprecatedExpYAt2( QStringLiteral( "$y_at(1)" ) );
|
||||
QgsExpression expYAt2( QStringLiteral( "y_at(@geometry, 1)" ) );
|
||||
context.setFeature( fPolyline );
|
||||
yAt = deprecatedExpYAt2.evaluate( &context );
|
||||
QCOMPARE( yAt.toDouble(), 0.0 );
|
||||
|
||||
QgsExpression deprecatedExpYAtNeg( QStringLiteral( "$y_at(-2)" ) );
|
||||
QgsExpression expYAtNeg( QStringLiteral( "y_at(@geometry, -2)" ) );
|
||||
context.setFeature( fPolygon );
|
||||
yAt = deprecatedExpYAtNeg.evaluate( &context );
|
||||
QCOMPARE( yAt.toDouble(), 6.0 );
|
||||
yAt = expYAtNeg.evaluate( &context );
|
||||
QCOMPARE( yAt.toDouble(), 6.0 );
|
||||
|
||||
QgsExpression expXAt( QStringLiteral( "x_at(1)" ) );
|
||||
QgsExpression deprecatedAliasexpXAt( QStringLiteral( "x_at(1)" ) );
|
||||
context.setFeature( fPolygon );
|
||||
xAt = expXAt.evaluate( &context );
|
||||
xAt = deprecatedAliasexpXAt.evaluate( &context );
|
||||
QCOMPARE( xAt.toDouble(), 10.0 );
|
||||
QgsExpression deprecatedAliasexpXAt2( QStringLiteral( "x_at(1)" ) );
|
||||
context.setFeature( fPolyline );
|
||||
xAt = expXAt.evaluate( &context );
|
||||
xAt = deprecatedAliasexpXAt2.evaluate( &context );
|
||||
QCOMPARE( xAt.toDouble(), 10.0 );
|
||||
|
||||
QgsExpression expXAtNeg( QStringLiteral( "x_at(-2)" ) );
|
||||
QgsExpression deprecatedAliasexpYAt( QStringLiteral( "y_at(1)" ) );
|
||||
context.setFeature( fPolygon );
|
||||
yAt = deprecatedAliasexpYAt.evaluate( &context );
|
||||
QCOMPARE( yAt.toDouble(), 1.0 );
|
||||
QgsExpression deprecatedAliasexpYAt2( QStringLiteral( "y_at(1)" ) );
|
||||
context.setFeature( fPolyline );
|
||||
yAt = deprecatedAliasexpYAt2.evaluate( &context );
|
||||
QCOMPARE( yAt.toDouble(), 0.0 );
|
||||
|
||||
// with a ZM geometry
|
||||
expXAt = QgsExpression( QStringLiteral( "x_at(@geometry, 2)" ) );
|
||||
context.setFeature( fMultiLineStringZM );
|
||||
xAt = expXAt.evaluate( &context );
|
||||
QCOMPARE( xAt.toDouble(), 30.0 );
|
||||
|
||||
QgsExpression expXAtNeg2( QStringLiteral( "x_at(@geometry, -2)" ) );
|
||||
context.setFeature( fPolygon );
|
||||
xAt = expXAtNeg.evaluate( &context );
|
||||
QCOMPARE( xAt.toDouble(), 2.0 );
|
||||
|
||||
QgsExpression expYAt( QStringLiteral( "y_at(2)" ) );
|
||||
QgsExpression expYAt3( QStringLiteral( "y_at(@geometry, 2)" ) );
|
||||
context.setFeature( fPolygon );
|
||||
yAt = expYAt.evaluate( &context );
|
||||
QCOMPARE( yAt.toDouble(), 6.0 );
|
||||
QgsExpression expYAt2( QStringLiteral( "$y_at(1)" ) );
|
||||
QgsExpression expYAt4( QStringLiteral( "y_at(@geometry, 1)" ) );
|
||||
context.setFeature( fPolyline );
|
||||
yAt = expYAt2.evaluate( &context );
|
||||
QCOMPARE( yAt.toDouble(), 0.0 );
|
||||
|
||||
QgsExpression expYAtNeg( QStringLiteral( "y_at(-2)" ) );
|
||||
// with a ZM geometry
|
||||
expYAt2 = QgsExpression( QStringLiteral( "y_at(@geometry, 2)" ) );
|
||||
context.setFeature( fMultiLineStringZM );
|
||||
yAt = expYAt2.evaluate( &context );
|
||||
QCOMPARE( yAt.toDouble(), 30.0 );
|
||||
|
||||
QgsExpression expYAtNeg2( QStringLiteral( "y_at(@geometry, -2)" ) );
|
||||
context.setFeature( fPolygon );
|
||||
yAt = expYAtNeg.evaluate( &context );
|
||||
yAt = expYAtNeg2.evaluate( &context );
|
||||
QCOMPARE( yAt.toDouble(), 6.0 );
|
||||
|
||||
// Test z_at
|
||||
|
||||
// a basic case
|
||||
QgsExpression expZAt( QStringLiteral( "z_at(@geometry, 1)" ) );
|
||||
context.setFeature( fPolylineZ );
|
||||
QVariant zAt = expZAt.evaluate( &context );
|
||||
QCOMPARE( zAt.toDouble(), 4.0 );
|
||||
|
||||
// with a negative range
|
||||
expZAt = QgsExpression( QStringLiteral( "z_at(@geometry, -1)" ) );
|
||||
context.setFeature( fPolylineZ );
|
||||
zAt = expZAt.evaluate( &context );
|
||||
QCOMPARE( zAt.toDouble(), 4.0 );
|
||||
|
||||
// with an index out of range
|
||||
expZAt = QgsExpression( QStringLiteral( "z_at(@geometry, 3)" ) );
|
||||
// even with a no Z geometry, an eval error should be raised.
|
||||
context.setFeature( fPolyline );
|
||||
zAt = expZAt.evaluate( &context );
|
||||
QVERIFY( expZAt.hasEvalError() );
|
||||
|
||||
// with a geom with no Z
|
||||
expZAt = QgsExpression( QStringLiteral( "z_at(@geometry, 1)" ) );
|
||||
context.setFeature( fPolyline );
|
||||
zAt = expZAt.evaluate( &context );
|
||||
QVERIFY( zAt.isNull() );
|
||||
|
||||
// with a geom with no Z but with M
|
||||
expZAt = QStringLiteral( "z_at(@geometry, 1)" );
|
||||
context.setFeature( fPolylineM );
|
||||
zAt = expZAt.evaluate( &context );
|
||||
QVERIFY( zAt.isNull() );
|
||||
|
||||
// with a multi geom
|
||||
expZAt = QStringLiteral( "z_at(@geometry, 2)" );
|
||||
context.setFeature( fMultiLineStringZM );
|
||||
zAt = expZAt.evaluate( &context );
|
||||
QCOMPARE( zAt.toDouble(), 30.0 );
|
||||
|
||||
// Test m_at
|
||||
|
||||
// a basic case
|
||||
QgsExpression expMAt( QStringLiteral( "m_at(@geometry, 1)" ) );
|
||||
context.setFeature( fPolylineM );
|
||||
QVariant mAt = expMAt.evaluate( &context );
|
||||
QCOMPARE( mAt.toDouble(), 8.0 );
|
||||
|
||||
// with a negative range
|
||||
expMAt = QgsExpression( QStringLiteral( "m_at(@geometry, -1)" ) );
|
||||
context.setFeature( fPolylineM );
|
||||
mAt = expMAt.evaluate( &context );
|
||||
QCOMPARE( mAt.toDouble(), 8.0 );
|
||||
|
||||
// with an index out of range
|
||||
expMAt = QgsExpression( QStringLiteral( "m_at(@geometry, 3)" ) );
|
||||
// even with a no M geometry, an eval error should be raised.
|
||||
context.setFeature( fPolyline );
|
||||
mAt = expMAt.evaluate( &context );
|
||||
QVERIFY( expMAt.hasEvalError() );
|
||||
|
||||
// with a geom with no M
|
||||
expMAt = QgsExpression( QStringLiteral( "m_at(@geometry, 1)" ) );
|
||||
context.setFeature( fPolyline );
|
||||
mAt = expMAt.evaluate( &context );
|
||||
QVERIFY( mAt.isNull() );
|
||||
|
||||
// with a geom with no M but with Z
|
||||
expMAt = QStringLiteral( "m_at(@geometry, 1)" );
|
||||
context.setFeature( fPolylineZ );
|
||||
mAt = expMAt.evaluate( &context );
|
||||
QVERIFY( mAt.isNull() );
|
||||
|
||||
// with a multi geom
|
||||
expMAt = QStringLiteral( "m_at(@geometry, 3)" );
|
||||
context.setFeature( fMultiLineStringZM );
|
||||
mAt = expMAt.evaluate( &context );
|
||||
QCOMPARE( mAt.toDouble(), 40.0 );
|
||||
|
||||
QgsExpression exp4( QStringLiteral( "bounds_width($geometry)" ) );
|
||||
context.setFeature( fPolygon );
|
||||
QVariant vBoundsWidth = exp4.evaluate( &context );
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user