Skip to content

Commit

Permalink
[geometry snapper] Fix missing vertices of snapped segment when snapp…
Browse files Browse the repository at this point in the history
…ing layer geometries against iself
  • Loading branch information
nirvn committed Aug 31, 2021
1 parent aac088b commit 47936c2
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
48 changes: 38 additions & 10 deletions src/analysis/processing/qgsalgorithmsnapgeometries.cpp
Expand Up @@ -125,11 +125,11 @@ QVariantMap QgsSnapGeometriesAlgorithm::processAlgorithm( const QVariantMap &par
if ( !sink )
throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );

const double step = source->featureCount() > 0 ? 100.0 / source->featureCount() : 1;
QgsFeatureIterator features = source->getFeatures();

if ( parameters.value( QStringLiteral( "INPUT" ) ) != parameters.value( QStringLiteral( "REFERENCE_LAYER" ) ) )
{
const double step = source->featureCount() > 0 ? 100.0 / source->featureCount() : 1;
if ( mode == 7 )
throw QgsProcessingException( QObject::tr( "This mode applies when the input and reference layer are the same." ) );

Expand Down Expand Up @@ -166,28 +166,56 @@ QVariantMap QgsSnapGeometriesAlgorithm::processAlgorithm( const QVariantMap &par
else
{
// snapping internally
QgsInternalGeometrySnapper snapper( tolerance, mode );
const double step = source->featureCount() > 0 ? 100.0 / ( source->featureCount() * 2 ) : 1;
long long processed = 0;

QgsInternalGeometrySnapper snapper( tolerance, mode );
QgsFeature f;
QList<QgsFeatureId> editedFeatureIds;
QMap<QgsFeatureId, QgsFeature> editedFeatures;
while ( features.nextFeature( f ) )
{
if ( feedback->isCanceled() )
break;

QgsFeature editedFeature( f );
if ( f.hasGeometry() )
{
QgsFeature outFeature( f );
outFeature.setGeometry( snapper.snapFeature( f ) );
if ( !sink->addFeature( outFeature, QgsFeatureSink::FastInsert ) )
throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );
editedFeature.setGeometry( snapper.snapFeature( f ) );
}
else
editedFeatureIds << editedFeature.id();
editedFeatures.insert( editedFeature.id(), editedFeature );
processed += 1;
}

// reversed order snapping round is required to insure geometries are snapped against all features
snapper = QgsInternalGeometrySnapper( tolerance, mode );
std::reverse( editedFeatureIds.begin(), editedFeatureIds.end() );
for ( const QgsFeatureId &fid : editedFeatureIds )
{
if ( feedback->isCanceled() )
break;

QgsFeature editedFeature( editedFeatures.value( fid ) );
if ( editedFeature.hasGeometry() )
{
if ( !sink->addFeature( f ) )
editedFeature.setGeometry( snapper.snapFeature( editedFeature ) );
editedFeatures.insert( editedFeature.id(), editedFeature );
}
}
std::reverse( editedFeatureIds.begin(), editedFeatureIds.end() );
processed += 1;

if ( !feedback->isCanceled() )
{
for ( const QgsFeatureId &fid : editedFeatureIds )
{
QgsFeature outFeature( editedFeatures.value( fid ) );
if ( !sink->addFeature( outFeature ) )
throw QgsProcessingException( writeFeatureError( sink.get(), parameters, QStringLiteral( "OUTPUT" ) ) );

feedback->setProgress( processed * step );
}
processed += 1;
feedback->setProgress( processed * step );
}
}

Expand Down
7 changes: 3 additions & 4 deletions src/analysis/vector/qgsgeometrysnapper.cpp
Expand Up @@ -584,20 +584,18 @@ QgsGeometry QgsGeometrySnapper::snapGeometry( const QgsGeometry &geometry, doubl
}
}

//nothing more to do for points
// no extra vertices to add for point geometry
if ( qgsgeometry_cast< const QgsPoint * >( subjGeom ) )
return QgsGeometry( subjGeom );


//or for end point snapping
// nor for no extra vertices modes and end point only snapping
if ( mode == PreferClosestNoExtraVertices || mode == PreferNodesNoExtraVertices || mode == EndPointPreferClosest || mode == EndPointPreferNodes || mode == EndPointToEndPoint )
{
QgsGeometry result( subjGeom );
result.removeDuplicateNodes();
return result;
}

// SnapIndex for subject feature
std::unique_ptr< QgsSnapIndex > subjSnapIndex( new QgsSnapIndex() );
subjSnapIndex->addGeometry( subjGeom );

Expand Down Expand Up @@ -758,3 +756,4 @@ QgsGeometry QgsInternalGeometrySnapper::snapFeature( const QgsFeature &feature )
mFirstFeature = false;
return geometry;
}

0 comments on commit 47936c2

Please sign in to comment.