Skip to content

Commit c0b94cf

Browse files
committed
Merge pull request #1744 from rldhont/expression_get_transform_geom
[FEATURE] Add get and trasnform geometry in Expression
2 parents 2b7e49b + a0ffad2 commit c0b94cf

File tree

4 files changed

+154
-2
lines changed

4 files changed

+154
-2
lines changed

resources/function_help/geometry

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<h3>getGeometry function</h3>
2+
Returns the feature's geometry
3+
4+
<h4>Syntax</h4>
5+
<pre>geometry( f )</pre>
6+
7+
<h4>Arguments</h4>
8+
f &rarr; QgsFeature
9+
10+
<h4>Example</h4>
11+
<pre> geomToWKT( geometry( getFeature( layer, attributeField, value ) ) ) &rarr; POINT(6 50)</pre>
12+
<pre> intersects( $geometry, geometry( getFeature( layer, attributeField, value ) ) ) &rarr; 1</pre>

resources/function_help/transform

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<h3>transformGeometry function</h3>
2+
Returns the geometry transforms from the source CRS to the dest CRS.
3+
4+
<h4>Syntax</h4>
5+
<pre>transform( geom, sAuthId, dAuthId )</pre>
6+
7+
<h4>Arguments</h4>
8+
geom &rarr; QgsGeometry
9+
10+
sCrsId &rarr; the Source Auth CRS Id
11+
12+
dCrsId &rarr; the Dest Auth CRS Id
13+
14+
<h4>Example</h4>
15+
<pre> geomToWKT( transform( $geometry, 'EPSG:2154', 'EPSG:4326' ) ) &rarr; POINT(0 51)</pre>

