@@ -102,6 +102,7 @@ void QgsExpression::setExpression( const QString &expression )
102102 d->mRootNode = ::parseExpression ( expression, d->mParserErrorString , d->mParserErrors );
103103 d->mEvalErrorString = QString ();
104104 d->mExp = expression;
105+ d->mIsPrepared = false ;
105106}
106107
107108QString QgsExpression::expression () const
@@ -313,13 +314,25 @@ bool QgsExpression::needsGeometry() const
313314 return d->mRootNode ->needsGeometry ();
314315}
315316
316- void QgsExpression::initGeomCalculator ()
317+ void QgsExpression::initGeomCalculator ( const QgsExpressionContext *context )
317318{
318- if ( d->mCalc )
319- return ;
320-
321- // Use planimetric as default
322- d->mCalc = std::shared_ptr<QgsDistanceArea>( new QgsDistanceArea () );
319+ if ( ! d->mCalc )
320+ d->mCalc = std::shared_ptr<QgsDistanceArea>( new QgsDistanceArea () );
321+ QString ellipsoid = context->variable ( " project_ellipsoid" ).toString ();
322+ QString distanceUnitsStr = context->variable ( " project_distance_units" ).toString ();
323+ QString areaUnitsStr = context->variable ( " project_area_units" ).toString ();
324+ QgsCoordinateReferenceSystem crs = context->variable ( " _layer_crs" ).value <QgsCoordinateReferenceSystem>();
325+ QgsCoordinateTransformContext tContext = context->variable ( " _project_transform_context" ).value <QgsCoordinateTransformContext>();
326+
327+ d->mCalc ->setEllipsoid ( ellipsoid.isEmpty () ? GEO_NONE : ellipsoid );
328+ if ( ! distanceUnitsStr.isEmpty () )
329+ setDistanceUnits ( QgsUnitTypes::stringToDistanceUnit ( distanceUnitsStr ) );
330+ if ( ! areaUnitsStr.isEmpty () )
331+ setAreaUnits ( QgsUnitTypes::stringToAreaUnit ( areaUnitsStr ) );
332+ if ( crs.isValid () )
333+ {
334+ d->mCalc ->setSourceCrs ( crs, tContext );
335+ }
323336}
324337
325338void QgsExpression::detach ()
@@ -361,6 +374,8 @@ bool QgsExpression::prepare( const QgsExpressionContext *context )
361374 return false ;
362375 }
363376
377+ initGeomCalculator ( context );
378+ d->mIsPrepared = true ;
364379 return d->mRootNode ->prepare ( this , context );
365380}
366381
@@ -385,6 +400,12 @@ QVariant QgsExpression::evaluate( const QgsExpressionContext *context )
385400 return QVariant ();
386401 }
387402
403+ if ( ! d->mIsPrepared )
404+ {
405+ qWarning ( " QgsExpression::evaluate() called on an expression not yet prepared !" );
406+ if ( ! prepare ( context ) )
407+ return QVariant ();
408+ }
388409 return d->mRootNode ->eval ( this , context );
389410}
390411
0 commit comments