def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) if source is None: raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) index = self.parameterAsEnum(parameters, self.TYPE, context) if index == 0: newType = QgsWkbTypes.Point elif index == 1: newType = QgsWkbTypes.Point if QgsWkbTypes.hasM(source.wkbType()): newType = QgsWkbTypes.addM(newType) if QgsWkbTypes.hasZ(source.wkbType()): newType = QgsWkbTypes.addZ(newType) elif index == 2: newType = QgsWkbTypes.LineString if QgsWkbTypes.hasM(source.wkbType()): newType = QgsWkbTypes.addM(newType) if QgsWkbTypes.hasZ(source.wkbType()): newType = QgsWkbTypes.addZ(newType) elif index == 3: newType = QgsWkbTypes.MultiLineString if QgsWkbTypes.hasM(source.wkbType()): newType = QgsWkbTypes.addM(newType) if QgsWkbTypes.hasZ(source.wkbType()): newType = QgsWkbTypes.addZ(newType) else: newType = QgsWkbTypes.Polygon if QgsWkbTypes.hasM(source.wkbType()): newType = QgsWkbTypes.addM(newType) if QgsWkbTypes.hasZ(source.wkbType()): newType = QgsWkbTypes.addZ(newType) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, source.fields(), newType, 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 for current, f in enumerate(features): if feedback.isCanceled(): break if not f.hasGeometry(): sink.addFeature(f, QgsFeatureSink.FastInsert) else: for p in self.convertGeometry(f.geometry(), index): feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(p) sink.addFeature(feat, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_LAYER)) input_wkb = layer.wkbType() if QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.LineGeometry: output_wkb = QgsWkbTypes.MultiPoint elif QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.PolygonGeometry: output_wkb = QgsWkbTypes.MultiLineString if QgsWkbTypes.hasZ(input_wkb): output_wkb = QgsWkbTypes.addZ(output_wkb) if QgsWkbTypes.hasM(input_wkb): output_wkb = QgsWkbTypes.addM(output_wkb) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(layer.fields(), output_wkb, layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, input_feature in enumerate(features): output_feature = input_feature input_geometry = input_feature.geometry() if input_geometry: output_geometry = QgsGeometry(input_geometry.geometry().boundary()) if not output_geometry: raise GeoAlgorithmExecutionException(self.tr("Error calculating boundary")) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) fields = source.fields() x_field_index = fields.lookupField(self.parameterAsString(parameters, self.XFIELD, context)) y_field_index = fields.lookupField(self.parameterAsString(parameters, self.YFIELD, context)) z_field_index = -1 if self.parameterAsString(parameters, self.ZFIELD, context): z_field_index = fields.lookupField(self.parameterAsString(parameters, self.ZFIELD, context)) m_field_index = -1 if self.parameterAsString(parameters, self.MFIELD, context): m_field_index = fields.lookupField(self.parameterAsString(parameters, self.MFIELD, context)) wkb_type = QgsWkbTypes.Point if z_field_index >= 0: wkb_type = QgsWkbTypes.addZ(wkb_type) if m_field_index >= 0: wkb_type = QgsWkbTypes.addM(wkb_type) target_crs = self.parameterAsCrs(parameters, self.TARGET_CRS, context) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, wkb_type, target_crs) request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry) features = source.getFeatures() total = 100.0 / source.featureCount() if source.featureCount() else 0 for current, feature in enumerate(features): if feedback.isCanceled(): break feedback.setProgress(int(current * total)) attrs = feature.attributes() try: x = float(attrs[x_field_index]) y = float(attrs[y_field_index]) point = QgsPoint(x, y) if z_field_index >= 0: try: point.addZValue(float(attrs[z_field_index])) except: point.addZValue(0.0) if m_field_index >= 0: try: point.addMValue(float(attrs[m_field_index])) except: point.addMValue(0.0) feature.setGeometry(QgsGeometry(point)) except: pass # no geometry sink.addFeature(feature) return {self.OUTPUT: dest_id}
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_LAYER)) geometry_type = self.getParameterValue(self.OUTPUT_GEOMETRY) wkb_type = None if geometry_type == 0: wkb_type = QgsWkbTypes.Polygon elif geometry_type == 1: wkb_type = QgsWkbTypes.LineString else: wkb_type = QgsWkbTypes.Point if self.getParameterValue(self.WITH_Z): wkb_type = QgsWkbTypes.addZ(wkb_type) if self.getParameterValue(self.WITH_M): wkb_type = QgsWkbTypes.addM(wkb_type) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter( layer.fields(), wkb_type, layer.crs()) expression = QgsExpression(self.getParameterValue(self.EXPRESSION)) if expression.hasParserError(): raise GeoAlgorithmExecutionException(expression.parserErrorString()) exp_context = QgsExpressionContext() exp_context.appendScope(QgsExpressionContextUtils.globalScope()) exp_context.appendScope(QgsExpressionContextUtils.projectScope()) exp_context.appendScope(QgsExpressionContextUtils.layerScope(layer)) if not expression.prepare(exp_context): raise GeoAlgorithmExecutionException( self.tr('Evaluation error: %s' % expression.evalErrorString())) features = vector.features(layer) total = 100.0 / len(features) for current, input_feature in enumerate(features): output_feature = input_feature exp_context.setFeature(input_feature) value = expression.evaluate(exp_context) if expression.hasEvalError(): raise GeoAlgorithmExecutionException( self.tr('Evaluation error: %s' % expression.evalErrorString())) if not value: output_feature.setGeometry(QgsGeometry()) else: if not isinstance(value, QgsGeometry): raise GeoAlgorithmExecutionException( self.tr('{} is not a geometry').format(value)) output_feature.setGeometry(value) writer.addFeature(output_feature) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): source = self.getParameterValue(self.INPUT) vlayer = dataobjects.getObjectFromUri(source) output = self.getOutputFromName(self.OUTPUT) fields = vlayer.fields() x_field_index = fields.lookupField(self.getParameterValue(self.XFIELD)) y_field_index = fields.lookupField(self.getParameterValue(self.YFIELD)) z_field_index = None if self.getParameterValue(self.ZFIELD): z_field_index = fields.lookupField(self.getParameterValue(self.ZFIELD)) m_field_index = None if self.getParameterValue(self.MFIELD): m_field_index = fields.lookupField(self.getParameterValue(self.MFIELD)) wkb_type = QgsWkbTypes.Point if z_field_index is not None: wkb_type = QgsWkbTypes.addZ(wkb_type) if m_field_index is not None: wkb_type = QgsWkbTypes.addM(wkb_type) crsId = self.getParameterValue(self.TARGET_CRS) target_crs = QgsCoordinateReferenceSystem() target_crs.createFromUserInput(crsId) writer = output.getVectorWriter(fields, wkb_type, target_crs) features = vector.features(vlayer) total = 100.0 / len(features) for current, feature in enumerate(features): progress.setPercentage(int(current * total)) attrs = feature.attributes() try: x = float(attrs[x_field_index]) y = float(attrs[y_field_index]) point = QgsPointV2(x, y) if z_field_index is not None: try: point.addZValue(float(attrs[z_field_index])) except: point.addZValue(0.0) if m_field_index is not None: try: point.addMValue(float(attrs[m_field_index])) except: point.addMValue(0.0) feature.setGeometry(QgsGeometry(point)) except: pass # no geometry writer.addFeature(feature) del writer
def outputWkbType(self, input_wkb): if QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.LineGeometry: output_wkb = QgsWkbTypes.MultiPoint elif QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.PolygonGeometry: output_wkb = QgsWkbTypes.MultiLineString if QgsWkbTypes.hasZ(input_wkb): output_wkb = QgsWkbTypes.addZ(output_wkb) if QgsWkbTypes.hasM(input_wkb): output_wkb = QgsWkbTypes.addM(output_wkb) return output_wkb
def convertWkbToLines(self, wkb): multi_wkb = QgsWkbTypes.NoGeometry if QgsWkbTypes.singleType(QgsWkbTypes.flatType(wkb)) == QgsWkbTypes.Polygon: multi_wkb = QgsWkbTypes.MultiLineString elif QgsWkbTypes.singleType(QgsWkbTypes.flatType(wkb)) == QgsWkbTypes.CurvePolygon: multi_wkb = QgsWkbTypes.MultiCurve if QgsWkbTypes.hasM(wkb): multi_wkb = QgsWkbTypes.addM(multi_wkb) if QgsWkbTypes.hasZ(wkb): multi_wkb = QgsWkbTypes.addZ(multi_wkb) return multi_wkb
def convertWkbToPolygons(self, wkb): multi_wkb = QgsWkbTypes.NoGeometry if QgsWkbTypes.singleType(QgsWkbTypes.flatType(wkb)) == QgsWkbTypes.LineString: multi_wkb = QgsWkbTypes.MultiPolygon elif QgsWkbTypes.singleType(QgsWkbTypes.flatType(wkb)) == QgsWkbTypes.CompoundCurve: multi_wkb = QgsWkbTypes.MultiSurface if QgsWkbTypes.hasM(wkb): multi_wkb = QgsWkbTypes.addM(multi_wkb) if QgsWkbTypes.hasZ(wkb): multi_wkb = QgsWkbTypes.addZ(multi_wkb) return multi_wkb
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) geometry_type = self.getParameterValue(self.OUTPUT_GEOMETRY) wkb_type = None if geometry_type == 0: wkb_type = QgsWkbTypes.Polygon elif geometry_type == 1: wkb_type = QgsWkbTypes.LineString else: wkb_type = QgsWkbTypes.Point if self.getParameterValue(self.WITH_Z): wkb_type = QgsWkbTypes.addZ(wkb_type) if self.getParameterValue(self.WITH_M): wkb_type = QgsWkbTypes.addM(wkb_type) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter(layer.fields(), wkb_type, layer.crs(), context) expression = QgsExpression(self.getParameterValue(self.EXPRESSION)) if expression.hasParserError(): raise GeoAlgorithmExecutionException(expression.parserErrorString()) exp_context = QgsExpressionContext(QgsExpressionContextUtils.globalProjectLayerScopes(layer)) if not expression.prepare(exp_context): raise GeoAlgorithmExecutionException( self.tr('Evaluation error: {0}').format(expression.evalErrorString())) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, input_feature in enumerate(features): output_feature = input_feature exp_context.setFeature(input_feature) value = expression.evaluate(exp_context) if expression.hasEvalError(): raise GeoAlgorithmExecutionException( self.tr('Evaluation error: {0}').format(expression.evalErrorString())) if not value: output_feature.setGeometry(QgsGeometry()) else: if not isinstance(value, QgsGeometry): raise GeoAlgorithmExecutionException( self.tr('{} is not a geometry').format(value)) output_feature.setGeometry(value) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) fields = source.fields() fields.append(QgsField('node_index', QVariant.Int)) fields.append(QgsField('distance', QVariant.Double)) fields.append(QgsField('angle', QVariant.Double)) out_wkb = QgsWkbTypes.Point if QgsWkbTypes.hasM(source.wkbType()): out_wkb = QgsWkbTypes.addM(out_wkb) if QgsWkbTypes.hasZ(source.wkbType()): out_wkb = QgsWkbTypes.addZ(out_wkb) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, out_wkb, source.sourceCrs()) features = source.getFeatures() total = 100.0 / source.featureCount() if source.featureCount() else 0 for current, f in enumerate(features): if feedback.isCanceled(): break input_geometry = f.geometry() if not input_geometry: sink.addFeature(f, QgsFeatureSink.FastInsert) else: i = 0 for part in input_geometry.geometry().coordinateSequence(): for ring in part: if feedback.isCanceled(): break for point in ring: distance = input_geometry.distanceToVertex(i) angle = math.degrees(input_geometry.angleAtVertex(i)) attrs = f.attributes() attrs.append(i) attrs.append(distance) attrs.append(angle) output_feature = QgsFeature() output_feature.setAttributes(attrs) output_feature.setGeometry(QgsGeometry(point.clone())) sink.addFeature(output_feature, QgsFeatureSink.FastInsert) i += 1 feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT_LAYER, context) input_wkb = source.wkbType() if QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.LineGeometry: output_wkb = QgsWkbTypes.MultiPoint elif QgsWkbTypes.geometryType(input_wkb) == QgsWkbTypes.PolygonGeometry: output_wkb = QgsWkbTypes.MultiLineString if QgsWkbTypes.hasZ(input_wkb): output_wkb = QgsWkbTypes.addZ(output_wkb) if QgsWkbTypes.hasM(input_wkb): output_wkb = QgsWkbTypes.addM(output_wkb) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LAYER, context, source.fields(), output_wkb, source.sourceCrs()) features = source.getFeatures() total = 100.0 / source.featureCount() for current, input_feature in enumerate(features): if feedback.isCanceled(): break output_feature = input_feature input_geometry = input_feature.geometry() if input_geometry: output_geometry = QgsGeometry(input_geometry.geometry().boundary()) if not output_geometry: raise GeoAlgorithmExecutionException( self.tr('Error calculating boundary')) output_feature.setGeometry(output_geometry) sink.addFeature(output_feature) feedback.setProgress(int(current * total)) return {self.OUTPUT_LAYER: dest_id}
def processAlgorithm(self, feedback): source = self.getParameterValue(self.INPUT) vlayer = dataobjects.getLayerFromString(source) output = self.getOutputFromName(self.OUTPUT) fields = vlayer.fields() x_field_index = fields.lookupField(self.getParameterValue(self.XFIELD)) y_field_index = fields.lookupField(self.getParameterValue(self.YFIELD)) z_field_index = None if self.getParameterValue(self.ZFIELD): z_field_index = fields.lookupField( self.getParameterValue(self.ZFIELD)) m_field_index = None if self.getParameterValue(self.MFIELD): m_field_index = fields.lookupField( self.getParameterValue(self.MFIELD)) wkb_type = QgsWkbTypes.Point if z_field_index is not None: wkb_type = QgsWkbTypes.addZ(wkb_type) if m_field_index is not None: wkb_type = QgsWkbTypes.addM(wkb_type) crsId = self.getParameterValue(self.TARGET_CRS) target_crs = QgsCoordinateReferenceSystem() target_crs.createFromUserInput(crsId) writer = output.getVectorWriter(fields, wkb_type, target_crs) features = vector.features(vlayer) total = 100.0 / len(features) for current, feature in enumerate(features): feedback.setProgress(int(current * total)) attrs = feature.attributes() try: x = float(attrs[x_field_index]) y = float(attrs[y_field_index]) point = QgsPointV2(x, y) if z_field_index is not None: try: point.addZValue(float(attrs[z_field_index])) except: point.addZValue(0.0) if m_field_index is not None: try: point.addMValue(float(attrs[m_field_index])) except: point.addMValue(0.0) feature.setGeometry(QgsGeometry(point)) except: pass # no geometry writer.addFeature(feature) 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)) index = self.parameterAsEnum(parameters, self.TYPE, context) if index == 0: newType = QgsWkbTypes.Point elif index == 1: newType = QgsWkbTypes.Point if QgsWkbTypes.hasM(source.wkbType()): newType = QgsWkbTypes.addM(newType) if QgsWkbTypes.hasZ(source.wkbType()): newType = QgsWkbTypes.addZ(newType) elif index == 2: newType = QgsWkbTypes.LineString if QgsWkbTypes.hasM(source.wkbType()): newType = QgsWkbTypes.addM(newType) if QgsWkbTypes.hasZ(source.wkbType()): newType = QgsWkbTypes.addZ(newType) elif index == 3: newType = QgsWkbTypes.MultiLineString if QgsWkbTypes.hasM(source.wkbType()): newType = QgsWkbTypes.addM(newType) if QgsWkbTypes.hasZ(source.wkbType()): newType = QgsWkbTypes.addZ(newType) else: newType = QgsWkbTypes.Polygon if QgsWkbTypes.hasM(source.wkbType()): newType = QgsWkbTypes.addM(newType) if QgsWkbTypes.hasZ(source.wkbType()): newType = QgsWkbTypes.addZ(newType) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, source.fields(), newType, 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 for current, f in enumerate(features): if feedback.isCanceled(): break if not f.hasGeometry(): sink.addFeature(f, QgsFeatureSink.FastInsert) else: for p in self.convertGeometry(f.geometry(), index): feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(p) sink.addFeature(feat, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) if source is None: raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) fields = source.fields() fields.append(QgsField('vertex_pos', QVariant.Int)) fields.append(QgsField('vertex_index', QVariant.Int)) fields.append(QgsField('vertex_part', QVariant.Int)) if QgsWkbTypes.geometryType(source.wkbType()) == QgsWkbTypes.PolygonGeometry: fields.append(QgsField('vertex_part_ring', QVariant.Int)) fields.append(QgsField('vertex_part_index', QVariant.Int)) fields.append(QgsField('distance', QVariant.Double)) fields.append(QgsField('angle', QVariant.Double)) wkb_type = QgsWkbTypes.Point if QgsWkbTypes.hasM(source.wkbType()): wkb_type = QgsWkbTypes.addM(wkb_type) if QgsWkbTypes.hasZ(source.wkbType()): wkb_type = QgsWkbTypes.addZ(wkb_type) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, wkb_type, source.sourceCrs(), QgsFeatureSink.RegeneratePrimaryKey) if sink is None: raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT)) vertex_indices_string = self.parameterAsString(parameters, self.VERTICES, context) indices = [] for vertex in vertex_indices_string.split(','): try: indices.append(int(vertex)) except: raise QgsProcessingException( self.tr('\'{}\' is not a valid vertex index').format(vertex)) features = source.getFeatures(QgsFeatureRequest(), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks) total = 100.0 / source.featureCount() if source.featureCount() else 0 for current, f in enumerate(features): if feedback.isCanceled(): break input_geometry = f.geometry() if not input_geometry: sink.addFeature(f, QgsFeatureSink.FastInsert) else: total_vertices = input_geometry.constGet().nCoordinates() for vertex in indices: if vertex < 0: vertex_index = total_vertices + vertex else: vertex_index = vertex if vertex_index < 0 or vertex_index >= total_vertices: continue (success, vertex_id) = input_geometry.vertexIdFromVertexNr(vertex_index) distance = input_geometry.distanceToVertex(vertex_index) angle = math.degrees(input_geometry.angleAtVertex(vertex_index)) output_feature = QgsFeature() attrs = f.attributes() attrs.append(vertex) attrs.append(vertex_index) attrs.append(vertex_id.part) if QgsWkbTypes.geometryType(source.wkbType()) == QgsWkbTypes.PolygonGeometry: attrs.append(vertex_id.ring) attrs.append(vertex_id.vertex) attrs.append(distance) attrs.append(angle) output_feature.setAttributes(attrs) point = input_geometry.vertexAt(vertex_index) output_feature.setGeometry(QgsGeometry(point)) sink.addFeature(output_feature, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def processAlgorithm(self, parameters, context, model_feedback): feedback = QgsProcessingMultiStepFeedback(2, model_feedback) source = self.parameterAsSource(parameters, self.INPUT, context) if source is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT)) group_field_name = self.parameterAsString(parameters, self.GROUP_FIELD, context) order_field_name = self.parameterAsString(parameters, self.ORDER_FIELD, context) date_format = self.parameterAsString(parameters, self.DATE_FORMAT, context) group_field_index = source.fields().lookupField(group_field_name) order_field_index = source.fields().lookupField(order_field_name) field_names = self.parameterAsFields(parameters, self.FIELDS, context) if group_field_index >= 0: group_field_def = source.fields().at(group_field_index) else: group_field_def = None order_field_def = source.fields().at(order_field_index) #Create output for lines fields = QgsFields() self.addFields(source, fields, 'start_order', field_names, order_field_def) self.addFields(source, fields, 'end_order', field_names, order_field_def) fields.append(QgsField('COUNT', QVariant.LongLong)) output_wkb = QgsWkbTypes.LineString if QgsWkbTypes.hasM(source.wkbType()): output_wkb = QgsWkbTypes.addM(output_wkb) if QgsWkbTypes.hasZ(source.wkbType()): output_wkb = QgsWkbTypes.addZ(output_wkb) (self.sink, self.dest_id) = self.parameterAsSink(parameters, self.OUTPUT_LINE, context, fields, output_wkb, source.sourceCrs()) if self.sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT_LINE)) #Create output for Points fields_point = QgsFields() fields_point.append(QgsField("fid", QVariant.Int, "int", 9, 0)) self.addFields(source, fields_point, 'end_order', field_names) fields_point.append(QgsField("COUNT", QVariant.LongLong)) fields_point.append(QgsField("COUNT_IN", QVariant.LongLong)) fields_point.append(QgsField("COUNT_OUT", QVariant.LongLong)) (self.sink_point, self.dest_id_point) = self.parameterAsSink( parameters, self.OUTPUT_POINT, context, fields_point, source.wkbType(), source.sourceCrs(), QgsFeatureSink.RegeneratePrimaryKey) if self.sink_point is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT_POINT)) #Compute the lines points = dict() features = source.getFeatures( QgsFeatureRequest(), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks) total = 100.0 / source.featureCount() if source.featureCount() else 0 for current, f in enumerate(features): if feedback.isCanceled(): return {} if not f.hasGeometry(): continue point = f.geometry().asPoint() if group_field_index >= 0: group = f[group_field_index] else: group = 1 order = f[order_field_index] if date_format != '': if isinstance(order, QDateTime): pass else: try: order = datetime.strptime(str(order), date_format) except ValueError as ve: feedback.reportError( self.tr('Invalid format {}').format(ve)) return {} data = [order, point] for indice in self.field_indices: data.append(f[indice]) if group in points: points[group].append(data) else: points[group] = [data] feedback.setProgress(int(current * total)) feedback.setCurrentStep(1) #Create the features current = 0 total = 100.0 / len(points) if points else 1 edge_ids = {} end_points = {} self.point_id = 0 for group, vertices in points.items(): if feedback.isCanceled(): return {} feedback.setProgress(int(current * total)) # log("attrs: {}".format(vertices)) vertices.sort(key=lambda x: (x[0] is None, x[0])) for i in range(len(vertices) - 1): if feedback.isCanceled(): return {} start_id = vertices[i][1].asWkt() end_id = vertices[i + 1][1].asWkt() edge_id = start_id + "-" + end_id if edge_id in edge_ids: f = edge_ids[edge_id] count_index = 2 * (len(self.field_indices) + 1) count = f.attribute(count_index) + 1 f.setAttribute(count_index, count) else: f = QgsFeature() attrs = [] attrs.append(vertices[i][0]) #Add Order begin for j in range(len( self.field_indices)): #Add Attrs for begin attrs.append( vertices[i][j + 2]) # +2 ignore order and point attrs.append(vertices[i + 1][0]) #Add Order end for j in range(0, len( self.field_indices)): #Add Attrs for end attrs.append( vertices[i + 1][j + 2]) # +2 ignore order and point attrs.append(1) #Count = 1 f.setAttributes(attrs) line = [vertices[i][1], vertices[i + 1][1]] geom = QgsGeometry() f.setGeometry(QgsGeometry(geom.fromPolylineXY(line))) edge_ids[edge_id] = f self.updatePoints(start_id, end_points, vertices[i], 'start') self.updatePoints(end_id, end_points, vertices[i + 1], 'end') current += 1 feedback.setProgress(int(current * total)) for id in edge_ids: if feedback.isCanceled(): return {} self.sink.addFeature(edge_ids[id], QgsFeatureSink.FastInsert) for id in end_points: if feedback.isCanceled(): return {} self.sink_point.addFeature(end_points[id], QgsFeatureSink.FastInsert) return {self.OUTPUT_LINE: self.dest_id}
def outputWkbType(self, inputWkb): return QgsWkbTypes.addZ(inputWkb)
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) if source is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT)) group_field_name = self.parameterAsString(parameters, self.GROUP_FIELD, context) order_field_name = self.parameterAsString(parameters, self.ORDER_FIELD, context) date_format = self.parameterAsString(parameters, self.DATE_FORMAT, context) text_dir = self.parameterAsString(parameters, self.OUTPUT_TEXT_DIR, context) group_field_index = source.fields().lookupField(group_field_name) order_field_index = source.fields().lookupField(order_field_name) if group_field_index >= 0: group_field_def = source.fields().at(group_field_index) else: group_field_def = None order_field_def = source.fields().at(order_field_index) fields = QgsFields() if group_field_def is not None: fields.append(group_field_def) begin_field = QgsField(order_field_def) begin_field.setName('begin') fields.append(begin_field) end_field = QgsField(order_field_def) end_field.setName('end') fields.append(end_field) output_wkb = QgsWkbTypes.LineString if QgsWkbTypes.hasM(source.wkbType()): output_wkb = QgsWkbTypes.addM(output_wkb) if QgsWkbTypes.hasZ(source.wkbType()): output_wkb = QgsWkbTypes.addZ(output_wkb) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, output_wkb, source.sourceCrs()) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) points = dict() features = source.getFeatures( QgsFeatureRequest().setSubsetOfAttributes( [group_field_index, order_field_index]), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks) total = 100.0 / source.featureCount() if source.featureCount() else 0 for current, f in enumerate(features): if feedback.isCanceled(): break if not f.hasGeometry(): continue point = f.geometry().constGet().clone() if group_field_index >= 0: group = f[group_field_index] else: group = 1 order = f[order_field_index] if date_format != '': order = datetime.strptime(str(order), date_format) if group in points: points[group].append((order, point)) else: points[group] = [(order, point)] feedback.setProgress(int(current * total)) feedback.setProgress(0) da = QgsDistanceArea() da.setSourceCrs(source.sourceCrs(), context.transformContext()) da.setEllipsoid(context.project().ellipsoid()) current = 0 total = 100.0 / len(points) if points else 1 for group, vertices in points.items(): if feedback.isCanceled(): break vertices.sort(key=lambda x: (x[0] is None, x[0])) f = QgsFeature() attributes = [] if group_field_index >= 0: attributes.append(group) attributes.extend([vertices[0][0], vertices[-1][0]]) f.setAttributes(attributes) line = [node[1] for node in vertices] if text_dir: fileName = os.path.join(text_dir, '%s.txt' % group) with open(fileName, 'w') as fl: fl.write('angle=Azimuth\n') fl.write('heading=Coordinate_System\n') fl.write('dist_units=Default\n') for i in range(len(line)): if i == 0: fl.write('startAt=%f;%f;90\n' % (line[i].x(), line[i].y())) fl.write('survey=Polygonal\n') fl.write('[data]\n') else: angle = line[i - 1].azimuth(line[i]) distance = da.measureLine(QgsPointXY(line[i - 1]), QgsPointXY(line[i])) fl.write('%f;%f;90\n' % (angle, distance)) f.setGeometry(QgsGeometry(QgsLineString(line))) sink.addFeature(f, QgsFeatureSink.FastInsert) current += 1 feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) fields = source.fields() x_field_index = fields.lookupField( self.parameterAsString(parameters, self.XFIELD, context)) y_field_index = fields.lookupField( self.parameterAsString(parameters, self.YFIELD, context)) z_field_index = -1 if self.parameterAsString(parameters, self.ZFIELD, context): z_field_index = fields.lookupField( self.parameterAsString(parameters, self.ZFIELD, context)) m_field_index = -1 if self.parameterAsString(parameters, self.MFIELD, context): m_field_index = fields.lookupField( self.parameterAsString(parameters, self.MFIELD, context)) wkb_type = QgsWkbTypes.Point if z_field_index >= 0: wkb_type = QgsWkbTypes.addZ(wkb_type) if m_field_index >= 0: wkb_type = QgsWkbTypes.addM(wkb_type) target_crs = self.parameterAsCrs(parameters, self.TARGET_CRS, context) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, wkb_type, target_crs) request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry) features = source.getFeatures() total = 100.0 / source.featureCount() if source.featureCount() else 0 for current, feature in enumerate(features): if feedback.isCanceled(): break feedback.setProgress(int(current * total)) attrs = feature.attributes() try: x = float(attrs[x_field_index]) y = float(attrs[y_field_index]) point = QgsPoint(x, y) if z_field_index >= 0: try: point.addZValue(float(attrs[z_field_index])) except: point.addZValue(0.0) if m_field_index >= 0: try: point.addMValue(float(attrs[m_field_index])) except: point.addMValue(0.0) feature.setGeometry(QgsGeometry(point)) except: pass # no geometry sink.addFeature(feature) return {self.OUTPUT: dest_id}
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) fields = source.fields() fields.append(QgsField('node_pos', QVariant.Int)) fields.append(QgsField('node_index', QVariant.Int)) fields.append(QgsField('node_part', QVariant.Int)) if QgsWkbTypes.geometryType(source.wkbType()) == QgsWkbTypes.PolygonGeometry: fields.append(QgsField('node_part_ring', QVariant.Int)) fields.append(QgsField('node_part_index', QVariant.Int)) fields.append(QgsField('distance', QVariant.Double)) fields.append(QgsField('angle', QVariant.Double)) wkb_type = QgsWkbTypes.Point if QgsWkbTypes.hasM(source.wkbType()): wkb_type = QgsWkbTypes.addM(wkb_type) if QgsWkbTypes.hasZ(source.wkbType()): wkb_type = QgsWkbTypes.addZ(wkb_type) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, wkb_type, source.sourceCrs()) node_indices_string = self.parameterAsString(parameters, self.NODES, context) indices = [] for node in node_indices_string.split(','): try: indices.append(int(node)) except: raise QgsProcessingException( self.tr('\'{}\' is not a valid node index').format(node)) features = source.getFeatures() total = 100.0 / source.featureCount() if source.featureCount() else 0 for current, f in enumerate(features): if feedback.isCanceled(): break input_geometry = f.geometry() if not input_geometry: sink.addFeature(f, QgsFeatureSink.FastInsert) else: total_nodes = input_geometry.constGet().nCoordinates() for node in indices: if node < 0: node_index = total_nodes + node else: node_index = node if node_index < 0 or node_index >= total_nodes: continue (success, vertex_id) = input_geometry.vertexIdFromVertexNr(node_index) distance = input_geometry.distanceToVertex(node_index) angle = math.degrees(input_geometry.angleAtVertex(node_index)) output_feature = QgsFeature() attrs = f.attributes() attrs.append(node) attrs.append(node_index) attrs.append(vertex_id.part) if QgsWkbTypes.geometryType(source.wkbType()) == QgsWkbTypes.PolygonGeometry: attrs.append(vertex_id.ring) attrs.append(vertex_id.vertex) attrs.append(distance) attrs.append(angle) output_feature.setAttributes(attrs) point = input_geometry.vertexAt(node_index) output_feature.setGeometry(QgsGeometry(point)) sink.addFeature(output_feature, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) if source is None: raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT)) group_field_name = self.parameterAsString(parameters, self.GROUP_FIELD, context) order_field_name = self.parameterAsString(parameters, self.ORDER_FIELD, context) date_format = self.parameterAsString(parameters, self.DATE_FORMAT, context) text_dir = self.parameterAsString(parameters, self.OUTPUT_TEXT_DIR, context) group_field_index = source.fields().lookupField(group_field_name) order_field_index = source.fields().lookupField(order_field_name) if group_field_index >= 0: group_field_def = source.fields().at(group_field_index) else: group_field_def = None order_field_def = source.fields().at(order_field_index) fields = QgsFields() if group_field_def is not None: fields.append(group_field_def) begin_field = QgsField(order_field_def) begin_field.setName('begin') fields.append(begin_field) end_field = QgsField(order_field_def) end_field.setName('end') fields.append(end_field) output_wkb = QgsWkbTypes.LineString if QgsWkbTypes.hasM(source.wkbType()): output_wkb = QgsWkbTypes.addM(output_wkb) if QgsWkbTypes.hasZ(source.wkbType()): output_wkb = QgsWkbTypes.addZ(output_wkb) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, output_wkb, source.sourceCrs()) if sink is None: raise QgsProcessingException(self.invalidSinkError(parameters, self.OUTPUT)) points = dict() features = source.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([group_field_index, order_field_index]), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks) total = 100.0 / source.featureCount() if source.featureCount() else 0 for current, f in enumerate(features): if feedback.isCanceled(): break if not f.hasGeometry(): continue point = f.geometry().constGet().clone() if group_field_index >= 0: group = f.attributes()[group_field_index] else: group = 1 order = f.attributes()[order_field_index] if date_format != '': order = datetime.strptime(str(order), date_format) if group in points: points[group].append((order, point)) else: points[group] = [(order, point)] feedback.setProgress(int(current * total)) feedback.setProgress(0) da = QgsDistanceArea() da.setSourceCrs(source.sourceCrs(), context.transformContext()) da.setEllipsoid(context.project().ellipsoid()) current = 0 total = 100.0 / len(points) if points else 1 for group, vertices in list(points.items()): if feedback.isCanceled(): break vertices.sort(key=lambda x: (x[0] is None, x[0])) f = QgsFeature() attributes = [] if group_field_index >= 0: attributes.append(group) attributes.extend([vertices[0][0], vertices[-1][0]]) f.setAttributes(attributes) line = [node[1] for node in vertices] if text_dir: fileName = os.path.join(text_dir, '%s.txt' % group) with open(fileName, 'w') as fl: fl.write('angle=Azimuth\n') fl.write('heading=Coordinate_System\n') fl.write('dist_units=Default\n') for i in range(len(line)): if i == 0: fl.write('startAt=%f;%f;90\n' % (line[i].x(), line[i].y())) fl.write('survey=Polygonal\n') fl.write('[data]\n') else: angle = line[i - 1].azimuth(line[i]) distance = da.measureLine(QgsPointXY(line[i - 1]), QgsPointXY(line[i])) fl.write('%f;%f;90\n' % (angle, distance)) f.setGeometry(QgsGeometry(QgsLineString(line))) sink.addFeature(f, QgsFeatureSink.FastInsert) current += 1 feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) fields = source.fields() fields.append(QgsField('node_pos', QVariant.Int)) fields.append(QgsField('node_index', QVariant.Int)) fields.append(QgsField('distance', QVariant.Double)) fields.append(QgsField('angle', QVariant.Double)) fields.append(QgsField('NUM_FIELD', QVariant.Int)) wkb_type = QgsWkbTypes.Point if QgsWkbTypes.hasM(source.wkbType()): wkb_type = QgsWkbTypes.addM(wkb_type) if QgsWkbTypes.hasZ(source.wkbType()): wkb_type = QgsWkbTypes.addZ(wkb_type) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, wkb_type, source.sourceCrs()) node_indices_string = self.parameterAsString(parameters, self.NODES, context) indices = [] for node in node_indices_string.split(','): try: indices.append(int(node)) except: raise QgsProcessingException( self.tr('\'{}\' is not a valid node index').format(node)) features = source.getFeatures() total = 100.0 / source.featureCount() if source.featureCount() else 0 for current, f in enumerate(features): if feedback.isCanceled(): break input_geometry = f.geometry() if not input_geometry: sink.addFeature(f, QgsFeatureSink.FastInsert) else: total_nodes = input_geometry.geometry().nCoordinates() for node in indices: if node < 0: node_index = total_nodes + node else: node_index = node if node_index < 0 or node_index >= total_nodes: continue distance = input_geometry.distanceToVertex(node_index) angle = math.degrees(input_geometry.angleAtVertex(node_index)) output_feature = QgsFeature() attrs = f.attributes() attrs.append(node) attrs.append(node_index) attrs.append(distance) attrs.append(angle) output_feature.setAttributes(attrs) point = input_geometry.vertexAt(node_index) output_feature.setGeometry(QgsGeometry(point)) sink.addFeature(output_feature, QgsFeatureSink.FastInsert) feedback.setProgress(int(current * total)) return {self.OUTPUT: dest_id}
def prepareAlgorithm(self, parameters, context, feedback): self.geometry_type = self.parameterAsEnum(parameters, self.OUTPUT_GEOMETRY, context) self.wkb_type = None if self.geometry_type == 0: self.wkb_type = QgsWkbTypes.Polygon elif self.geometry_type == 1: self.wkb_type = QgsWkbTypes.LineString else: self.wkb_type = QgsWkbTypes.Point if self.parameterAsBool(parameters, self.WITH_Z, context): self.wkb_type = QgsWkbTypes.addZ(self.wkb_type) if self.parameterAsBool(parameters, self.WITH_M, context): self.wkb_type = QgsWkbTypes.addM(self.wkb_type) self.expression = QgsExpression(self.parameterAsString(parameters, self.EXPRESSION, context)) if self.expression.hasParserError(): feedback.reportError(self.expression.parserErrorString()) return False self.expression_context = self.createExpressionContext(parameters, context) if not self.expression.prepare(self.expression_context): feedback.reportErro( self.tr('Evaluation error: {0}').format(self.expression.evalErrorString())) return False return True