diff --git a/python/core/qgsvectorlayereditutils.sip b/python/core/qgsvectorlayereditutils.sip index 943b12f0ed0..a129ff6c88d 100644 --- a/python/core/qgsvectorlayereditutils.sip +++ b/python/core/qgsvectorlayereditutils.sip @@ -28,6 +28,8 @@ class QgsVectorLayerEditUtils /** Adds a ring to polygon/multipolygon features * @param ring ring to add * @param featureId if specified, feature ID for feature ring was added to will be stored in this parameter + * @param preferredFeatureIds if specified, the features will be the first candidates for adding a ring. Otherwise + * all intersecting features are tested and the ring is added to the first valid feature. @return 0 in case of success, 1 problem with feature type, diff --git a/src/core/qgsvectorlayer.cpp b/src/core/qgsvectorlayer.cpp index 62f93f968d6..de56144f8a4 100644 --- a/src/core/qgsvectorlayer.cpp +++ b/src/core/qgsvectorlayer.cpp @@ -1064,7 +1064,7 @@ int QgsVectorLayer::addRing( const QList& ring, QgsFeatureId* featureI return 6; QgsVectorLayerEditUtils utils( this ); - return utils.addRing( ring, featureId ); + return utils.addRing( ring, featureId, mSelectedFeatureIds ); } int QgsVectorLayer::addRing( QgsCurveV2* ring, QgsFeatureId* featureId ) @@ -1087,7 +1087,7 @@ int QgsVectorLayer::addRing( QgsCurveV2* ring, QgsFeatureId* featureId ) } QgsVectorLayerEditUtils utils( this ); - return utils.addRing( ring, featureId ); + return utils.addRing( ring, featureId, mSelectedFeatureIds ); } int QgsVectorLayer::addPart( const QList &points ) diff --git a/src/core/qgsvectorlayereditutils.cpp b/src/core/qgsvectorlayereditutils.cpp index 6938402681b..67a50c6ef31 100644 --- a/src/core/qgsvectorlayereditutils.cpp +++ b/src/core/qgsvectorlayereditutils.cpp @@ -104,7 +104,7 @@ bool QgsVectorLayerEditUtils::deleteVertex( QgsFeatureId atFeatureId, int atVert return true; } -int QgsVectorLayerEditUtils::addRing( const QList& ring, QgsFeatureId* featureId ) +int QgsVectorLayerEditUtils::addRing( const QList& ring, QgsFeatureId* featureId, const QgsFeatureIds& preferredFeatureIds ) { QgsLineStringV2* ringLine = new QgsLineStringV2(); QList< QgsPointV2 > ringPoints; @@ -114,10 +114,10 @@ int QgsVectorLayerEditUtils::addRing( const QList& ring, QgsFeatureId* ringPoints.append( QgsPointV2( ringIt->x(), ringIt->y() ) ); } ringLine->setPoints( ringPoints ); - return addRing( ringLine, featureId ); + return addRing( ringLine, featureId, preferredFeatureIds ); } -int QgsVectorLayerEditUtils::addRing( QgsCurveV2* ring, QgsFeatureId* featureId ) +int QgsVectorLayerEditUtils::addRing( QgsCurveV2* ring, QgsFeatureId* modifiedFeatureId, const QgsFeatureIds& preferredFeatureIds ) { if ( !L->hasGeometryType() ) { @@ -126,22 +126,45 @@ int QgsVectorLayerEditUtils::addRing( QgsCurveV2* ring, QgsFeatureId* featureId } int addRingReturnCode = 5; //default: return code for 'ring not inserted' - QgsRectangle bBox = ring->boundingBox(); - QgsFeatureIterator fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) ); - QgsFeature f; - while ( fit.nextFeature( f ) ) - { - //add ring takes ownership of ring, and deletes it if there's an error - addRingReturnCode = f.geometry()->addRing( static_cast< QgsCurveV2* >( ring->clone() ) ); - if ( addRingReturnCode == 0 ) - { - L->editBuffer()->changeGeometry( f.id(), f.geometry() ); - if ( featureId ) - *featureId = f.id(); - //setModified( true, true ); - break; + //see if part can be added to preferred features + if ( !preferredFeatureIds.isEmpty() ) + { + QgsFeatureIterator fit = L->getFeatures( QgsFeatureRequest().setFilterFids( preferredFeatureIds ) ); + while ( fit.nextFeature( f ) ) + { + //add ring takes ownership of ring, and deletes it if there's an error + addRingReturnCode = f.geometry()->addRing( static_cast< QgsCurveV2* >( ring->clone() ) ); + if ( addRingReturnCode == 0 ) + { + L->editBuffer()->changeGeometry( f.id(), f.geometry() ); + if ( modifiedFeatureId ) + *modifiedFeatureId = f.id(); + + break; + } + } + } + + //no match so far, so check other intersecting features + if ( addRingReturnCode != 0 ) + { + QgsRectangle bBox = ring->boundingBox(); + QgsFeatureIterator fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) ); + while ( fit.nextFeature( f ) ) + { + //add ring takes ownership of ring, and deletes it if there's an error + addRingReturnCode = f.geometry()->addRing( static_cast< QgsCurveV2* >( ring->clone() ) ); + if ( addRingReturnCode == 0 ) + { + L->editBuffer()->changeGeometry( f.id(), f.geometry() ); + if ( modifiedFeatureId ) + *modifiedFeatureId = f.id(); + + //setModified( true, true ); + break; + } } } diff --git a/src/core/qgsvectorlayereditutils.h b/src/core/qgsvectorlayereditutils.h index d08bdd4fe78..a09313cac62 100644 --- a/src/core/qgsvectorlayereditutils.h +++ b/src/core/qgsvectorlayereditutils.h @@ -56,6 +56,8 @@ class CORE_EXPORT QgsVectorLayerEditUtils /** Adds a ring to polygon/multipolygon features * @param ring ring to add * @param featureId if specified, feature ID for feature ring was added to will be stored in this parameter + * @param preferredFeatureIds if specified, the features will be the first candidates for adding a ring. Otherwise + * all intersecting features are tested and the ring is added to the first valid feature. @return 0 in case of success, 1 problem with feature type, @@ -63,11 +65,13 @@ class CORE_EXPORT QgsVectorLayerEditUtils 3 ring not valid, 4 ring crosses existing rings, 5 no feature found where ring can be inserted*/ - int addRing( const QList& ring, QgsFeatureId* featureId = 0 ); + int addRing( const QList& ring, QgsFeatureId* featureId = 0, const QgsFeatureIds& preferredFeatureIds = QgsFeatureIds() ); /** Adds a ring to polygon/multipolygon features * @param ring ring to add * @param featureId if specified, feature ID for feature ring was added to will be stored in this parameter + * @param preferredFeatureIds if specified, the features will be the first candidates for adding a ring. Otherwise + * all intersecting features are tested and the ring is added to the first valid feature. @return 0 in case of success, 1 problem with feature type, @@ -75,7 +79,7 @@ class CORE_EXPORT QgsVectorLayerEditUtils 3 ring not valid, 4 ring crosses existing rings, 5 no feature found where ring can be inserted*/ - int addRing( QgsCurveV2* ring, QgsFeatureId* featureId = 0 ); + int addRing( QgsCurveV2* ring, QgsFeatureId* modifiedFeatureId = 0, const QgsFeatureIds& preferredFeatureIds = QgsFeatureIds() ); /** Adds a new part polygon to a multipart feature @return