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) 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)) 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, 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 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 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 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 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 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, 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 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, feedback): ''' Here is where the processing itself takes place. ''' # if not is_dependencies_satisfied: return {} # Init # The number of features in the input layer could be trimmed to user selection. the_layer = self.parameterAsSource(parameters, self.THE_LAYER, context) gok = QgsWkbTypes.geometryType( the_layer.wkbType()) == QgsWkbTypes.PointGeometry if the_layer is None or not gok: raise QgsProcessingException( self.invalidSourceError(parameters, self.THE_LAYER)) # bCHscal = self.parameterAsBool(parameters, self.BSCALE, context) if bCHscal: # Use another channel for scaling. All data from that channel will be used. scally = self.parameterAsSource(parameters, self.SCALLY, context) if scally is None or the_layer.wkbType() != QgsWkbTypes.Point: raise QgsProcessingException( self.invalidSourceError(parameters, self.SCALLY)) fidu_fld = self.parameterAsString(parameters, self.FID_FLD, context) data_fld = self.parameterAsString(parameters, self.DATA_FLD, context) line_fld = self.parameterAsString(parameters, self.LINE_FLD, context) invP = self.parameterAsBool(parameters, self.INVERTP, context) dumval = self.parameterAsDouble(parameters, self.DUMVAL, context) scale = self.parameterAsDouble(parameters, self.SCALE, context) offset = self.parameterAsDouble(parameters, self.OFFSET, context) join_to_line = self.parameterAsBool(parameters, self.JOINL, context) data = the_layer.fields().at(the_layer.fields().lookupField(data_fld)) fidu = the_layer.fields().at(the_layer.fields().lookupField(fidu_fld)) if not data.isNumeric() or not fidu.isNumeric(): raise QgsProcessingException( self.invalidSourceError(parameters, self.THE_LAYER)) line = the_layer.fields().at(the_layer.fields().lookupField(line_fld)) data_ix = the_layer.fields().lookupField(data_fld) line_ix = the_layer.fields().lookupField(line_fld) fidu_ix = the_layer.fields().lookupField(fidu_fld) # Set output vector layer: point(X, Y, M) M is data value at that point output_wkb = QgsWkbTypes.LineString output_wkb = QgsWkbTypes.addM(output_wkb) # Fields of stacked profiles vector line_def = the_layer.fields().at(line_ix) fields = QgsFields() if line_def is not None: fields = QgsFields() fields.append(QgsField('Line', QVariant.String, '', 16)) fields.append(QgsField('Type', QVariant.String, '', 2)) fields.append(QgsField('NbPts', QVariant.Int, '', 10, 0)) fields.append(QgsField('Azimuth', QVariant.Double, '', 10, 6)) fields.append(QgsField('DistEP', QVariant.Double, '', 10, 2)) fields.append(QgsField('Length', QVariant.Double, '', 10, 2)) (sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context, fields, output_wkb, the_layer.sourceCrs()) if sink is None: raise QgsProcessingException( self.invalidSinkError(parameters, self.OUTPUT)) # Get the features and fields of interest features = the_layer.getFeatures( QgsFeatureRequest().setSubsetOfAttributes( [fidu_ix, line_ix, data_ix]), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks) # CSV # Find min/max of data values for all lines and save each line in a csv file # Then process each line separately: can have any number of lines... lines = [] xyzf = [] lineN = '' nL = 0 TL = 0. total = 60.0 / the_layer.featureCount() if the_layer.featureCount( ) else 0 stat = QgsStatisticalSummary() for current, ft in enumerate(features): if feedback.isCanceled(): break feedback.setProgress(int(current * total)) if not ft.hasGeometry(): continue # if ft[line.name()] != lineN: if xyzf != []: lines.append([lineN, nL]) the_csv = os.path.join(self.tmpDir, '%s.csv' % str(lineN)) with codecs.open(the_csv, 'w', 'utf-8') as fo: fo.write('X,Y,FID,Data\n') for ar in xyzf: fo.write(','.join(map(str, ar))) fo.write('\n') le = sqrt((xyzf[0][0] - xyzf[-1][0])**2 + (xyzf[0][1] - xyzf[-1][1])**2) if le > TL: TL = le xyzf = [] nL = 0 lineN = ft[line.name()] # rdata = float(ft[data.name()]) fiduu = int(ft[fidu.name()]) if abs(rdata - dumval) < 1e-6: # Dummy value: skip continue # stat.addVariant(ft[data.name()]) # how to handle QgsMultiPoint ??? if (the_layer.wkbType() == QgsWkbTypes.MultiPoint or the_layer.wkbType() == QgsWkbTypes.MultiPointM or the_layer.wkbType() == QgsWkbTypes.MultiPointZ or the_layer.wkbType() == QgsWkbTypes.MultiPointZM or the_layer.wkbType() == QgsWkbTypes.MultiPoint25D): # Suppose they all have the same attributes: # in this case it seems useless to get more than the first point, but... points = ft.geometry().constGet().clone() else: points = [ft.geometry().constGet().clone()] try: for point in points: xyzf.append([point.x(), point.y(), fiduu, rdata]) nL += 1 except: pass # last line if xyzf != []: lines.append([lineN, nL]) the_csv = os.path.join(self.tmpDir, '%s.csv' % str(lineN)) with codecs.open(the_csv, 'w', 'utf-8') as fo: fo.write('X,Y,FID,Data\n') for ar in xyzf: fo.write(','.join(map(str, ar))) fo.write('\n') le = sqrt((xyzf[0][0] - xyzf[-1][0])**2 + (xyzf[0][1] - xyzf[-1][1])**2) if le > TL: TL = le # stat.finalize() self.dmean = stat.mean() self.mult = TL / (stat.max() - stat.min()) # if bCHscal: # Scaling field: retrieve its stats scch_fld = self.parameterAsString(parameters, self.SCALCH, context) scch = scally.fields().at(scally.fields().lookupField(scch_fld)) scch_ix = scally.fields().lookupField(scch_fld) scch_f = scally.getFeatures( QgsFeatureRequest().setSubsetOfAttributes([scch_ix]), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks) stat = QgsStatisticalSummary() for current, ft in enumerate(scch_f): stat.addVariant(ft[scch.name()]) stat.finalize() self.dmean = stat.mean() self.mult = TL / (stat.max() - stat.min()) # if invP: iv = -1 else: iv = 1 # Profile total = 40.0 / (len(lines) + 1) # For each line: for current, z in enumerate(lines): line = z[0] if feedback.isCanceled(): break if not ft.hasGeometry(): continue feedback.setProgress(int(current * total) + 60.) # Read line back from csv the_csv = os.path.join(self.tmpDir, '%s.csv' % str(line)) if not os.path.exists(the_csv): raise ValueError( 'It seems parameters are swaped: LINE <-> DATA!') ar = pd.read_csv(the_csv) ar = ar.sort_values('FID') # Create the profile px, py = self._do_profile(ar, iv, scale, offset) #Construct vector layer f = QgsFeature() typeL = str(self.type) azimut = float(self.azimut) Len = float(self.length) CLen = float(self.clength) f.setAttributes( [str(line), typeL, int(len(px)), azimut, Len, CLen]) line_pts = [ QgsPoint(x, y, m=m) for x, y, m in zip(px, py, ar.Data) ] if join_to_line: # Join profile to its line e = len(ar) - 1 ar0 = [QgsPoint(ar.X[0], ar.Y[0], m=0.)] ar1 = [QgsPoint(ar.X[e], ar.Y[e], m=0.)] line_pts = ar0 + line_pts + ar1 # f.setGeometry(QgsGeometry(QgsLineString(line_pts))) sink.addFeature(f, QgsFeatureSink.FastInsert) # Delete temp csv file try: os.remove(the_csv) except: pass 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 outputWkbType(self, inputWkb): return QgsWkbTypes.addM(inputWkb)
def processAlgorithm(self, parameters, context, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) 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()) 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() 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, feedback): source = self.parameterAsSource(parameters, self.INPUT, context) 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()) 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) 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, feedback): 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): 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 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