def processAlgorithm(self, parameters, context, feedback): filename = self.getParameterValue(self.INPUT) layer = QgsProcessingUtils.mapLayerFromString(filename, context) filename = self.getParameterValue(self.INTERSECT) selectLayer = QgsProcessingUtils.mapLayerFromString(filename, context) predicates = self.getParameterValue(self.PREDICATE) precision = self.getParameterValue(self.PRECISION) index = QgsProcessingUtils.createSpatialIndex(layer, context) output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context) if 'disjoint' in predicates: disjoinSet = [] for feat in QgsProcessingUtils.getFeatures(layer, context): disjoinSet.append(feat.id()) selectedSet = [] features = QgsProcessingUtils.getFeatures(selectLayer, context) total = 100.0 / QgsProcessingUtils.featureCount(selectLayer, context) for current, f in enumerate(features): geom = vector.snapToPrecision(f.geometry(), precision) bbox = geom.boundingBox() bbox.grow(0.51 * precision) intersects = index.intersects(bbox) request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([]) for feat in layer.getFeatures(request): tmpGeom = vector.snapToPrecision(feat.geometry(), precision) res = False for predicate in predicates: if predicate == 'disjoint': if tmpGeom.intersects(geom): try: disjoinSet.remove(feat.id()) except: pass # already removed else: res = getattr(tmpGeom, predicate)(geom) if res: selectedSet.append(feat.id()) break feedback.setProgress(int(current * total)) if 'disjoint' in predicates: selectedSet = selectedSet + disjoinSet features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): if f.id() in selectedSet: writer.addFeature(f) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): filename = self.getParameterValue(self.INPUT) layer = QgsProcessingUtils.mapLayerFromString(filename, context) field = self.getParameterValue(self.FIELD) method = self.getParameterValue(self.METHOD) index = layer.fields().lookupField(field) features = QgsProcessingUtils.getFeatures(layer, context) featureCount = QgsProcessingUtils.featureCount(layer, context) unique = QgsProcessingUtils.uniqueValues(layer, index, context) value = int(self.getParameterValue(self.NUMBER)) if method == 0: if value > featureCount: raise GeoAlgorithmExecutionException( self.tr('Selected number is greater that feature count. ' 'Choose lesser value and try again.')) else: if value > 100: raise GeoAlgorithmExecutionException( self.tr("Percentage can't be greater than 100. Set " "correct value and try again.")) value = value / 100.0 writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context) selran = [] total = 100.0 / (featureCount * len(unique)) features = QgsProcessingUtils.getFeatures(layer, context) classes = defaultdict(list) for i, feature in enumerate(features): attrs = feature.attributes() classes[attrs[index]].append(feature) feedback.setProgress(int(i * total)) for subset in classes.values(): selValue = value if method != 1 else int(round(value * len(subset), 0)) selran.extend(random.sample(subset, selValue)) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for (i, feat) in enumerate(selran): writer.addFeature(feat) feedback.setProgress(int(i * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) crsId = self.getParameterValue(self.TARGET_CRS) targetCrs = QgsCoordinateReferenceSystem() targetCrs.createFromUserInput(crsId) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(), targetCrs, context) layerCrs = layer.crs() crsTransform = QgsCoordinateTransform(layerCrs, targetCrs) outFeat = QgsFeature() features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): geom = f.geometry() geom.transform(crsTransform) outFeat.setGeometry(geom) outFeat.setAttributes(f.attributes()) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer self.crs = targetCrs
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_VECTOR), context) rasterPath = str(self.getParameterValue(self.INPUT_RASTER)) rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly) geoTransform = rasterDS.GetGeoTransform() rasterDS = None fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) fields.append(QgsField('line_id', QVariant.Int, '', 10, 0)) fields.append(QgsField('point_id', QVariant.Int, '', 10, 0)) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(fields, QgsWkbTypes.Point, layer.crs(), context) outFeature = QgsFeature() outFeature.setFields(fields) self.fid = 0 self.lineId = 0 self.pointId = 0 features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): geom = f.geometry() if geom.isMultipart(): lines = geom.asMultiPolyline() for line in lines: for i in range(len(line) - 1): p1 = line[i] p2 = line[i + 1] (x1, y1) = raster.mapToPixel(p1.x(), p1.y(), geoTransform) (x2, y2) = raster.mapToPixel(p2.x(), p2.y(), geoTransform) self.buildLine(x1, y1, x2, y2, geoTransform, writer, outFeature) else: points = geom.asPolyline() for i in range(len(points) - 1): p1 = points[i] p2 = points[i + 1] (x1, y1) = raster.mapToPixel(p1.x(), p1.y(), geoTransform) (x2, y2) = raster.mapToPixel(p2.x(), p2.y(), geoTransform) self.buildLine(x1, y1, x2, y2, geoTransform, writer, outFeature) self.pointId = 0 self.lineId += 1 feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter(layer.fields(), QgsWkbTypes.Polygon, layer.crs(), context) distance = self.getParameterValue(self.DISTANCE) segments = int(self.getParameterValue(self.SEGMENTS)) join_style = self.getParameterValue(self.JOIN_STYLE) + 1 if self.getParameterValue(self.SIDE) == 0: side = QgsGeometry.SideLeft else: side = QgsGeometry.SideRight miter_limit = self.getParameterValue(self.MITRE_LIMIT) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, input_feature in enumerate(features): output_feature = input_feature input_geometry = input_feature.geometry() if input_geometry: output_geometry = input_geometry.singleSidedBuffer(distance, segments, side, join_style, miter_limit) if not output_geometry: raise GeoAlgorithmExecutionException( self.tr('Error calculating single sided buffer')) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) fields = layer.fields() writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, layer.wkbType(), layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) geoms = dict() for current, f in enumerate(features): geoms[f.id()] = f.geometry() feedback.setProgress(int(current * total)) cleaned = dict(geoms) for i, g in list(geoms.items()): for j in list(cleaned.keys()): if i == j or i not in cleaned: continue if g.isGeosEqual(cleaned[j]): del cleaned[j] total = 100.0 / len(cleaned) request = QgsFeatureRequest().setFilterFids(list(cleaned.keys())) for current, f in enumerate(layer.getFeatures(request)): writer.addFeature(f) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) valuesFieldName = self.getParameterValue(self.VALUES_FIELD_NAME) categoriesFieldName = self.getParameterValue(self.CATEGORIES_FIELD_NAME) output = self.getOutputFromName(self.OUTPUT) valuesField = layer.fields().lookupField(valuesFieldName) categoriesField = layer.fields().lookupField(categoriesFieldName) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) values = {} for current, feat in enumerate(features): feedback.setProgress(int(current * total)) attrs = feat.attributes() try: value = float(attrs[valuesField]) cat = str(attrs[categoriesField]) if cat not in values: values[cat] = [] values[cat].append(value) except: pass fields = ['category', 'min', 'max', 'mean', 'stddev', 'sum', 'count'] writer = output.getTableWriter(fields) stat = QgsStatisticalSummary(QgsStatisticalSummary.Min | QgsStatisticalSummary.Max | QgsStatisticalSummary.Mean | QgsStatisticalSummary.StDevSample | QgsStatisticalSummary.Sum | QgsStatisticalSummary.Count) for (cat, v) in list(values.items()): stat.calculate(v) record = [cat, stat.min(), stat.max(), stat.mean(), stat.sampleStDev(), stat.sum(), stat.count()] writer.addRecord(record)
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) max_iterations = self.getParameterValue(self.MAX_ITERATIONS) angle_tolerance = self.getParameterValue(self.ANGLE_TOLERANCE) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, input_feature in enumerate(features): output_feature = input_feature input_geometry = input_feature.geometry() if input_geometry: output_geometry = input_geometry.orthogonalize(1.0e-8, max_iterations, angle_tolerance) if not output_geometry: raise GeoAlgorithmExecutionException( self.tr('Error orthogonalizing geometry')) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter(layer.fields(), QgsWkbTypes.Point, layer.crs(), context) outFeat = QgsFeature() features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, feat in enumerate(features): inGeom = feat.geometry() attrs = feat.attributes() if inGeom.isNull(): outGeom = QgsGeometry(None) else: outGeom = QgsGeometry(inGeom.centroid()) if not outGeom: raise GeoAlgorithmExecutionException( self.tr('Error calculating centroid')) outFeat.setGeometry(outGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context) start_distance = self.getParameterValue(self.START_DISTANCE) end_distance = self.getParameterValue(self.END_DISTANCE) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, input_feature in enumerate(features): output_feature = input_feature input_geometry = input_feature.geometry() if input_geometry: output_geometry = input_geometry.extendLine(start_distance, end_distance) if not output_geometry: raise GeoAlgorithmExecutionException( self.tr('Error calculating extended line')) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), QgsWkbTypes.Polygon, layer.crs(), context) outFeat = QgsFeature() features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): outGeomList = [] if f.geometry().isMultipart(): outGeomList = f.geometry().asMultiPolyline() else: outGeomList.append(f.geometry().asPolyline()) polyGeom = self.removeBadLines(outGeomList) if len(polyGeom) != 0: outFeat.setGeometry(QgsGeometry.fromPolygon(polyGeom)) attrs = f.attributes() outFeat.setAttributes(attrs) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, inFeat in enumerate(features): outFeat = QgsFeature() attrs = inFeat.attributes() outFeat.setAttributes(attrs) inGeom = inFeat.geometry() if inGeom: outGeom = inGeom.mergeLines() if outGeom is None: raise GeoAlgorithmExecutionException( self.tr('Error merging lines')) outFeat.setGeometry(outGeom) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) fields = layer.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)) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter(fields, QgsWkbTypes.Point, layer.crs(), context) node_indices_string = self.getParameterValue(self.NODES) indices = [] for node in node_indices_string.split(','): try: indices.append(int(node)) except: raise GeoAlgorithmExecutionException( self.tr('\'{}\' is not a valid node index').format(node)) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): input_geometry = f.geometry() if not input_geometry: writer.addFeature(f) 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.fromPoint(point)) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) fields = layer.fields() fields.append(QgsField('node_index', QVariant.Int)) fields.append(QgsField('distance', QVariant.Double)) fields.append(QgsField('angle', QVariant.Double)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Point, layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): input_geometry = f.geometry() if not input_geometry: writer.addFeature(f) else: points = vector.extractPoints(input_geometry) for i, point in enumerate(points): 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.fromPoint(point)) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) fieldName = self.getParameterValue(self.FIELD) idx = layer.fields().lookupField(fieldName) fields = layer.fields() fields[idx] = QgsField(fieldName, QVariant.Double, '', 24, 15) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, layer.wkbType(), layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): value = f[idx] try: if '%' in value: f[idx] = float(value.replace('%', '')) / 100.0 else: f[idx] = float(value) except: f[idx] = None writer.addFeature(f) feedback.setProgress(int(current * total)) del writer
def layerOmmb(self, layer, context, writer, feedback): req = QgsFeatureRequest().setSubsetOfAttributes([]) features = QgsProcessingUtils.getFeatures(layer, context, req) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) newgeometry = QgsGeometry() first = True for current, inFeat in enumerate(features): if first: newgeometry = inFeat.geometry() first = False else: newgeometry = newgeometry.combine(inFeat.geometry()) feedback.setProgress(int(current * total)) geometry, area, angle, width, height = newgeometry.orientedMinimumBoundingBox() if geometry: outFeat = QgsFeature() outFeat.setGeometry(geometry) outFeat.setAttributes([area, width * 2 + height * 2, angle, width, height]) writer.addFeature(outFeat)
def processAlgorithm(self, parameters, context, feedback): filename = self.getParameterValue(self.INPUT) layer = QgsProcessingUtils.mapLayerFromString(filename, context) method = self.getParameterValue(self.METHOD) features = QgsProcessingUtils.getFeatures(layer, context) featureCount = QgsProcessingUtils.featureCount(layer, context) value = int(self.getParameterValue(self.NUMBER)) if method == 0: if value > featureCount: raise GeoAlgorithmExecutionException( self.tr('Selected number is greater than feature count. ' 'Choose a lower value and try again.')) else: if value > 100: raise GeoAlgorithmExecutionException( self.tr("Percentage can't be greater than 100. Set a " "different value and try again.")) value = int(round(value / 100.0000, 4) * featureCount) selran = random.sample(list(range(featureCount)), value) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context) total = 100.0 / featureCount for i, feat in enumerate(features): if i in selran: writer.addFeature(feat) feedback.setProgress(int(i * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layerA = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(Difference.INPUT), context) layerB = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(Difference.OVERLAY), context) geomType = QgsWkbTypes.multiType(layerA.wkbType()) writer = self.getOutputFromName( Difference.OUTPUT).getVectorWriter(layerA.fields(), geomType, layerA.crs(), context) outFeat = QgsFeature() index = QgsProcessingUtils.createSpatialIndex(layerB, context) selectionA = QgsProcessingUtils.getFeatures(layerA, context) total = 100.0 / QgsProcessingUtils.featureCount(layerA, context) for current, inFeatA in enumerate(selectionA): geom = inFeatA.geometry() diff_geom = QgsGeometry(geom) attrs = inFeatA.attributes() intersections = index.intersects(geom.boundingBox()) request = QgsFeatureRequest().setFilterFids(intersections).setSubsetOfAttributes([]) for inFeatB in layerB.getFeatures(request): tmpGeom = inFeatB.geometry() if diff_geom.intersects(tmpGeom): diff_geom = QgsGeometry(diff_geom.difference(tmpGeom)) try: outFeat.setGeometry(diff_geom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: QgsMessageLog.logMessage(self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.'), self.tr('Processing'), QgsMessageLog.WARNING) continue feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context) delta_x = self.getParameterValue(self.DELTA_X) delta_y = self.getParameterValue(self.DELTA_Y) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, input_feature in enumerate(features): output_feature = input_feature input_geometry = input_feature.geometry() if input_geometry: output_geometry = input_geometry output_geometry.translate(delta_x, delta_y) if not output_geometry: raise GeoAlgorithmExecutionException( self.tr('Error translating geometry')) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) min_area = self.getParameterValue(self.MIN_AREA) if min_area is not None: try: min_area = float(min_area) except: pass if min_area == 0.0: min_area = -1.0 writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): if f.hasGeometry(): if min_area is not None: f.setGeometry(f.geometry().removeInteriorRings(min_area)) else: f.setGeometry(f.geometry().removeInteriorRings()) writer.addFeature(f) feedback.setProgress(int(current * total)) del writer
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 / QgsProcessingUtils.featureCount(layer, context) 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): inLayer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) inField = self.getParameterValue(self.INPUT_FIELD) targetLayer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.TARGET_LAYER), context) targetField = self.getParameterValue(self.TARGET_FIELD) matType = self.getParameterValue(self.MATRIX_TYPE) nPoints = self.getParameterValue(self.NEAREST_POINTS) outputFile = self.getOutputFromName(self.DISTANCE_MATRIX) if nPoints < 1: nPoints = QgsProcessingUtils.featureCount(targetLayer, context) self.writer = outputFile.getTableWriter([]) if matType == 0: # Linear distance matrix self.linearMatrix(context, inLayer, inField, targetLayer, targetField, matType, nPoints, feedback) elif matType == 1: # Standard distance matrix self.regularMatrix(context, inLayer, inField, targetLayer, targetField, nPoints, feedback) elif matType == 2: # Summary distance matrix self.linearMatrix(context, inLayer, inField, targetLayer, targetField, matType, nPoints, feedback)
def regularMatrix(self, context, inLayer, inField, targetLayer, targetField, nPoints, feedback): index = QgsProcessingUtils.createSpatialIndex(targetLayer, context) inIdx = inLayer.fields().lookupField(inField) distArea = QgsDistanceArea() first = True features = QgsProcessingUtils.getFeatures(inLayer, context) total = 100.0 / QgsProcessingUtils.featureCount(inLayer, context) for current, inFeat in enumerate(features): inGeom = inFeat.geometry() inID = str(inFeat.attributes()[inIdx]) featList = index.nearestNeighbor(inGeom.asPoint(), nPoints) if first: first = False data = ['ID'] for i in range(len(featList)): data.append('DIST_{0}'.format(i + 1)) self.writer.addRecord(data) data = [inID] for i in featList: request = QgsFeatureRequest().setFilterFid(i) outFeat = next(targetLayer.getFeatures(request)) outGeom = outFeat.geometry() dist = distArea.measureLine(inGeom.asPoint(), outGeom.asPoint()) data.append(str(float(dist))) self.writer.addRecord(data) feedback.setProgress(int(current * total))
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) iterations = self.getParameterValue(self.ITERATIONS) offset = self.getParameterValue(self.OFFSET) max_angle = self.getParameterValue(self.MAX_ANGLE) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, input_feature in enumerate(features): output_feature = input_feature if input_feature.geometry(): output_geometry = input_feature.geometry().smooth(iterations, offset, -1, max_angle) if not output_geometry: raise GeoAlgorithmExecutionException( self.tr('Error smoothing geometry')) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): fieldname = self.getParameterValue(self.FIELD) output = self.getOutputFromName(self.OUTPUT) vlayer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) fieldindex = vlayer.fields().lookupField(fieldname) fields = vlayer.fields() fields.append(QgsField('NUM_FIELD', QVariant.Int)) writer = output.getVectorWriter(fields, vlayer.wkbType(), vlayer.crs(), context) outFeat = QgsFeature() classes = {} features = QgsProcessingUtils.getFeatures(vlayer, context) total = 100.0 / QgsProcessingUtils.featureCount(vlayer, context) for current, feature in enumerate(features): feedback.setProgress(int(current * total)) inGeom = feature.geometry() outFeat.setGeometry(inGeom) atMap = feature.attributes() clazz = atMap[fieldindex] if clazz not in classes: classes[clazz] = len(list(classes.keys())) atMap.append(classes[clazz]) outFeat.setAttributes(atMap) writer.addFeature(outFeat) del writer
def processAlgorithm(self, parameters, context, feedback): layerPoints = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.POINTS), context) layerHubs = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.HUBS), context) fieldName = self.getParameterValue(self.FIELD) units = self.UNITS[self.getParameterValue(self.UNIT)] if layerPoints.source() == layerHubs.source(): raise GeoAlgorithmExecutionException( self.tr('Same layer given for both hubs and spokes')) fields = layerPoints.fields() fields.append(QgsField('HubName', QVariant.String)) fields.append(QgsField('HubDist', QVariant.Double)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Point, layerPoints.crs(), context) index = QgsProcessingUtils.createSpatialIndex(layerHubs, context) distance = QgsDistanceArea() distance.setSourceCrs(layerPoints.crs()) distance.setEllipsoid(QgsProject.instance().ellipsoid()) # Scan source points, find nearest hub, and write to output file features = QgsProcessingUtils.getFeatures(layerPoints, context) total = 100.0 / QgsProcessingUtils.featureCount(layerPoints, context) for current, f in enumerate(features): src = f.geometry().boundingBox().center() neighbors = index.nearestNeighbor(src, 1) ft = next(layerHubs.getFeatures(QgsFeatureRequest().setFilterFid(neighbors[0]).setSubsetOfAttributes([fieldName], layerHubs.fields()))) closest = ft.geometry().boundingBox().center() hubDist = distance.measureLine(src, closest) attributes = f.attributes() attributes.append(ft[fieldName]) if units == 'Feet': attributes.append(hubDist * 3.2808399) elif units == 'Miles': attributes.append(hubDist * 0.000621371192) elif units == 'Kilometers': attributes.append(hubDist / 1000.0) elif units != 'Meters': attributes.append(sqrt( pow(src.x() - closest.x(), 2.0) + pow(src.y() - closest.y(), 2.0))) else: attributes.append(hubDist) feat = QgsFeature() feat.setAttributes(attributes) feat.setGeometry(QgsGeometry.fromPoint(src)) writer.addFeature(feat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): source = self.getParameterValue(self.INPUT) vlayer = QgsProcessingUtils.mapLayerFromString(source, context) 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, context) features = QgsProcessingUtils.getFeatures(vlayer, context) total = 100.0 / QgsProcessingUtils.featureCount(vlayer, context) 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 = QgsPoint(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): filename = self.getParameterValue(self.INPUT) inputLayer = QgsProcessingUtils.mapLayerFromString(filename, context) method = self.getParameterValue(self.METHOD) filename2 = self.getParameterValue(self.INTERSECT) selectLayer = QgsProcessingUtils.mapLayerFromString(filename2, context) predicates = self.getParameterValue(self.PREDICATE) precision = self.getParameterValue(self.PRECISION) oldSelection = set(inputLayer.selectedFeatureIds()) inputLayer.removeSelection() index = QgsProcessingUtils.createSpatialIndex(inputLayer, context) if 'disjoint' in predicates: disjoinSet = [] for feat in QgsProcessingUtils.getFeatures(inputLayer, context): disjoinSet.append(feat.id()) geom = QgsGeometry() selectedSet = [] features = QgsProcessingUtils.getFeatures(selectLayer, context) total = 100.0 / QgsProcessingUtils.featureCount(selectLayer, context) for current, f in enumerate(features): geom = vector.snapToPrecision(f.geometry(), precision) bbox = geom.boundingBox() bbox.grow(0.51 * precision) intersects = index.intersects(bbox) request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([]) for feat in inputLayer.getFeatures(request): tmpGeom = vector.snapToPrecision(feat.geometry(), precision) res = False for predicate in predicates: if predicate == 'disjoint': if tmpGeom.intersects(geom): try: disjoinSet.remove(feat.id()) except: pass # already removed else: res = getattr(tmpGeom, predicate)(geom) if res: selectedSet.append(feat.id()) break feedback.setProgress(int(current * total)) if 'disjoint' in predicates: selectedSet = selectedSet + disjoinSet if method == 1: selectedSet = list(oldSelection.union(selectedSet)) elif method == 2: selectedSet = list(oldSelection.difference(selectedSet)) inputLayer.selectByIds(selectedSet) self.setOutputValue(self.OUTPUT, filename)
def processAlgorithm(self, parameters, context, feedback): polyLayer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.POLYGONS), context) pointLayer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.POINTS), context) fieldName = self.getParameterValue(self.FIELD) fieldIdx = pointLayer.fields().lookupField(self.getParameterValue(self.WEIGHT)) fields = polyLayer.fields() fields.append(QgsField(fieldName, QVariant.Int)) (idxCount, fieldList) = vector.findOrCreateField(polyLayer, polyLayer.fields(), fieldName) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, polyLayer.wkbType(), polyLayer.crs(), context) spatialIndex = QgsProcessingUtils.createSpatialIndex(pointLayer, context) ftPoint = QgsFeature() outFeat = QgsFeature() geom = QgsGeometry() features = QgsProcessingUtils.getFeatures(polyLayer, context) total = 100.0 / QgsProcessingUtils.featureCount(polyLayer, context) for current, ftPoly in enumerate(features): geom = ftPoly.geometry() engine = QgsGeometry.createGeometryEngine(geom.geometry()) engine.prepareGeometry() attrs = ftPoly.attributes() count = 0 points = spatialIndex.intersects(geom.boundingBox()) if len(points) > 0: feedback.setProgressText(str(len(points))) request = QgsFeatureRequest().setFilterFids(points).setSubsetOfAttributes([fieldIdx]) fit = pointLayer.getFeatures(request) ftPoint = QgsFeature() while fit.nextFeature(ftPoint): tmpGeom = QgsGeometry(ftPoint.geometry()) if engine.contains(tmpGeom.geometry()): weight = str(ftPoint.attributes()[fieldIdx]) try: count += float(weight) except: # Ignore fields with non-numeric values pass outFeat.setGeometry(geom) if idxCount == len(attrs): attrs.append(count) else: attrs[idxCount] = count outFeat.setAttributes(attrs) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layers = self.getParameterValue(self.INPUT_DATASOURCES) query = self.getParameterValue(self.INPUT_QUERY) uid_field = self.getParameterValue(self.INPUT_UID_FIELD) geometry_field = self.getParameterValue(self.INPUT_GEOMETRY_FIELD) geometry_type = self.getParameterValue(self.INPUT_GEOMETRY_TYPE) geometry_crs = self.getParameterValue(self.INPUT_GEOMETRY_CRS) df = QgsVirtualLayerDefinition() layerIdx = 1 if layers: for layerSource in layers.split(';'): layer = QgsProcessingUtils.mapLayerFromString(layerSource, context) if layer: df.addSource('input{}'.format(layerIdx), layer.id()) layerIdx += 1 if query == '': raise GeoAlgorithmExecutionException( self.tr('Empty SQL. Please enter valid SQL expression and try again.')) else: df.setQuery(query) if uid_field: df.setUid(uid_field) if geometry_type == 1: # no geometry df.setGeometryWkbType(QgsWkbTypes.NullGeometry) else: if geometry_field: df.setGeometryField(geometry_field) if geometry_type > 1: df.setGeometryWkbType(geometry_type - 1) if geometry_crs: crs = QgsCoordinateReferenceSystem(geometry_crs) if crs.isValid(): df.setGeometrySrid(crs.postgisSrid()) vLayer = QgsVectorLayer(df.toString(), "temp_vlayer", "virtual") if not vLayer.isValid(): raise GeoAlgorithmExecutionException(vLayer.dataProvider().error().message()) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter(vLayer.fields(), vLayer.wkbType() if geometry_type != 1 else 1, vLayer.crs(), context) features = QgsProcessingUtils.getFeatures(vLayer, context) total = 100.0 / QgsProcessingUtils.featureCount(vLayer, context) outFeat = QgsFeature() for current, inFeat in enumerate(features): outFeat.setAttributes(inFeat.attributes()) if geometry_type != 1: outFeat.setGeometry(inFeat.geometry()) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT_LAYER), context) writer = self.getOutputFromName(self.OUTPUT_TABLE).getVectorWriter( layer.fields(), QgsWkbTypes.NoGeometry, QgsCoordinateReferenceSystem(), context) request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry) features = QgsProcessingUtils.getFeatures(layer, context, request) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, input_feature in enumerate(features): writer.addFeature(input_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, context, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, input_feature in enumerate(features): if input_feature.hasGeometry(): writer.addFeature(input_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT_LAYER), context) valuesFieldName = self.getParameterValue(self.VALUES_FIELD_NAME) categoriesFieldName = self.getParameterValue( self.CATEGORIES_FIELD_NAME) output = self.getOutputFromName(self.OUTPUT) valuesField = layer.fields().lookupField(valuesFieldName) categoriesField = layer.fields().lookupField(categoriesFieldName) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) values = {} for current, feat in enumerate(features): feedback.setProgress(int(current * total)) attrs = feat.attributes() try: value = float(attrs[valuesField]) cat = str(attrs[categoriesField]) if cat not in values: values[cat] = [] values[cat].append(value) except: pass fields = ['category', 'min', 'max', 'mean', 'stddev', 'sum', 'count'] writer = output.getTableWriter(fields) stat = QgsStatisticalSummary(QgsStatisticalSummary.Min | QgsStatisticalSummary.Max | QgsStatisticalSummary.Mean | QgsStatisticalSummary.StDevSample | QgsStatisticalSummary.Sum | QgsStatisticalSummary.Count) for (cat, v) in list(values.items()): stat.calculate(v) record = [ cat, stat.min(), stat.max(), stat.mean(), stat.sampleStDev(), stat.sum(), stat.count() ] writer.addRecord(record)
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT_LAYER), context) fieldName = self.getParameterValue(self.FIELD_NAME) outputFile = self.getOutputValue(self.OUTPUT_HTML_FILE) request = QgsFeatureRequest().setFlags( QgsFeatureRequest.NoGeometry).setSubsetOfAttributes([fieldName], layer.fields()) stat = QgsStringStatisticalSummary() features = QgsProcessingUtils.getFeatures(layer, context, request) count = QgsProcessingUtils.featureCount(layer, context) total = 100.0 / float(count) for current, ft in enumerate(features): stat.addValue(ft[fieldName]) feedback.setProgress(int(current * total)) stat.finalize() data = [] data.append(self.tr('Analyzed layer: {}').format(layer.name())) data.append(self.tr('Analyzed field: {}').format(fieldName)) data.append(self.tr('Minimum length: {}').format(stat.minLength())) data.append(self.tr('Maximum length: {}').format(stat.maxLength())) data.append(self.tr('Mean length: {}').format(stat.meanLength())) data.append( self.tr('Filled values: {}').format(stat.count() - stat.countMissing())) data.append( self.tr('NULL (missing) values: {}').format(stat.countMissing())) data.append(self.tr('Count: {}').format(stat.count())) data.append(self.tr('Unique: {}').format(stat.countDistinct())) data.append(self.tr('Minimum string value: {}').format(stat.min())) data.append(self.tr('Maximum string value: {}').format(stat.max())) self.createHTML(outputFile, data) self.setOutputValue(self.MIN_LEN, stat.minLength()) self.setOutputValue(self.MAX_LEN, stat.maxLength()) self.setOutputValue(self.MEAN_LEN, stat.meanLength()) self.setOutputValue(self.FILLED, stat.count() - stat.countMissing()) self.setOutputValue(self.EMPTY, stat.countMissing()) self.setOutputValue(self.COUNT, stat.count()) self.setOutputValue(self.UNIQUE, stat.countDistinct()) self.setOutputValue(self.MIN_VALUE, stat.min()) self.setOutputValue(self.MAX_VALUE, stat.max())
def processAlgorithm(self, context, feedback): layerHub = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.HUBS), context) layerSpoke = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.SPOKES), context) fieldHub = self.getParameterValue(self.HUB_FIELD) fieldSpoke = self.getParameterValue(self.SPOKE_FIELD) if layerHub.source() == layerSpoke.source(): raise GeoAlgorithmExecutionException( self.tr('Same layer given for both hubs and spokes')) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layerSpoke.fields(), QgsWkbTypes.LineString, layerSpoke.crs(), context) spokes = QgsProcessingUtils.getFeatures(layerSpoke, context) hubs = QgsProcessingUtils.getFeatures(layerHub, context) total = 100.0 / QgsProcessingUtils.featureCount(layerSpoke, context) for current, spokepoint in enumerate(spokes): p = spokepoint.geometry().boundingBox().center() spokeX = p.x() spokeY = p.y() spokeId = str(spokepoint[fieldSpoke]) for hubpoint in hubs: hubId = str(hubpoint[fieldHub]) if hubId == spokeId: p = hubpoint.geometry().boundingBox().center() hubX = p.x() hubY = p.y() f = QgsFeature() f.setAttributes(spokepoint.attributes()) f.setGeometry( QgsGeometry.fromPolyline( [QgsPoint(spokeX, spokeY), QgsPoint(hubX, hubY)])) writer.addFeature(f) break feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, context, feedback): layer = dataobjects.getLayerFromString(self.getParameterValue(self.POINTS)) output = self.getOutputValue(self.OUTPUT) spatialIndex = vector.spatialindex(layer) neighbour = QgsFeature() distance = QgsDistanceArea() sumDist = 0.00 A = layer.extent() A = float(A.width() * A.height()) features = QgsProcessingUtils.getFeatures(layer, context) count = QgsProcessingUtils.featureCount(layer, context) total = 100.0 / count for current, feat in enumerate(features): neighbourID = spatialIndex.nearestNeighbor( feat.geometry().asPoint(), 2)[1] request = QgsFeatureRequest().setFilterFid(neighbourID).setSubsetOfAttributes([]) neighbour = next(layer.getFeatures(request)) sumDist += distance.measureLine(neighbour.geometry().asPoint(), feat.geometry().asPoint()) feedback.setProgress(int(current * total)) do = float(sumDist) / count de = float(0.5 / math.sqrt(count / A)) d = float(do / de) SE = float(0.26136 / math.sqrt(count ** 2 / A)) zscore = float((do - de) / SE) data = [] data.append('Observed mean distance: ' + str(do)) data.append('Expected mean distance: ' + str(de)) data.append('Nearest neighbour index: ' + str(d)) data.append('Number of points: ' + str(count)) data.append('Z-Score: ' + str(zscore)) self.createHTML(output, data) self.setOutputValue(self.OBSERVED_MD, float(data[0].split(': ')[1])) self.setOutputValue(self.EXPECTED_MD, float(data[1].split(': ')[1])) self.setOutputValue(self.NN_INDEX, float(data[2].split(': ')[1])) self.setOutputValue(self.POINT_COUNT, float(data[3].split(': ')[1])) self.setOutputValue(self.Z_SCORE, float(data[4].split(': ')[1]))
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT), context) fieldName = self.getParameterValue(self.FIELD) geomType = QgsWkbTypes.multiType(layer.wkbType()) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields(), geomType, layer.crs(), context) outFeat = QgsFeature() inGeom = QgsGeometry() index = layer.fields().lookupField(fieldName) collection_geom = {} collection_attrs = {} features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, feature in enumerate(features): atMap = feature.attributes() idVar = atMap[index] if idVar in [None, NULL]: outFeat.setAttributes(atMap) outFeat.setGeometry(feature.geometry()) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) continue key = str(idVar).strip() if key not in collection_geom: collection_geom[key] = [] collection_attrs[key] = atMap inGeom = feature.geometry() collection_geom[key].append(inGeom) feedback.setProgress(int(current * total)) for key, geoms in collection_geom.items(): outFeat.setAttributes(collection_attrs[key]) outFeat.setGeometry(QgsGeometry.collectGeometry(geoms)) writer.addFeature(outFeat) del writer
def processAlgorithm(self, context, feedback): vlayer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT)) output = self.getOutputFromName(self.OUTPUT) if self.getParameterValue(self.FIELDS): fields = vlayer.fields() else: fields = QgsFields() if self.getParameterValue(self.GEOMETRY): fieldsCount = fields.count() fields.append(QgsField('area', QVariant.Double, 'double', 16, 2)) fields.append(QgsField('perimeter', QVariant.Double, 'double', 16, 2)) allLinesList = [] features = QgsProcessingUtils.getFeatures(vlayer, context, QgsFeatureRequest().setSubsetOfAttributes([])) feedback.pushInfo(self.tr('Processing lines...')) total = 40.0 / QgsProcessingUtils.featureCount(vlayer, context) for current, inFeat in enumerate(features): if inFeat.geometry(): allLinesList.append(inFeat.geometry()) feedback.setProgress(int(current * total)) feedback.setProgress(40) feedback.pushInfo(self.tr('Noding lines...')) allLines = QgsGeometry.unaryUnion(allLinesList) feedback.setProgress(45) feedback.pushInfo(self.tr('Polygonizing...')) polygons = QgsGeometry.polygonize([allLines]) if polygons.isEmpty(): raise GeoAlgorithmExecutionException(self.tr('No polygons were created!')) feedback.setProgress(50) feedback.pushInfo('Saving polygons...') writer = output.getVectorWriter(fields, QgsWkbTypes.Polygon, vlayer.crs(), context) total = 50.0 / polygons.geometry().numGeometries() for i in range(polygons.geometry().numGeometries()): outFeat = QgsFeature() geom = QgsGeometry(polygons.geometry().geometryN(i).clone()) outFeat.setGeometry(geom) if self.getParameterValue(self.GEOMETRY): outFeat.setAttributes([None] * fieldsCount + [geom.geometry().area(), geom.geometry().perimeter()]) writer.addFeature(outFeat) feedback.setProgress(50 + int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT), context) distance = self.getParameterValue(self.DISTANCE) start_offset = self.getParameterValue(self.START_OFFSET) end_offset = self.getParameterValue(self.END_OFFSET) fields = layer.fields() fields.append(QgsField('distance', QVariant.Double)) fields.append(QgsField('angle', QVariant.Double)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QgsWkbTypes.Point, layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, input_feature in enumerate(features): input_geometry = input_feature.geometry() if not input_geometry: writer.addFeature(input_feature) else: if input_geometry.type == QgsWkbTypes.PolygonGeometry: length = input_geometry.geometry().perimeter() else: length = input_geometry.length() - end_offset current_distance = start_offset while current_distance <= length: point = input_geometry.interpolate(current_distance) angle = math.degrees( input_geometry.interpolateAngle(current_distance)) output_feature = QgsFeature() output_feature.setGeometry(point) attrs = input_feature.attributes() attrs.append(current_distance) attrs.append(angle) output_feature.setAttributes(attrs) writer.addFeature(output_feature) current_distance += distance feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, context, feedback): vlayer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) output = self.getOutputFromName(self.OUTPUT) fields = vlayer.fields() writer = output.getVectorWriter(fields, QgsWkbTypes.LineString, vlayer.crs(), context) outFeat = QgsFeature() features = QgsProcessingUtils.getFeatures(vlayer, context) total = 100.0 / QgsProcessingUtils.featureCount(vlayer, context) for current, feature in enumerate(features): feedback.setProgress(int(current * total)) inGeom = feature.geometry() atMap = feature.attributes() segments = self.extractAsSingleSegments(inGeom) outFeat.setAttributes(atMap) for segment in segments: outFeat.setGeometry(segment) writer.addFeature(outFeat) del writer
def featureOmbb(self, layer, context, writer, feedback): features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) outFeat = QgsFeature() for current, inFeat in enumerate(features): geometry, area, angle, width, height = inFeat.geometry().orientedMinimumBoundingBox() if geometry: outFeat.setGeometry(geometry) attrs = inFeat.attributes() attrs.extend([area, width * 2 + height * 2, angle, width, height]) outFeat.setAttributes(attrs) writer.addFeature(outFeat) else: feedback.pushInfo(self.tr("Can't calculate an OMBB for feature {0}.").format(inFeat.id())) feedback.setProgress(int(current * total))
def linearMatrix(self, context, inLayer, inField, targetLayer, targetField, matType, nPoints, feedback): if matType == 0: self.writer.addRecord(['InputID', 'TargetID', 'Distance']) else: self.writer.addRecord(['InputID', 'MEAN', 'STDDEV', 'MIN', 'MAX']) index = QgsProcessingUtils.createSpatialIndex(targetLayer, context) inIdx = inLayer.fields().lookupField(inField) outIdx = targetLayer.fields().lookupField(targetField) distArea = QgsDistanceArea() features = QgsProcessingUtils.getFeatures(inLayer, context) total = 100.0 / QgsProcessingUtils.featureCount(inLayer, context) for current, inFeat in enumerate(features): inGeom = inFeat.geometry() inID = str(inFeat.attributes()[inIdx]) featList = index.nearestNeighbor(inGeom.asPoint(), nPoints) distList = [] vari = 0.0 request = QgsFeatureRequest().setFilterFids(featList).setSubsetOfAttributes([outIdx]) for outFeat in targetLayer.getFeatures(request): outID = outFeat.attributes()[outIdx] outGeom = outFeat.geometry() dist = distArea.measureLine(inGeom.asPoint(), outGeom.asPoint()) if matType == 0: self.writer.addRecord([inID, str(outID), str(dist)]) else: distList.append(float(dist)) if matType != 0: mean = sum(distList) / len(distList) for i in distList: vari += (i - mean) * (i - mean) vari = math.sqrt(vari / len(distList)) self.writer.addRecord([inID, str(mean), str(vari), str(min(distList)), str(max(distList))]) feedback.setProgress(int(current * total))
def processAlgorithm(self, context, feedback): output = self.getOutputFromName(self.OUTPUT) vlayer = \ QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) fields = vlayer.fields() fields.append(QgsField('AUTO', QVariant.Int)) writer = output.getVectorWriter(fields, vlayer.wkbType(), vlayer.crs(), context) outFeat = QgsFeature() features = QgsProcessingUtils.getFeatures(vlayer, context) total = 100.0 / QgsProcessingUtils.featureCount(vlayer, context) for current, feat in enumerate(features): feedback.setProgress(int(current * total)) geom = feat.geometry() outFeat.setGeometry(geom) attrs = feat.attributes() attrs.append(current) outFeat.setAttributes(attrs) writer.addFeature(outFeat) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT), context) tolerance = self.getParameterValue(self.TOLERANCE) method = self.getParameterValue(self.METHOD) pointsBefore = 0 pointsAfter = 0 writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields(), layer.wkbType(), layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) if method != 0: simplifier = QgsMapToPixelSimplifier( QgsMapToPixelSimplifier.SimplifyGeometry, tolerance, method) for current, input_feature in enumerate(features): out_feature = input_feature if input_feature.geometry(): input_geometry = input_feature.geometry() pointsBefore += input_geometry.geometry().nCoordinates() if method == 0: # distance output_geometry = input_geometry.simplify(tolerance) else: output_geometry = simplifier.simplify(input_geometry) pointsAfter += output_geometry.geometry().nCoordinates() out_feature.setGeometry(output_geometry) writer.addFeature(out_feature) feedback.setProgress(int(current * total)) del writer QgsMessageLog.logMessage( self. tr('Simplify: Input geometries have been simplified from {0} to {1} points' ).format(pointsBefore, pointsAfter), self.tr('Processing'), QgsMessageLog.INFO)
def featureExtent(self, layer, context, writer, feedback): features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) feat = QgsFeature() for current, f in enumerate(features): rect = f.geometry().boundingBox() minx = rect.xMinimum() miny = rect.yMinimum() maxx = rect.xMaximum() maxy = rect.yMaximum() height = rect.height() width = rect.width() cntx = minx + width / 2.0 cnty = miny + height / 2.0 area = width * height perim = 2 * width + 2 * height rect = [ QgsPoint(minx, miny), QgsPoint(minx, maxy), QgsPoint(maxx, maxy), QgsPoint(maxx, miny), QgsPoint(minx, miny) ] geometry = QgsGeometry().fromPolygon([rect]) feat.setGeometry(geometry) attrs = [ minx, miny, maxx, maxy, cntx, cnty, area, perim, height, width, ] feat.setAttributes(attrs) writer.addFeature(feat) feedback.setProgress(int(current * total))
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter(layer.fields(), QgsWkbTypes.Point, layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, input_feature in enumerate(features): output_feature = input_feature if input_feature.geometry(): output_geometry = input_feature.geometry().centroid() if not output_geometry: QgsMessageLog.logMessage('Error calculating centroid for feature {}'.format(input_feature.id()), self.tr('Processing'), QgsMessageLog.WARNING) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), QgsWkbTypes.LineString, layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): if f.hasGeometry(): lines = QgsGeometry(f.geometry().geometry().boundary()).asGeometryCollection() for line in lines: f.setGeometry(line) writer.addFeature(f) else: writer.addFeature(f) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context) vertices = self.getParameterValue(self.VERTICES) isPolygon = layer.geometryType() == QgsWkbTypes.PolygonGeometry writer = self.getOutputFromName( self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): feature = f if feature.hasGeometry(): new_geometry = feature.geometry().densifyByCount(int(vertices)) feature.setGeometry(new_geometry) writer.addFeature(feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, context, feedback): layerA = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(Difference.INPUT), context) layerB = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(Difference.OVERLAY), context) geomType = QgsWkbTypes.multiType(layerA.wkbType()) writer = self.getOutputFromName(Difference.OUTPUT).getVectorWriter( layerA.fields(), geomType, layerA.crs(), context) outFeat = QgsFeature() index = QgsProcessingUtils.createSpatialIndex(layerB, context) selectionA = QgsProcessingUtils.getFeatures(layerA, context) total = 100.0 / QgsProcessingUtils.featureCount(layerA, context) for current, inFeatA in enumerate(selectionA): geom = inFeatA.geometry() diff_geom = QgsGeometry(geom) attrs = inFeatA.attributes() intersections = index.intersects(geom.boundingBox()) request = QgsFeatureRequest().setFilterFids( intersections).setSubsetOfAttributes([]) for inFeatB in layerB.getFeatures(request): tmpGeom = inFeatB.geometry() if diff_geom.intersects(tmpGeom): diff_geom = QgsGeometry(diff_geom.difference(tmpGeom)) try: outFeat.setGeometry(diff_geom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: QgsMessageLog.logMessage( self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' ), self.tr('Processing'), QgsMessageLog.WARNING) continue feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) field_name = self.getParameterValue(self.FIELD_NAME) field = layer.fields().at(layer.fields().lookupField(field_name)) output_file = self.getOutputValue(self.OUTPUT_HTML_FILE) request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry).setSubsetOfAttributes([field_name], layer.fields()) features = QgsProcessingUtils.getFeatures(layer, context, request) count = QgsProcessingUtils.featureCount(layer, context) data = [] data.append(self.tr('Analyzed layer: {}').format(layer.name())) data.append(self.tr('Analyzed field: {}').format(field_name)) if field.isNumeric(): data.extend(self.calcNumericStats(features, feedback, field, count)) elif field.type() in (QVariant.Date, QVariant.Time, QVariant.DateTime): data.extend(self.calcDateTimeStats(features, feedback, field, count)) else: data.extend(self.calcStringStats(features, feedback, field, count)) self.createHTML(output_file, data)
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT_LAYER), context) tolerance = self.getParameterValue(self.TOLERANCE) fields = layer.fields() fields.append(QgsField('dist_pole', QVariant.Double)) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( fields, QgsWkbTypes.Point, layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, input_feature in enumerate(features): output_feature = input_feature input_geometry = input_feature.geometry() if input_geometry: output_geometry, distance = input_geometry.poleOfInaccessibility( tolerance) if not output_geometry: raise GeoAlgorithmExecutionException( self.tr('Error calculating pole of inaccessibility')) attrs = input_feature.attributes() attrs.append(distance) output_feature.setAttributes(attrs) output_feature.setGeometry(output_geometry) else: attrs = input_feature.attributes() attrs.append(NULL) output_feature.setAttributes(attrs) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT_LAYER), context) 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(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) 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) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, 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 / QgsProcessingUtils.featureCount(layer, context) 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 layerOmmb(self, layer, context, writer, feedback): req = QgsFeatureRequest().setSubsetOfAttributes([]) features = QgsProcessingUtils.getFeatures(layer, context, req) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) newgeometry = QgsGeometry() first = True for current, inFeat in enumerate(features): if first: newgeometry = inFeat.geometry() first = False else: newgeometry = newgeometry.combine(inFeat.geometry()) feedback.setProgress(int(current * total)) geometry, area, angle, width, height = newgeometry.orientedMinimumBoundingBox( ) if geometry: outFeat = QgsFeature() outFeat.setGeometry(geometry) outFeat.setAttributes( [area, width * 2 + height * 2, angle, width, height]) writer.addFeature(outFeat)
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT), context) fields = layer.fields() fields.append(QgsField('node_index', QVariant.Int)) fields.append(QgsField('distance', QVariant.Double)) fields.append(QgsField('angle', QVariant.Double)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QgsWkbTypes.Point, layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, f in enumerate(features): input_geometry = f.geometry() if not input_geometry: writer.addFeature(f) else: points = vector.extractPoints(input_geometry) for i, point in enumerate(points): 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.fromPoint(point)) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter(layer.fields(), QgsWkbTypes.Point, layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) for current, input_feature in enumerate(features): output_feature = input_feature input_geometry = input_feature.geometry() if input_geometry: output_geometry = input_geometry.pointOnSurface() if not output_geometry: raise GeoAlgorithmExecutionException( self.tr('Error calculating point on surface')) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.INPUT_LAYER), context) fieldName = self.getParameterValue(self.FIELD_NAME) fieldType = self.TYPES[self.getParameterValue(self.FIELD_TYPE)] width = self.getParameterValue(self.FIELD_LENGTH) precision = self.getParameterValue(self.FIELD_PRECISION) newField = self.getParameterValue(self.NEW_FIELD) formula = self.getParameterValue(self.FORMULA) output = self.getOutputFromName(self.OUTPUT_LAYER) fields = layer.fields() if newField: fields.append(QgsField(fieldName, fieldType, '', width, precision)) writer = output.getVectorWriter(fields, layer.wkbType(), layer.crs(), context) exp = QgsExpression(formula) da = QgsDistanceArea() da.setSourceCrs(layer.crs()) da.setEllipsoid(QgsProject.instance().ellipsoid()) exp.setGeomCalculator(da) exp.setDistanceUnits(QgsProject.instance().distanceUnits()) exp.setAreaUnits(QgsProject.instance().areaUnits()) exp_context = QgsExpressionContext( QgsExpressionContextUtils.globalProjectLayerScopes(layer)) if not exp.prepare(exp_context): raise GeoAlgorithmExecutionException( self.tr('Evaluation error: {0}').format(exp.evalErrorString())) outFeature = QgsFeature() outFeature.initAttributes(len(fields)) outFeature.setFields(fields) error = '' calculationSuccess = True features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) rownum = 1 for current, f in enumerate(features): rownum = current + 1 exp_context.setFeature(f) exp_context.lastScope().setVariable("row_number", rownum) value = exp.evaluate(exp_context) if exp.hasEvalError(): calculationSuccess = False error = exp.evalErrorString() break else: outFeature.setGeometry(f.geometry()) for fld in f.fields(): outFeature[fld.name()] = f[fld.name()] outFeature[fieldName] = value writer.addFeature(outFeature) feedback.setProgress(int(current * total)) del writer if not calculationSuccess: raise GeoAlgorithmExecutionException( self.tr('An error occurred while evaluating the calculation ' 'string:\n{0}').format(error))
def buffering(feedback, context, writer, distance, field, useField, layer, dissolve, segments, endCapStyle=1, joinStyle=1, mitreLimit=2): if useField: field = layer.fields().lookupField(field) outFeat = QgsFeature() current = 0 features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) # With dissolve if dissolve: buffered_geometries = [] for inFeat in features: attrs = inFeat.attributes() if useField: value = attrs[field] else: value = distance inGeom = inFeat.geometry() buffered_geometries.append( inGeom.buffer(float(value), segments, endCapStyle, joinStyle, mitreLimit)) current += 1 feedback.setProgress(int(current * total)) final_geometry = QgsGeometry.unaryUnion(buffered_geometries) outFeat.setGeometry(final_geometry) outFeat.setAttributes(attrs) writer.addFeature(outFeat) else: # Without dissolve for inFeat in features: attrs = inFeat.attributes() if useField: value = attrs[field] else: value = distance inGeom = inFeat.geometry() outFeat = QgsFeature() outGeom = inGeom.buffer(float(value), segments, endCapStyle, joinStyle, mitreLimit) outFeat.setGeometry(outGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) current += 1 feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, context, feedback): layer = self.getParameterValue(self.INPUT_LAYER) mapping = self.getParameterValue(self.FIELDS_MAPPING) output = self.getOutputFromName(self.OUTPUT_LAYER) layer = QgsProcessingUtils.mapLayerFromString(layer, context) fields = QgsFields() expressions = [] da = QgsDistanceArea() da.setSourceCrs(layer.crs()) da.setEllipsoid(QgsProject.instance().ellipsoid()) exp_context = layer.createExpressionContext() for field_def in mapping: fields.append( QgsField(field_def['name'], field_def['type'], field_def['length'], field_def['precision'])) expression = QgsExpression(field_def['expression']) expression.setGeomCalculator(da) expression.setDistanceUnits(QgsProject.instance().distanceUnits()) expression.setAreaUnits(QgsProject.instance().areaUnits()) expression.prepare(exp_context) if expression.hasParserError(): raise GeoAlgorithmExecutionException( self.tr(u'Parser error in expression "{}": {}').format( str(expression.expression()), str(expression.parserErrorString()))) expressions.append(expression) writer = output.getVectorWriter(fields, layer.wkbType(), layer.crs(), context) # Create output vector layer with new attributes error_exp = None inFeat = QgsFeature() outFeat = QgsFeature() features = QgsProcessingUtils.getFeatures(layer, context) count = QgsProcessingUtils.featureCount(layer, context) if count > 0: total = 100.0 / count for current, inFeat in enumerate(features): rownum = current + 1 geometry = inFeat.geometry() outFeat.setGeometry(geometry) attrs = [] for i in range(0, len(mapping)): field_def = mapping[i] expression = expressions[i] exp_context.setFeature(inFeat) exp_context.lastScope().setVariable("row_number", rownum) value = expression.evaluate(exp_context) if expression.hasEvalError(): error_exp = expression break attrs.append(value) outFeat.setAttributes(attrs) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) else: feedback.setProgress(100) del writer if error_exp is not None: raise GeoAlgorithmExecutionException( self.tr(u'Evaluation error in expression "{}": {}').format( str(error_exp.expression()), str(error_exp.parserErrorString())))
def processAlgorithm(self, context, feedback): layer = QgsProcessingUtils.mapLayerFromString( self.getParameterValue(self.POINTS), context) weightField = self.getParameterValue(self.WEIGHT) uniqueField = self.getParameterValue(self.UID) if weightField is None: weightIndex = -1 else: weightIndex = layer.fields().lookupField(weightField) if uniqueField is None: uniqueIndex = -1 else: uniqueIndex = layer.fields().lookupField(uniqueField) fieldList = QgsFields() fieldList.append(QgsField('MEAN_X', QVariant.Double, '', 24, 15)) fieldList.append(QgsField('MEAN_Y', QVariant.Double, '', 24, 15)) fieldList.append(QgsField('UID', QVariant.String, '', 255)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fieldList, QgsWkbTypes.Point, layer.crs(), context) features = QgsProcessingUtils.getFeatures(layer, context) total = 100.0 / QgsProcessingUtils.featureCount(layer, context) means = {} for current, feat in enumerate(features): feedback.setProgress(int(current * total)) if uniqueIndex == -1: clazz = "Single class" else: clazz = str(feat.attributes()[uniqueIndex]).strip() if weightIndex == -1: weight = 1.00 else: try: weight = float(feat.attributes()[weightIndex]) except: weight = 1.00 if weight < 0: raise GeoAlgorithmExecutionException( self. tr('Negative weight value found. Please fix your data and try again.' )) if clazz not in means: means[clazz] = (0, 0, 0) (cx, cy, totalweight) = means[clazz] geom = QgsGeometry(feat.geometry()) geom = vector.extractPoints(geom) for i in geom: cx += i.x() * weight cy += i.y() * weight totalweight += weight means[clazz] = (cx, cy, totalweight) current = 0 total = 100.0 / len(means) for (clazz, values) in list(means.items()): outFeat = QgsFeature() cx = values[0] / values[2] cy = values[1] / values[2] meanPoint = QgsPoint(cx, cy) outFeat.setGeometry(QgsGeometry.fromPoint(meanPoint)) outFeat.setAttributes([cx, cy, clazz]) writer.addFeature(outFeat) current += 1 feedback.setProgress(int(current * total)) del writer