mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-07 00:03:52 -05:00
[expressions] Add 'reverse' variant for reversing a string
Allows using a string argument for the reverse function, which returns a reversed version of the string
This commit is contained in:
parent
117a69e465
commit
59d6850aac
@ -1,15 +1,30 @@
|
||||
{
|
||||
"name": "reverse",
|
||||
"type": "function",
|
||||
"groups": ["GeometryGroup"],
|
||||
"description": "Reverses the direction of a line string by reversing the order of its vertices.",
|
||||
"arguments": [{
|
||||
"arg": "geometry",
|
||||
"description": "a geometry"
|
||||
}],
|
||||
"examples": [{
|
||||
"expression": "geom_to_wkt(reverse(geom_from_wkt('LINESTRING(0 0, 1 1, 2 2)')))",
|
||||
"returns": "'LINESTRING(2 2, 1 1, 0 0)'"
|
||||
"groups": ["String", "GeometryGroup"],
|
||||
"description": "Reverses the direction of a line string or reverses a string of text.",
|
||||
"variants": [{
|
||||
"variant": "String variant",
|
||||
"variant_description": "Reverses the order of characters in a string.",
|
||||
"arguments": [{
|
||||
"arg": "string",
|
||||
"description": "string to reverse"
|
||||
}],
|
||||
"examples": [{
|
||||
"expression": "reverse('hello')",
|
||||
"returns": "'olleh'"
|
||||
}]
|
||||
}, {
|
||||
"variant": "Geometry variant",
|
||||
"variant_description": "Reverses the direction of a line string by reversing the order of its vertices.",
|
||||
"arguments": [{
|
||||
"arg": "geometry",
|
||||
"description": "a geometry"
|
||||
}],
|
||||
"examples": [{
|
||||
"expression": "geom_to_wkt(reverse(geom_from_wkt('LINESTRING(0 0, 1 1, 2 2)')))",
|
||||
"returns": "'LINESTRING(2 2, 1 1, 0 0)'"
|
||||
}]
|
||||
}],
|
||||
"tags": ["direction", "order", "vertices", "reverses", "line", "reversing"]
|
||||
}
|
||||
|
||||
@ -5252,38 +5252,48 @@ static QVariant fcnDifference( const QVariantList &values, const QgsExpressionCo
|
||||
|
||||
static QVariant fcnReverse( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
{
|
||||
QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent );
|
||||
if ( fGeom.isNull() )
|
||||
if ( QgsVariantUtils::isNull( values.at( 0 ) ) )
|
||||
return QVariant();
|
||||
|
||||
QVariant result;
|
||||
if ( !fGeom.isMultipart() )
|
||||
{
|
||||
const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( fGeom.constGet() );
|
||||
if ( !curve )
|
||||
return QVariant();
|
||||
// two variants, one for geometry, one for string
|
||||
|
||||
QgsCurve *reversed = curve->reversed();
|
||||
result = reversed ? QVariant::fromValue( QgsGeometry( reversed ) ) : QVariant();
|
||||
}
|
||||
else
|
||||
QgsGeometry fGeom = QgsExpressionUtils::getGeometry( values.at( 0 ), parent, true );
|
||||
if ( !fGeom.isNull() )
|
||||
{
|
||||
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection *>( fGeom.constGet() );
|
||||
std::unique_ptr< QgsGeometryCollection > reversed( collection->createEmptyWithSameType() );
|
||||
for ( int i = 0; i < collection->numGeometries(); ++i )
|
||||
QVariant result;
|
||||
if ( !fGeom.isMultipart() )
|
||||
{
|
||||
if ( const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( collection->geometryN( i ) ) )
|
||||
{
|
||||
reversed->addGeometry( curve->reversed() );
|
||||
}
|
||||
else
|
||||
{
|
||||
reversed->addGeometry( collection->geometryN( i )->clone() );
|
||||
}
|
||||
const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( fGeom.constGet() );
|
||||
if ( !curve )
|
||||
return QVariant();
|
||||
|
||||
QgsCurve *reversed = curve->reversed();
|
||||
result = reversed ? QVariant::fromValue( QgsGeometry( reversed ) ) : QVariant();
|
||||
}
|
||||
result = reversed ? QVariant::fromValue( QgsGeometry( std::move( reversed ) ) ) : QVariant();
|
||||
else
|
||||
{
|
||||
const QgsGeometryCollection *collection = qgsgeometry_cast< const QgsGeometryCollection *>( fGeom.constGet() );
|
||||
std::unique_ptr< QgsGeometryCollection > reversed( collection->createEmptyWithSameType() );
|
||||
for ( int i = 0; i < collection->numGeometries(); ++i )
|
||||
{
|
||||
if ( const QgsCurve *curve = qgsgeometry_cast<const QgsCurve * >( collection->geometryN( i ) ) )
|
||||
{
|
||||
reversed->addGeometry( curve->reversed() );
|
||||
}
|
||||
else
|
||||
{
|
||||
reversed->addGeometry( collection->geometryN( i )->clone() );
|
||||
}
|
||||
}
|
||||
result = reversed ? QVariant::fromValue( QgsGeometry( std::move( reversed ) ) ) : QVariant();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
|
||||
//fall back to string variant
|
||||
QString string = QgsExpressionUtils::getStringValue( values.at( 0 ), parent );
|
||||
std::reverse( string.begin(), string.end() );
|
||||
return string;
|
||||
}
|
||||
|
||||
static QVariant fcnExteriorRing( const QVariantList &values, const QgsExpressionContext *, QgsExpression *parent, const QgsExpressionNodeFunction * )
|
||||
@ -9056,7 +9066,7 @@ const QList<QgsExpressionFunction *> &QgsExpression::Functions()
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "point_on_surface" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) ), fcnPointOnSurface, QStringLiteral( "GeometryGroup" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "pole_of_inaccessibility" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) )
|
||||
<< QgsExpressionFunction::Parameter( QStringLiteral( "tolerance" ) ), fcnPoleOfInaccessibility, QStringLiteral( "GeometryGroup" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "reverse" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) ), fcnReverse, QStringLiteral( "GeometryGroup" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "reverse" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) ), fcnReverse, { QStringLiteral( "String" ), QStringLiteral( "GeometryGroup" ) } )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "exterior_ring" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) ), fcnExteriorRing, QStringLiteral( "GeometryGroup" ) )
|
||||
<< new QgsStaticExpressionFunction( QStringLiteral( "interior_ring_n" ), QgsExpressionFunction::ParameterList() << QgsExpressionFunction::Parameter( QStringLiteral( "geometry" ) )
|
||||
<< QgsExpressionFunction::Parameter( QStringLiteral( "index" ) ),
|
||||
|
||||
@ -1242,7 +1242,6 @@ class TestQgsExpression : public QObject
|
||||
QTest::newRow( "end_point multipoint" ) << "geom_to_wkt(end_point(geom_from_wkt('MULTIPOINT((3 3), (1 1), (2 2))')))" << false << QVariant( "Point (2 2)" );
|
||||
QTest::newRow( "end_point line" ) << "geom_to_wkt(end_point(geom_from_wkt('LINESTRING(4 1, 1 1, 2 2)')))" << false << QVariant( "Point (2 2)" );
|
||||
QTest::newRow( "end_point polygon" ) << "geom_to_wkt(end_point(geom_from_wkt('POLYGON((-1 -1, 4 0, 4 2, 0 2, -1 -1))')))" << false << QVariant( "Point (-1 -1)" );
|
||||
QTest::newRow( "reverse not geom" ) << "reverse('g')" << true << QVariant();
|
||||
QTest::newRow( "reverse null" ) << "reverse(NULL)" << false << QVariant();
|
||||
QTest::newRow( "reverse point" ) << "reverse(geom_from_wkt('POINT(1 2)'))" << false << QVariant();
|
||||
QTest::newRow( "reverse polygon" ) << "reverse(geom_from_wkt('POLYGON((-1 -1, 4 0, 4 2, 0 2, -1 -1))'))" << false << QVariant();
|
||||
@ -1696,6 +1695,8 @@ class TestQgsExpression : public QObject
|
||||
QTest::newRow( "regexp_replace non greedy" ) << "regexp_replace('HeLLo','(?<=H).*?L', '-')" << false << QVariant( "H-Lo" );
|
||||
QTest::newRow( "regexp_replace cap group" ) << "regexp_replace('HeLLo','(eL)', 'x\\\\1x')" << false << QVariant( "HxeLxLo" );
|
||||
QTest::newRow( "regexp_replace invalid" ) << "regexp_replace('HeLLo','[[[', '-')" << true << QVariant();
|
||||
QTest::newRow( "reverse string" ) << "reverse('HeLLo')" << false << QVariant( "oLLeH" );
|
||||
QTest::newRow( "reverse empty string" ) << "reverse('')" << false << QVariant( "" );
|
||||
QTest::newRow( "substr" ) << "substr('HeLLo', 3,2)" << false << QVariant( "LL" );
|
||||
QTest::newRow( "substr named parameters" ) << "substr(string:='HeLLo',start:=3,length:=2)" << false << QVariant( "LL" );
|
||||
QTest::newRow( "substr negative start" ) << "substr('HeLLo', -4)" << false << QVariant( "eLLo" );
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user