Skip to content

Commit

Permalink
Merge pull request #1744 from rldhont/expression_get_transform_geom
Browse files Browse the repository at this point in the history
[FEATURE] Add get and trasnform geometry in Expression
  • Loading branch information
NathanW2 committed Jan 2, 2015
2 parents 2b7e49b + a0ffad2 commit c0b94cf
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 2 deletions.
12 changes: 12 additions & 0 deletions resources/function_help/geometry
@@ -0,0 +1,12 @@
<h3>getGeometry function</h3>
Returns the feature's geometry

<h4>Syntax</h4>
<pre>geometry( f )</pre>

<h4>Arguments</h4>
f &rarr; QgsFeature

<h4>Example</h4>
<pre> geomToWKT( geometry( getFeature( layer, attributeField, value ) ) ) &rarr; POINT(6 50)</pre>
<pre> intersects( $geometry, geometry( getFeature( layer, attributeField, value ) ) ) &rarr; 1</pre>
15 changes: 15 additions & 0 deletions resources/function_help/transform
@@ -0,0 +1,15 @@
<h3>transformGeometry function</h3>
Returns the geometry transforms from the source CRS to the dest CRS.

<h4>Syntax</h4>
<pre>transform( geom, sAuthId, dAuthId )</pre>

<h4>Arguments</h4>
geom &rarr; QgsGeometry

sCrsId &rarr; the Source Auth CRS Id

dCrsId &rarr; the Dest Auth CRS Id

