def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) reference_layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.REFERENCE_LAYER), context) tolerance = self.getParameterValue(self.TOLERANCE) mode = self.getParameterValue(self.BEHAVIOR) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) self.processed = 0 self.feedback = feedback self.total = 100.0 / layer.featureCount() if layer.featureCount() else 0 if self.getParameterValue(self.INPUT) != self.getParameterValue(self.REFERENCE_LAYER): snapper = QgsGeometrySnapper(reference_layer) snapper.featureSnapped.connect(self.featureSnapped) snapped_features = snapper.snapFeatures(features, tolerance, mode) for f in snapped_features: writer.addFeature(f, QgsFeatureSink.FastInsert) else: # snapping internally snapper = QgsInternalGeometrySnapper(tolerance, mode) processed = 0 for f in features: out_feature = f out_feature.setGeometry(snapper.snapFeature(f)) writer.addFeature(out_feature, QgsFeatureSink.FastInsert) processed += 1 feedback.setProgress(processed * self.total) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT)) reference_layer = dataobjects.getLayerFromString(self.getParameterValue(self.REFERENCE_LAYER)) tolerance = self.getParameterValue(self.TOLERANCE) mode = self.getParameterValue(self.BEHAVIOR) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields(), layer.wkbType(), layer.crs()) features = vector.features(layer) self.processed = 0 self.feedback = feedback self.total = 100.0 / len(features) if self.getParameterValue(self.INPUT) != self.getParameterValue(self.REFERENCE_LAYER): snapper = QgsGeometrySnapper(reference_layer) snapper.featureSnapped.connect(self.featureSnapped) snapped_features = snapper.snapFeatures(features, tolerance, mode) for f in snapped_features: writer.addFeature(QgsFeature(f)) else: # snapping internally snapper = QgsInternalGeometrySnapper(tolerance, mode) processed = 0 for f in features: out_feature = f out_feature.setGeometry(snapper.snapFeature(f)) writer.addFeature(out_feature) processed += 1 feedback.setProgress(processed * self.total) del writer
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) if source is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT)) reference_source = self.parameterAsSource(parameters, self.REFERENCE_LAYER, context) if reference_source is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.REFERENCE_LAYER)) tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context) mode = self.parameterAsEnum(parameters, self.BEHAVIOR, context) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, source.fields(), source.wkbType(), source.sourceCrs()) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) features = source.getFeatures() total = 100.0 / source.featureCount() if source.featureCount() else 0 if parameters[self.INPUT] != parameters[self.REFERENCE_LAYER]: snapper = QgsGeometrySnapper(reference_source) processed = 0 for f in features: if feedback.isCanceled(): break if f.hasGeometry(): out_feature = f out_feature.setGeometry( snapper.snapGeometry(f.geometry(), tolerance, mode)) sink.addFeature(out_feature, QgsFeatureSink.FastInsert) else: sink.addFeature(f) processed += 1 feedback.setProgress(processed * total) else: # snapping internally snapper = QgsInternalGeometrySnapper(tolerance, mode) processed = 0 for f in features: if feedback.isCanceled(): break out_feature = f out_feature.setGeometry(snapper.snapFeature(f)) sink.addFeature(out_feature, QgsFeatureSink.FastInsert) processed += 1 feedback.setProgress(processed * total) return {self.OUTPUT: dest_id}
def snapToLayer(self, inputLyr, refLyr, tol, behavior, onlySelected=False, feedback=None): """ Snaps and updates inpytLyr """ snapper = QgsGeometrySnapper(refLyr) if inputLyr != refLyr and behavior != 7 else QgsInternalGeometrySnapper(tol, behavior) iterator, featCount = self.getFeatureList(inputLyr, onlySelected=onlySelected) size = 100/featCount if featCount else 0 deleteList = [] inputLyr.startEditing() inputLyr.beginEditCommand('Snapping Features') for current, feat in enumerate(iterator): featid = feat.id() geom = feat.geometry() if feedback is not None and feedback.isCanceled(): break elif not feat.hasGeometry() or geom.isNull() or geom.isEmpty(): deleteList.append(featid) elif geom.type() == QgsWkbTypes.LineGeometry and geom.length() < tol: deleteList.append(featid) else: # remove duplicate nodes to avoid problem in snapping geom.removeDuplicateNodes() fixedGeom = geom.makeValid() if not fixedGeom.isNull(): outputGeom = snapper.snapGeometry(fixedGeom, tol, behavior) if inputLyr != refLyr and behavior != 7 else snapper.snapFeature(feat) if geom is None: deleteList.append(featid) else: inputLyr.changeGeometry(featid, outputGeom) if feedback is not None: feedback.setProgress(size * current) inputLyr.deleteFeatures(deleteList) inputLyr.endEditCommand()