src/core/qgsexpression.cpp

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,8 +1298,14 @@ static QVariant fcnCombine( const QVariantList& values, const QgsFeature*, QgsEx
12981298
}
12991299
static QVariant fcnGeomToWKT( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
13001300
{
1301+
if ( values.length() < 1 || values.length() > 2 )
1302+
return QVariant();
1303+
13011304
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1302-
QString wkt = fGeom.exportToWkt();
1305+
int prec = 8;
1306+
if ( values.length() == 2 )
1307+
prec = getIntValue( values.at( 1 ), parent );
1308+
QString wkt = fGeom.exportToWkt( prec );
13031309
return QVariant( wkt );
13041310
}
13051311

@@ -1546,6 +1552,34 @@ static QVariant fcnSpecialColumn( const QVariantList& values, const QgsFeature*
15461552
return QgsExpression::specialColumn( varName );
15471553
}
15481554

1555+
static QVariant fcnGetGeometry( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
1556+
{
1557+
QgsFeature feat = getFeature( values.at( 0 ), parent );
1558+
QgsGeometry* geom = feat.geometry();
1559+
if ( geom )
1560+
return QVariant::fromValue( *geom );
1561+
return QVariant();
1562+
}
1563+
1564+
static QVariant fcnTransformGeometry( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
1565+
{
1566+
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
1567+
QString sAuthId = getStringValue( values.at( 1 ), parent );
1568+
QString dAuthId = getStringValue( values.at( 2 ), parent );
1569+
1570+
QgsCoordinateReferenceSystem s;
1571+
if ( ! s.createFromOgcWmsCrs( sAuthId ) )
1572+
return QVariant::fromValue( fGeom );
1573+
QgsCoordinateReferenceSystem d;
1574+
if ( ! d.createFromOgcWmsCrs( dAuthId ) )
1575+
return QVariant::fromValue( fGeom );
1576+
1577+
QgsCoordinateTransform t( s, d );
1578+
if ( fGeom.transform( t ) == 0 )
1579+
return QVariant::fromValue( fGeom );
1580+
return QVariant();
1581+
}
1582+
15491583
static QVariant fcnGetFeature( const QVariantList& values, const QgsFeature *, QgsExpression* parent )
15501584
{
15511585
//arguments: 1. layer id / name, 2. key attribute, 3. eq value
@@ -1765,7 +1799,9 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
17651799
<< new StaticFunction( "symDifference", 2, fcnSymDifference, "Geometry" )
17661800
<< new StaticFunction( "combine", 2, fcnCombine, "Geometry" )
17671801
<< new StaticFunction( "union", 2, fcnCombine, "Geometry" )
1768-
<< new StaticFunction( "geomToWKT", 1, fcnGeomToWKT, "Geometry" )
1802+
<< new StaticFunction( "geomToWKT", -1, fcnGeomToWKT, "Geometry" )
1803+
<< new StaticFunction( "geometry", 1, fcnGetGeometry, "Geometry" )
1804+
<< new StaticFunction( "transform", 3, fcnTransformGeometry, "Geometry" )
17691805
<< new StaticFunction( "$rownum", 0, fcnRowNumber, "Record" )
17701806
<< new StaticFunction( "$id", 0, fcnFeatureId, "Record" )
17711807
<< new StaticFunction( "$currentfeature", 0, fcnFeature, "Record" )

tests/src/core/testqgsexpression.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,37 @@ class TestQgsExpression: public QObject
745745
QVariant vYMax = exp9.evaluate( &fPolygon );
746746
QCOMPARE( vYMax.toDouble(), 6.0 );
747747
}
748+
749+
void eval_geometry_wkt()
750+
{
751+
QgsPolyline polyline, polygon_ring;
752+
polyline << QgsPoint( 0, 0 ) << QgsPoint( 10, 0 );
753+
polygon_ring << QgsPoint( 2, 1 ) << QgsPoint( 10, 1 ) << QgsPoint( 10, 6 ) << QgsPoint( 2, 6 ) << QgsPoint( 2, 1 );
754+
755+
QgsPolygon polygon;
756+
polygon << polygon_ring;
757+
758+
QgsFeature fPoint, fPolygon, fPolyline;
759+
fPoint.setGeometry( QgsGeometry::fromPoint( QgsPoint( -1.23456789, 9.87654321 ) ) );
760+
fPolyline.setGeometry( QgsGeometry::fromPolyline( polyline ) );
761+
fPolygon.setGeometry( QgsGeometry::fromPolygon( polygon ) );
762+
763+
QgsExpression exp1( "geomToWKT($geometry)" );
764+
QVariant vWktLine = exp1.evaluate( &fPolyline );
765+
QCOMPARE( vWktLine.toString(), QString( "LINESTRING(0 0, 10 0)" ) );
766+
767+
QgsExpression exp2( "geomToWKT($geometry)" );
768+
QVariant vWktPolygon = exp2.evaluate( &fPolygon );
769+
QCOMPARE( vWktPolygon.toString(), QString( "POLYGON((2 1,10 1,10 6,2 6,2 1))" ) );
770+
771+
QgsExpression exp3( "geomToWKT($geometry)" );
772+
QVariant vWktPoint = exp3.evaluate( &fPoint );
773+
QCOMPARE( vWktPoint.toString(), QString( "POINT(-1.23456789 9.87654321)" ) );
774+
775+
QgsExpression exp4( "geomToWKT($geometry, 3)" );
776+
QVariant vWktPointSimplify = exp4.evaluate( &fPoint );
777+
QCOMPARE( vWktPointSimplify.toString(), QString( "POINT(-1.235 9.877)" ) );
778+
}
748779

749780
void eval_geometry_constructor_data()
750781
{
@@ -803,6 +834,64 @@ class TestQgsExpression: public QObject
803834
QgsGeometry outGeom = out.value<QgsGeometry>();
804835
QCOMPARE( geom->equals( &outGeom ), true );
805836
}
837+
838+
void eval_geometry_access_transform_data()
839+
{
840+
QTest::addColumn<QString>( "string" );
841+
QTest::addColumn<void*>( "geomptr" );
842+
QTest::addColumn<bool>( "evalError" );
843+
844+
QgsPoint point( 123, 456 );
845+
QgsPolyline line;
846+
line << QgsPoint( 1, 1 ) << QgsPoint( 4, 2 ) << QgsPoint( 3, 1 );
847+
848+
QgsPolyline polyline, polygon_ring;
849+
polyline << QgsPoint( 0, 0 ) << QgsPoint( 10, 0 );
850+
polygon_ring << QgsPoint( 1, 1 ) << QgsPoint( 6, 1 ) << QgsPoint( 6, 6 ) << QgsPoint( 1, 6 ) << QgsPoint( 1, 1 );
851+
QgsPolygon polygon;
852+
polygon << polygon_ring;
853+
854+
QTest::newRow( "geometry Point" ) << "geometry( $currentfeature )" << ( void* ) QgsGeometry::fromPoint( point ) << false;
855+
QTest::newRow( "geometry Line" ) << "geometry( $currentfeature )" << ( void* ) QgsGeometry::fromPolyline( line ) << false;
856+
QTest::newRow( "geometry Polyline" ) << "geometry( $currentfeature )" << ( void* ) QgsGeometry::fromPolyline( polyline ) << false;
857+
QTest::newRow( "geometry Polygon" ) << "geometry( $currentfeature )" << ( void* ) QgsGeometry::fromPolygon( polygon ) << false;
858+
859+
QgsCoordinateReferenceSystem s;
860+
s.createFromOgcWmsCrs( "EPSG:4326" );
861+
QgsCoordinateReferenceSystem d;
862+
d.createFromOgcWmsCrs( "EPSG:3857" );
863+
QgsCoordinateTransform t( s, d );
864+
865+
QgsGeometry* tLine = QgsGeometry::fromPolyline( line );
866+
tLine->transform( t );
867+
QgsGeometry* tPolygon = QgsGeometry::fromPolygon( polygon );
868+
tPolygon->transform( t );
869+
870+
QTest::newRow( "transform Line" ) << "transform( geomFromWKT('" + QgsGeometry::fromPolyline( line )->exportToWkt() + "'), 'EPSG:4326', 'EPSG:3857' )" << ( void* ) tLine << false;
871+
QTest::newRow( "transform Polygon" ) << "transform( geomFromWKT('" + QgsGeometry::fromPolygon( polygon )->exportToWkt() + "'), 'EPSG:4326', 'EPSG:3857' )" << ( void* ) tPolygon << false;
872+
}
873+
874+
void eval_geometry_access_transform()
875+
{
876+
QFETCH( QString, string );
877+
QFETCH( void*, geomptr );
878+
QFETCH( bool, evalError );
879+
880+
QgsGeometry* geom = ( QgsGeometry* ) geomptr;
881+
882+
QgsFeature f;
883+
f.setGeometry( geom );
884+
885+
QgsExpression exp( string );
886+
QCOMPARE( exp.hasParserError(), false );
887+
QCOMPARE( exp.needsGeometry(), false );
888+
QVariant out = exp.evaluate( &f );
889+
QCOMPARE( exp.hasEvalError(), evalError );
890+
891+
QCOMPARE( out.canConvert<QgsGeometry>(), true );
892+
QgsGeometry outGeom = out.value<QgsGeometry>();
893+
QCOMPARE( geom->equals( &outGeom ), true );
894+
}
806895

807896
void eval_spatial_operator_data()
808897
{

0 commit comments

Comments
 (0)