Skip to content

Commit

Permalink
Followup e5ea5ff, better API
Browse files Browse the repository at this point in the history
  • Loading branch information
nyalldawson committed Oct 9, 2015
1 parent c62d81a commit 4925a54
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 45 deletions.
6 changes: 3 additions & 3 deletions python/core/qgsvectorlayereditutils.sip
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,17 @@ class QgsVectorLayerEditUtils

/** Adds a ring to polygon/multipolygon features
* @param ring ring to add
* @param modifiedFeatureId 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
* @param targetFeatureIds if specified, only these features will be the candidates for adding a ring. Otherwise
* all intersecting features are tested and the ring is added to the first valid feature.
* @param modifiedFeatureId if specified, feature ID for feature that ring was added to will be stored in this parameter
@return
0 in case of success,
1 problem with feature type,
2 ring not closed,
3 ring not valid,
4 ring crosses existing rings,
5 no feature found where ring can be inserted*/
int addRing( const QList<QgsPoint>& ring, QgsFeatureId* modifiedFeatureId = 0 );
int addRing( const QList<QgsPoint>& ring, const QgsFeatureIds& targetFeatureIds = QgsFeatureIds(), QgsFeatureId* modifiedFeatureId = 0 );

/** Adds a new part polygon to a multipart feature
@return
Expand Down
33 changes: 31 additions & 2 deletions src/core/qgsvectorlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1064,7 +1064,21 @@ int QgsVectorLayer::addRing( const QList<QgsPoint>& ring, QgsFeatureId* featureI
return 6;

QgsVectorLayerEditUtils utils( this );
return utils.addRing( ring, featureId, mSelectedFeatureIds );
int result = 5;

//first try with selected features
if ( !mSelectedFeatureIds.isEmpty() )
{
result = utils.addRing( ring, mSelectedFeatureIds, featureId );
}

if ( result != 0 )
{
//try with all intersecting features
result = utils.addRing( ring, QgsFeatureIds(), featureId );
}

return result;
}

int QgsVectorLayer::addRing( QgsCurveV2* ring, QgsFeatureId* featureId )
Expand All @@ -1087,7 +1101,22 @@ int QgsVectorLayer::addRing( QgsCurveV2* ring, QgsFeatureId* featureId )
}

QgsVectorLayerEditUtils utils( this );
return utils.addRing( ring, featureId, mSelectedFeatureIds );
int result = 5;

//first try with selected features
if ( !mSelectedFeatureIds.isEmpty() )
{
result = utils.addRing( static_cast< QgsCurveV2* >( ring->clone() ), mSelectedFeatureIds, featureId );
}

if ( result != 0 )
{
//try with all intersecting features
result = utils.addRing( static_cast< QgsCurveV2* >( ring->clone() ), QgsFeatureIds(), featureId );
}

delete ring;
return result;
}

int QgsVectorLayer::addPart( const QList<QgsPoint> &points )
Expand Down
57 changes: 23 additions & 34 deletions src/core/qgsvectorlayereditutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ bool QgsVectorLayerEditUtils::deleteVertex( QgsFeatureId atFeatureId, int atVert
return true;
}

int QgsVectorLayerEditUtils::addRing( const QList<QgsPoint>& ring, QgsFeatureId* modifiedFeatureId, const QgsFeatureIds& preferredFeatureIds )
int QgsVectorLayerEditUtils::addRing( const QList<QgsPoint>& ring, const QgsFeatureIds& targetFeatureIds, QgsFeatureId* modifiedFeatureId )
{
QgsLineStringV2* ringLine = new QgsLineStringV2();
QList< QgsPointV2 > ringPoints;
Expand All @@ -114,10 +114,10 @@ int QgsVectorLayerEditUtils::addRing( const QList<QgsPoint>& ring, QgsFeatureId*
ringPoints.append( QgsPointV2( ringIt->x(), ringIt->y() ) );
}
ringLine->setPoints( ringPoints );
return addRing( ringLine, modifiedFeatureId, preferredFeatureIds );
return addRing( ringLine, targetFeatureIds, modifiedFeatureId );
}

int QgsVectorLayerEditUtils::addRing( QgsCurveV2* ring, QgsFeatureId* modifiedFeatureId, const QgsFeatureIds& preferredFeatureIds )
int QgsVectorLayerEditUtils::addRing( QgsCurveV2* ring, const QgsFeatureIds& targetFeatureIds, QgsFeatureId* modifiedFeatureId )
{
if ( !L->hasGeometryType() )
{
Expand All @@ -128,43 +128,32 @@ int QgsVectorLayerEditUtils::addRing( QgsCurveV2* ring, QgsFeatureId* modifiedFe
int addRingReturnCode = 5; //default: return code for 'ring not inserted'
QgsFeature f;

//see if part can be added to preferred features
if ( !preferredFeatureIds.isEmpty() )
QgsFeatureIterator fit;
if ( !targetFeatureIds.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;
}
}
//check only specified features
fit = L->getFeatures( QgsFeatureRequest().setFilterFids( targetFeatureIds ) );
}

//no match so far, so check other intersecting features
if ( addRingReturnCode != 0 )
else
{
//check all intersecting features
QgsRectangle bBox = ring->boundingBox();
QgsFeatureIterator fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
while ( fit.nextFeature( f ) )
fit = L->getFeatures( QgsFeatureRequest().setFilterRect( bBox ).setFlags( QgsFeatureRequest::ExactIntersect ) );
}

//find first valid feature we can add the ring to
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 )
{
//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();
L->editBuffer()->changeGeometry( f.id(), f.geometry() );
if ( modifiedFeatureId )
*modifiedFeatureId = f.id();

//setModified( true, true );
break;
}
//setModified( true, true );
break;
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/core/qgsvectorlayereditutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,31 +55,31 @@ 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
* @param targetFeatureIds if specified, only these features will be the candidates for adding a ring. Otherwise
* all intersecting features are tested and the ring is added to the first valid feature.
* @param modifiedFeatureId if specified, feature ID for feature that ring was added to will be stored in this parameter
@return
0 in case of success,
1 problem with feature type,
2 ring not closed,
3 ring not valid,
4 ring crosses existing rings,
5 no feature found where ring can be inserted*/
int addRing( const QList<QgsPoint>& ring, QgsFeatureId* featureId = 0, const QgsFeatureIds& preferredFeatureIds = QgsFeatureIds() );
int addRing( const QList<QgsPoint>& ring, const QgsFeatureIds& targetFeatureIds = QgsFeatureIds(), QgsFeatureId* modifiedFeatureId = 0 );

/** Adds a ring to polygon/multipolygon features
* @param ring ring to add
* @param modifiedFeatureId 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
* @param targetFeatureIds if specified, only these features will be the candidates for adding a ring. Otherwise
* all intersecting features are tested and the ring is added to the first valid feature.
* @param modifiedFeatureId if specified, feature ID for feature that ring was added to will be stored in this parameter
@return
0 in case of success,
1 problem with feature type,
2 ring not closed,
3 ring not valid,
4 ring crosses existing rings,
5 no feature found where ring can be inserted*/
int addRing( QgsCurveV2* ring, QgsFeatureId* modifiedFeatureId = 0, const QgsFeatureIds& preferredFeatureIds = QgsFeatureIds() );
int addRing( QgsCurveV2* ring, const QgsFeatureIds& preferredFeatureIds = QgsFeatureIds(), QgsFeatureId* modifiedFeatureId = 0 );

/** Adds a new part polygon to a multipart feature
@return
Expand Down

0 comments on commit 4925a54

Please sign in to comment.