26 QString QgsSnapGeometriesAlgorithm::name()
const
28 return QStringLiteral(
"snapgeometries" );
31 QString QgsSnapGeometriesAlgorithm::displayName()
const
33 return QObject::tr(
"Snap geometries to layer" );
36 QString QgsSnapGeometriesAlgorithm::shortHelpString()
const
38 return QObject::tr(
"Snaps the geometries in a layer. Snapping can be done either to the geometries "
39 "from another layer, or to geometries within the same layer." )
40 + QStringLiteral(
"\n\n" )
41 + QObject::tr(
"A tolerance is specified in layer units to control how close vertices need "
42 "to be to the reference layer geometries before they are snapped." )
43 + QStringLiteral(
"\n\n" )
44 + QObject::tr(
"Snapping occurs to both nodes and edges. Depending on the snapping behavior, "
45 "either nodes or edges will be preferred." )
46 + QStringLiteral(
"\n\n" )
47 + QObject::tr(
"Vertices will be inserted or removed as required to make the geometries match "
48 "the reference geometries." );
51 QStringList QgsSnapGeometriesAlgorithm::tags()
const
53 return QObject::tr(
"geometry,snap,tolerance" ).split(
',' );
56 QString QgsSnapGeometriesAlgorithm::group()
const
58 return QObject::tr(
"Vector geometry" );
61 QString QgsSnapGeometriesAlgorithm::groupId()
const
63 return QStringLiteral(
"vectorgeometry" );
66 QgsProcessingAlgorithm::Flags QgsSnapGeometriesAlgorithm::flags()
const
73 bool QgsSnapGeometriesAlgorithm::supportInPlaceEdit(
const QgsMapLayer *l )
const
75 const QgsVectorLayer *layer = qobject_cast< const QgsVectorLayer * >( l );
82 void QgsSnapGeometriesAlgorithm::initAlgorithm(
const QVariantMap & )
89 std::unique_ptr< QgsProcessingParameterDistance > tolParam = std::make_unique< QgsProcessingParameterDistance >( QStringLiteral(
"TOLERANCE" ), QObject::tr(
"Tolerance" ), 10.0, QStringLiteral(
"INPUT" ),
false, 0.00000001 );
90 tolParam->setMetadata(
93 QStringLiteral(
"widget_wrapper" ),
95 QStringLiteral(
"decimals" ), 8
99 addParameter( tolParam.release() );
101 const QStringList options = QStringList()
102 << QObject::tr(
"Prefer aligning nodes, insert extra vertices where required" )
103 << QObject::tr(
"Prefer closest point, insert extra vertices where required" )
104 << QObject::tr(
"Prefer aligning nodes, don't insert new vertices" )
105 << QObject::tr(
"Prefer closest point, don't insert new vertices" )
106 << QObject::tr(
"Move end points only, prefer aligning nodes" )
107 << QObject::tr(
"Move end points only, prefer closest point" )
108 << QObject::tr(
"Snap end points to end points only" )
109 << QObject::tr(
"Snap to anchor nodes (single layer only)" );
110 addParameter(
new QgsProcessingParameterEnum( QStringLiteral(
"BEHAVIOR" ), QObject::tr(
"Behavior" ), options,
false, QVariantList() << 0 ) );
115 QgsSnapGeometriesAlgorithm *QgsSnapGeometriesAlgorithm::createInstance()
const
117 return new QgsSnapGeometriesAlgorithm();
122 std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral(
"INPUT" ), context ) );
126 const std::unique_ptr< QgsProcessingFeatureSource > referenceSource( parameterAsSource( parameters, QStringLiteral(
"REFERENCE_LAYER" ), context ) );
127 if ( !referenceSource )
130 const double tolerance = parameterAsDouble( parameters, QStringLiteral(
"TOLERANCE" ), context );
134 std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral(
"OUTPUT" ), context, dest, source->fields(), source->wkbType(), source->sourceCrs() ) );
140 if ( parameters.value( QStringLiteral(
"INPUT" ) ) != parameters.value( QStringLiteral(
"REFERENCE_LAYER" ) ) )
142 const double step = source->featureCount() > 0 ? 100.0 / source->featureCount() : 1;
144 throw QgsProcessingException( QObject::tr(
"This mode applies when the input and reference layer are the same." ) );
147 long long processed = 0;
157 outFeature.setGeometry( snapper.snapGeometry( f.
geometry(), tolerance, mode ) );
163 if ( !sink->addFeature( f ) )
170 else if ( mode == 7 )
174 feedback->
pushInfo( QObject::tr(
"Snapped %n geometries.",
nullptr, modified ) );
179 const double step = source->featureCount() > 0 ? 100.0 / ( source->featureCount() * 2 ) : 1;
180 long long processed = 0;
184 QList<QgsFeatureId> editedFeatureIds;
185 QMap<QgsFeatureId, QgsFeature> editedFeatures;
194 editedFeature.setGeometry( snapper.snapFeature( f ) );
196 editedFeatureIds << editedFeature.id();
197 editedFeatures.insert( editedFeature.id(), editedFeature );
203 std::reverse( editedFeatureIds.begin(), editedFeatureIds.end() );
204 for (
const QgsFeatureId &fid : std::as_const( editedFeatureIds ) )
209 QgsFeature editedFeature( editedFeatures.value( fid ) );
210 if ( editedFeature.hasGeometry() )
212 editedFeature.setGeometry( snapper.snapFeature( editedFeature ) );
213 editedFeatures.insert( editedFeature.id(), editedFeature );
216 std::reverse( editedFeatureIds.begin(), editedFeatureIds.end() );
221 for (
const QgsFeatureId &fid : std::as_const( editedFeatureIds ) )
223 QgsFeature outFeature( editedFeatures.value( fid ) );
224 if ( !sink->addFeature( outFeature ) )
233 outputs.insert( QStringLiteral(
"OUTPUT" ), dest );