<h4>Example</h4>
<pre> geomToWKT( transform( $geometry, 'EPSG:2154', 'EPSG:4326' ) ) &rarr; POINT(0 51)</pre>
40 changes: 38 additions & 2 deletions src/core/qgsexpression.cpp
Expand Up @@ -1298,8 +1298,14 @@ static QVariant fcnCombine( const QVariantList& values, const QgsFeature*, QgsEx
}
static QVariant fcnGeomToWKT( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
{
if ( values.length() < 1 || values.length() > 2 )
return QVariant();

QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
QString wkt = fGeom.exportToWkt();
int prec = 8;
if ( values.length() == 2 )
prec = getIntValue( values.at( 1 ), parent );
QString wkt = fGeom.exportToWkt( prec );
return QVariant( wkt );
}

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

static QVariant fcnGetGeometry( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
{
QgsFeature feat = getFeature( values.at( 0 ), parent );
QgsGeometry* geom = feat.geometry();
if ( geom )
return QVariant::fromValue( *geom );
return QVariant();
}

static QVariant fcnTransformGeometry( const QVariantList& values, const QgsFeature*, QgsExpression* parent )
{
QgsGeometry fGeom = getGeometry( values.at( 0 ), parent );
QString sAuthId = getStringValue( values.at( 1 ), parent );
QString dAuthId = getStringValue( values.at( 2 ), parent );

QgsCoordinateReferenceSystem s;
if ( ! s.createFromOgcWmsCrs( sAuthId ) )
return QVariant::fromValue( fGeom );
QgsCoordinateReferenceSystem d;
if ( ! d.createFromOgcWmsCrs( dAuthId ) )
return QVariant::fromValue( fGeom );

QgsCoordinateTransform t( s, d );
if ( fGeom.transform( t ) == 0 )
return QVariant::fromValue( fGeom );
return QVariant();
}

static QVariant fcnGetFeature( const QVariantList& values, const QgsFeature *, QgsExpression* parent )
{
//arguments: 1. layer id / name, 2. key attribute, 3. eq value
Expand Down Expand Up @@ -1765,7 +1799,9 @@ const QList<QgsExpression::Function*> &QgsExpression::Functions()
<< new StaticFunction( "symDifference", 2, fcnSymDifference, "Geometry" )
<< new StaticFunction( "combine", 2, fcnCombine, "Geometry" )
<< new StaticFunction( "union", 2, fcnCombine, "Geometry" )
<< new StaticFunction( "geomToWKT", 1, fcnGeomToWKT, "Geometry" )
<< new StaticFunction( "geomToWKT", -1, fcnGeomToWKT, "Geometry" )
<< new StaticFunction( "geometry", 1, fcnGetGeometry, "Geometry" )
<< new StaticFunction( "transform", 3, fcnTransformGeometry, "Geometry" )
<< new StaticFunction( "$rownum", 0, fcnRowNumber, "Record" )
<< new StaticFunction( "$id", 0, fcnFeatureId, "Record" )
<< new StaticFunction( "$currentfeature", 0, fcnFeature, "Record" )
Expand Down
89 changes: 89 additions & 0 deletions tests/src/core/testqgsexpression.cpp
Expand Up @@ -745,6 +745,37 @@ class TestQgsExpression: public QObject
QVariant vYMax = exp9.evaluate( &fPolygon );
QCOMPARE( vYMax.toDouble(), 6.0 );
}

void eval_geometry_wkt()
{
QgsPolyline polyline, polygon_ring;
polyline << QgsPoint( 0, 0 ) << QgsPoint( 10, 0 );
polygon_ring << QgsPoint( 2, 1 ) << QgsPoint( 10, 1 ) << QgsPoint( 10, 6 ) << QgsPoint( 2, 6 ) << QgsPoint( 2, 1 );

QgsPolygon polygon;
polygon << polygon_ring;

QgsFeature fPoint, fPolygon, fPolyline;
fPoint.setGeometry( QgsGeometry::fromPoint( QgsPoint( -1.23456789, 9.87654321 ) ) );
fPolyline.setGeometry( QgsGeometry::fromPolyline( polyline ) );
fPolygon.setGeometry( QgsGeometry::fromPolygon( polygon ) );

QgsExpression exp1( "geomToWKT($geometry)" );
QVariant vWktLine = exp1.evaluate( &fPolyline );
QCOMPARE( vWktLine.toString(), QString( "LINESTRING(0 0, 10 0)" ) );

QgsExpression exp2( "geomToWKT($geometry)" );
QVariant vWktPolygon = exp2.evaluate( &fPolygon );
QCOMPARE( vWktPolygon.toString(), QString( "POLYGON((2 1,10 1,10 6,2 6,2 1))" ) );

QgsExpression exp3( "geomToWKT($geometry)" );
QVariant vWktPoint = exp3.evaluate( &fPoint );
QCOMPARE( vWktPoint.toString(), QString( "POINT(-1.23456789 9.87654321)" ) );

QgsExpression exp4( "geomToWKT($geometry, 3)" );
QVariant vWktPointSimplify = exp4.evaluate( &fPoint );
QCOMPARE( vWktPointSimplify.toString(), QString( "POINT(-1.235 9.877)" ) );
}

void eval_geometry_constructor_data()
{
Expand Down Expand Up @@ -803,6 +834,64 @@ class TestQgsExpression: public QObject
QgsGeometry outGeom = out.value<QgsGeometry>();
QCOMPARE( geom->equals( &outGeom ), true );
}

void eval_geometry_access_transform_data()
{
QTest::addColumn<QString>( "string" );
QTest::addColumn<void*>( "geomptr" );
QTest::addColumn<bool>( "evalError" );

QgsPoint point( 123, 456 );
QgsPolyline line;
line << QgsPoint( 1, 1 ) << QgsPoint( 4, 2 ) << QgsPoint( 3, 1 );

QgsPolyline polyline, polygon_ring;
polyline << QgsPoint( 0, 0 ) << QgsPoint( 10, 0 );
polygon_ring << QgsPoint( 1, 1 ) << QgsPoint( 6, 1 ) << QgsPoint( 6, 6 ) << QgsPoint( 1, 6 ) << QgsPoint( 1, 1 );
QgsPolygon polygon;
polygon << polygon_ring;

QTest::newRow( "geometry Point" ) << "geometry( $currentfeature )" << ( void* ) QgsGeometry::fromPoint( point ) << false;
QTest::newRow( "geometry Line" ) << "geometry( $currentfeature )" << ( void* ) QgsGeometry::fromPolyline( line ) << false;
QTest::newRow( "geometry Polyline" ) << "geometry( $currentfeature )" << ( void* ) QgsGeometry::fromPolyline( polyline ) << false;
QTest::newRow( "geometry Polygon" ) << "geometry( $currentfeature )" << ( void* ) QgsGeometry::fromPolygon( polygon ) << false;

QgsCoordinateReferenceSystem s;
s.createFromOgcWmsCrs( "EPSG:4326" );
QgsCoordinateReferenceSystem d;
d.createFromOgcWmsCrs( "EPSG:3857" );
QgsCoordinateTransform t( s, d );

QgsGeometry* tLine = QgsGeometry::fromPolyline( line );
tLine->transform( t );
QgsGeometry* tPolygon = QgsGeometry::fromPolygon( polygon );
tPolygon->transform( t );

QTest::newRow( "transform Line" ) << "transform( geomFromWKT('" + QgsGeometry::fromPolyline( line )->exportToWkt() + "'), 'EPSG:4326', 'EPSG:3857' )" << ( void* ) tLine << false;
QTest::newRow( "transform Polygon" ) << "transform( geomFromWKT('" + QgsGeometry::fromPolygon( polygon )->exportToWkt() + "'), 'EPSG:4326', 'EPSG:3857' )" << ( void* ) tPolygon << false;
}

void eval_geometry_access_transform()
{
QFETCH( QString, string );
QFETCH( void*, geomptr );
QFETCH( bool, evalError );

QgsGeometry* geom = ( QgsGeometry* ) geomptr;

QgsFeature f;
f.setGeometry( geom );

QgsExpression exp( string );
QCOMPARE( exp.hasParserError(), false );
QCOMPARE( exp.needsGeometry(), false );
QVariant out = exp.evaluate( &f );
QCOMPARE( exp.hasEvalError(), evalError );

QCOMPARE( out.canConvert<QgsGeometry>(), true );
QgsGeometry outGeom = out.value<QgsGeometry>();
QCOMPARE( geom->equals( &outGeom ), true );
}

void eval_spatial_operator_data()
{
Expand Down

0 comments on commit c0b94cf

Please sign in to comment.