From 257e5e52d021151c6fbcab03c3ee7d2647e53905 Mon Sep 17 00:00:00 2001 From: Nyall Dawson Date: Tue, 20 Nov 2018 16:16:21 +1000 Subject: [PATCH] Add method to set QgsFeature geometry directly from QgsAbstractGeometry Allows feat.setGeometry(QgsPoint(1,2)) instead of the more obscure feat.setGeometry(QgsGeometry(QgsPoint(1,2))) (cherry picked from commit e21ea25c662c7d23e5757234f6844f5bd7201c6d) --- python/core/auto_generated/qgsfeature.sip.in | 16 +++++++++++++++- src/core/qgsfeature.cpp | 7 +++++++ src/core/qgsfeature.h | 19 ++++++++++++++++++- tests/src/core/testqgsfeature.cpp | 7 +++++++ tests/src/python/test_qgsfeature.py | 13 ++++++++++++- 5 files changed, 59 insertions(+), 3 deletions(-) diff --git a/python/core/auto_generated/qgsfeature.sip.in b/python/core/auto_generated/qgsfeature.sip.in index 81230ddc068d..309d6ca1bffd 100644 --- a/python/core/auto_generated/qgsfeature.sip.in +++ b/python/core/auto_generated/qgsfeature.sip.in @@ -13,7 +13,6 @@ - class QgsFeature { %Docstring @@ -329,6 +328,21 @@ Set the feature's geometry. The feature will be valid after. .. seealso:: :py:func:`clearGeometry` %End + void setGeometry( QgsAbstractGeometry *geometry /Transfer/ ); +%Docstring +Set the feature's ``geometry``. Ownership of the geometry is transferred to the feature. +The feature will be made valid after calling this method. + +.. seealso:: :py:func:`geometry` + +.. seealso:: :py:func:`clearGeometry` + +.. versionadded:: 3.6 +%End +%MethodCode + sipCpp->setGeometry( std::unique_ptr< QgsAbstractGeometry>( a0 ) ); +%End + void clearGeometry(); %Docstring Removes any geometry associated with the feature. diff --git a/src/core/qgsfeature.cpp b/src/core/qgsfeature.cpp index 108d56229d52..e28ff53f4da6 100644 --- a/src/core/qgsfeature.cpp +++ b/src/core/qgsfeature.cpp @@ -141,6 +141,13 @@ void QgsFeature::setGeometry( const QgsGeometry &geometry ) d->valid = true; } +void QgsFeature::setGeometry( std::unique_ptr geometry ) +{ + d.detach(); + d->geometry = QgsGeometry( std::move( geometry ) ); + d->valid = true; +} + void QgsFeature::clearGeometry() { setGeometry( QgsGeometry() ); diff --git a/src/core/qgsfeature.h b/src/core/qgsfeature.h index a949411a2d38..040ae1993ceb 100644 --- a/src/core/qgsfeature.h +++ b/src/core/qgsfeature.h @@ -30,12 +30,13 @@ email : sherman at mrcc.com #include "qgsattributes.h" #include "qgsfields.h" #include "qgsfeatureid.h" - +#include class QgsFeature; class QgsFeaturePrivate; class QgsField; class QgsGeometry; class QgsRectangle; +class QgsAbstractGeometry; /*************************************************************************** @@ -345,6 +346,22 @@ class CORE_EXPORT QgsFeature */ void setGeometry( const QgsGeometry &geometry ); + /** + * Set the feature's \a geometry. Ownership of the geometry is transferred to the feature. + * The feature will be made valid after calling this method. + * \see geometry() + * \see clearGeometry() + * \since QGIS 3.6 + */ +#ifndef SIP_RUN + void setGeometry( std::unique_ptr< QgsAbstractGeometry > geometry ); +#else + void setGeometry( QgsAbstractGeometry *geometry SIP_TRANSFER ); + % MethodCode + sipCpp->setGeometry( std::unique_ptr< QgsAbstractGeometry>( a0 ) ); + % End +#endif + /** * Removes any geometry associated with the feature. * \see setGeometry() diff --git a/tests/src/core/testqgsfeature.cpp b/tests/src/core/testqgsfeature.cpp index 4ed3e07d63cb..96ae802abd09 100644 --- a/tests/src/core/testqgsfeature.cpp +++ b/tests/src/core/testqgsfeature.cpp @@ -306,6 +306,13 @@ void TestQgsFeature::geometry() QCOMPARE( copy.geometry().asWkb(), geomByRef.asWkb() ); QCOMPARE( feature.geometry().asWkb(), mGeometry.asWkb() ); + //setGeometry using abstract geom + copy = feature; + QCOMPARE( copy.geometry().asWkb(), mGeometry.asWkb() ); + copy.setGeometry( qgis::make_unique< QgsPoint >( 5, 6 ) ); + QCOMPARE( copy.geometry().asWkt(), QStringLiteral( "Point (5 6)" ) ); + QCOMPARE( feature.geometry().asWkb(), mGeometry.asWkb() ); + //clearGeometry QgsFeature geomFeature; geomFeature.setGeometry( QgsGeometry( mGeometry2 ) ); diff --git a/tests/src/python/test_qgsfeature.py b/tests/src/python/test_qgsfeature.py index 037cd02aaa2c..a7304d3d2856 100644 --- a/tests/src/python/test_qgsfeature.py +++ b/tests/src/python/test_qgsfeature.py @@ -15,7 +15,14 @@ import qgis # NOQA import os -from qgis.core import QgsFeature, QgsGeometry, QgsPointXY, QgsVectorLayer, NULL, QgsFields, QgsField +from qgis.core import (QgsFeature, + QgsPoint, + QgsGeometry, + QgsPointXY, + QgsVectorLayer, + NULL, + QgsFields, + QgsField) from qgis.testing import start_app, unittest from utilities import unitTestDataPath @@ -138,6 +145,10 @@ def test_SetGeometry(self): myMessage = '\nExpected: %s\nGot: %s' % (myExpectedGeometry, myGeometry) assert myGeometry is not None, myMessage + # set from QgsAbstractGeometry + feat.setGeometry(QgsPoint(12, 34)) + self.assertEqual(feat.geometry().asWkt(), 'Point (12 34)') + if __name__ == '__main__': unittest.main()