From 880505a6f8c8a84a941a6e483d3c17df5c57c3bd Mon Sep 17 00:00:00 2001 From: Joonalai Date: Mon, 13 Jan 2025 14:43:44 +0200 Subject: [PATCH] Add only topo points to editable layers --- src/app/qgsmaptooladdfeature.cpp | 85 +++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 28 deletions(-) diff --git a/src/app/qgsmaptooladdfeature.cpp b/src/app/qgsmaptooladdfeature.cpp index ed5e3e42bc9f..3f1ebcf45d9d 100644 --- a/src/app/qgsmaptooladdfeature.cpp +++ b/src/app/qgsmaptooladdfeature.cpp @@ -28,8 +28,10 @@ #include "qgisapp.h" #include "qgsexpressioncontextutils.h" #include "qgsrubberband.h" +#include "qgsmultipoint.h" #include +#include QgsMapToolAddFeature::QgsMapToolAddFeature( QgsMapCanvas *canvas, QgsAdvancedDigitizingDockWidget *cadDockWidget, CaptureMode mode ) : QgsMapToolDigitizeFeature( canvas, cadDockWidget, mode ) @@ -143,45 +145,72 @@ void QgsMapToolAddFeature::featureDigitized( const QgsFeature &feature ) } if ( topologicalEditing ) { - const QList layers = canvas()->layers( true ); + QList sm = snappingMatches(); + sm.erase( std::remove_if( sm.begin(), sm.end(), []( const QgsPointLocator::Match &match ) { + return match.layer() == nullptr; + } ), + sm.end() ); - for ( QgsMapLayer *layer : layers ) + if ( sm.size() ) { - QgsVectorLayer *vectorLayer = qobject_cast( layer ); + QgsMultiPoint *snapPoints = new QgsMultiPoint(); - if ( !vectorLayer || !vectorLayer->isEditable() ) - continue; - - if ( !( vectorLayer->geometryType() == Qgis::GeometryType::Polygon || vectorLayer->geometryType() == Qgis::GeometryType::Line ) ) - continue; + for ( int i = 0; i < sm.size(); ++i ) + { + snapPoints->addGeometry( feature.geometry().vertexAt( i ).clone() ); + } - vectorLayer->beginEditCommand( tr( "Topological points added by 'Add Feature'" ) ); + QgsPointSequence topoPoints; + for ( int j = 0; j < snapPoints->partCount(); ++j ) + { + topoPoints.append( *snapPoints->pointN( j ) ); + } - int res = 2; - if ( vectorLayer->crs() != vlayer->crs() ) + const QList layers = canvas()->layers( true ); + for ( QgsMapLayer *layer : layers ) { - QgsGeometry transformedGeom = feature.geometry(); - try + QgsVectorLayer *vectorLayer = qobject_cast( layer ); + if ( !vectorLayer || !vectorLayer->isEditable() ) + continue; + + if ( !( vectorLayer->geometryType() == Qgis::GeometryType::Polygon || vectorLayer->geometryType() == Qgis::GeometryType::Line ) ) + continue; + + vectorLayer->beginEditCommand( tr( "Topological points added by 'Add Feature'" ) ); + + int res = 2; + if ( vectorLayer->crs() != vlayer->crs() ) { - // transform digitized geometry from vlayer crs to vectorLayer crs and add topological points - transformedGeom.transform( QgsCoordinateTransform( vlayer->crs(), vectorLayer->crs(), vectorLayer->transformContext() ) ); - res = vectorLayer->addTopologicalPoints( transformedGeom ); + try + { + QgsMultiPoint *transformedGeom = snapPoints->clone(); + // transform digitized geometry from vlayer crs to vectorLayer crs and add topological points + transformedGeom->transform( QgsCoordinateTransform( vlayer->crs(), vectorLayer->crs(), vectorLayer->transformContext() ) ); + + QgsPointSequence trarnsformedtopoPoints; + for ( int j = 0; j < transformedGeom->partCount(); ++j ) + { + trarnsformedtopoPoints.append( *transformedGeom->pointN( j ) ); + } + + res = vectorLayer->addTopologicalPoints( trarnsformedtopoPoints ); + } + catch ( QgsCsException &cse ) + { + Q_UNUSED( cse ) + QgsDebugError( QStringLiteral( "transformation to vectorLayer coordinate failed" ) ); + } } - catch ( QgsCsException &cse ) + else { - Q_UNUSED( cse ) - QgsDebugError( QStringLiteral( "transformation to vectorLayer coordinate failed" ) ); + res = vectorLayer->addTopologicalPoints( topoPoints ); } - } - else - { - res = vectorLayer->addTopologicalPoints( feature.geometry() ); - } - if ( res == 0 ) // i.e. if any points were added - vectorLayer->endEditCommand(); - else - vectorLayer->destroyEditCommand(); + if ( res == 0 ) // i.e. if points were added + vectorLayer->endEditCommand(); + else + vectorLayer->destroyEditCommand(); + } } } }