def exportVectorLayer(self, orgFilename): # TODO: improve this. We are now exporting if it is not a shapefile, # but the functionality of v.in.ogr could be used for this. # We also export if there is a selection if not os.path.exists(orgFilename) or not orgFilename.endswith('shp'): layer = dataobjects.getLayerFromString(orgFilename, False) if layer: filename = dataobjects.exportVectorLayer(layer) else: layer = dataobjects.getLayerFromString(orgFilename, False) if layer: useSelection = \ ProcessingConfig.getSetting(ProcessingConfig.USE_SELECTED) if useSelection and layer.selectedFeatureCount() != 0: filename = dataobjects.exportVectorLayer(layer) else: filename = orgFilename else: filename = orgFilename destFilename = 'a' + os.path.basename(self.getTempFilename()) self.exportedLayers[orgFilename] = destFilename command = 'v.in.ogr' min_area = self.getParameterValue(self.GRASS_MIN_AREA_PARAMETER) command += ' min_area=' + str(min_area) snap = self.getParameterValue(self.GRASS_SNAP_TOLERANCE_PARAMETER) command += ' snap=' + str(snap) command += ' input="' + os.path.dirname(filename) + '"' command += ' layer=' + os.path.basename(filename)[:-4] command += ' output=' + destFilename command += ' --overwrite -o' return command
def processAlgorithm(self, feedback): inLayer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) inField = self.getParameterValue(self.INPUT_FIELD) targetLayer = dataobjects.getLayerFromString( self.getParameterValue(self.TARGET_LAYER)) 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 = len(vector.features(targetLayer)) self.writer = outputFile.getTableWriter([]) if matType == 0: # Linear distance matrix self.linearMatrix(inLayer, inField, targetLayer, targetField, matType, nPoints, feedback) elif matType == 1: # Standard distance matrix self.regularMatrix(inLayer, inField, targetLayer, targetField, nPoints, feedback) elif matType == 2: # Summary distance matrix self.linearMatrix(inLayer, inField, targetLayer, targetField, matType, nPoints, feedback)
def getDefaultCellsize(self): cellsize = 0 for param in self.parameters: if param.value: if isinstance(param, ParameterRaster): if isinstance(param.value, QgsRasterLayer): layer = param.value else: layer = dataobjects.getLayerFromString(param.value) cellsize = max(cellsize, (layer.extent().xMaximum() - layer.extent().xMinimum()) / layer.width()) elif isinstance(param, ParameterMultipleInput): layers = param.value.split(';') for layername in layers: layer = dataobjects.getLayerFromString(layername) if isinstance(layer, QgsRasterLayer): cellsize = max(cellsize, ( layer.extent().xMaximum() - layer.extent().xMinimum()) / layer.width()) if cellsize == 0: cellsize = 1 return cellsize
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT)) reference_layer = dataobjects.getLayerFromString(self.getParameterValue(self.REFERENCE_LAYER)) tolerance = self.getParameterValue(self.TOLERANCE) mode = self.getParameterValue(self.BEHAVIOR) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields(), layer.wkbType(), layer.crs()) features = vector.features(layer) self.processed = 0 self.feedback = feedback self.total = 100.0 / len(features) if self.getParameterValue(self.INPUT) != self.getParameterValue(self.REFERENCE_LAYER): snapper = QgsGeometrySnapper(reference_layer) snapper.featureSnapped.connect(self.featureSnapped) snapped_features = snapper.snapFeatures(features, tolerance, mode) for f in snapped_features: writer.addFeature(QgsFeature(f)) else: # snapping internally snapper = QgsInternalGeometrySnapper(tolerance, mode) processed = 0 for f in features: out_feature = f out_feature.setGeometry(snapper.snapFeature(f)) writer.addFeature(out_feature) processed += 1 feedback.setProgress(processed * self.total) del writer
def processAlgorithm(self, feedback): polyLayer = dataobjects.getLayerFromString(self.getParameterValue(self.POLYGONS)) pointLayer = dataobjects.getLayerFromString(self.getParameterValue(self.POINTS)) 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.toList(), polyLayer.wkbType(), polyLayer.crs()) spatialIndex = vector.spatialindex(pointLayer) ftPoint = QgsFeature() outFeat = QgsFeature() geom = QgsGeometry() features = vector.features(polyLayer) total = 100.0 / len(features) 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, feedback): filename = self.getParameterValue(self.INPUT) inputLayer = dataobjects.getLayerFromString(filename) method = self.getParameterValue(self.METHOD) filename2 = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getLayerFromString(filename2) predicates = self.getParameterValue(self.PREDICATE) precision = self.getParameterValue(self.PRECISION) oldSelection = set(inputLayer.selectedFeatureIds()) inputLayer.removeSelection() index = vector.spatialindex(inputLayer) if 'disjoint' in predicates: disjoinSet = [] for feat in vector.features(inputLayer): disjoinSet.append(feat.id()) geom = QgsGeometry() selectedSet = [] features = vector.features(selectLayer) total = 100.0 / len(features) for current, f in enumerate(features): geom = vector.snapToPrecision(f.geometry(), precision) bbox = vector.bufferedBoundingBox(geom.boundingBox(), 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, feedback): vlayerA = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT)) vlayerB = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT2)) geomType = QgsWkbTypes.multiType(vlayerA.wkbType()) fields = vector.combineVectorFields(vlayerA, vlayerB) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, geomType, vlayerA.crs()) outFeat = QgsFeature() index = vector.spatialindex(vlayerB) selectionA = vector.features(vlayerA) total = 100.0 / len(selectionA) for current, inFeatA in enumerate(selectionA): feedback.setProgress(int(current * total)) geom = inFeatA.geometry() atMapA = inFeatA.attributes() intersects = index.intersects(geom.boundingBox()) request = QgsFeatureRequest().setFilterFids(intersects) engine = None if len(intersects) > 0: # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine(geom.geometry()) engine.prepareGeometry() for inFeatB in vlayerB.getFeatures(request): tmpGeom = inFeatB.geometry() if engine.intersects(tmpGeom.geometry()): atMapB = inFeatB.attributes() int_geom = QgsGeometry(geom.intersection(tmpGeom)) if int_geom.wkbType() == QgsWkbTypes.Unknown or QgsWkbTypes.flatType(int_geom.geometry().wkbType()) == QgsWkbTypes.GeometryCollection: int_com = geom.combine(tmpGeom) int_geom = QgsGeometry() if int_com: int_sym = geom.symDifference(tmpGeom) int_geom = QgsGeometry(int_com.difference(int_sym)) if int_geom.isEmpty() or not int_geom.isGeosValid(): ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('GEOS geoprocessing error: One or ' 'more input features have invalid ' 'geometry.')) try: if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[int_geom.wkbType()]]: outFeat.setGeometry(int_geom) attrs = [] attrs.extend(atMapA) attrs.extend(atMapB) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.')) continue del writer
def processAlgorithm(self, feedback): filename = self.getParameterValue(self.INPUT) layer = dataobjects.getLayerFromString(filename) filename = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getLayerFromString(filename) predicates = self.getParameterValue(self.PREDICATE) precision = self.getParameterValue(self.PRECISION) index = vector.spatialindex(layer) output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(layer.fields(), layer.wkbType(), layer.crs()) if 'disjoint' in predicates: disjoinSet = [] for feat in vector.features(layer): disjoinSet.append(feat.id()) selectedSet = [] features = vector.features(selectLayer) total = 100.0 / len(features) for current, f in enumerate(features): geom = vector.snapToPrecision(f.geometry(), precision) bbox = vector.bufferedBoundingBox(geom.boundingBox(), 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 = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): if f.id() in selectedSet: writer.addFeature(f) feedback.setProgress(int(current * total)) del writer
def convertUnsupportedFormats(self, feedback): i = 0 feedback.setProgressText(self.tr('Converting outputs')) for out in self.outputs: if isinstance(out, OutputVector): if out.compatible is not None: layer = dataobjects.getLayerFromString(out.compatible) if layer is None: # For the case of memory layer, if the # getCompatible method has been called continue writer = out.getVectorWriter( layer.fields(), layer.wkbType(), layer.crs() ) features = vector.features(layer) for feature in features: writer.addFeature(feature) elif isinstance(out, OutputRaster): if out.compatible is not None: layer = dataobjects.getLayerFromString(out.compatible) format = self.getFormatShortNameFromFilename(out.value) orgFile = out.compatible destFile = out.value crsid = layer.crs().authid() settings = QgsSettings() path = str(settings.value('/GdalTools/gdalPath', '')) envval = str(os.getenv('PATH')) if not path.lower() in envval.lower().split(os.pathsep): envval += '%s%s' % (os.pathsep, path) os.putenv('PATH', envval) command = 'gdal_translate -of %s -a_srs %s %s %s' % (format, crsid, orgFile, destFile) if os.name == 'nt': command = command.split(" ") else: command = [command] proc = subprocess.Popen( command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=False, ) proc.communicate() elif isinstance(out, OutputTable): if out.compatible is not None: layer = dataobjects.getLayerFromString(out.compatible) writer = out.getTableWriter(layer.fields()) features = vector.features(layer) for feature in features: writer.addRecord(feature) feedback.setProgress(100 * i / float(len(self.outputs)))
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) 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()) 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 = 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, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) byFeature = self.getParameterValue(self.BY_FEATURE) fields = [ QgsField('MINX', QVariant.Double), QgsField('MINY', QVariant.Double), QgsField('MAXX', QVariant.Double), QgsField('MAXY', QVariant.Double), QgsField('CNTX', QVariant.Double), QgsField('CNTY', QVariant.Double), QgsField('AREA', QVariant.Double), QgsField('PERIM', QVariant.Double), QgsField('HEIGHT', QVariant.Double), QgsField('WIDTH', QVariant.Double), ] writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Polygon, layer.crs()) if byFeature: self.featureExtent(layer, writer, feedback) else: self.layerExtent(layer, writer, feedback) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) shape = self.getParameterValue(self.SHAPE) width = self.getParameterValue(self.WIDTH) height = self.getParameterValue(self.HEIGHT) rotation = self.getParameterValue(self.ROTATION) segments = self.getParameterValue(self.SEGMENTS) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter( layer.fields().toList(), QgsWkbTypes.Polygon, layer.crs()) features = vector.features(layer) if shape == 0: self.rectangles(writer, features, width, height, rotation) elif shape == 1: self.diamonds(writer, features, width, height, rotation) else: self.ovals(writer, features, width, height, rotation, segments) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter( layer.fields().toList(), QgsWkbTypes.LineString, layer.crs()) distance = self.getParameterValue(self.DISTANCE) segments = int(self.getParameterValue(self.SEGMENTS)) join_style = self.getParameterValue(self.JOIN_STYLE) + 1 miter_limit = self.getParameterValue(self.MITRE_LIMIT) 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 = input_geometry.offsetCurve(distance, segments, join_style, miter_limit) if not output_geometry: raise GeoAlgorithmExecutionException( self.tr('Error calculating line offset')) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, feedback): fileName = self.getParameterValue(self.INPUT) layer = dataobjects.getLayerFromString(fileName) crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.CRS)) provider = layer.dataProvider() ds = provider.dataSourceUri() p = re.compile('\|.*') dsPath = p.sub('', ds) if dsPath.lower().endswith('.shp'): dsPath = dsPath[:-4] wkt = crs.toWkt() with open(dsPath + '.prj', 'w') as f: f.write(wkt) qpjFile = dsPath + '.qpj' if os.path.exists(qpjFile): with open(qpjFile, 'w') as f: f.write(wkt) layer.setCrs(crs) iface.mapCanvas().refresh() self.setOutputValue(self.OUTPUT, fileName)
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT)) 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()) features = vector.features(layer) total = 100.0 / len(features) 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, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter( layer.fields().toList(), layer.wkbType(), layer.crs()) features = vector.features(layer) total = 100.0 / len(features) 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, feedback): layer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT)) crsId = self.getParameterValue(self.TARGET_CRS) targetCrs = QgsCoordinateReferenceSystem() targetCrs.createFromUserInput(crsId) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields().toList(), layer.wkbType(), targetCrs) layerCrs = layer.crs() crsTransform = QgsCoordinateTransform(layerCrs, targetCrs) outFeat = QgsFeature() features = vector.features(layer) total = 100.0 / len(features) 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, feedback): filename = self.getParameterValue(self.INPUT) layer = dataobjects.getLayerFromString(filename) method = self.getParameterValue(self.METHOD) features = vector.features(layer) featureCount = len(features) 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().toList(), layer.wkbType(), layer.crs()) 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 checkParameterValuesBeforeExecuting(self): """ We check that there are no multiband layers, which are not supported by SAGA, and that raster layers have the same grid extent """ extent = None for param in self.parameters: files = [] if isinstance(param, ParameterRaster): files = [param.value] elif (isinstance(param, ParameterMultipleInput) and param.datatype == dataobjects.TYPE_RASTER): if param.value is not None: files = param.value.split(";") for f in files: layer = dataobjects.getLayerFromString(f) if layer is None: continue if layer.bandCount() > 1: return self.tr('Input layer {0} has more than one band.\n' 'Multiband layers are not supported by SAGA').format(layer.name()) if not self.allowUnmatchingGridExtents: if extent is None: extent = (layer.extent(), layer.height(), layer.width()) else: extent2 = (layer.extent(), layer.height(), layer.width()) if extent != extent2: return self.tr("Input layers do not have the same grid extent.")
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT)) value = self.getParameterValue(self.NUMBER) output = self.getOutputFromName(self.OUTPUT) raster = gdal.Open(layer.source(), gdal.GA_ReadOnly) geoTransform = raster.GetGeoTransform() cellsize = (layer.extent().xMaximum() - layer.extent().xMinimum()) \ / layer.width() w = RasterWriter(output.getCompatibleFileName(self), layer.extent().xMinimum(), layer.extent().yMinimum(), layer.extent().xMaximum(), layer.extent().yMaximum(), cellsize, 1, layer.crs(), geoTransform ) w.matrix.fill(value) w.close()
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT_LAYER)) 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 = vector.features(layer) total = 100.0 / len(features) 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, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter( layer.fields().toList(), QgsWkbTypes.Point, 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 = 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, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) 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().toList(), layer.wkbType(), layer.crs()) features = vector.features(layer) total = 100.0 / len(features) 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, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter( layer.fields(), QgsWkbTypes.Point, layer.crs()) outFeat = QgsFeature() features = vector.features(layer) total = 100.0 / len(features) 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, feedback): fieldType = self.getParameterValue(self.FIELD_TYPE) fieldName = self.getParameterValue(self.FIELD_NAME) fieldLength = self.getParameterValue(self.FIELD_LENGTH) fieldPrecision = self.getParameterValue(self.FIELD_PRECISION) output = self.getOutputFromName(self.OUTPUT_LAYER) layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) fields = layer.fields() fields.append(QgsField(fieldName, self.TYPES[fieldType], '', fieldLength, fieldPrecision)) writer = output.getVectorWriter(fields, layer.wkbType(), layer.crs()) outFeat = QgsFeature() features = vector.features(layer) total = 100.0 / len(features) for current, feat in enumerate(features): feedback.setProgress(int(current * total)) geom = feat.geometry() outFeat.setGeometry(geom) atMap = feat.attributes() atMap.append(None) outFeat.setAttributes(atMap) writer.addFeature(outFeat) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT)) 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()) features = vector.features(layer) total = 100.0 / len(features) 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 processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter( layer.fields(), QgsWkbTypes.Point, layer.crs()) features = vector.features(layer) total = 100.0 / len(features) 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: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Error calculating centroid for feature {}'.format(input_feature.id())) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, feedback): fieldname = self.getParameterValue(self.FIELD) output = self.getOutputFromName(self.OUTPUT) vlayer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT)) fieldindex = vlayer.fields().lookupField(fieldname) fields = vlayer.fields() fields.append(QgsField('NUM_FIELD', QVariant.Int)) writer = output.getVectorWriter(fields, vlayer.wkbType(), vlayer.crs()) outFeat = QgsFeature() classes = {} features = vector.features(vlayer) total = 100.0 / len(features) 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, feedback): layer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT)) fields_to_delete = self.getParameterValue(self.COLUMNS).split(';') fields = layer.fields() field_indices = [] # loop through twice - first we need to build up a list of original attribute indices for f in fields_to_delete: index = fields.lookupField(f) field_indices.append(index) # important - make sure we remove from the end so we aren't changing used indices as we go field_indices.sort(reverse=True) # this second time we make a cleaned version of the fields for index in field_indices: fields.remove(index) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, layer.wkbType(), layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): attributes = f.attributes() for index in field_indices: del attributes[index] f.setAttributes(attributes) writer.addFeature(f) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT_VECTOR)) 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.toList(), QgsWkbTypes.Point, layer.crs()) outFeature = QgsFeature() outFeature.setFields(fields) self.fid = 0 self.lineId = 0 self.pointId = 0 features = vector.features(layer) total = 100.0 / len(features) 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, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT)) useField = self.getParameterValue(self.METHOD) == 1 fieldName = self.getParameterValue(self.FIELD) f = QgsField('value', QVariant.String, '', 255) if useField: index = layer.fields().lookupField(fieldName) fType = layer.fields()[index].type() if fType in [ QVariant.Int, QVariant.UInt, QVariant.LongLong, QVariant.ULongLong ]: f.setType(fType) f.setLength(20) elif fType == QVariant.Double: f.setType(QVariant.Double) f.setLength(20) f.setPrecision(6) else: f.setType(QVariant.String) f.setLength(255) fields = [ QgsField('id', QVariant.Int, '', 20), f, QgsField('area', QVariant.Double, '', 20, 6), QgsField('perim', QVariant.Double, '', 20, 6) ] writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QgsWkbTypes.Polygon, layer.crs()) outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() fid = 0 val = None features = vector.features(layer) if useField: unique = layer.uniqueValues(index) current = 0 total = 100.0 / (len(features) * len(unique)) for i in unique: first = True hull = [] features = vector.features(layer) for f in features: idVar = f[fieldName] if str(idVar).strip() == str(i).strip(): if first: val = idVar first = False inGeom = f.geometry() points = vector.extractPoints(inGeom) hull.extend(points) current += 1 feedback.setProgress(int(current * total)) if len(hull) >= 3: tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull)) try: outGeom = tmpGeom.convexHull() (area, perim) = vector.simpleMeasure(outGeom) outFeat.setGeometry(outGeom) outFeat.setAttributes([fid, val, area, perim]) writer.addFeature(outFeat) except: raise GeoAlgorithmExecutionException( self.tr('Exception while computing convex hull')) fid += 1 else: hull = [] total = 100.0 / layer.featureCount() features = vector.features(layer) for current, f in enumerate(features): inGeom = f.geometry() points = vector.extractPoints(inGeom) hull.extend(points) feedback.setProgress(int(current * total)) tmpGeom = QgsGeometry(outGeom.fromMultiPoint(hull)) try: outGeom = tmpGeom.convexHull() (area, perim) = vector.simpleMeasure(outGeom) outFeat.setGeometry(outGeom) outFeat.setAttributes([0, 'all', area, perim]) writer.addFeature(outFeat) except: raise GeoAlgorithmExecutionException( self.tr('Exception while computing convex hull')) del writer
def processAlgorithm(self, feedback): layerA = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_A)) splitLayer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_B)) sameLayer = self.getParameterValue( self.INPUT_A) == self.getParameterValue(self.INPUT_B) fieldList = layerA.fields() writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fieldList, QgsWkbTypes.multiType(layerA.wkbType()), layerA.crs()) spatialIndex = QgsSpatialIndex() splitGeoms = {} request = QgsFeatureRequest() request.setSubsetOfAttributes([]) for aSplitFeature in vector.features(splitLayer, request): splitGeoms[aSplitFeature.id()] = aSplitFeature.geometry() spatialIndex.insertFeature(aSplitFeature) # honor the case that user has selection on split layer and has setting "use selection" outFeat = QgsFeature() features = vector.features(layerA) if len(features) == 0: total = 100 else: total = 100.0 / float(len(features)) for current, inFeatA in enumerate(features): inGeom = inFeatA.geometry() attrsA = inFeatA.attributes() outFeat.setAttributes(attrsA) if inGeom.isMultipart(): inGeoms = [] for g in inGeom.asGeometryCollection(): inGeoms.append(g) else: inGeoms = [inGeom] lines = spatialIndex.intersects(inGeom.boundingBox()) if len(lines) > 0: # has intersection of bounding boxes splittingLines = [] engine = QgsGeometry.createGeometryEngine(inGeom.geometry()) engine.prepareGeometry() for i in lines: try: splitGeom = splitGeoms[i] except: continue # check if trying to self-intersect if sameLayer: if inFeatA.id() == i: continue if engine.intersects(splitGeom.geometry()): splittingLines.append(splitGeom) if len(splittingLines) > 0: for splitGeom in splittingLines: splitterPList = None outGeoms = [] split_geom_engine = QgsGeometry.createGeometryEngine( splitGeom.geometry()) split_geom_engine.prepareGeometry() while len(inGeoms) > 0: inGeom = inGeoms.pop() if inGeom.isNull( ): # this has been encountered and created a run-time error continue if split_geom_engine.intersects(inGeom.geometry()): inPoints = vector.extractPoints(inGeom) if splitterPList is None: splitterPList = vector.extractPoints( splitGeom) try: result, newGeometries, topoTestPoints = inGeom.splitGeometry( splitterPList, False) except: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self. tr('Geometry exception while splitting' )) result = 1 # splitGeometry: If there are several intersections # between geometry and splitLine, only the first one is considered. if result == 0: # split occurred if inPoints == vector.extractPoints( inGeom): # bug in splitGeometry: sometimes it returns 0 but # the geometry is unchanged outGeoms.append(inGeom) else: inGeoms.append(inGeom) for aNewGeom in newGeometries: inGeoms.append(aNewGeom) else: outGeoms.append(inGeom) else: outGeoms.append(inGeom) inGeoms = outGeoms parts = [] for aGeom in inGeoms: passed = True if QgsWkbTypes.geometryType( aGeom.wkbType()) == QgsWkbTypes.LineGeometry: numPoints = aGeom.geometry().numPoints() if numPoints <= 2: if numPoints == 2: passed = not aGeom.geometry().isClosed( ) # tests if vertex 0 = vertex 1 else: passed = False # sometimes splitting results in lines of zero length if passed: parts.append(aGeom) if len(parts) > 0: outFeat.setGeometry(QgsGeometry.collectGeometry(parts)) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString(self.getParameterValue(self.INPUT_LAYER)) 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()) exp = QgsExpression(formula) da = QgsDistanceArea() da.setSourceCrs(layer.crs()) da.setEllipsoidalMode(True) 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 = vector.features(layer) total = 100.0 / len(features) 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 processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_VECTOR)) startPoints = dataobjects.getLayerFromString( self.getParameterValue(self.START_POINTS)) endPoint = self.getParameterValue(self.END_POINT) strategy = self.getParameterValue(self.STRATEGY) directionFieldName = self.getParameterValue(self.DIRECTION_FIELD) forwardValue = self.getParameterValue(self.VALUE_FORWARD) backwardValue = self.getParameterValue(self.VALUE_BACKWARD) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) speedFieldName = self.getParameterValue(self.SPEED_FIELD) defaultSpeed = self.getParameterValue(self.DEFAULT_SPEED) tolerance = self.getParameterValue(self.TOLERANCE) fields = QgsFields() fields.append(QgsField('start', QVariant.String, '', 254, 0)) fields.append(QgsField('end', QVariant.String, '', 254, 0)) fields.append(QgsField('cost', QVariant.Double, '', 20, 7)) feat = QgsFeature() feat.setFields(fields) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( fields.toList(), QgsWkbTypes.LineString, layer.crs()) tmp = endPoint.split(',') endPoint = QgsPoint(float(tmp[0]), float(tmp[1])) directionField = -1 if directionFieldName is not None: directionField = layer.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName is not None: speedField = layer.fields().lookupField(speedFieldName) director = QgsVectorLayerDirector(layer, directionField, forwardValue, backwardValue, bothValue, defaultDirection) distUnit = iface.mapCanvas().mapSettings().destinationCrs().mapUnits() multiplier = QgsUnitTypes.fromUnitToUnitFactor( distUnit, QgsUnitTypes.DistanceMeters) if strategy == 0: strategy = QgsNetworkDistanceStrategy() else: strategy = QgsNetworkSpeedStrategy(speedField, defaultSpeed, multiplier * 1000.0 / 3600.0) multiplier = 3600 director.addStrategy(strategy) builder = QgsGraphBuilder( iface.mapCanvas().mapSettings().destinationCrs(), True, tolerance) feedback.pushInfo(self.tr('Loading start points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) features = vector.features(startPoints, request) count = len(features) points = [endPoint] for f in features: points.append(f.geometry().asPoint()) feedback.pushInfo(self.tr('Building graph...')) snappedPoints = director.makeGraph(builder, points) feedback.pushInfo(self.tr('Calculating shortest paths...')) graph = builder.graph() idxEnd = graph.findVertex(snappedPoints[0]) route = [] total = 100.0 / count for i in range(1, count + 1): idxStart = graph.findVertex(snappedPoints[i]) tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0) if tree[idxEnd] == -1: msg = self.tr( 'There is no route from start point ({}) to end point ({}).' .format(points[i].toString(), endPoint.toString())) feedback.setProgressText(msg) ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, msg) continue cost = 0.0 current = idxEnd while current != idxStart: cost += graph.edge(tree[current]).cost(0) route.append( graph.vertex(graph.edge(tree[current]).inVertex()).point()) current = graph.edge(tree[current]).outVertex() route.append(snappedPoints[i]) route.reverse() geom = QgsGeometry.fromPolyline(route) feat.setGeometry(geom) feat['start'] = points[i].toString() feat['end'] = endPoint.toString() feat['cost'] = cost / multiplier writer.addFeature(feat) route[:] = [] feedback.setProgress(int(i * total)) del writer
def processAlgorithm(self, context, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) fieldName = self.getParameterValue(self.FIELD_NAME) outputFile = self.getOutputValue(self.OUTPUT_HTML_FILE) request = QgsFeatureRequest().setFlags( QgsFeatureRequest.NoGeometry).setSubsetOfAttributes([fieldName], layer.fields()) stat = QgsStatisticalSummary() features = QgsProcessingUtils.getFeatures(layer, context, request) count = QgsProcessingUtils.featureCount(layer, context) total = 100.0 / float(count) for current, ft in enumerate(features): stat.addVariant(ft[fieldName]) feedback.setProgress(int(current * total)) stat.finalize() count = stat.count() uniqueValue = stat.variety() minValue = stat.min() maxValue = stat.max() rValue = stat.range() sumValue = stat.sum() meanValue = stat.mean() medianValue = stat.median() stdDevValue = stat.stDev() cvValue = stdDevValue / meanValue if meanValue != 0 else 0 minority = stat.minority() majority = stat.majority() firstQuartile = stat.firstQuartile() thirdQuartile = stat.thirdQuartile() iqr = stat.interQuartileRange() nullValues = stat.countMissing() data = [] data.append(self.tr('Analyzed layer: {}').format(layer.name())) data.append(self.tr('Analyzed field: {}').format(fieldName)) data.append(self.tr('Count: {}').format(count)) data.append(self.tr('Unique values: {}').format(uniqueValue)) data.append(self.tr('Minimum value: {}').format(minValue)) data.append(self.tr('Maximum value: {}').format(maxValue)) data.append(self.tr('Range: {}').format(rValue)) data.append(self.tr('Sum: {}').format(sumValue)) data.append(self.tr('Mean value: {}').format(meanValue)) data.append(self.tr('Median value: {}').format(medianValue)) data.append(self.tr('Standard deviation: {}').format(stdDevValue)) data.append(self.tr('Coefficient of Variation: {}').format(cvValue)) data.append( self.tr('Minority (rarest occurring value): {}').format(minority)) data.append( self.tr('Majority (most frequently occurring value): {}').format( majority)) data.append(self.tr('First quartile: {}').format(firstQuartile)) data.append(self.tr('Third quartile: {}').format(thirdQuartile)) data.append(self.tr('NULL (missing) values: {}').format(nullValues)) data.append(self.tr('Interquartile Range (IQR): {}').format(iqr)) self.createHTML(outputFile, data) self.setOutputValue(self.COUNT, count) self.setOutputValue(self.UNIQUE, uniqueValue) self.setOutputValue(self.MIN, minValue) self.setOutputValue(self.MAX, maxValue) self.setOutputValue(self.RANGE, rValue) self.setOutputValue(self.SUM, sumValue) self.setOutputValue(self.MEAN, meanValue) self.setOutputValue(self.MEDIAN, medianValue) self.setOutputValue(self.STD_DEV, stdDevValue) self.setOutputValue(self.MINORITY, minority) self.setOutputValue(self.MAJORITY, majority) self.setOutputValue(self.FIRSTQUARTILE, firstQuartile) self.setOutputValue(self.THIRDQUARTILE, thirdQuartile) self.setOutputValue(self.NULLVALUES, nullValues) self.setOutputValue(self.IQR, iqr)
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_VECTOR)) 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('poly_id', QVariant.Int, '', 10, 0)) fields.append(QgsField('point_id', QVariant.Int, '', 10, 0)) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( fields.toList(), QgsWkbTypes.Point, layer.crs()) outFeature = QgsFeature() outFeature.setFields(fields) fid = 0 polyId = 0 pointId = 0 features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): geom = f.geometry() bbox = geom.boundingBox() xMin = bbox.xMinimum() xMax = bbox.xMaximum() yMin = bbox.yMinimum() yMax = bbox.yMaximum() (startRow, startColumn) = raster.mapToPixel(xMin, yMax, geoTransform) (endRow, endColumn) = raster.mapToPixel(xMax, yMin, geoTransform) # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine(geom.geometry()) engine.prepareGeometry() for row in range(startRow, endRow + 1): for col in range(startColumn, endColumn + 1): (x, y) = raster.pixelToMap(row, col, geoTransform) point = QgsPointV2() point.setX(x) point.setY(y) if engine.contains(point): outFeature.setGeometry(QgsGeometry(point)) outFeature['id'] = fid outFeature['poly_id'] = polyId outFeature['point_id'] = pointId fid += 1 pointId += 1 writer.addFeature(outFeature) pointId = 0 polyId += 1 feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, feedback): inLayer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT)) boundary = self.getParameterValue(self.MODE) == self.MODE_BOUNDARY smallestArea = self.getParameterValue( self.MODE) == self.MODE_SMALLEST_AREA if inLayer.selectedFeatureCount() == 0: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self.tr('{0}: (No selection in input layer "{1}")').format( self.displayName(), self.getParameterValue(self.INPUT))) featToEliminate = [] selFeatIds = inLayer.selectedFeatureIds() output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(inLayer.fields(), inLayer.wkbType(), inLayer.crs()) for aFeat in inLayer.getFeatures(): if aFeat.id() in selFeatIds: # Keep references to the features to eliminate featToEliminate.append(aFeat) else: # write the others to output writer.addFeature(aFeat) # Delete all features to eliminate in processLayer processLayer = output.layer processLayer.startEditing() # ANALYZE if len(featToEliminate) > 0: # Prevent zero division start = 20.00 add = 80.00 / len(featToEliminate) else: start = 100 feedback.setProgress(start) madeProgress = True # We go through the list and see if we find any polygons we can # merge the selected with. If we have no success with some we # merge and then restart the whole story. while madeProgress: # Check if we made any progress madeProgress = False featNotEliminated = [] # Iterate over the polygons to eliminate for i in range(len(featToEliminate)): feat = featToEliminate.pop() geom2Eliminate = feat.geometry() bbox = geom2Eliminate.boundingBox() fit = processLayer.getFeatures( QgsFeatureRequest().setFilterRect( bbox).setSubsetOfAttributes([])) mergeWithFid = None mergeWithGeom = None max = 0 min = -1 selFeat = QgsFeature() # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine( geom2Eliminate.geometry()) engine.prepareGeometry() while fit.nextFeature(selFeat): selGeom = selFeat.geometry() if engine.intersects(selGeom.geometry()): # We have a candidate iGeom = geom2Eliminate.intersection(selGeom) if not iGeom: continue if boundary: selValue = iGeom.length() else: # area. We need a common boundary in # order to merge if 0 < iGeom.length(): selValue = selGeom.area() else: selValue = -1 if -1 != selValue: useThis = True if smallestArea: if -1 == min: min = selValue else: if selValue < min: min = selValue else: useThis = False else: if selValue > max: max = selValue else: useThis = False if useThis: mergeWithFid = selFeat.id() mergeWithGeom = QgsGeometry(selGeom) # End while fit if mergeWithFid is not None: # A successful candidate newGeom = mergeWithGeom.combine(geom2Eliminate) if processLayer.changeGeometry(mergeWithFid, newGeom): madeProgress = True else: raise GeoAlgorithmExecutionException( self. tr('Could not replace geometry of feature with id {0}' ).format(mergeWithFid)) start = start + add feedback.setProgress(start) else: featNotEliminated.append(feat) # End for featToEliminate featToEliminate = featNotEliminated # End while if not processLayer.commitChanges(): raise GeoAlgorithmExecutionException( self.tr('Could not commit changes')) for feature in featNotEliminated: writer.addFeature(feature)
def processAlgorithm(self, feedback): layerPoints = dataobjects.getLayerFromString( self.getParameterValue(self.POINTS)) layerHubs = dataobjects.getLayerFromString( self.getParameterValue(self.HUBS)) 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()) index = vector.spatialindex(layerHubs) distance = QgsDistanceArea() distance.setSourceCrs(layerPoints.crs()) distance.setEllipsoidalMode(True) # Scan source points, find nearest hub, and write to output file features = vector.features(layerPoints) total = 100.0 / len(features) 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, context, feedback): lineLayer = dataobjects.getLayerFromString( self.getParameterValue(self.LINES)) polyLayer = dataobjects.getLayerFromString( self.getParameterValue(self.POLYGONS)) lengthFieldName = self.getParameterValue(self.LEN_FIELD) countFieldName = self.getParameterValue(self.COUNT_FIELD) (idxLength, fieldList) = vector.findOrCreateField(polyLayer, polyLayer.fields(), lengthFieldName) (idxCount, fieldList) = vector.findOrCreateField(polyLayer, fieldList, countFieldName) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fieldList.toList(), polyLayer.wkbType(), polyLayer.crs(), context) spatialIndex = vector.spatialindex(lineLayer) ftLine = QgsFeature() ftPoly = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() distArea = QgsDistanceArea() features = QgsProcessingUtils.getFeatures(polyLayer, context) total = 100.0 / QgsProcessingUtils.featureCount(polyLayer, context) hasIntersections = False for current, ftPoly in enumerate(features): inGeom = ftPoly.geometry() attrs = ftPoly.attributes() count = 0 length = 0 hasIntersections = False lines = spatialIndex.intersects(inGeom.boundingBox()) engine = None if len(lines) > 0: hasIntersections = True # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine(inGeom.geometry()) engine.prepareGeometry() if hasIntersections: request = QgsFeatureRequest().setFilterFids( lines).setSubsetOfAttributes([]) for ftLine in lineLayer.getFeatures(request): tmpGeom = ftLine.geometry() if engine.intersects(tmpGeom.geometry()): outGeom = inGeom.intersection(tmpGeom) length += distArea.measureLength(outGeom) count += 1 outFeat.setGeometry(inGeom) if idxLength == len(attrs): attrs.append(length) else: attrs[idxLength] = length 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, feedback): """ Based on code by Matthew Perry https://gist.github.com/perrygeo/5667173 """ layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_VECTOR)) rasterPath = str(self.getParameterValue(self.INPUT_RASTER)) bandNumber = self.getParameterValue(self.RASTER_BAND) columnPrefix = self.getParameterValue(self.COLUMN_PREFIX) useGlobalExtent = self.getParameterValue(self.GLOBAL_EXTENT) rasterDS = gdal.Open(rasterPath, gdal.GA_ReadOnly) geoTransform = rasterDS.GetGeoTransform() rasterBand = rasterDS.GetRasterBand(bandNumber) noData = rasterBand.GetNoDataValue() cellXSize = abs(geoTransform[1]) cellYSize = abs(geoTransform[5]) rasterXSize = rasterDS.RasterXSize rasterYSize = rasterDS.RasterYSize rasterBBox = QgsRectangle(geoTransform[0], geoTransform[3] - cellYSize * rasterYSize, geoTransform[0] + cellXSize * rasterXSize, geoTransform[3]) rasterGeom = QgsGeometry.fromRect(rasterBBox) crs = osr.SpatialReference() crs.ImportFromProj4(str(layer.crs().toProj4())) if useGlobalExtent: xMin = rasterBBox.xMinimum() xMax = rasterBBox.xMaximum() yMin = rasterBBox.yMinimum() yMax = rasterBBox.yMaximum() (startColumn, startRow) = mapToPixel(xMin, yMax, geoTransform) (endColumn, endRow) = mapToPixel(xMax, yMin, geoTransform) width = endColumn - startColumn height = endRow - startRow srcOffset = (startColumn, startRow, width, height) srcArray = rasterBand.ReadAsArray(*srcOffset) srcArray = srcArray * rasterBand.GetScale() + rasterBand.GetOffset( ) newGeoTransform = ( geoTransform[0] + srcOffset[0] * geoTransform[1], geoTransform[1], 0.0, geoTransform[3] + srcOffset[1] * geoTransform[5], 0.0, geoTransform[5], ) memVectorDriver = ogr.GetDriverByName('Memory') memRasterDriver = gdal.GetDriverByName('MEM') fields = layer.fields() (idxMin, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'min', 21, 6) (idxMax, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'max', 21, 6) (idxSum, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'sum', 21, 6) (idxCount, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'count', 21, 6) (idxMean, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'mean', 21, 6) (idxStd, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'std', 21, 6) (idxUnique, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'unique', 21, 6) (idxRange, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'range', 21, 6) (idxVar, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'var', 21, 6) (idxMedian, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'median', 21, 6) if hasSciPy: (idxMode, fields) = vector.findOrCreateField(layer, fields, columnPrefix + 'mode', 21, 6) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( fields.toList(), layer.wkbType(), layer.crs()) outFeat = QgsFeature() outFeat.initAttributes(len(fields)) outFeat.setFields(fields) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): geom = f.geometry() intersectedGeom = rasterGeom.intersection(geom) ogrGeom = ogr.CreateGeometryFromWkt(intersectedGeom.exportToWkt()) if not useGlobalExtent: bbox = intersectedGeom.boundingBox() xMin = bbox.xMinimum() xMax = bbox.xMaximum() yMin = bbox.yMinimum() yMax = bbox.yMaximum() (startColumn, startRow) = mapToPixel(xMin, yMax, geoTransform) (endColumn, endRow) = mapToPixel(xMax, yMin, geoTransform) width = endColumn - startColumn height = endRow - startRow if width == 0 or height == 0: continue srcOffset = (startColumn, startRow, width, height) srcArray = rasterBand.ReadAsArray(*srcOffset) srcArray = srcArray * rasterBand.GetScale( ) + rasterBand.GetOffset() newGeoTransform = ( geoTransform[0] + srcOffset[0] * geoTransform[1], geoTransform[1], 0.0, geoTransform[3] + srcOffset[1] * geoTransform[5], 0.0, geoTransform[5], ) # Create a temporary vector layer in memory memVDS = memVectorDriver.CreateDataSource('out') memLayer = memVDS.CreateLayer('poly', crs, ogr.wkbPolygon) ft = ogr.Feature(memLayer.GetLayerDefn()) ft.SetGeometry(ogrGeom) memLayer.CreateFeature(ft) ft.Destroy() # Rasterize it rasterizedDS = memRasterDriver.Create('', srcOffset[2], srcOffset[3], 1, gdal.GDT_Byte) rasterizedDS.SetGeoTransform(newGeoTransform) gdal.RasterizeLayer(rasterizedDS, [1], memLayer, burn_values=[1]) rasterizedArray = rasterizedDS.ReadAsArray() srcArray = numpy.nan_to_num(srcArray) masked = numpy.ma.MaskedArray( srcArray, mask=numpy.logical_or(srcArray == noData, numpy.logical_not(rasterizedArray))) outFeat.setGeometry(geom) attrs = f.attributes() v = float(masked.min()) attrs.insert(idxMin, None if numpy.isnan(v) else v) v = float(masked.max()) attrs.insert(idxMax, None if numpy.isnan(v) else v) v = float(masked.sum()) attrs.insert(idxSum, None if numpy.isnan(v) else v) attrs.insert(idxCount, int(masked.count())) v = float(masked.mean()) attrs.insert(idxMean, None if numpy.isnan(v) else v) v = float(masked.std()) attrs.insert(idxStd, None if numpy.isnan(v) else v) attrs.insert(idxUnique, numpy.unique(masked.compressed()).size) v = float(masked.max()) - float(masked.min()) attrs.insert(idxRange, None if numpy.isnan(v) else v) v = float(masked.var()) attrs.insert(idxVar, None if numpy.isnan(v) else v) v = float(numpy.ma.median(masked)) attrs.insert(idxMedian, None if numpy.isnan(v) else v) if hasSciPy: attrs.insert(idxMode, float(mode(masked, axis=None)[0][0])) outFeat.setAttributes(attrs) writer.addFeature(outFeat) memVDS = None rasterizedDS = None feedback.setProgress(int(current * total)) rasterDS = None del writer
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(ConcaveHull.INPUT)) alpha = self.getParameterValue(self.ALPHA) holes = self.getParameterValue(self.HOLES) no_multigeom = self.getParameterValue(self.NO_MULTIGEOMETRY) # Delaunay triangulation from input point layer feedback.setProgressText(self.tr('Creating Delaunay triangles...')) delone_triangles = processing.run("qgis:delaunaytriangulation", layer, None)['OUTPUT'] delaunay_layer = dataobjects.getLayerFromString(delone_triangles) # Get max edge length from Delaunay triangles feedback.setProgressText(self.tr('Computing edges max length...')) features = delaunay_layer.getFeatures() if len(features) == 0: raise GeoAlgorithmExecutionException( self.tr('No Delaunay triangles created.')) counter = 50. / len(features) lengths = [] edges = {} for feat in features: line = feat.geometry().asPolygon()[0] for i in range(len(line) - 1): lengths.append(sqrt(line[i].sqrDist(line[i + 1]))) edges[feat.id()] = max(lengths[-3:]) feedback.setProgress(feat.id() * counter) max_length = max(lengths) # Get features with longest edge longer than alpha*max_length feedback.setProgressText(self.tr('Removing features...')) counter = 50. / len(edges) i = 0 ids = [] for id, max_len in list(edges.items()): if max_len > alpha * max_length: ids.append(id) feedback.setProgress(50 + i * counter) i += 1 # Remove features delaunay_layer.selectByIds(ids) delaunay_layer.startEditing() delaunay_layer.deleteSelectedFeatures() delaunay_layer.commitChanges() # Dissolve all Delaunay triangles feedback.setProgressText(self.tr('Dissolving Delaunay triangles...')) dissolved = processing.run("qgis:dissolve", delaunay_layer, True, None, None)['OUTPUT'] dissolved_layer = dataobjects.getLayerFromString(dissolved) # Save result feedback.setProgressText(self.tr('Saving data...')) feat = QgsFeature() dissolved_layer.getFeatures( QgsFeatureRequest().setFilterFid(0)).nextFeature(feat) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields().toList(), QgsWkbTypes.Polygon, layer.crs()) geom = feat.geometry() if no_multigeom and geom.isMultipart(): # Only singlepart geometries are allowed geom_list = geom.asMultiPolygon() for single_geom_list in geom_list: single_feature = QgsFeature() single_geom = QgsGeometry.fromPolygon(single_geom_list) if not holes: # Delete holes deleted = True while deleted: deleted = single_geom.deleteRing(1) single_feature.setGeometry(single_geom) writer.addFeature(single_feature) else: # Multipart geometries are allowed if not holes: # Delete holes deleted = True while deleted: deleted = geom.deleteRing(1) writer.addFeature(feat) del writer
def processAlgorithm(self, feedback): filename = self.getParameterValue(self.INPUT) layer = dataobjects.getLayerFromString(filename) field = self.getParameterValue(self.FIELD) method = self.getParameterValue(self.METHOD) index = layer.fields().lookupField(field) features = vector.features(layer) featureCount = len(features) unique = vector.getUniqueValues(layer, index) 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().toList(), layer.wkbType(), layer.crs()) selran = [] current = 0 total = 100.0 / (featureCount * len(unique)) features = vector.features(layer) if not len(unique) == featureCount: for classValue in unique: classFeatures = [] for i, feature in enumerate(features): attrs = feature.attributes() if attrs[index] == classValue: classFeatures.append(i) current += 1 feedback.setProgress(int(current * total)) if method == 1: selValue = int(round(value * len(classFeatures), 0)) else: selValue = value if selValue >= len(classFeatures): selFeat = classFeatures else: selFeat = random.sample(classFeatures, selValue) selran.extend(selFeat) else: selran = list(range(featureCount)) features = vector.features(layer) total = 100.0 / len(features) for (i, feat) in enumerate(features): if i in selran: writer.addFeature(feat) feedback.setProgress(int(i * total)) del writer
def processAlgorithm(self, feedback): target = dataobjects.getLayerFromString( self.getParameterValue(self.TARGET)) join = dataobjects.getLayerFromString(self.getParameterValue( self.JOIN)) predicates = self.getParameterValue(self.PREDICATE) precision = self.getParameterValue(self.PRECISION) summary = self.getParameterValue(self.SUMMARY) == 1 keep = self.getParameterValue(self.KEEP) == 1 sumList = self.getParameterValue(self.STATS).lower().split(',') targetFields = target.fields() joinFields = join.fields() fieldList = QgsFields() if not summary: joinFields = vector.testForUniqueness(targetFields, joinFields) seq = list(range(len(targetFields) + len(joinFields))) targetFields.extend(joinFields) targetFields = dict(list(zip(seq, targetFields))) else: numFields = {} for j in range(len(joinFields)): if joinFields[j].type() in [ QVariant.Int, QVariant.Double, QVariant.LongLong, QVariant.UInt, QVariant.ULongLong ]: numFields[j] = [] for i in sumList: field = QgsField(i + str(joinFields[j].name()), QVariant.Double, '', 24, 16) fieldList.append(field) field = QgsField('count', QVariant.Double, '', 24, 16) fieldList.append(field) joinFields = vector.testForUniqueness(targetFields, fieldList) targetFields.extend(fieldList) seq = list(range(len(targetFields))) targetFields = dict(list(zip(seq, targetFields))) fields = QgsFields() for f in list(targetFields.values()): fields.append(f) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, target.wkbType(), target.crs()) outFeat = QgsFeature() inFeatB = QgsFeature() inGeom = QgsGeometry() index = vector.spatialindex(join) mapP2 = dict() features = vector.features(join) for f in features: mapP2[f.id()] = QgsFeature(f) features = vector.features(target) total = 100.0 / len(features) for c, f in enumerate(features): atMap1 = f.attributes() outFeat.setGeometry(f.geometry()) inGeom = vector.snapToPrecision(f.geometry(), precision) none = True joinList = [] if inGeom.type() == QgsWkbTypes.PointGeometry: bbox = inGeom.buffer(10, 2).boundingBox() else: bbox = inGeom.boundingBox() bufferedBox = vector.bufferedBoundingBox(bbox, 0.51 * precision) joinList = index.intersects(bufferedBox) if len(joinList) > 0: count = 0 for i in joinList: inFeatB = mapP2[i] inGeomB = vector.snapToPrecision(inFeatB.geometry(), precision) res = False for predicate in predicates: res = getattr(inGeom, predicate)(inGeomB) if res: break if res: count = count + 1 none = False atMap2 = inFeatB.attributes() if not summary: atMap = atMap1 atMap2 = atMap2 atMap.extend(atMap2) atMap = dict(list(zip(seq, atMap))) break else: for j in list(numFields.keys()): numFields[j].append(atMap2[j]) if summary and not none: atMap = atMap1 for j in list(numFields.keys()): for k in sumList: if k == 'sum': atMap.append( sum(self._filterNull(numFields[j]))) elif k == 'mean': try: nn_count = sum(1 for _ in self._filterNull( numFields[j])) atMap.append( sum(self._filterNull(numFields[j])) / nn_count) except ZeroDivisionError: atMap.append(NULL) elif k == 'min': try: atMap.append( min(self._filterNull(numFields[j]))) except ValueError: atMap.append(NULL) elif k == 'median': atMap.append(self._median(numFields[j])) else: try: atMap.append( max(self._filterNull(numFields[j]))) except ValueError: atMap.append(NULL) numFields[j] = [] atMap.append(count) atMap = dict(list(zip(seq, atMap))) if none: outFeat.setAttributes(atMap1) else: outFeat.setAttributes(list(atMap.values())) if keep: writer.addFeature(outFeat) else: if not none: writer.addFeature(outFeat) feedback.setProgress(int(c * total)) del writer
def processAlgorithm(self, feedback): layerA = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT)) layerB = dataobjects.getLayerFromString( self.getParameterValue(self.OVERLAY)) geomType = QgsWkbTypes.multiType(layerA.wkbType()) fields = vector.combineVectorFields(layerA, layerB) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, geomType, layerA.crs()) featB = QgsFeature() outFeat = QgsFeature() indexA = vector.spatialindex(layerB) indexB = vector.spatialindex(layerA) featuresA = vector.features(layerA) featuresB = vector.features(layerB) total = 100.0 / (len(featuresA) * len(featuresB)) count = 0 for featA in featuresA: geom = featA.geometry() diffGeom = QgsGeometry(geom) attrs = featA.attributes() intersects = indexA.intersects(geom.boundingBox()) request = QgsFeatureRequest().setFilterFids( intersects).setSubsetOfAttributes([]) for featB in layerB.getFeatures(request): tmpGeom = featB.geometry() if diffGeom.intersects(tmpGeom): diffGeom = QgsGeometry(diffGeom.difference(tmpGeom)) try: outFeat.setGeometry(diffGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) continue count += 1 feedback.setProgress(int(count * total)) length = len(layerA.fields()) for featA in featuresB: geom = featA.geometry() diffGeom = QgsGeometry(geom) attrs = featA.attributes() attrs = [NULL] * length + attrs intersects = indexB.intersects(geom.boundingBox()) request = QgsFeatureRequest().setFilterFids( intersects).setSubsetOfAttributes([]) for featB in layerA.getFeatures(request): tmpGeom = featB.geometry() if diffGeom.intersects(tmpGeom): diffGeom = QgsGeometry(diffGeom.difference(tmpGeom)) try: outFeat.setGeometry(diffGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) continue count += 1 feedback.setProgress(int(count * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.POINTS)) 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 = [ QgsField('MEAN_X', QVariant.Double, '', 24, 15), QgsField('MEAN_Y', QVariant.Double, '', 24, 15), QgsField('UID', QVariant.String, '', 255) ] writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fieldList, QgsWkbTypes.Point, layer.crs()) features = vector.features(layer) total = 100.0 / len(features) 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
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT)) method = self.getParameterValue(self.METHOD) geometryType = layer.geometryType() fields = layer.fields() export_z = False export_m = False if geometryType == QgsWkbTypes.PolygonGeometry: areaName = vector.createUniqueFieldName('area', fields) fields.append(QgsField(areaName, QVariant.Double)) perimeterName = vector.createUniqueFieldName('perimeter', fields) fields.append(QgsField(perimeterName, QVariant.Double)) elif geometryType == QgsWkbTypes.LineGeometry: lengthName = vector.createUniqueFieldName('length', fields) fields.append(QgsField(lengthName, QVariant.Double)) else: xName = vector.createUniqueFieldName('xcoord', fields) fields.append(QgsField(xName, QVariant.Double)) yName = vector.createUniqueFieldName('ycoord', fields) fields.append(QgsField(yName, QVariant.Double)) if QgsWkbTypes.hasZ(layer.wkbType()): export_z = True zName = vector.createUniqueFieldName('zcoord', fields) fields.append(QgsField(zName, QVariant.Double)) if QgsWkbTypes.hasM(layer.wkbType()): export_m = True zName = vector.createUniqueFieldName('mvalue', fields) fields.append(QgsField(zName, QVariant.Double)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields.toList(), layer.wkbType(), layer.crs()) ellips = None crs = None coordTransform = None # Calculate with: # 0 - layer CRS # 1 - project CRS # 2 - ellipsoidal if method == 2: ellips = QgsProject.instance().ellipsoid() crs = layer.crs().srsid() elif method == 1: mapCRS = iface.mapCanvas().mapSettings().destinationCrs() layCRS = layer.crs() coordTransform = QgsCoordinateTransform(layCRS, mapCRS) outFeat = QgsFeature() outFeat.initAttributes(len(fields)) outFeat.setFields(fields) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): inGeom = f.geometry() if method == 1: inGeom.transform(coordTransform) (attr1, attr2) = vector.simpleMeasure(inGeom, method, ellips, crs) outFeat.setGeometry(inGeom) attrs = f.attributes() attrs.append(attr1) if attr2 is not None: attrs.append(attr2) # add point z/m if export_z: attrs.append(inGeom.geometry().z()) if export_m: attrs.append(inGeom.geometry().m()) outFeat.setAttributes(attrs) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.VECTOR)) fieldName = self.getParameterValue(self.FIELD) minDistance = float(self.getParameterValue(self.MIN_DISTANCE)) strategy = self.getParameterValue(self.STRATEGY) fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QgsWkbTypes.Point, layer.crs()) da = QgsDistanceArea() features = vector.features(layer) for current, f in enumerate(features): fGeom = f.geometry() bbox = fGeom.boundingBox() if strategy == 0: pointCount = int(f[fieldName]) else: pointCount = int(round(f[fieldName] * da.measureArea(fGeom))) if strategy == 0 and pointCount == 0: continue index = QgsSpatialIndex() points = dict() nPoints = 0 nIterations = 0 maxIterations = pointCount * 200 total = 100.0 / pointCount random.seed() while nIterations < maxIterations and nPoints < pointCount: rx = bbox.xMinimum() + bbox.width() * random.random() ry = bbox.yMinimum() + bbox.height() * random.random() pnt = QgsPoint(rx, ry) geom = QgsGeometry.fromPoint(pnt) if geom.within(fGeom) and \ vector.checkMinDistance(pnt, index, minDistance, points): f = QgsFeature(nPoints) f.initAttributes(1) f.setFields(fields) f.setAttribute('id', nPoints) f.setGeometry(geom) writer.addFeature(f) index.insertFeature(f) points[nPoints] = pnt nPoints += 1 feedback.setProgress(int(nPoints * total)) nIterations += 1 if nPoints < pointCount: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Can not generate requested number of random ' 'points. Maximum number of attempts exceeded.')) feedback.setProgress(0) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) 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()) 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 = vector.features(layer) total = 100.0 / len(features) 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, context, feedback): expression = self.getParameterValue(self.EXPRESSION) layersValue = self.getParameterValue(self.LAYERS) layersDict = {} if layersValue: layers = [ dataobjects.getLayerFromString(f) for f in layersValue.split(";") ] layersDict = { os.path.basename(lyr.source().split(".")[0]): lyr for lyr in layers } for lyr in QgsProcessingUtils.compatibleRasterLayers( QgsProject.instance()): name = lyr.name() if (name + "@") in expression: layersDict[name] = lyr entries = [] for name, lyr in layersDict.items(): for n in range(lyr.bandCount()): entry = QgsRasterCalculatorEntry() entry.ref = '{:s}@{:d}'.format(name, n + 1) entry.raster = lyr entry.bandNumber = n + 1 entries.append(entry) output = self.getOutputValue(self.OUTPUT) extentValue = self.getParameterValue(self.EXTENT) if extentValue: extent = extentValue.split(',') bbox = QgsRectangle(float(extent[0]), float(extent[2]), float(extent[1]), float(extent[3])) else: if layersDict: bbox = list(layersDict.values())[0].extent() for lyr in layersDict.values(): bbox.combineExtentWith(lyr.extent()) else: raise GeoAlgorithmExecutionException( self.tr("No layers selected")) def _cellsize(layer): return (layer.extent().xMaximum() - layer.extent().xMinimum()) / layer.width() cellsize = self.getParameterValue(self.CELLSIZE) or min( [_cellsize(lyr) for lyr in layersDict.values()]) width = math.floor((bbox.xMaximum() - bbox.xMinimum()) / cellsize) height = math.floor((bbox.yMaximum() - bbox.yMinimum()) / cellsize) driverName = GdalUtils.getFormatShortNameFromFilename(output) calc = QgsRasterCalculator(expression, output, driverName, bbox, width, height, entries) res = calc.processCalculation() if res == QgsRasterCalculator.ParserError: raise GeoAlgorithmExecutionException( self.tr("Error parsing formula"))
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_VECTOR)) startPoints = dataobjects.getLayerFromString( self.getParameterValue(self.START_POINTS)) strategy = self.getParameterValue(self.STRATEGY) travelCost = self.getParameterValue(self.TRAVEL_COST) directionFieldName = self.getParameterValue(self.DIRECTION_FIELD) forwardValue = self.getParameterValue(self.VALUE_FORWARD) backwardValue = self.getParameterValue(self.VALUE_BACKWARD) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) speedFieldName = self.getParameterValue(self.SPEED_FIELD) defaultSpeed = self.getParameterValue(self.DEFAULT_SPEED) tolerance = self.getParameterValue(self.TOLERANCE) fields = QgsFields() fields.append(QgsField('type', QVariant.String, '', 254, 0)) fields.append(QgsField('start', QVariant.String, '', 254, 0)) feat = QgsFeature() feat.setFields(fields) writerPoints = self.getOutputFromName( self.OUTPUT_POINTS).getVectorWriter(fields, QgsWkbTypes.MultiPoint, layer.crs()) writerPolygons = self.getOutputFromName( self.OUTPUT_POLYGON).getVectorWriter(fields, QgsWkbTypes.Polygon, layer.crs()) directionField = -1 if directionFieldName is not None: directionField = layer.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName is not None: speedField = layer.fields().lookupField(speedFieldName) director = QgsVectorLayerDirector(layer, directionField, forwardValue, backwardValue, bothValue, defaultDirection) distUnit = iface.mapCanvas().mapSettings().destinationCrs().mapUnits() multiplier = QgsUnitTypes.fromUnitToUnitFactor( distUnit, QgsUnitTypes.DistanceMeters) if strategy == 0: strategy = QgsNetworkDistanceStrategy() else: strategy = QgsNetworkSpeedStrategy(speedField, defaultSpeed, multiplier * 1000.0 / 3600.0) director.addStrategy(strategy) builder = QgsGraphBuilder( iface.mapCanvas().mapSettings().destinationCrs(), True, tolerance) feedback.pushInfo(self.tr('Loading start points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) features = vector.features(startPoints, request) points = [] for f in features: points.append(f.geometry().asPoint()) feedback.pushInfo(self.tr('Building graph...')) snappedPoints = director.makeGraph(builder, points) feedback.pushInfo(self.tr('Calculating service areas...')) graph = builder.graph() vertices = [] upperBoundary = [] lowerBoundary = [] total = 100.0 / len(snappedPoints) for i, p in enumerate(snappedPoints): idxStart = graph.findVertex(snappedPoints[i]) origPoint = points[i].toString() tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0) for j, v in enumerate(cost): if v > travelCost and tree[j] != -1: vertexId = graph.edge(tree[j]).outVertex() if cost[vertexId] <= travelCost: vertices.append(j) for j in vertices: upperBoundary.append( graph.vertex(graph.edge(tree[j]).inVertex()).point()) lowerBoundary.append( graph.vertex(graph.edge(tree[j]).outVertex()).point()) geomUpper = QgsGeometry.fromMultiPoint(upperBoundary) geomLower = QgsGeometry.fromMultiPoint(lowerBoundary) feat.setGeometry(geomUpper) feat['type'] = 'upper' feat['start'] = origPoint writerPoints.addFeature(feat) feat.setGeometry(geomLower) feat['type'] = 'lower' feat['start'] = origPoint writerPoints.addFeature(feat) upperBoundary.append(origPoint) lowerBoundary.append(origPoint) geomUpper = QgsGeometry.fromMultiPoint(upperBoundary) geomLower = QgsGeometry.fromMultiPoint(lowerBoundary) geom = geomUpper.convexHull() feat.setGeometry(geom) feat['type'] = 'upper' feat['start'] = origPoint writerPolygons.addFeature(feat) geom = geomLower.convexHull() feat.setGeometry(geom) feat['type'] = 'lower' feat['start'] = origPoint writerPolygons.addFeature(feat) vertices[:] = [] upperBoundary[:] = [] lowerBoundary[:] = [] feedback.setProgress(int(i * total)) del writerPoints del writerPolygons
def processAlgorithm(self, feedback): connection = self.getParameterValue(self.DATABASE) db = postgis.GeoDB.from_name(connection) schema = self.getParameterValue(self.SCHEMA) overwrite = self.getParameterValue(self.OVERWRITE) createIndex = self.getParameterValue(self.CREATEINDEX) convertLowerCase = self.getParameterValue(self.LOWERCASE_NAMES) dropStringLength = self.getParameterValue(self.DROP_STRING_LENGTH) forceSinglePart = self.getParameterValue(self.FORCE_SINGLEPART) primaryKeyField = self.getParameterValue(self.PRIMARY_KEY) or 'id' encoding = self.getParameterValue(self.ENCODING) layerUri = self.getParameterValue(self.INPUT) layer = dataobjects.getLayerFromString(layerUri) table = self.getParameterValue(self.TABLENAME) if table: table.strip() if not table or table == '': table = layer.name() table = table.replace('.', '_') table = table.replace(' ', '').lower()[0:62] providerName = 'postgres' geomColumn = self.getParameterValue(self.GEOMETRY_COLUMN) if not geomColumn: geomColumn = 'the_geom' options = {} if overwrite: options['overwrite'] = True if convertLowerCase: options['lowercaseFieldNames'] = True geomColumn = geomColumn.lower() if dropStringLength: options['dropStringConstraints'] = True if forceSinglePart: options['forceSinglePartGeometryType'] = True # Clear geometry column for non-geometry tables if not layer.hasGeometryType(): geomColumn = None uri = db.uri uri.setDataSource(schema, table, geomColumn, '', primaryKeyField) if encoding: layer.setProviderEncoding(encoding) (ret, errMsg) = QgsVectorLayerImport.importLayer( layer, uri.uri(), providerName, self.crs, False, False, options, ) if ret != 0: raise GeoAlgorithmExecutionException( self.tr('Error importing to PostGIS\n{0}').format(errMsg)) if geomColumn and createIndex: db.create_spatial_index(table, schema, geomColumn) db.vacuum_analyze(table, schema)
def ogrConnectionString(uri): """Generates OGR connection sting from layer source """ ogrstr = None layer = dataobjects.getLayerFromString(uri, False) if layer is None: return '"' + uri + '"' provider = layer.dataProvider().name() if provider == 'spatialite': # dbname='/geodata/osm_ch.sqlite' table="places" (Geometry) sql= regex = re.compile("dbname='(.+)'") r = regex.search(str(layer.source())) ogrstr = r.groups()[0] elif provider == 'postgres': # dbname='ktryjh_iuuqef' host=spacialdb.com port=9999 # user='******' password='******' sslmode=disable # key='gid' estimatedmetadata=true srid=4326 type=MULTIPOLYGON # table="t4" (geom) sql= dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri()) conninfo = dsUri.connectionInfo() conn = None ok = False while not conn: try: conn = psycopg2.connect(dsUri.connectionInfo()) except psycopg2.OperationalError: (ok, user, passwd) = QgsCredentials.instance().get(conninfo, dsUri.username(), dsUri.password()) if not ok: break dsUri.setUsername(user) dsUri.setPassword(passwd) if not conn: raise RuntimeError('Could not connect to PostgreSQL database - check connection info') if ok: QgsCredentials.instance().put(conninfo, user, passwd) ogrstr = "PG:%s" % dsUri.connectionInfo() elif provider == "oracle": # OCI:user/password@host:port/service:table dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri()) ogrstr = "OCI:" if dsUri.username() != "": ogrstr += dsUri.username() if dsUri.password() != "": ogrstr += "/" + dsUri.password() delim = "@" if dsUri.host() != "": ogrstr += delim + dsUri.host() delim = "" if dsUri.port() != "" and dsUri.port() != '1521': ogrstr += ":" + dsUri.port() ogrstr += "/" if dsUri.database() != "": ogrstr += dsUri.database() elif dsUri.database() != "": ogrstr += delim + dsUri.database() if ogrstr == "OCI:": raise RuntimeError('Invalid oracle data source - check connection info') ogrstr += ":" if dsUri.schema() != "": ogrstr += dsUri.schema() + "." ogrstr += dsUri.table() else: ogrstr = str(layer.source()).split("|")[0] return '"' + ogrstr + '"'
def processAlgorithm(self, feedback): radius = self.getParameterValue(self.DISTANCE) horizontal = self.getParameterValue(self.HORIZONTAL) output = self.getOutputFromName(self.OUTPUT_LAYER) layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_LAYER)) writer = output.getVectorWriter(layer.fields(), layer.wkbType(), layer.crs()) features = vector.features(layer) total = 100.0 / len(features) duplicates = dict() for current, f in enumerate(features): wkt = f.geometry().exportToWkt() if wkt not in duplicates: duplicates[wkt] = [f.id()] else: duplicates[wkt].extend([f.id()]) feedback.setProgress(int(current * total)) current = 0 total = 100.0 / len(duplicates) feedback.setProgress(0) fullPerimeter = 2 * math.pi for (geom, fids) in list(duplicates.items()): count = len(fids) if count == 1: f = next( layer.getFeatures(QgsFeatureRequest().setFilterFid( fids[0]))) writer.addFeature(f) else: angleStep = fullPerimeter / count if count == 2 and horizontal: currentAngle = math.pi / 2 else: currentAngle = 0 old_point = QgsGeometry.fromWkt(geom).asPoint() request = QgsFeatureRequest().setFilterFids(fids).setFlags( QgsFeatureRequest.NoGeometry) for f in layer.getFeatures(request): sinusCurrentAngle = math.sin(currentAngle) cosinusCurrentAngle = math.cos(currentAngle) dx = radius * sinusCurrentAngle dy = radius * cosinusCurrentAngle new_point = QgsPoint(old_point.x() + dx, old_point.y() + dy) out_feature = QgsFeature() out_feature.setGeometry(QgsGeometry.fromPoint(new_point)) out_feature.setAttributes(f.attributes()) writer.addFeature(out_feature) currentAngle += angleStep current += 1 feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, feedback): layerA = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_A)) layerB = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_B)) sameLayer = self.getParameterValue( self.INPUT_A) == self.getParameterValue(self.INPUT_B) fieldList = layerA.fields() writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fieldList, QgsWkbTypes.LineString, layerA.crs()) spatialIndex = vector.spatialindex(layerB) outFeat = QgsFeature() features = vector.features(layerA) total = 100.0 / float(len(features)) for current, inFeatA in enumerate(features): inGeom = inFeatA.geometry() attrsA = inFeatA.attributes() outFeat.setAttributes(attrsA) inLines = [inGeom] lines = spatialIndex.intersects(inGeom.boundingBox()) engine = None if len(lines) > 0: # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine(inGeom.geometry()) engine.prepareGeometry() if len(lines) > 0: # hasIntersections splittingLines = [] request = QgsFeatureRequest().setFilterFids( lines).setSubsetOfAttributes([]) for inFeatB in layerB.getFeatures(request): # check if trying to self-intersect if sameLayer: if inFeatA.id() == inFeatB.id(): continue splitGeom = inFeatB.geometry() if engine.intersects(splitGeom.geometry()): splittingLines.append(splitGeom) if len(splittingLines) > 0: for splitGeom in splittingLines: splitterPList = vector.extractPoints(splitGeom) outLines = [] split_geom_engine = QgsGeometry.createGeometryEngine( splitGeom.geometry()) split_geom_engine.prepareGeometry() while len(inLines) > 0: inGeom = inLines.pop() inPoints = vector.extractPoints(inGeom) if split_geom_engine.intersects(inGeom.geometry()): try: result, newGeometries, topoTestPoints = inGeom.splitGeometry( splitterPList, False) except: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self. tr('Geometry exception while splitting' )) result = 1 # splitGeometry: If there are several intersections # between geometry and splitLine, only the first one is considered. if result == 0: # split occurred if inPoints == vector.extractPoints( inGeom): # bug in splitGeometry: sometimes it returns 0 but # the geometry is unchanged outLines.append(inGeom) else: inLines.append(inGeom) for aNewGeom in newGeometries: inLines.append(aNewGeom) else: outLines.append(inGeom) else: outLines.append(inGeom) inLines = outLines for aLine in inLines: if len(aLine.asPolyline()) > 2 or \ (len(aLine.asPolyline()) == 2 and aLine.asPolyline()[0] != aLine.asPolyline()[1]): # sometimes splitting results in lines of zero length outFeat.setGeometry(aLine) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def setLayer(self, layer): if isinstance(layer, str): layer = dataobjects.getLayerFromString(_resolveLayers(layer)) self.widget.setLayer(layer)
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.VECTOR)) pointCount = float(self.getParameterValue(self.POINT_NUMBER)) minDistance = float(self.getParameterValue(self.MIN_DISTANCE)) fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QgsWkbTypes.Point, layer.crs()) nPoints = 0 nIterations = 0 maxIterations = pointCount * 200 featureCount = layer.featureCount() total = 100.0 / pointCount index = QgsSpatialIndex() points = dict() da = QgsDistanceArea() request = QgsFeatureRequest() random.seed() while nIterations < maxIterations and nPoints < pointCount: # pick random feature fid = random.randint(0, featureCount - 1) f = next( layer.getFeatures( request.setFilterFid(fid).setSubsetOfAttributes([]))) fGeom = f.geometry() if fGeom.isMultipart(): lines = fGeom.asMultiPolyline() # pick random line lineId = random.randint(0, len(lines) - 1) vertices = lines[lineId] else: vertices = fGeom.asPolyline() # pick random segment if len(vertices) == 2: vid = 0 else: vid = random.randint(0, len(vertices) - 2) startPoint = vertices[vid] endPoint = vertices[vid + 1] length = da.measureLine(startPoint, endPoint) dist = length * random.random() if dist > minDistance: d = dist / (length - dist) rx = (startPoint.x() + d * endPoint.x()) / (1 + d) ry = (startPoint.y() + d * endPoint.y()) / (1 + d) # generate random point pnt = QgsPoint(rx, ry) geom = QgsGeometry.fromPoint(pnt) if vector.checkMinDistance(pnt, index, minDistance, points): f = QgsFeature(nPoints) f.initAttributes(1) f.setFields(fields) f.setAttribute('id', nPoints) f.setGeometry(geom) writer.addFeature(f) index.insertFeature(f) points[nPoints] = pnt nPoints += 1 feedback.setProgress(int(nPoints * total)) nIterations += 1 if nPoints < pointCount: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Can not generate requested number of random points. ' 'Maximum number of attempts exceeded.')) del writer
##Table=group ##Input=vector ##Fields=Field Input ##Frequency=output table from processing.tools.vector import TableWriter from collections import defaultdict from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException from processing.tools import dataobjects layer = dataobjects.getLayerFromString(Input) inputFields = layer.fields() fieldIdxs = [] fields = Fields.split(',') for f in fields: idx = inputFields.indexFromName(f) if idx == -1: raise GeoAlgorithmExecutionException('Field not found:' + f) fieldIdxs.append(idx) writer = TableWriter(Frequency, None, fields + ['FREQ']) counts = {} feats = processing.features(layer) nFeats = len(feats) counts = defaultdict(int) for i, feat in enumerate(feats): feedback.setProgress(int(100 * i / nFeats)) attrs = feat.attributes() clazz = tuple([attrs[i] for i in fieldIdxs]) counts[clazz] += 1
def setLayer(self, layer): if isinstance(layer, str): layer = dataobjects.getLayerFromString(_resolveLayers(layer)) self._layer = layer self.refreshItems()
def processAlgorithm(self, feedback): layer = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT_VECTOR)) 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.toList(), QgsWkbTypes.Point, layer.crs()) outFeature = QgsFeature() outFeature.setFields(fields) self.fid = 0 self.lineId = 0 self.pointId = 0 features = vector.features(layer) total = 100.0 / len(features) 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, feedback): vlayerA = dataobjects.getLayerFromString( self.getParameterValue(Union.INPUT)) vlayerB = dataobjects.getLayerFromString( self.getParameterValue(Union.INPUT2)) geomType = vlayerA.wkbType() fields = vector.combineVectorFields(vlayerA, vlayerB) writer = self.getOutputFromName(Union.OUTPUT).getVectorWriter( fields, geomType, vlayerA.crs()) inFeatA = QgsFeature() inFeatB = QgsFeature() outFeat = QgsFeature() indexA = vector.spatialindex(vlayerB) indexB = vector.spatialindex(vlayerA) count = 0 nElement = 0 featuresA = vector.features(vlayerA) nFeat = len(featuresA) for inFeatA in featuresA: feedback.setProgress(nElement / float(nFeat) * 50) nElement += 1 lstIntersectingB = [] geom = inFeatA.geometry() atMapA = inFeatA.attributes() intersects = indexA.intersects(geom.boundingBox()) if len(intersects) < 1: try: outFeat.setGeometry(geom) outFeat.setAttributes(atMapA) writer.addFeature(outFeat) except: # This really shouldn't happen, as we haven't # edited the input geom at all ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) else: request = QgsFeatureRequest().setFilterFids(intersects) engine = QgsGeometry.createGeometryEngine(geom.geometry()) engine.prepareGeometry() for inFeatB in vlayerB.getFeatures(request): count += 1 atMapB = inFeatB.attributes() tmpGeom = inFeatB.geometry() if engine.intersects(tmpGeom.geometry()): int_geom = geom.intersection(tmpGeom) lstIntersectingB.append(tmpGeom) if not int_geom: # There was a problem creating the intersection ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('GEOS geoprocessing error: One or more input features have invalid geometry.' )) int_geom = QgsGeometry() else: int_geom = QgsGeometry(int_geom) if int_geom.wkbType( ) == QgsWkbTypes.Unknown or QgsWkbTypes.flatType( int_geom.geometry().wkbType( )) == QgsWkbTypes.GeometryCollection: # Intersection produced different geomety types temp_list = int_geom.asGeometryCollection() for i in temp_list: if i.type() == geom.type(): int_geom = QgsGeometry(i) try: outFeat.setGeometry(int_geom) outFeat.setAttributes(atMapA + atMapB) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) else: # Geometry list: prevents writing error # in geometries of different types # produced by the intersection # fix #3549 if int_geom.wkbType() in wkbTypeGroups[ wkbTypeGroups[int_geom.wkbType()]]: try: outFeat.setGeometry(int_geom) outFeat.setAttributes(atMapA + atMapB) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) # the remaining bit of inFeatA's geometry # if there is nothing left, this will just silently fail and we're good diff_geom = QgsGeometry(geom) if len(lstIntersectingB) != 0: intB = QgsGeometry.unaryUnion(lstIntersectingB) diff_geom = diff_geom.difference(intB) if diff_geom.wkbType() == 0 or QgsWkbTypes.flatType( diff_geom.geometry().wkbType( )) == QgsWkbTypes.GeometryCollection: temp_list = diff_geom.asGeometryCollection() for i in temp_list: if i.type() == geom.type(): diff_geom = QgsGeometry(i) try: outFeat.setGeometry(diff_geom) outFeat.setAttributes(atMapA) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) length = len(vlayerA.fields()) atMapA = [None] * length featuresA = vector.features(vlayerB) nFeat = len(featuresA) for inFeatA in featuresA: feedback.setProgress(nElement / float(nFeat) * 100) add = False geom = inFeatA.geometry() diff_geom = QgsGeometry(geom) atMap = [None] * length atMap.extend(inFeatA.attributes()) intersects = indexB.intersects(geom.boundingBox()) if len(intersects) < 1: try: outFeat.setGeometry(geom) outFeat.setAttributes(atMap) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) else: request = QgsFeatureRequest().setFilterFids(intersects) # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine(diff_geom.geometry()) engine.prepareGeometry() for inFeatB in vlayerA.getFeatures(request): atMapB = inFeatB.attributes() tmpGeom = inFeatB.geometry() if engine.intersects(tmpGeom.geometry()): add = True diff_geom = QgsGeometry(diff_geom.difference(tmpGeom)) else: try: # Ihis only happens if the bounding box # intersects, but the geometry doesn't outFeat.setGeometry(diff_geom) outFeat.setAttributes(atMap) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) if add: try: outFeat.setGeometry(diff_geom) outFeat.setAttributes(atMap) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) nElement += 1 del writer