예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
    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}
예제 #4
0
 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()