From b160f101c21fc85b15cf52eb54793676c1baa087 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Sat, 6 Aug 2016 22:25:25 +1000 Subject: [PATCH] QgsExpression::setGeomCalculator now takes a pointer This allows the calculator to be cleared --- python/core/qgsexpression.sip | 5 +++-- src/app/qgsattributetabledialog.cpp | 4 ++-- src/app/qgsfieldcalculator.cpp | 2 +- src/core/qgsexpression.cpp | 10 +++++++--- src/core/qgsexpression.h | 5 +++-- src/core/qgsvectorlayerfeatureiterator.cpp | 2 +- src/gui/qgsexpressionbuilderwidget.cpp | 2 +- tests/src/core/testqgsexpression.cpp | 6 +++--- 8 files changed, 21 insertions(+), 15 deletions(-) diff --git a/python/core/qgsexpression.sip b/python/core/qgsexpression.sip index 5bacca4e4a4..550f74806bb 100644 --- a/python/core/qgsexpression.sip +++ b/python/core/qgsexpression.sip @@ -99,10 +99,11 @@ class QgsExpression * (used by $length, $area and $perimeter functions only). By default, no geometry * calculator is set and all distance and area calculations are performed using simple * cartesian methods (ie no ellipsoidal calculations). + * @param calc geometry calculator. Ownership is not transferred. Set to a nullptr to force + * cartesian calculations. * @see geomCalculator() */ - //TODO QGIS 3.0 change calc to a pointer, so that calculator can be cleared by passing nullptr - void setGeomCalculator( const QgsDistanceArea &calc ); + void setGeomCalculator( const QgsDistanceArea* calc ); /** Returns the desired distance units for calculations involving geomCalculator(), eg "$length" and "$perimeter". * @note distances are only converted when a geomCalculator() has been set diff --git a/src/app/qgsattributetabledialog.cpp b/src/app/qgsattributetabledialog.cpp index e92b348b23f..cf0e7a98c69 100644 --- a/src/app/qgsattributetabledialog.cpp +++ b/src/app/qgsattributetabledialog.cpp @@ -443,7 +443,7 @@ void QgsAttributeTableDialog::runFieldCalculation( QgsVectorLayer* layer, const QString error; QgsExpression exp( expression ); - exp.setGeomCalculator( *myDa ); + exp.setGeomCalculator( myDa ); exp.setDistanceUnits( QgsProject::instance()->distanceUnits() ); exp.setAreaUnits( QgsProject::instance()->areaUnits() ); bool useGeometry = exp.needsGeometry(); @@ -945,7 +945,7 @@ void QgsAttributeTableDialog::setFilterExpression( const QString& filterString, QApplication::setOverrideCursor( Qt::WaitCursor ); - filterExpression.setGeomCalculator( myDa ); + filterExpression.setGeomCalculator( &myDa ); filterExpression.setDistanceUnits( QgsProject::instance()->distanceUnits() ); filterExpression.setAreaUnits( QgsProject::instance()->areaUnits() ); QgsFeatureRequest request( mMainView->masterModel()->request() ); diff --git a/src/app/qgsfieldcalculator.cpp b/src/app/qgsfieldcalculator.cpp index 43058e5f79e..b594450a1b9 100644 --- a/src/app/qgsfieldcalculator.cpp +++ b/src/app/qgsfieldcalculator.cpp @@ -164,7 +164,7 @@ void QgsFieldCalculator::accept() QString calcString = builder->expressionText(); QgsExpression exp( calcString ); - exp.setGeomCalculator( myDa ); + exp.setGeomCalculator( &myDa ); exp.setDistanceUnits( QgsProject::instance()->distanceUnits() ); exp.setAreaUnits( QgsProject::instance()->areaUnits() ); diff --git a/src/core/qgsexpression.cpp b/src/core/qgsexpression.cpp index 0db1b9ca316..c7cb23f2737 100644 --- a/src/core/qgsexpression.cpp +++ b/src/core/qgsexpression.cpp @@ -3500,9 +3500,13 @@ void QgsExpression::detach() } } -void QgsExpression::setGeomCalculator( const QgsDistanceArea &calc ) +void QgsExpression::setGeomCalculator( const QgsDistanceArea *calc ) { - d->mCalc = QSharedPointer( new QgsDistanceArea( calc ) ); + detach(); + if ( calc ) + d->mCalc = QSharedPointer( new QgsDistanceArea( *calc ) ); + else + d->mCalc.clear(); } bool QgsExpression::prepare( const QgsExpressionContext *context ) @@ -3633,7 +3637,7 @@ QString QgsExpression::replaceExpressionText( const QString &action, const QgsEx if ( distanceArea ) { //if QgsDistanceArea specified for area/distance conversion, use it - exp.setGeomCalculator( *distanceArea ); + exp.setGeomCalculator( distanceArea ); } QVariant result = exp.evaluate( context ); diff --git a/src/core/qgsexpression.h b/src/core/qgsexpression.h index 15a72494dc1..7adbd71a569 100644 --- a/src/core/qgsexpression.h +++ b/src/core/qgsexpression.h @@ -219,10 +219,11 @@ class CORE_EXPORT QgsExpression * (used by $length, $area and $perimeter functions only). By default, no geometry * calculator is set and all distance and area calculations are performed using simple * cartesian methods (ie no ellipsoidal calculations). + * @param calc geometry calculator. Ownership is not transferred. Set to a nullptr to force + * cartesian calculations. * @see geomCalculator() */ - //TODO QGIS 3.0 change calc to a pointer, so that calculator can be cleared by passing nullptr - void setGeomCalculator( const QgsDistanceArea &calc ); + void setGeomCalculator( const QgsDistanceArea* calc ); /** Returns the desired distance units for calculations involving geomCalculator(), eg "$length" and "$perimeter". * @note distances are only converted when a geomCalculator() has been set diff --git a/src/core/qgsvectorlayerfeatureiterator.cpp b/src/core/qgsvectorlayerfeatureiterator.cpp index 62b30a31111..cbd48ab1cb5 100644 --- a/src/core/qgsvectorlayerfeatureiterator.cpp +++ b/src/core/qgsvectorlayerfeatureiterator.cpp @@ -529,7 +529,7 @@ void QgsVectorLayerFeatureIterator::prepareExpression( int fieldIdx ) da.setSourceCrs( mSource->mCrsId ); da.setEllipsoidalMode( true ); da.setEllipsoid( QgsProject::instance()->readEntry( "Measure", "/Ellipsoid", GEO_NONE ) ); - exp->setGeomCalculator( da ); + exp->setGeomCalculator( &da ); exp->setDistanceUnits( QgsProject::instance()->distanceUnits() ); exp->setAreaUnits( QgsProject::instance()->areaUnits() ); diff --git a/src/gui/qgsexpressionbuilderwidget.cpp b/src/gui/qgsexpressionbuilderwidget.cpp index 2f7bb80db95..dd620ce8fb7 100644 --- a/src/gui/qgsexpressionbuilderwidget.cpp +++ b/src/gui/qgsexpressionbuilderwidget.cpp @@ -540,7 +540,7 @@ void QgsExpressionBuilderWidget::on_txtExpressionString_textChanged() if ( mLayer ) { // Only set calculator if we have layer, else use default. - exp.setGeomCalculator( mDa ); + exp.setGeomCalculator( &mDa ); if ( !mFeature.isValid() ) { diff --git a/tests/src/core/testqgsexpression.cpp b/tests/src/core/testqgsexpression.cpp index 023332a26a4..3ed5ddcab64 100644 --- a/tests/src/core/testqgsexpression.cpp +++ b/tests/src/core/testqgsexpression.cpp @@ -1685,7 +1685,7 @@ class TestQgsExpression: public QObject // test area with geomCalculator QgsExpression expArea2( "$area" ); - expArea2.setGeomCalculator( da ); + expArea2.setGeomCalculator( &da ); vArea = expArea2.evaluate( &context ); expected = 1009089817.0; QVERIFY( qgsDoubleNear( vArea.toDouble(), expected, 1.0 ) ); @@ -1716,7 +1716,7 @@ class TestQgsExpression: public QObject // test perimeter with geomCalculator QgsExpression expPerimeter2( "$perimeter" ); - expPerimeter2.setGeomCalculator( da ); + expPerimeter2.setGeomCalculator( &da ); vPerimeter = expPerimeter2.evaluate( &context ); expected = 128289.074; QVERIFY( qgsDoubleNear( vPerimeter.toDouble(), expected, 0.001 ) ); @@ -1753,7 +1753,7 @@ class TestQgsExpression: public QObject // test length with geomCalculator QgsExpression expLength2( "$length" ); - expLength2.setGeomCalculator( da ); + expLength2.setGeomCalculator( &da ); vLength = expLength2.evaluate( &context ); expected = 26932.156; QVERIFY( qgsDoubleNear( vLength.toDouble(), expected, 0.001 ) );