def getSafeExportedLayers(self): '''Returns not the value entered by the user, but a string with semicolon-separated filenames which contains the data of the selected layers, but saved in a standard format (currently shapefiles for vector layers and GeoTiff for raster) so that they can be opened by most external applications. If there is a selection and QGIS is configured to use just the selection, if exports the layer even if it is already in a suitable format. Works only if the layer represented by the parameter value is currently loaded in QGIS. Otherwise, it will not perform any export and return the current value string. If the current value represents a layer in a suitable format, it does no export at all and returns that value. Currently, it works just for vector layer. In the case of raster layers, it returns the parameter value. The layers are exported just the first time the method is called. The method can be called several times and it will always return the same string, performing the export only the first time.''' if self.exported: return self.exported self.exported = self.value layers = self.value.split(";") if layers == None or len(layers) == 0: return self.value if self.datatype == ParameterMultipleInput.TYPE_RASTER: for layerfile in layers: layer = dataobjects.getObjectFromUri(layerfile, False) if layer: filename = dataobjects.exportRasterLayer(layer) self.exported = self.exported.replace(layerfile, filename) return self.exported else: for layerfile in layers: layer = dataobjects.getObjectFromUri(layerfile, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exported = self.exported.replace(layerfile, filename) return self.exported
def processAlgorithm(self, progress): polyLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.POLYGONS)) pointLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.POINTS)) fieldName = self.getParameterValue(self.FIELD) classFieldName = self.getParameterValue(self.CLASSFIELD) polyProvider = polyLayer.dataProvider() fields = polyProvider.fields() fields.append(QgsField(fieldName, QVariant.Int)) classFieldIndex = pointLayer.fieldNameIndex(classFieldName) (idxCount, fieldList) = vector.findOrCreateField(polyLayer, polyLayer.pendingFields(), fieldName) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields.toList(), polyProvider.geometryType(), polyProvider.crs()) spatialIndex = vector.spatialindex(pointLayer) ftPoint = QgsFeature() outFeat = QgsFeature() geom = QgsGeometry() current = 0 hasIntersections = False features = vector.features(polyLayer) total = 100.0 / float(len(features)) for ftPoly in features: geom = ftPoly.geometry() attrs = ftPoly.attributes() classes = [] hasIntersections = False points = spatialIndex.intersects(geom.boundingBox()) if len(points) > 0: hasIntersections = True if hasIntersections: for i in points: request = QgsFeatureRequest().setFilterFid(i) ftPoint = pointLayer.getFeatures(request).next() tmpGeom = QgsGeometry(ftPoint.geometry()) if geom.contains(tmpGeom): clazz = ftPoint.attributes()[classFieldIndex] if clazz not in classes: classes.append(clazz) outFeat.setGeometry(geom) if idxCount == len(attrs): attrs.append(len(classes)) else: attrs[idxCount] = len(classes) outFeat.setAttributes(attrs) writer.addFeature(outFeat) current += 1 progress.setPercentage(current / total) del writer
def convertUnsupportedFormats(self, progress): i = 0 progress.setText("Converting outputs") for out in self.outputs: if isinstance(out, OutputVector): if out.compatible is not None: layer = dataobjects.getObjectFromUri(out.compatible) if layer is None: # For the case of memory layer, if the # getCompatible method has been called continue provider = layer.dataProvider() writer = out.getVectorWriter(provider.fields(), provider.geometryType(), 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.getObjectFromUri(out.compatible) provider = layer.dataProvider() writer = QgsRasterFileWriter(out.value) format = self.getFormatShortNameFromFilename(out.value) writer.setOutputFormat(format) writer.writeRaster(layer.pipe(), layer.width(), layer.height(), layer.extent(), layer.crs()) elif isinstance(out, OutputTable): if out.compatible is not None: layer = dataobjects.getObjectFromUri(out.compatible) provider = layer.dataProvider() writer = out.getTableWriter(provider.fields()) features = vector.features(layer) for feature in features: writer.addRecord(feature) progress.setPercentage(100 * i / float(len(self.outputs)))
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) layer = dataobjects.getObjectFromUri(filename) filename = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getObjectFromUri(filename) index = vector.spatialindex(layer) geom = QgsGeometry() selectedSet = [] current = 0 features = vector.features(selectLayer) featureCount = len(features) total = 100.0 / float(len(features)) for current,f in enumerate(features): geom = QgsGeometry(f.geometry()) intersects = index.intersects(geom.boundingBox()) for i in intersects: request = QgsFeatureRequest().setFilterFid(i) feat = layer.getFeatures(request).next() tmpGeom = QgsGeometry(feat.geometry()) if geom.intersects(tmpGeom): selectedSet.append(feat.id()) progress.setPercentage(int(current * total)) output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(layer.fields(), layer.geometryType(), layer.crs()) for (i, feat) in enumerate(features): if feat.id() in selectedSet: writer.addFeature(feat) progress.setPercentage(100 * i / float(featureCount)) del writer
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) inputLayer = dataobjects.getObjectFromUri(filename) method = self.getParameterValue(self.METHOD) filename = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getObjectFromUri(filename) oldSelection = set(inputLayer.selectedFeaturesIds()) index = vector.spatialindex(inputLayer) geom = QgsGeometry() selectedSet = [] current = 0 features = vector.features(selectLayer) total = 100.0 / float(len(features)) for f in features: geom = QgsGeometry(f.geometry()) intersects = index.intersects(geom.boundingBox()) for i in intersects: request = QgsFeatureRequest().setFilterFid(i) feat = inputLayer.getFeatures(request).next() tmpGeom = QgsGeometry(feat.geometry()) if geom.intersects(tmpGeom): selectedSet.append(feat.id()) current += 1 progress.setPercentage(int(current * total)) if method == 1: selectedSet = list(oldSelection.union(selectedSet)) elif method == 2: selectedSet = list(oldSelection.difference(selectedSet)) inputLayer.setSelectedFeatures(selectedSet) self.setOutputValue(self.OUTPUT, filename)
def processAlgorithm(self, progress): inLayer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_LAYER)) inField = self.getParameterValue(self.INPUT_FIELD) targetLayer = dataobjects.getObjectFromUri( 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, progress) elif matType == 1: # Standard distance matrix self.regularMatrix(inLayer, inField, targetLayer, targetField, nPoints, progress) elif matType == 2: # Summary distance matrix self.linearMatrix(inLayer, inField, targetLayer, targetField, matType, nPoints, progress)
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.getObjectFromUri(orgFilename, False) if layer: filename = dataobjects.exportVectorLayer(layer) else: layer = dataobjects.getObjectFromUri(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 = self.getTempFilename() self.exportedLayers[orgFilename] = destFilename command = 'v.in.ogr' min_area = self.getParameterValue(self.GRASS_MIN_AREA_PARAMETER) command += ' min_area=' + unicode(min_area) snap = self.getParameterValue(self.GRASS_SNAP_TOLERANCE_PARAMETER) command += ' snap=' + unicode(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, progress): layerA = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_A)) layerB = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_B)) fieldA = self.getParameterValue(self.FIELD_A) fieldB = self.getParameterValue(self.FIELD_B) idxA = layerA.fields().lookupField(fieldA) idxB = layerB.fields().lookupField(fieldB) fieldList = [layerA.fields()[idxA], layerB.fields()[idxB]] writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fieldList, QgsWkbTypes.Point, layerA.crs()) spatialIndex = vector.spatialindex(layerB) outFeat = QgsFeature() features = vector.features(layerA) total = 100.0 / len(features) hasIntersections = False for current, inFeatA in enumerate(features): inGeom = inFeatA.geometry() 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) for inFeatB in layerB.getFeatures(request): tmpGeom = inFeatB.geometry() points = [] attrsA = inFeatA.attributes() attrsB = inFeatB.attributes() if engine.intersects(tmpGeom.geometry()): tempGeom = inGeom.intersection(tmpGeom) if tempGeom.type() == QgsWkbTypes.PointGeometry: if tempGeom.isMultipart(): points = tempGeom.asMultiPoint() else: points.append(tempGeom.asPoint()) for j in points: outFeat.setGeometry(tempGeom.fromPoint(j)) outFeat.setAttributes([attrsA[idxA], attrsB[idxB]]) writer.addFeature(outFeat) progress.setPercentage(int(current * total)) del writer
def getMinCoveringExtent(self): first = True found = False for param in self.params: if param.value: if isinstance(param, (ParameterRaster, ParameterVector)): if isinstance(param.value, (QgsRasterLayer, QgsVectorLayer)): layer = param.value else: layer = dataobjects.getObjectFromUri(param.value) if layer: found = True self.addToRegion(layer, first) first = False elif isinstance(param, ParameterMultipleInput): layers = param.value.split(";") for layername in layers: layer = dataobjects.getObjectFromUri(layername, first) if layer: found = True self.addToRegion(layer, first) first = False if found: return "{},{},{},{}".format(self.xmin, self.xmax, self.ymin, self.ymax) else: return None
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.getObjectFromUri(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.getObjectFromUri(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, progress): inputZiekenhuis = self.getParameterValue(self.INPUTZIEKENHUIS) inputBuffers = self.getParameterValue(self.INPUTBUFFERS) berekeningswijze = self.getParameterValue(self.BEREKENINGSWIJZE) outputTable = self.getParameterValue(self.OUTPUTTABLE) outputFeature = self.getParameterValue(self.OUTPUTFEATURE) inputZiekenhuislayer = dataobjects.getObjectFromUri(inputZiekenhuis) inputBuffersLayer = dataobjects.getObjectFromUri(inputBuffers) verdieping = VerdiepingUitBlootstellingsHoogte(inputBuffersLayer) if verdieping > 0: selected = runalg("qgis:selectbylocation", inputZiekenhuislayer, inputBuffersLayer, [u"intersects"] , 0, 0 )['OUTPUT'] # selectie_gebouwen = dataobjects.getObjectFromUri(selected) selectedCount = inputZiekenhuislayer.selectedFeatureCount() print selected +" >aantal> "+ str(selectedCount) if selectedCount == 0: print("Er liggen geen gebouwen binnen de opgegeven buffers!") if berekeningswijze == "Maximum telling": MaximumTelling(inputZiekenhuislayer, outputTable, outputFeature) elif berekeningswijze == "Minimum telling": MinimumTelling(inputZiekenhuislayer, inputBuffers, outputTable, outputFeature) elif berekeningswijze == "Tussenvorm": TussenTelling(inputZiekenhuislayer, outputTable, outputFeature) elif verdieping == 0: raise Exception("Het bufferbestand is leeg, er kan geen blootstellingshoogte bepaald worden.") else: raise Exception("Negatieve hoogte buffers: ondergronds wordt geen blootstelling berekend.")
def calculateResamplingExtent(self): '''this method calculates the resampling extent, but it might set self.resample to false if, with the current layers, there is no need to resample''' auto = ProcessingConfig.getSetting(SagaUtils.SAGA_AUTO_RESAMPLING) if auto: first = True; self.inputExtentsCount = 0 for param in self.parameters: if param.value: if isinstance(param, ParameterRaster): if isinstance(param.value, QgsRasterLayer): layer = param.value else: layer = dataobjects.getObjectFromUri(param.value) self.addToResamplingExtent(layer, first) first = False if isinstance(param, ParameterMultipleInput): if param.datatype == ParameterMultipleInput.TYPE_RASTER: layers = param.value.split(";") for layername in layers: layer = dataobjects.getObjectFromUri(layername) self.addToResamplingExtent(layer, first) first = False if self.inputExtentsCount < 2: self.resample = False else: self.xmin = ProcessingConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_XMIN) self.xmax = ProcessingConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_XMAX) self.ymin = ProcessingConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_YMIN) self.ymax = ProcessingConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_YMAX) self.cellsize = ProcessingConfig.getSetting(SagaUtils.SAGA_RESAMPLING_REGION_CELLSIZE)
def processAlgorithm(self, progress): polyLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.POLYGONS)) pointLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.POINTS)) fieldName = self.getParameterValue(self.FIELD) fieldIdx = pointLayer.fieldNameIndex(self.getParameterValue(self.WEIGHT)) polyProvider = polyLayer.dataProvider() idxCount, fieldList = utils.findOrCreateField(polyLayer, polyLayer.pendingFields(), fieldName) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fieldList.toList(), polyProvider.geometryType(), polyProvider.crs()) spatialIndex = utils.spatialindex(pointLayer) ftPoint = QgsFeature() outFeat = QgsFeature() geom = QgsGeometry() current = 0 hasIntersections = False features = vector.features(polyLayer) total = 100.0 / float(len(features)) for ftPoly in features: geom = ftPoly.geometry() attrs = ftPoly.attributes() count = 0 hasIntersections = False points = spatialIndex.intersects(geom.boundingBox()) if len(points) > 0: hasIntersections = True if hasIntersections: progress.setText(str(len(points))) for i in points: request = QgsFeatureRequest().setFilterFid(i) ftPoint = pointLayer.getFeatures(request).next() tmpGeom = QgsGeometry(ftPoint.geometry()) if geom.contains(tmpGeom): weight = str(ftPoint.attributes()[fieldIdx]) try: count += float(weight) except: pass #ignore fields with non-numeric values outFeat.setGeometry(geom) if idxCount == len(attrs): attrs.append(count) else: attrs[idxCount] = count outFeat.setAttributes(attrs) writer.addFeature(outFeat) current += 1 progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layer1 = dataobjects.getObjectFromUri( self.getParameterValue(self.LAYER1)) layer2 = dataobjects.getObjectFromUri( self.getParameterValue(self.LAYER2)) if layer1.wkbType() != layer2.wkbType(): raise GeoAlgorithmExecutionException( self.tr('Merged layers must have be same type of geometry')) count = 0 fields = [] layers = [layer1, layer2] for layer in layers: count += layer.featureCount() for sfield in layer.pendingFields(): found = None for dfield in fields: if dfield.name() == sfield.name() and \ dfield.type() == sfield.type(): found = dfield break if not found: fields.append(sfield) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, layer1.wkbType(), layer1.crs()) total = 100.0 / float(count) count = 0 for layer in layers: idx = {} for dfield in fields: i = 0 for sfield in layer.pendingFields(): if sfield.name() == dfield.name() and \ sfield.type() == dfield.type(): idx[dfield] = i break i += 1 features = vector.features(layer) for f in features: sAttributes = f.attributes() dAttributes = [] for dfield in fields: if dfield in idx: dAttributes.append(sAttributes[idx[dfield]]) else: dAttributes.append(dfield.type()) f.setAttributes(dAttributes) writer.addFeature(f) count += 1 progress.setPercentage(int(count * total)) del writer
def processAlgorithm(self, progress): polyLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.POLYGONS)) pointLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.POINTS)) fieldName = self.getParameterValue(self.FIELD) fieldIdx = pointLayer.fieldNameIndex(self.getParameterValue(self.WEIGHT)) polyProvider = polyLayer.dataProvider() fields = polyProvider.fields() fields.append(QgsField(fieldName, QVariant.Int)) (idxCount, fieldList) = vector.findOrCreateField(polyLayer, polyLayer.pendingFields(), fieldName) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields.toList(), polyProvider.geometryType(), polyProvider.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: progress.setText(unicode(len(points))) request = QgsFeatureRequest().setFilterFids(points) fit = pointLayer.getFeatures(request) ftPoint = QgsFeature() while fit.nextFeature(ftPoint): tmpGeom = QgsGeometry(ftPoint.geometry()) if engine.contains(tmpGeom.geometry()): weight = unicode(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) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): roads_layer = self.getParameterValue(self.ROADS) roads_layer = getObjectFromUri(roads_layer) index_cost_strategy = self.getParameterValue(self.STRATEGY) for strategy in self.strategies: if strategy == self.strategies[index_cost_strategy]: cost_strategy = strategy break field = self.getParameterValue(self.FIELD) field = roads_layer.fieldNameIndex(field) exits_layer = self.getParameterValue(self.EXITS) exits_layer = getObjectFromUri(exits_layer) idp_layer = self.getParameterValue(self.IDP) idp_layer = getObjectFromUri(idp_layer) if field < 0 and cost_strategy != 'distance': raise GeoAlgorithmExecutionException('Invalid cost and field') output_exits = self.getOutputValue(self.OUTPUT_EXITS) output_routes = self.getOutputValue(self.OUTPUT_ROUTE) tied_points = [] for f in idp_layer.getFeatures(): tied_points.append(f.geometry().asPoint()) for f in exits_layer.getFeatures(): tied_points.append(f.geometry().asPoint()) if field < 0: graph = InasafeGraph(roads_layer, tied_points) else: graph = InasafeGraph(roads_layer, tied_points, coef=field) exit, route = graph.cost_exits(idp_layer, exits_layer, cost_strategy) exit_layer = QgsVectorFileWriter( output_exits, None, exit.dataProvider().fields(), QGis.WKBPoint, roads_layer.crs() ) for feature in exit.getFeatures(): exit_layer.addFeature(feature) del exit_layer route_layer = QgsVectorFileWriter( output_routes, None, route.dataProvider().fields(), QGis.WKBMultiLineString, roads_layer.crs() ) for feature in route.getFeatures(): route_layer.addFeature(feature) del route_layer
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri(self.getParameterValue(Difference.INPUT)) layerB = dataobjects.getObjectFromUri(self.getParameterValue(Difference.OVERLAY)) GEOS_EXCEPT = True FEATURE_EXCEPT = True writer = self.getOutputFromName(Difference.OUTPUT).getVectorWriter(layerA.pendingFields(), layerA.dataProvider().geometryType(), layerA.dataProvider().crs()) inFeatA = QgsFeature() inFeatB = QgsFeature() outFeat = QgsFeature() index = utils.spatialindex(layerB) selectionA = vector.features(layerA) current = 0 total = 100.0 / float(len(selectionA)) for inFeatA in selectionA: add = True geom = QgsGeometry(inFeatA.geometry()) diff_geom = QgsGeometry(geom) attrs = inFeatA.attributes() intersections = index.intersects(geom.boundingBox()) for i in intersections: request = QgsFeatureRequest().setFilterFid(i) inFeatB = layerB.getFeatures(request).next() tmpGeom = QgsGeometry(inFeatB.geometry()) try: if diff_geom.intersects(tmpGeom): diff_geom = QgsGeometry(diff_geom.difference(tmpGeom)) except: GEOS_EXCEPT = False add = False break if add: try: outFeat.setGeometry(diff_geom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: FEATURE_EXCEPT = False continue current += 1 progress.setPercentage(int(current * total)) del writer if not GEOS_EXCEPT: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, "Geometry exception while computing difference") if not FEATURE_EXCEPT: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, "Feature exception while computing difference")
def processAlgorithm(self, progress): inLayerA = self.getParameterValue(self.INPUT_LAYER_A) ogrLayerA = ogrConnectionString(inLayerA)[1:-1] layernameA = ogrLayerName(inLayerA) inLayerB = self.getParameterValue(self.INPUT_LAYER_B) ogrLayerB = ogrConnectionString(inLayerB)[1:-1] layernameB = ogrLayerName(inLayerB) fieldA = unicode(self.getParameterValue(self.FIELD_A)) fieldB = unicode(self.getParameterValue(self.FIELD_B)) dsUriA = QgsDataSourceURI(self.getParameterValue(self.INPUT_LAYER_A)) geomColumnA = dsUriA.geometryColumn() dsUriB = QgsDataSourceURI(self.getParameterValue(self.INPUT_LAYER_B)) geomColumnB = dsUriB.geometryColumn() layerA = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_LAYER_A)) geomTypeA = layerA.geometryType() wkbTypeA = layerA.wkbType() sridA = layerA.crs().postgisSrid() layerB = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_LAYER_B)) geomTypeB = layerB.geometryType() wkbTypeB = layerB.wkbType() sridB = layerB.crs().postgisSrid() multi = self.getParameterValue(self.MULTI) schema = unicode(self.getParameterValue(self.SCHEMA)) table = unicode(self.getParameterValue(self.TABLE)) if multi: sqlstring = "-sql \"WITH temp_table AS (SELECT ST_Union(" + geomColumnB + ") AS geom FROM " + layernameB + ") SELECT ST_ShortestLine(g1." + geomColumnA + ",g2.geom) AS geom, ST_Distance(g1." + geomColumnA + ",g2.geom) AS distance, g1." + fieldA + " AS id_from FROM " + layernameA + " AS g1, temp_table AS g2\" -nln " + schema + "." + table + " -lco FID=gid -lco GEOMETRY_NAME=geom -nlt LINESTRING --config PG_USE_COPY YES -a_srs EPSG:" + str(sridA) + "" else: sqlstring = "-sql \"SELECT ST_ShortestLine(g1." + geomColumnA + ",g2." + geomColumnB + ") AS geom, ST_Distance(g1." + geomColumnA + ",g2." + geomColumnB + ") AS distance, g1." + fieldA + " AS id_from, g2." + fieldB + " AS id_to FROM " + layernameA + " AS g1, " + layernameB + " AS g2\" -nln " + schema + "." + table + " -lco FID=gid -lco GEOMETRY_NAME=geom -nlt LINESTRING --config PG_USE_COPY YES" options = unicode(self.getParameterValue(self.OPTIONS)) arguments = [] arguments.append('-f') arguments.append('PostgreSQL') arguments.append(ogrLayerA) arguments.append(ogrLayerA) arguments.append(sqlstring) arguments.append('-overwrite') if len(options) > 0: arguments.append(options) #print table commands = [] if isWindows(): commands = ['cmd.exe', '/C ', 'ogr2ogr.exe', GdalUtils.escapeAndJoin(arguments)] else: commands = ['ogr2ogr', GdalUtils.escapeAndJoin(arguments)] GdalUtils.runGdal(commands, progress) output = self.getOutputValue(self.OUTPUT) f = open(output, 'w') f.write('<pre>') for s in GdalUtils.getConsoleOutput()[1:]: f.write(unicode(s)) f.write('</pre>') f.close()
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri(self.getParameterValue(Difference.INPUT)) layerB = dataobjects.getObjectFromUri(self.getParameterValue(Difference.OVERLAY)) ignoreInvalid = self.getParameterValue(Difference.IGNORE_INVALID) geomType = layerA.dataProvider().geometryType() writer = self.getOutputFromName(Difference.OUTPUT).getVectorWriter( layerA.pendingFields(), geomType, layerA.dataProvider().crs() ) outFeat = QgsFeature() index = vector.spatialindex(layerB) selectionA = vector.features(layerA) total = 100.0 / len(selectionA) for current, inFeatA in enumerate(selectionA): add = True geom = QgsGeometry(inFeatA.geometry()) diff_geom = QgsGeometry(geom) attrs = inFeatA.attributes() intersections = index.intersects(geom.boundingBox()) for i in intersections: request = QgsFeatureRequest().setFilterFid(i) inFeatB = layerB.getFeatures(request).next() tmpGeom = QgsGeometry(inFeatB.geometry()) if diff_geom.intersects(tmpGeom): diff_geom = QgsGeometry(diff_geom.difference(tmpGeom)) if diff_geom.isGeosEmpty(): ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr("Feature with NULL geometry found.")) if not diff_geom.isGeosValid(): if ignoreInvalid: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr("GEOS geoprocessing error: One or more input features have invalid geometry."), ) add = False else: raise GeoAlgorithmExecutionException( self.tr( 'Features with invalid geometries found. Please fix these errors or specify the "Ignore invalid input features" flag' ) ) break if add: try: outFeat.setGeometry(diff_geom) 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 progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layer1 = dataobjects.getObjectFromUri(self.getParameterValue(self.LAYER1)) layer2 = dataobjects.getObjectFromUri(self.getParameterValue(self.LAYER2)) fields = [] layers = [layer1, layer2] totalfeaturecount = 0 if (layer1.dataProvider().geometryType() != layer2.dataProvider().geometryType()): raise GeoAlgorithmExecutionException("Merged layers must all be same type of geometry (" + \ mmqgisx_wkbtype_to_text(layer2.dataProvider().geometryType()) + " != " + \ mmqgisx_wkbtype_to_text(layer2.dataProvider().geometryType()) + ")") for layer in layers: totalfeaturecount += layer.featureCount() # Add any fields not in the composite field list for sfield in layer.pendingFields(): found = None for dfield in fields: if (dfield.name() == sfield.name()) and (dfield.type() == sfield.type()): found = dfield break if not found: fields.append(sfield) output = self.getOutputFromName(self.SAVENAME) out = output.getVectorWriter(fields, layer1.wkbType(), layer1.crs()) # Copy layer features to output file featurecount = 0 for layer in layers: idx = {} for dfield in fields: i = 0 for sfield in layer.pendingFields(): if (sfield.name() == dfield.name()) and (sfield.type() == dfield.type()): idx[dfield] = i break i += 1 features = vector.features(layer) for feature in features: sattributes = feature.attributes() dattributes = [] for dfield in fields: if (dfield in idx): dattributes.append(sattributes[idx[dfield]]) else: dattributes.append(dfield.type()) feature.setAttributes(dattributes) out.addFeature(feature) featurecount += 1 progress.setPercentage(float(featurecount) / totalfeaturecount * 100) del out
def convertUnsupportedFormats(self, progress): i = 0 progress.setText(self.tr('Converting outputs')) for out in self.outputs: if isinstance(out, OutputVector): if out.compatible is not None: layer = dataobjects.getObjectFromUri(out.compatible) if layer is None: # For the case of memory layer, if the # getCompatible method has been called continue provider = layer.dataProvider() writer = out.getVectorWriter( provider.fields(), provider.geometryType(), 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.getObjectFromUri(out.compatible) format = self.getFormatShortNameFromFilename(out.value) orgFile = out.compatible destFile = out.value crsid = layer.crs().authid() settings = QSettings() path = unicode(settings.value('/GdalTools/gdalPath', '')) envval = unicode(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.getObjectFromUri(out.compatible) provider = layer.dataProvider() writer = out.getTableWriter(provider.fields()) features = vector.features(layer) for feature in features: writer.addRecord(feature) progress.setPercentage(100 * i / float(len(self.outputs)))
def processAlgorithm(self, progress): vlayerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) vlayerB = dataobjects.getObjectFromUri( 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): progress.setPercentage(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.isGeosEmpty() 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, progress): layerA = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_A)) layerB = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT_B)) fieldA = self.getParameterValue(self.FIELD_A) fieldB = self.getParameterValue(self.FIELD_B) idxA = layerA.fieldNameIndex(fieldA) idxB = layerB.fieldNameIndex(fieldB) fieldList = [layerA.pendingFields()[idxA], layerB.pendingFields()[idxB]] writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fieldList, QGis.WKBPoint, layerA.dataProvider().crs()) spatialIndex = vector.spatialindex(layerB) outFeat = QgsFeature() features = vector.features(layerA) total = 100.0 / len(features) hasIntersections = False for current, inFeatA in enumerate(features): inGeom = inFeatA.geometry() hasIntersections = False lines = spatialIndex.intersects(inGeom.boundingBox()) if len(lines) > 0: hasIntersections = True if hasIntersections: for i in lines: request = QgsFeatureRequest().setFilterFid(i) inFeatB = layerB.getFeatures(request).next() tmpGeom = QgsGeometry(inFeatB.geometry()) points = [] attrsA = inFeatA.attributes() attrsB = inFeatB.attributes() if inGeom.intersects(tmpGeom): tempGeom = inGeom.intersection(tmpGeom) if tempGeom.type() == QGis.Point: if tempGeom.isMultipart(): points = tempGeom.asMultiPoint() else: points.append(tempGeom.asPoint()) for j in points: outFeat.setGeometry(tempGeom.fromPoint(j)) outFeat.setAttributes([attrsA[idxA], attrsB[idxB]]) writer.addFeature(outFeat) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) inputLayer = dataobjects.getObjectFromUri(filename) method = self.getParameterValue(self.METHOD) filename2 = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getObjectFromUri(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 progress.setPercentage(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, progress): vlayerA = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) vlayerB = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT2)) vproviderA = vlayerA.dataProvider() fields = vector.combineVectorFields(vlayerA, vlayerB) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, vproviderA.geometryType(), vproviderA.crs() ) inFeatA = QgsFeature() inFeatB = QgsFeature() outFeat = QgsFeature() index = vector.spatialindex(vlayerB) nElement = 0 selectionA = vector.features(vlayerA) nFeat = len(selectionA) for inFeatA in selectionA: nElement += 1 progress.setPercentage(nElement / float(nFeat) * 100) geom = QgsGeometry(inFeatA.geometry()) atMapA = inFeatA.attributes() intersects = index.intersects(geom.boundingBox()) for i in intersects: request = QgsFeatureRequest().setFilterFid(i) inFeatB = vlayerB.getFeatures(request).next() tmpGeom = QgsGeometry(inFeatB.geometry()) try: if geom.intersects(tmpGeom): atMapB = inFeatB.attributes() int_geom = QgsGeometry(geom.intersection(tmpGeom)) if ( int_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(int_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection ): int_com = geom.combine(tmpGeom) int_sym = geom.symDifference(tmpGeom) int_geom = QgsGeometry(int_com.difference(int_sym)) 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 except: break del writer
def processAlgorithm(self, progress): polyLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.POLYGONS)) pointLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.POINTS)) fieldName = self.getParameterValue(self.FIELD) classFieldName = self.getParameterValue(self.CLASSFIELD) polyProvider = polyLayer.dataProvider() fields = polyProvider.fields() fields.append(QgsField(fieldName, QVariant.Int)) classFieldIndex = pointLayer.fieldNameIndex(classFieldName) (idxCount, fieldList) = vector.findOrCreateField(polyLayer, polyLayer.pendingFields(), fieldName) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields.toList(), polyProvider.geometryType(), polyProvider.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() classes = set() points = spatialIndex.intersects(geom.boundingBox()) if len(points) > 0: request = QgsFeatureRequest().setFilterFids(points) fit = pointLayer.getFeatures(request) ftPoint = QgsFeature() while fit.nextFeature(ftPoint): tmpGeom = QgsGeometry(ftPoint.geometry()) if engine.contains(tmpGeom.geometry()): clazz = ftPoint.attributes()[classFieldIndex] if clazz not in classes: classes.add(clazz) outFeat.setGeometry(geom) if idxCount == len(attrs): attrs.append(len(classes)) else: attrs[idxCount] = len(classes) outFeat.setAttributes(attrs) writer.addFeature(outFeat) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): hublayer = dataobjects.getObjectFromUri(self.getParameterValue(self.HUBNAME)) spokelayer = dataobjects.getObjectFromUri(self.getParameterValue(self.SPOKENAME)) hubattr = self.getParameterValue(self.HUBATTRIBUTE) spokeattr = self.getParameterValue(self.SPOKEATTRIBUTE) if hublayer == spokelayer: raise GeoAlgorithmExecutionException ("Same layer given for both hubs and spokes") hubindex = hublayer.dataProvider().fieldNameIndex(hubattr) spokeindex = spokelayer.dataProvider().fieldNameIndex(spokeattr) outfields = spokelayer.pendingFields() output = self.getOutputFromName(self.SAVENAME) out = output.getVectorWriter(outfields, QGis.WKBLineString, spokelayer.crs()) # Scan spoke points linecount = 0 spokepoints = vector.features(spokelayer) i = 0 for spokepoint in spokepoints: i += 1 spokex = spokepoint.geometry().boundingBox().center().x() spokey = spokepoint.geometry().boundingBox().center().y() spokeid = unicode(spokepoint.attributes()[spokeindex]) progress.setPercentage(float(i) / len(spokepoints) * 100) # Scan hub points to find first matching hub hubpoints = vector.features(hublayer) for hubpoint in hubpoints: hubid = unicode(hubpoint.attributes()[hubindex]) if hubid == spokeid: hubx = hubpoint.geometry().boundingBox().center().x() huby = hubpoint.geometry().boundingBox().center().y() # Write line to the output file outfeature = QgsFeature() outfeature.setAttributes(spokepoint.attributes()) polyline = [] polyline.append(QgsPoint(spokex, spokey)) polyline.append(QgsPoint(hubx, huby)) geometry = QgsGeometry() outfeature.setGeometry(geometry.fromPolyline(polyline)) out.addFeature(outfeature) linecount = linecount + 1 break del out if linecount <= 0: raise GeoAlgorithmExecutionException("No spoke/hub matches found to create lines")
def processAlgorithm(self, progress): vlayerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) vlayerB = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT2)) vproviderA = vlayerA.dataProvider() geomType = vproviderA.geometryType() if geomType in GEOM_25D: raise GeoAlgorithmExecutionException( self.tr('Input layer has unsupported geometry type {}').format(geomType)) fields = vector.combineVectorFields(vlayerA, vlayerB) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, geomType, vproviderA.crs()) outFeat = QgsFeature() index = vector.spatialindex(vlayerB) selectionA = vector.features(vlayerA) total = 100.0 / len(selectionA) for current, inFeatA in enumerate(selectionA): progress.setPercentage(int(current * total)) geom = QgsGeometry(inFeatA.geometry()) atMapA = inFeatA.attributes() intersects = index.intersects(geom.boundingBox()) for i in intersects: request = QgsFeatureRequest().setFilterFid(i) inFeatB = vlayerB.getFeatures(request).next() tmpGeom = QgsGeometry(inFeatB.geometry()) if geom.intersects(tmpGeom): atMapB = inFeatB.attributes() int_geom = QgsGeometry(geom.intersection(tmpGeom)) if int_geom.wkbType() == QGis.WKBUnknown or QgsWKBTypes.flatType(int_geom.geometry().wkbType()) == QgsWKBTypes.GeometryCollection: int_com = geom.combine(tmpGeom) int_sym = geom.symDifference(tmpGeom) int_geom = QgsGeometry(int_com.difference(int_sym)) if int_geom.isGeosEmpty() or not int_geom.isGeosValid(): ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('GEOS geoprocessing error: One or ' 'more input features have invalid ' 'geometry.')) break 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, progress): filename = self.getParameterValue(self.INPUT) layer = dataobjects.getObjectFromUri(filename) filename = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getObjectFromUri(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 progress.setPercentage(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) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(Difference.INPUT)) layerB = dataobjects.getObjectFromUri( self.getParameterValue(Difference.OVERLAY)) geomType = layerA.dataProvider().geometryType() if geomType in GEOM_25D: raise GeoAlgorithmExecutionException( self.tr('Input layer has unsupported geometry type {}').format(geomType)) writer = self.getOutputFromName( Difference.OUTPUT).getVectorWriter(layerA.pendingFields(), geomType, layerA.dataProvider().crs()) outFeat = QgsFeature() index = vector.spatialindex(layerB) selectionA = vector.features(layerA) total = 100.0 / len(selectionA) for current, inFeatA in enumerate(selectionA): add = True geom = QgsGeometry(inFeatA.geometry()) diff_geom = QgsGeometry(geom) attrs = inFeatA.attributes() intersections = index.intersects(geom.boundingBox()) for i in intersections: request = QgsFeatureRequest().setFilterFid(i) inFeatB = layerB.getFeatures(request).next() tmpGeom = QgsGeometry(inFeatB.geometry()) if diff_geom.intersects(tmpGeom): diff_geom = QgsGeometry(diff_geom.difference(tmpGeom)) if diff_geom.isGeosEmpty() or not diff_geom.isGeosValid(): ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('GEOS geoprocessing error: One or ' 'more input features have invalid ' 'geometry.')) add = False break if add: try: outFeat.setGeometry(diff_geom) 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 progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.VECTOR)) value = float(self.getParameterValue(self.VALUE)) 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(value) else: pointCount = int(round(value * da.measureArea(fGeom))) 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 = self.getParameterValue(self.INPUT_LAYER) mapping = self.getParameterValue(self.FIELDS_MAPPING) output = self.getOutputFromName(self.OUTPUT_LAYER) layer = dataobjects.getObjectFromUri(layer) fields = [] expressions = [] da = QgsDistanceArea() da.setSourceCrs(layer.crs().srsid()) da.setEllipsoidalMode( iface.mapCanvas().mapSettings().hasCrsTransformEnabled()) da.setEllipsoid(QgsProject.instance().readEntry( 'Measure', '/Ellipsoid', GEO_NONE)[0]) exp_context = layer.createExpressionContext() for field_def in mapping: fields.append( QgsField(name=field_def['name'], type=field_def['type'], len=field_def['length'], prec=field_def['precision'])) expression = QgsExpression(field_def['expression']) expression.setGeomCalculator(da) expression.setDistanceUnits(QgsProject.instance().distanceUnits()) expression.setAreaUnits(QgsProject.instance().areaUnits()) expression.prepare(exp_context) if expression.hasParserError(): raise GeoAlgorithmExecutionException( self.tr(u'Parser error in expression "{}": {}').format( unicode(expression.expression()), unicode(expression.parserErrorString()))) expressions.append(expression) writer = output.getVectorWriter(fields, layer.wkbType(), layer.crs()) # Create output vector layer with new attributes error_exp = None inFeat = QgsFeature() outFeat = QgsFeature() features = vector.features(layer) total = 100.0 / len(features) for current, inFeat in enumerate(features): rownum = current + 1 geometry = inFeat.geometry() outFeat.setGeometry(geometry) attrs = [] for i in range(0, len(mapping)): field_def = mapping[i] expression = expressions[i] exp_context.setFeature(inFeat) exp_context.lastScope().setVariable("row_number", rownum) value = expression.evaluate(exp_context) if expression.hasEvalError(): error_exp = expression break attrs.append(value) outFeat.setAttributes(attrs) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer if error_exp is not None: raise GeoAlgorithmExecutionException( self.tr(u'Evaluation error in expression "{}": {}').format( unicode(error_exp.expression()), unicode(error_exp.parserErrorString())))
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_VECTOR)) rasterPath = unicode(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(), QGis.WKBPoint, layer.crs()) outFeature = QgsFeature() outFeature.setFields(fields) point = QgsPoint() 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) for row in xrange(startRow, endRow + 1): for col in xrange(startColumn, endColumn + 1): (x, y) = raster.pixelToMap(row, col, geoTransform) point.setX(x) point.setY(y) if geom.contains(point): outFeature.setGeometry(QgsGeometry.fromPoint(point)) outFeature['id'] = fid outFeature['poly_id'] = polyId outFeature['point_id'] = pointId fid += 1 pointId += 1 writer.addFeature(outFeature) pointId = 0 polyId += 1 progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, feedback): inLayer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) boundary = self.getParameterValue(self.MODE) == self.MODE_BOUNDARY smallestArea = self.getParameterValue( self.MODE) == self.MODE_SMALLEST_AREA keepSelection = self.getParameterValue(self.KEEPSELECTION) processLayer = vector.duplicateInMemory(inLayer) if not keepSelection: # Make a selection with the values provided attribute = self.getParameterValue(self.ATTRIBUTE) comparison = self.comparisons[self.getParameterValue( self.COMPARISON)] comparisonvalue = self.getParameterValue(self.COMPARISONVALUE) selectindex = vector.resolveFieldIndex(processLayer, attribute) selectType = processLayer.fields()[selectindex].type() selectionError = False if selectType in [ QVariant.Int, QVariant.LongLong, QVariant.UInt, QVariant.ULongLong ]: try: y = int(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to integer' % str(comparisonvalue)) elif selectType == QVariant.Double: try: y = float(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to float' % str(comparisonvalue)) elif selectType == QVariant.String: # 10: string, boolean try: y = str(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to Unicode' % str(comparisonvalue)) elif selectType == QVariant.Date: # date dateAndFormat = comparisonvalue.split(' ') if len(dateAndFormat) == 1: # QDate object y = QLocale.system().toDate(dateAndFormat[0]) if y.isNull(): msg = self.tr( 'Cannot convert "%s" to date with system date format %s' % (str(dateAndFormat), QLocale.system().dateFormat())) elif len(dateAndFormat) == 2: y = QDate.fromString(dateAndFormat[0], dateAndFormat[1]) if y.isNull(): msg = self.tr( 'Cannot convert "%s" to date with format string "%s"' % (str(dateAndFormat[0]), dateAndFormat[1])) else: y = QDate() msg = '' if y.isNull(): # Conversion was unsuccessful selectionError = True msg += self.tr( 'Enter the date and the date format, e.g. "07.26.2011" "MM.dd.yyyy".' ) if (comparison == 'begins with' or comparison == 'contains') \ and selectType != QVariant.String: selectionError = True msg = self.tr('"%s" can only be used with string fields' % comparison) selected = [] if selectionError: raise GeoAlgorithmExecutionException( self.tr('Error in selection input: %s' % msg)) else: for feature in processLayer.getFeatures(): aValue = feature.attributes()[selectindex] if aValue is None: continue if selectType in [ QVariant.Int, QVariant.LongLong, QVariant.UInt, QVariant.ULongLong ]: x = int(aValue) elif selectType == QVariant.Double: x = float(aValue) elif selectType == QVariant.String: # 10: string, boolean x = str(aValue) elif selectType == QVariant.Date: # date x = aValue # should be date match = False if comparison == '==': match = x == y elif comparison == '!=': match = x != y elif comparison == '>': match = x > y elif comparison == '>=': match = x >= y elif comparison == '<': match = x < y elif comparison == '<=': match = x <= y elif comparison == 'begins with': match = x.startswith(y) elif comparison == 'contains': match = x.find(y) >= 0 if match: selected.append(feature.id()) processLayer.selectByIds(selected) if processLayer.selectedFeatureCount() == 0: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self.tr('%s: (No selection in input layer "%s")' % (self.commandLineName(), self.getParameterValue(self.INPUT)))) # Keep references to the features to eliminate featToEliminate = [] for aFeat in processLayer.selectedFeatures(): featToEliminate.append(aFeat) # Delete all features to eliminate in processLayer (we won't save this) processLayer.startEditing() processLayer.deleteSelectedFeatures() # 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 %s' % mergeWithFid)) start = start + add feedback.setProgress(start) else: featNotEliminated.append(feat) # End for featToEliminate featToEliminate = featNotEliminated # End while # Create output output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(processLayer.fields(), processLayer.wkbType(), processLayer.crs()) # Write all features that are left over to output layer iterator = processLayer.getFeatures() for feature in iterator: writer.addFeature(feature) # Leave processLayer untouched processLayer.rollBack() for feature in featNotEliminated: writer.addFeature(feature)
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) fields = [QgsField('POINTA', QVariant.Double, '', 24, 15), QgsField('POINTB', QVariant.Double, '', 24, 15), QgsField('POINTC', QVariant.Double, '', 24, 15)] writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(fields, QgsWkbTypes.Polygon, layer.crs()) pts = [] ptDict = {} ptNdx = -1 c = voronoi.Context() features = vector.features(layer) total = 100.0 / len(features) for current, inFeat in enumerate(features): geom = QgsGeometry(inFeat.geometry()) if geom.isEmpty(): continue if geom.isMultipart(): points = geom.asMultiPoint() else: points = [geom.asPoint()] for n, point in enumerate(points): x = point.x() y = point.y() pts.append((x, y)) ptNdx += 1 ptDict[ptNdx] = (inFeat.id(), n) feedback.setProgress(int(current * total)) if len(pts) < 3: raise GeoAlgorithmExecutionException( self.tr('Input file should contain at least 3 points. Choose ' 'another file and try again.')) uniqueSet = set(item for item in pts) ids = [pts.index(item) for item in uniqueSet] sl = voronoi.SiteList([voronoi.Site(*i) for i in uniqueSet]) c.triangulate = True voronoi.voronoi(sl, c) triangles = c.triangles feat = QgsFeature() total = 100.0 / len(triangles) for current, triangle in enumerate(triangles): indices = list(triangle) indices.append(indices[0]) polygon = [] attrs = [] step = 0 for index in indices: fid, n = ptDict[ids[index]] request = QgsFeatureRequest().setFilterFid(fid) inFeat = next(layer.getFeatures(request)) geom = QgsGeometry(inFeat.geometry()) if geom.isMultipart(): point = QgsPoint(geom.asMultiPoint()[n]) else: point = QgsPoint(geom.asPoint()) polygon.append(point) if step <= 3: attrs.append(ids[index]) step += 1 feat.setAttributes(attrs) geometry = QgsGeometry().fromPolygon([polygon]) feat.setGeometry(geometry) writer.addFeature(feat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, feedback): fieldName = self.getParameterValue(self.FIELD_NAME) fieldType = self.getParameterValue(self.FIELD_TYPE) fieldLength = self.getParameterValue(self.FIELD_LENGTH) fieldPrecision = self.getParameterValue(self.FIELD_PRECISION) code = self.getParameterValue(self.FORMULA) globalExpression = self.getParameterValue(self.GLOBAL) output = self.getOutputFromName(self.OUTPUT_LAYER) layer = dataobjects.getObjectFromUri( 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() new_ns = {} # Run global code if globalExpression.strip() != '': try: bytecode = compile(globalExpression, '<string>', 'exec') exec(bytecode, new_ns) except: raise GeoAlgorithmExecutionException( self.tr("FieldPyculator code execute error.Global code block can't be executed!\n%s\n%s") % (str(sys.exc_info()[0].__name__), str(sys.exc_info()[1]))) # Replace all fields tags fields = layer.fields() num = 0 for field in fields: field_name = str(field.name()) replval = '__attr[' + str(num) + ']' code = code.replace('<' + field_name + '>', replval) num += 1 # Replace all special vars code = code.replace('$id', '__id') code = code.replace('$geom', '__geom') need_id = code.find('__id') != -1 need_geom = code.find('__geom') != -1 need_attrs = code.find('__attr') != -1 # Compile try: bytecode = compile(code, '<string>', 'exec') except: raise GeoAlgorithmExecutionException( self.tr("FieldPyculator code execute error.Field code block can't be executed!\n%s\n%s") % (str(sys.exc_info()[0].__name__), str(sys.exc_info()[1]))) # Run features = vector.features(layer) total = 100.0 / len(features) for current, feat in enumerate(features): feedback.setProgress(int(current * total)) attrs = feat.attributes() feat_id = feat.id() # Add needed vars if need_id: new_ns['__id'] = feat_id if need_geom: geom = feat.geometry() new_ns['__geom'] = geom if need_attrs: pyattrs = [a for a in attrs] new_ns['__attr'] = pyattrs # Clear old result if self.RESULT_VAR_NAME in new_ns: del new_ns[self.RESULT_VAR_NAME] # Exec exec(bytecode, new_ns) # Check result if self.RESULT_VAR_NAME not in new_ns: raise GeoAlgorithmExecutionException( self.tr("FieldPyculator code execute error\n" "Field code block does not return '%s1' variable! " "Please declare this variable in your code!") % self.RESULT_VAR_NAME) # Write feature outFeat.setGeometry(feat.geometry()) attrs.append(new_ns[self.RESULT_VAR_NAME]) outFeat.setAttributes(attrs) writer.addFeature(outFeat) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_VECTOR)) startPoints = dataobjects.getObjectFromUri( 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(), iface.mapCanvas().hasCrsTransformEnabled(), 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, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(Clip.INPUT)) layerB = dataobjects.getObjectFromUri( self.getParameterValue(Clip.OVERLAY)) geomType = layerA.dataProvider().geometryType() if geomType in GEOM_25D: raise GeoAlgorithmExecutionException( self.tr('Input layer does not support 2.5D type geometry ({}).' ).format(QgsWKBTypes.displayString(geomType))) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layerA.pendingFields(), layerA.dataProvider().geometryType(), layerA.dataProvider().crs()) inFeatA = QgsFeature() inFeatB = QgsFeature() outFeat = QgsFeature() index = vector.spatialindex(layerB) selectionA = vector.features(layerA) total = 100.0 / len(selectionA) for current, inFeatA in enumerate(selectionA): geom = QgsGeometry(inFeatA.geometry()) attrs = inFeatA.attributes() intersects = index.intersects(geom.boundingBox()) first = True found = False if len(intersects) > 0: for i in intersects: layerB.getFeatures(QgsFeatureRequest().setFilterFid( i)).nextFeature(inFeatB) tmpGeom = QgsGeometry(inFeatB.geometry()) if tmpGeom.intersects(geom): found = True if first: outFeat.setGeometry(QgsGeometry(tmpGeom)) first = False else: cur_geom = QgsGeometry(outFeat.geometry()) new_geom = QgsGeometry(cur_geom.combine(tmpGeom)) if new_geom.isGeosEmpty( ) or not new_geom.isGeosValid(): ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr('GEOS geoprocessing error: One or ' 'more input features have invalid ' 'geometry.')) break outFeat.setGeometry(QgsGeometry(new_geom)) if found: cur_geom = QgsGeometry(outFeat.geometry()) new_geom = QgsGeometry(geom.intersection(cur_geom)) if new_geom.wkbType( ) == QGis.WKBUnknown or QgsWKBTypes.flatType( new_geom.geometry().wkbType( )) == QgsWKBTypes.GeometryCollection: int_com = QgsGeometry(geom.combine(cur_geom)) int_sym = QgsGeometry(geom.symDifference(cur_geom)) new_geom = QgsGeometry(int_com.difference(int_sym)) if new_geom.isGeosEmpty( ) or not new_geom.isGeosValid(): ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr( 'GEOS geoprocessing error: One or more ' 'input features have invalid geometry.')) continue try: outFeat.setGeometry(new_geom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr('Feature geometry error: One or more ' 'output features ignored due to ' 'invalid geometry.')) continue progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): commands = list() self.exportedLayers = {} self.preProcessInputs() # 1: Export rasters to sgrd and vectors to shp # Tables must be in dbf format. We check that. for param in self.parameters: if isinstance(param, ParameterRaster): if param.value is None: continue if param.value.endswith('sdat'): param.value = param.value[:-4] + "sgrd" elif not param.value.endswith('sgrd'): exportCommand = self.exportRasterLayer(param.value) if exportCommand is not None: commands.append(exportCommand) if isinstance(param, ParameterVector): if param.value is None: continue layer = dataobjects.getObjectFromUri(param.value, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[param.value] = filename elif not param.value.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterTable): if param.value is None: continue table = dataobjects.getObjectFromUri(param.value, False) if table: filename = dataobjects.exportTable(table) self.exportedLayers[param.value] = filename elif not param.value.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterMultipleInput): if param.value is None: continue layers = param.value.split(';') if layers is None or len(layers) == 0: continue if param.datatype == ParameterMultipleInput.TYPE_RASTER: for i, layerfile in enumerate(layers): if layerfile.endswith('sdat'): layerfile = param.value[:-4] + "sgrd" layers[i] = layerfile elif not layerfile.endswith('sgrd'): exportCommand = self.exportRasterLayer(layerfile) if exportCommand is not None: commands.append(exportCommand) param.value = ";".join(layers) elif param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY: for layerfile in layers: layer = dataobjects.getObjectFromUri(layerfile, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[layerfile] = filename elif not layerfile.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) # 2: Set parameters and outputs command = self.undecoratedGroup + ' "' + self.cmdname + '"' command += ' ' + ' '.join(self.hardcodedStrings) for param in self.parameters: if param.value is None: continue if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable)): value = param.value if value in self.exportedLayers.keys(): command += ' -' + param.name + ' "' \ + self.exportedLayers[value] + '"' else: command += ' -' + param.name + ' "' + value + '"' elif isinstance(param, ParameterMultipleInput): s = param.value for layer in self.exportedLayers.keys(): s = s.replace(layer, self.exportedLayers[layer]) command += ' -' + param.name + ' "' + s + '"' elif isinstance(param, ParameterBoolean): if param.value: command += ' -' + param.name.strip() + " true" else: command += ' -' + param.name.strip() + " false" elif isinstance(param, ParameterFixedTable): tempTableFile = getTempFilename('txt') f = open(tempTableFile, 'w') f.write('\t'.join([col for col in param.cols]) + '\n') values = param.value.split(',') for i in range(0, len(values), 3): s = values[i] + '\t' + values[i + 1] + '\t' + values[i + 2] + '\n' f.write(s) f.close() command += ' -' + param.name + ' "' + tempTableFile + '"' elif isinstance(param, ParameterExtent): # 'We have to substract/add half cell size, since SAGA is # center based, not corner based halfcell = self.getOutputCellsize() / 2 offset = [halfcell, -halfcell, halfcell, -halfcell] values = param.value.split(',') for i in range(4): command += ' -' + self.extentParamNames[i] + ' ' \ + unicode(float(values[i]) + offset[i]) elif isinstance(param, (ParameterNumber, ParameterSelection)): command += ' -' + param.name + ' ' + unicode(param.value) else: command += ' -' + param.name + ' "' + unicode(param.value) + '"' for out in self.outputs: command += ' -' + out.name + ' "' + out.getCompatibleFileName(self) + '"' commands.append(command) # special treatment for RGB algorithm #TODO: improve this and put this code somewhere else for out in self.outputs: if isinstance(out, OutputRaster): filename = out.getCompatibleFileName(self) filename2 = filename + '.sgrd' if self.cmdname == 'RGB Composite': commands.append('io_grid_image 0 -IS_RGB -GRID:"' + filename2 + '" -FILE:"' + filename + '"') # 3: Run SAGA commands = self.editCommands(commands) SagaUtils.createSagaBatchJobFileFromSagaCommands(commands) loglines = [] loglines.append(self.tr('SAGA execution commands')) for line in commands: progress.setCommand(line) loglines.append(line) if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_COMMANDS): ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) SagaUtils.executeSaga(progress) if self.crs is not None: for out in self.outputs: if isinstance(out, (OutputVector, OutputRaster)): prjFile = os.path.splitext(out.getCompatibleFileName(self))[0] + ".prj" with open(prjFile, "w") as f: f.write(self.crs.toWkt())
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.POINTS)) weightField = self.getParameterValue(self.WEIGHT) uniqueField = self.getParameterValue(self.UID) if weightField is None: weightIndex = -1 else: weightIndex = layer.fieldNameIndex(weightField) if uniqueField is None: uniqueIndex = -1 else: uniqueIndex = layer.fieldNameIndex(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, QGis.WKBPoint, layer.crs()) features = vector.features(layer) total = 100.0 / len(features) if len(features) > 0 else 1 means = {} for current, feat in enumerate(features): progress.setPercentage(int(current * total)) if uniqueIndex == -1: clazz = "Single class" else: clazz = unicode(feat.attributes()[uniqueIndex]).strip() if weightIndex == -1: weight = 1.00 else: try: weight = float(feat.attributes()[weightIndex]) except: weight = 1.00 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) if len(means) > 0 else 1 for (clazz, values) in means.iteritems(): if values[2]: 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 progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): vlayerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) vlayerB = dataobjects.getObjectFromUri( 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): progress.setPercentage(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.isGeosEmpty() 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): layer = dataobjects.getObjectFromUri( 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 = processing.getObject(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 = processing.getObject(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, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue( self.LAYER)) self.setOutputValue(self.CRS, layer.crs().authid())
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) index = self.getParameterValue(self.TYPE) splitNodes = False if index == 0: newType = QgsWkbTypes.Point elif index == 1: newType = QgsWkbTypes.Point splitNodes = True elif index == 2: newType = QgsWkbTypes.LineString elif index == 3: newType = QgsWkbTypes.MultiLineString elif index == 4: newType = QgsWkbTypes.Polygon else: newType = QgsWkbTypes.Point writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.fields(), newType, layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): geom = f.geometry() geomType = geom.wkbType() if geomType in [QgsWkbTypes.Point, QgsWkbTypes.Point25D]: if newType == QgsWkbTypes.Point: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from {0} to {1}').format(geomType, newType)) elif geomType in [QgsWkbTypes.MultiPoint, QgsWkbTypes.MultiPoint25D]: if newType == QgsWkbTypes.Point and splitNodes: points = geom.asMultiPoint() for p in points: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from {0} to {1}').format(geomType, newType)) elif geomType in [QgsWkbTypes.LineString, QgsWkbTypes.LineString25D]: if newType == QgsWkbTypes.Point and splitNodes: points = geom.asPolyline() for p in points: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.LineString: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from {0} to {1}').format(geomType, newType)) elif geomType in [QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiLineString25D]: if newType == QgsWkbTypes.Point and splitNodes: lines = geom.asMultiPolyline() for line in lines: for p in line: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.LineString: lines = geom.asMultiPolyline() for line in lines: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPolyline(line)) writer.addFeature(feat) elif newType == QgsWkbTypes.MultiLineString: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from {0} to {1}').format(geomType, newType)) elif geomType in [QgsWkbTypes.Polygon, QgsWkbTypes.Polygon25D]: if newType == QgsWkbTypes.Point and splitNodes: rings = geom.asPolygon() for ring in rings: for p in ring: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.MultiLineString: rings = geom.asPolygon() feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromMultiPolyline(rings)) writer.addFeature(feat) elif newType == QgsWkbTypes.Polygon: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from {0} to {1}').format(geomType, newType)) elif geomType in [QgsWkbTypes.MultiPolygon, QgsWkbTypes.MultiPolygon25D]: if newType == QgsWkbTypes.Point and splitNodes: polygons = geom.asMultiPolygon() for polygon in polygons: for line in polygon: for p in line: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPoint(p)) writer.addFeature(feat) elif newType == QgsWkbTypes.Point: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(geom.centroid()) writer.addFeature(feat) elif newType == QgsWkbTypes.LineString: polygons = geom.asMultiPolygon() for polygons in polygons: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPolyline(polygon)) writer.addFeature(feat) elif newType == QgsWkbTypes.Polygon: polygons = geom.asMultiPolygon() for polygon in polygons: feat = QgsFeature() feat.setAttributes(f.attributes()) feat.setGeometry(QgsGeometry.fromPolygon(polygon)) writer.addFeature(feat) elif newType in [QgsWkbTypes.MultiLineString, QgsWkbTypes.MultiPolygon]: writer.addFeature(f) else: raise GeoAlgorithmExecutionException( self.tr('Cannot convert from {0} to {1}').format(geomType, newType)) feedback.setProgress(int(current * total)) del writer
def getObject(uri): """Returns the QGIS object identified by the given URI.""" return dataobjects.getObjectFromUri(uri)
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri(self.getParameterValue( self.INPUT)) hSpacing = self.getParameterValue(self.HSPACING) vSpacing = self.getParameterValue(self.VSPACING) if hSpacing <= 0 or vSpacing <= 0: raise GeoAlgorithmExecutionException( self.tr('Invalid grid spacing: %s/%s' % (hSpacing, vSpacing))) 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): geom = f.geometry() geomType = geom.wkbType() if geomType == QgsWkbTypes.Point: points = self._gridify([geom.asPoint()], hSpacing, vSpacing) newGeom = QgsGeometry.fromPoint(points[0]) elif geomType == QgsWkbTypes.MultiPoint: points = self._gridify(geom.aMultiPoint(), hSpacing, vSpacing) newGeom = QgsGeometry.fromMultiPoint(points) elif geomType == QgsWkbTypes.LineString: points = self._gridify(geom.asPolyline(), hSpacing, vSpacing) if len(points) < 2: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Failed to gridify feature with FID %s' % f.id())) newGeom = None else: newGeom = QgsGeometry.fromPolyline(points) elif geomType == QgsWkbTypes.MultiLineString: polyline = [] for line in geom.asMultiPolyline(): points = self._gridify(line, hSpacing, vSpacing) if len(points) > 1: polyline.append(points) if len(polyline) <= 0: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Failed to gridify feature with FID %s' % f.id())) newGeom = None else: newGeom = QgsGeometry.fromMultiPolyline(polyline) elif geomType == QgsWkbTypes.Polygon: polygon = [] for line in geom.asPolygon(): points = self._gridify(line, hSpacing, vSpacing) if len(points) > 1: polygon.append(points) if len(polygon) <= 0: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Failed to gridify feature with FID %s' % f.id())) newGeom = None else: newGeom = QgsGeometry.fromPolygon(polygon) elif geomType == QgsWkbTypes.MultiPolygon: multipolygon = [] for polygon in geom.asMultiPolygon(): newPolygon = [] for line in polygon: points = self._gridify(line, hSpacing, vSpacing) if len(points) > 2: newPolygon.append(points) if len(newPolygon) > 0: multipolygon.append(newPolygon) if len(multipolygon) <= 0: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Failed to gridify feature with FID %s' % f.id())) newGeom = None else: newGeom = QgsGeometry.fromMultiPolygon(multipolygon) if newGeom is not None: feat = QgsFeature() feat.setGeometry(newGeom) feat.setAttributes(f.attributes()) writer.addFeature(feat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, progress): target = dataobjects.getObjectFromUri( self.getParameterValue(self.TARGET)) join = dataobjects.getObjectFromUri(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: if predicate == 'intersects': res = inGeom.intersects(inGeomB) elif predicate == 'contains': res = inGeom.contains(inGeomB) elif predicate == 'equals': res = inGeom.equals(inGeomB) elif predicate == 'touches': res = inGeom.touches(inGeomB) elif predicate == 'overlaps': res = inGeom.overlaps(inGeomB) elif predicate == 'within': res = inGeom.within(inGeomB) elif predicate == 'crosses': res = inGeom.crosses(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) progress.setPercentage(int(c * total)) del writer
def processAlgorithm(self, progress): swmm_cli = os.path.abspath(ProcessingConfig.getSetting('Swmm_CLI')) if not swmm_cli: raise GeoAlgorithmExecutionException( 'Swmm command line toom is not configured.\n\ Please configure it before running Swmm algorithms.') folder = ProcessingConfig.getSetting(ProcessingConfig.OUTPUT_FOLDER) filename = os.path.join(folder, 'swmm.inp') f = codecs.open(filename, 'w', encoding='utf-8') f.write('[TITLE]\n') f.write(self.getParameterValue(self.TITLE) + '\n\n') f.write( self.swmmKeyVal(self.OPTIONS, self.getParameterValue(self.TITLE))) f.write( self.swmmKeyVal(self.REPORT, self.getParameterValue(self.TITLE))) f.write(self.swmmTable(self.FILES)) f.write(self.swmmTable(self.RAINGAGES)) f.write(self.swmmTable(self.HYDROGRAPHS)) f.write( self.swmmKeyVal(self.EVAPORATION, self.getParameterValue(self.TITLE))) f.write(self.swmmTable(self.TEMPERATURE)) f.write(self.swmmTable(self.SUBCATCHMENTS)) f.write(self.swmmTable(self.SUBAREAS)) f.write(self.swmmTable(self.INFILTRATION)) f.write(self.swmmTable(self.LID_CONTROLS)) f.write(self.swmmTable(self.LID_USAGE)) f.write(self.swmmTable(self.AQUIFERS)) f.write(self.swmmTable(self.GROUNDWATER)) f.write(self.swmmTable(self.SNOWPACKS)) f.write(self.swmmTable(self.JUNCTIONS)) f.write(self.swmmTable(self.OUTFALLS)) f.write(self.swmmTable(self.DIVIDERS)) f.write(self.swmmTable(self.STORAGE)) f.write(self.swmmTable(self.CONDUITS)) f.write(self.swmmTable(self.PUMPS)) f.write(self.swmmTable(self.ORIFICES)) f.write(self.swmmTable(self.WEIRS)) f.write(self.swmmTable(self.OUTLETS)) f.write(self.swmmTable(self.XSECTIONS)) f.write(self.swmmTable(self.TRANSECTS)) f.write(self.swmmTable(self.LOSSES)) f.write(self.swmmTable(self.CONTROLS)) f.write(self.swmmTable(self.POLLUTANTS)) f.write(self.swmmTable(self.LANDUSES)) f.write(self.swmmTable(self.COVERAGES)) f.write(self.swmmTable(self.BUILDUP)) f.write(self.swmmTable(self.WASHOFF)) f.write(self.swmmTable(self.TREATMENT)) f.write(self.swmmTable(self.INFLOWS)) f.write(self.swmmTable(self.DWF)) f.write(self.swmmTable(self.PATTERNS)) f.write(self.swmmTable(self.RDII)) f.write(self.swmmTable(self.LOADINGS)) f.write(self.swmmTable(self.CURVES)) f.write(self.swmmTable(self.TIMESERIES)) f.close() outfilename = os.path.join(folder, 'swmm.out') progress.setText('running simulation') log = "" proc = subprocess.Popen( # this doesn't work on linux, but IMHO should # [swmm_cli, filename, outfilename] # this works on linux swmm_cli + ' ' + filename + ' ' + outfilename, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=False, ).stdout for line in iter(proc.readline, ''): log += line ProcessingLog.addToLog(ProcessingLog.LOG_INFO, log) if re.search('There are errors', log): o = open(outfilename, 'r') ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, o.read()) o.close() raise RuntimeError('There were errors, look into logs for details') progress.setText('postprocessing output') # put features in a map indexed by the identifier (first column) layer = dataobjects.getObjectFromUri( self.getParameterValue(self.JUNCTIONS)) node_fields = QgsFields() node_fields.append(QgsField('Node', QVariant.String)) node_fields.append(QgsField('Time', QVariant.String)) node_fields.append(QgsField('Inflow', QVariant.Double)) node_fields.append(QgsField('Flooding', QVariant.Double)) node_fields.append(QgsField('Depth', QVariant.Double)) node_fields.append(QgsField('Head', QVariant.Double)) node_feat = {} for feat in layer.getFeatures(): if feat.geometry() and feat.geometry().exportToWkt(): node_feat[feat.attributes()[0]] = feat node_writer = self.getOutputFromName(self.NODE_OUTPUT).getVectorWriter( node_fields.toList(), QGis.WKBPoint, layer.crs()) node_table_writer = self.getOutputFromName( self.NODE_TABLE_OUTPUT).getTableWriter(node_fields.toList()) layer = dataobjects.getObjectFromUri( self.getParameterValue(self.CONDUITS)) link_fields = QgsFields() link_fields.append(QgsField('Link', QVariant.String)) link_fields.append(QgsField('Time', QVariant.String)) link_fields.append(QgsField('Flow', QVariant.Double)) link_fields.append(QgsField('Velocity', QVariant.Double)) link_fields.append(QgsField('Depth', QVariant.Double)) link_fields.append(QgsField('PercentFull', QVariant.Double)) link_feat = {} for feat in layer.getFeatures(): if feat.geometry() and feat.geometry().exportToWkt(): link_feat[feat.attributes()[0]] = feat link_writer = self.getOutputFromName(self.LINK_OUTPUT).getVectorWriter( link_fields.toList(), QGis.WKBLineString, layer.crs()) # here we create output layers # it's a python implementation of a join # on the identifyer field between the results an the JUNCTIONS or PIPES # geometries total_size = os.path.getsize(outfilename) total_read = 0 o = codecs.open(outfilename, 'r', encoding='utf-8') # get nodes results link_id = '' node_id = '' line = o.readline() while line: line = line.rstrip() if (node_id or link_id) and not line: link_id = '' node_id = '' if re.search('^ <<< Node ', line): node_id = line[11:-4] for i in range(5): line = o.readline() line = line.rstrip() if re.search('^ <<< Link ', line): link_id = line[11:-4] for i in range(5): line = o.readline() line = line.rstrip() if node_id: feature = QgsFeature(node_fields) tbl = line.split() if len(tbl) >= 6: feature['Node'] = node_id feature['Time'] = convert_date(tbl[0]) + ' ' + tbl[1] feature['Inflow'] = tbl[2] feature['Flooding'] = tbl[3] feature['Depth'] = tbl[4] feature['Head'] = tbl[5] feat = node_feat.get(node_id, None) if feat: feature.setGeometry(feat.geometry()) node_writer.addFeature(feature) node_table_writer.addRecord([node_id] + tbl) if link_id: feature = QgsFeature(link_fields) tbl = line.split() if len(tbl) >= 6: feature['Link'] = link_id feature['Time'] = convert_date(tbl[0]) + ' ' + tbl[1] feature['Flow'] = tbl[2] feature['Velocity'] = tbl[3] feature['Depth'] = tbl[4] feature['PercentFull'] = tbl[5] feat = link_feat.get(link_id, None) if feat: feature.setGeometry(feat.geometry()) link_writer.addFeature(feature) line = o.readline() total_read += len(line) progress.setPercentage(int(100 * total_read / total_size)) o.close()
def processAlgorithm(self, progress): useField = not self.getParameterValue(Dissolve.DISSOLVE_ALL) field_names = self.getParameterValue(Dissolve.FIELD) vlayerA = dataobjects.getObjectFromUri( self.getParameterValue(Dissolve.INPUT)) writer = self.getOutputFromName(Dissolve.OUTPUT).getVectorWriter( vlayerA.fields().toList(), vlayerA.wkbType(), vlayerA.crs()) outFeat = QgsFeature() features = vector.features(vlayerA) total = 100.0 / len(features) if not useField: first = True # we dissolve geometries in blocks using unaryUnion geom_queue = [] for current, inFeat in enumerate(features): progress.setPercentage(int(current * total)) if first: outFeat.setAttributes(inFeat.attributes()) first = False tmpInGeom = inFeat.geometry() if tmpInGeom.isEmpty() or tmpInGeom.isGeosEmpty(): continue errors = tmpInGeom.validateGeometry() if len(errors) != 0: for error in errors: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr('ValidateGeometry()' 'error: One or more ' 'input features have ' 'invalid geometry: ') + error.what()) continue geom_queue.append(tmpInGeom) if len(geom_queue) > 10000: # queue too long, combine it try: temp_output_geometry = QgsGeometry.unaryUnion( geom_queue) geom_queue = [temp_output_geometry] except: raise GeoAlgorithmExecutionException( self.tr('Geometry exception while dissolving')) try: outFeat.setGeometry(QgsGeometry.unaryUnion(geom_queue)) except: raise GeoAlgorithmExecutionException( self.tr('Geometry exception while dissolving')) writer.addFeature(outFeat) else: field_indexes = [ vlayerA.fields().lookupField(f) for f in field_names.split(';') ] attribute_dict = {} geometry_dict = defaultdict(lambda: []) for inFeat in features: attrs = inFeat.attributes() index_attrs = tuple([attrs[i] for i in field_indexes]) tmpInGeom = QgsGeometry(inFeat.geometry()) if tmpInGeom.isGeosEmpty(): continue errors = tmpInGeom.validateGeometry() if len(errors) != 0: for error in errors: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr('ValidateGeometry() ' 'error: One or more input' 'features have invalid ' 'geometry: ') + error.what()) if not index_attrs in attribute_dict: # keep attributes of first feature attribute_dict[index_attrs] = attrs geometry_dict[index_attrs].append(tmpInGeom) nFeat = len(attribute_dict) nElement = 0 for key, value in list(geometry_dict.items()): outFeat = QgsFeature() nElement += 1 progress.setPercentage(int(nElement * 100 / nFeat)) try: tmpOutGeom = QgsGeometry.unaryUnion(value) except: raise GeoAlgorithmExecutionException( self.tr('Geometry exception while dissolving')) outFeat.setGeometry(tmpOutGeom) outFeat.setAttributes(attribute_dict[key]) writer.addFeature(outFeat) del writer
def processAlgorithm(self, progress): """ Based on code by Matthew Perry https://gist.github.com/perrygeo/5667173 """ layer = dataobjects.getObjectFromUri( 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 progress.setPercentage(int(current * total)) rasterDS = None del writer
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_A)) layerB = dataobjects.getObjectFromUri( 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) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, feedback): layer = dataobjects.getObjectFromUri(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, progress): database = self.getParameterValue(self.DATABASE) uri = QgsDataSourceUri(database) if uri.database() is '': if '|layerid' in database: database = database[:database.find('|layerid')] uri = QgsDataSourceUri('dbname=\'%s\'' % (database)) db = spatialite.GeoDB(uri) 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.getObjectFromUri(layerUri) table = self.getParameterValue(self.TABLENAME) if table: table.strip() if not table or table == '': table = layer.name() table = table.replace(' ', '').lower() providerName = 'spatialite' 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('', 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 Spatialite\n%s' % errMsg)) if geomColumn and createIndex: db.create_spatial_index(table, geomColumn)
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_A)) layerB = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_B)) fieldA = self.getParameterValue(self.FIELD_A) fieldB = self.getParameterValue(self.FIELD_B) idxA = layerA.fieldNameIndex(fieldA) idxB = layerB.fieldNameIndex(fieldB) fieldList = [ layerA.pendingFields()[idxA], layerB.pendingFields()[idxB] ] writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fieldList, QGis.WKBPoint, layerA.dataProvider().crs()) spatialIndex = vector.spatialindex(layerB) outFeat = QgsFeature() features = vector.features(layerA) total = 100.0 / len(features) hasIntersections = False for current, inFeatA in enumerate(features): inGeom = inFeatA.geometry() hasIntersections = False lines = spatialIndex.intersects(inGeom.boundingBox()) if len(lines) > 0: hasIntersections = True if hasIntersections: for i in lines: request = QgsFeatureRequest().setFilterFid(i) inFeatB = layerB.getFeatures(request).next() tmpGeom = QgsGeometry(inFeatB.geometry()) points = [] attrsA = inFeatA.attributes() attrsB = inFeatB.attributes() if inGeom.intersects(tmpGeom): tempGeom = inGeom.intersection(tmpGeom) if tempGeom.type() == QGis.Point: if tempGeom.isMultipart(): points = tempGeom.asMultiPoint() else: points.append(tempGeom.asPoint()) for j in points: outFeat.setGeometry(tempGeom.fromPoint(j)) outFeat.setAttributes( [attrsA[idxA], attrsB[idxB]]) writer.addFeature(outFeat) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, feedback): source_layer = dataobjects.getObjectFromUri( self.getParameterValue(Clip.INPUT)) mask_layer = dataobjects.getObjectFromUri( self.getParameterValue(Clip.OVERLAY)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( source_layer.fields(), QgsWkbTypes.multiType(source_layer.wkbType()), source_layer.crs()) # first build up a list of clip geometries clip_geoms = [] for maskFeat in vector.features( mask_layer, QgsFeatureRequest().setSubsetOfAttributes([])): clip_geoms.append(maskFeat.geometry()) # are we clipping against a single feature? if so, we can show finer progress reports if len(clip_geoms) > 1: combined_clip_geom = QgsGeometry.unaryUnion(clip_geoms) single_clip_feature = False else: combined_clip_geom = clip_geoms[0] single_clip_feature = True # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine( combined_clip_geom.geometry()) engine.prepareGeometry() tested_feature_ids = set() for i, clip_geom in enumerate(clip_geoms): input_features = [ f for f in vector.features( source_layer, QgsFeatureRequest().setFilterRect(clip_geom.boundingBox())) ] if not input_features: continue if single_clip_feature: total = 100.0 / len(input_features) else: total = 0 for current, in_feat in enumerate(input_features): if not in_feat.geometry(): continue if in_feat.id() in tested_feature_ids: # don't retest a feature we have already checked continue tested_feature_ids.add(in_feat.id()) if not engine.intersects(in_feat.geometry().geometry()): continue if not engine.contains(in_feat.geometry().geometry()): cur_geom = in_feat.geometry() new_geom = combined_clip_geom.intersection(cur_geom) if new_geom.wkbType( ) == QgsWkbTypes.Unknown or QgsWkbTypes.flatType( new_geom.geometry().wkbType( )) == QgsWkbTypes.GeometryCollection: int_com = in_feat.geometry().combine(new_geom) int_sym = in_feat.geometry().symDifference(new_geom) new_geom = int_com.difference(int_sym) else: # clip geometry totally contains feature geometry, so no need to perform intersection new_geom = in_feat.geometry() try: out_feat = QgsFeature() out_feat.setGeometry(new_geom) out_feat.setAttributes(in_feat.attributes()) writer.addFeature(out_feat) except: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr('Feature geometry error: One or more ' 'output features ignored due to ' 'invalid geometry.')) continue if single_clip_feature: feedback.setProgress(int(current * total)) if not single_clip_feature: # coarse progress report for multiple clip geometries feedback.setProgress(100.0 * i / len(clip_geoms)) del writer
def processAlgorithm(self, progress): radius = self.getParameterValue(self.DISTANCE) horizontal = self.getParameterValue(self.HORIZONTAL) output = self.getOutputFromName(self.OUTPUT_LAYER) layer = dataobjects.getObjectFromUri(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()]) progress.setPercentage(int(current * total)) current = 0 total = 100.0 / len(duplicates) progress.setPercentage(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 progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, feedback): layerPoints = dataobjects.getObjectFromUri( self.getParameterValue(self.POINTS)) layerHubs = dataobjects.getObjectFromUri( self.getParameterValue(self.HUBS)) fieldName = self.getParameterValue(self.FIELD) addLines = self.getParameterValue(self.GEOMETRY) 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().srsid()) 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, feedback): lineLayer = dataobjects.getObjectFromUri( self.getParameterValue(self.LINES)) polyLayer = dataobjects.getObjectFromUri( 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()) spatialIndex = vector.spatialindex(lineLayer) ftLine = QgsFeature() ftPoly = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() distArea = QgsDistanceArea() features = vector.features(polyLayer) total = 100.0 / len(features) 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, progress): polyLayer = dataobjects.getObjectFromUri( self.getParameterValue(self.POLYGONS)) pointLayer = dataobjects.getObjectFromUri( self.getParameterValue(self.POINTS)) fieldName = self.getParameterValue(self.FIELD) fieldIdx = pointLayer.fieldNameIndex( self.getParameterValue(self.WEIGHT)) polyProvider = polyLayer.dataProvider() fields = polyProvider.fields() fields.append(QgsField(fieldName, QVariant.Int)) (idxCount, fieldList) = vector.findOrCreateField(polyLayer, polyLayer.pendingFields(), fieldName) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields.toList(), polyProvider.geometryType(), polyProvider.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: progress.setText(unicode(len(points))) request = QgsFeatureRequest().setFilterFids(points) fit = pointLayer.getFeatures(request) ftPoint = QgsFeature() while fit.nextFeature(ftPoint): tmpGeom = QgsGeometry(ftPoint.geometry()) if engine.contains(tmpGeom.geometry()): weight = unicode(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) progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): filename = self.getParameterValue(self.INPUT) inputLayer = dataobjects.getObjectFromUri(filename) method = self.getParameterValue(self.METHOD) filename2 = self.getParameterValue(self.INTERSECT) selectLayer = dataobjects.getObjectFromUri(filename2) predicates = self.getParameterValue(self.PREDICATE) precision = self.getParameterValue(self.PRECISION) oldSelection = set(inputLayer.selectedFeaturesIds()) 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) for i in intersects: request = QgsFeatureRequest().setFilterFid(i) feat = inputLayer.getFeatures(request).next() 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: if predicate == 'intersects': res = tmpGeom.intersects(geom) elif predicate == 'contains': res = tmpGeom.contains(geom) elif predicate == 'equals': res = tmpGeom.equals(geom) elif predicate == 'touches': res = tmpGeom.touches(geom) elif predicate == 'overlaps': res = tmpGeom.overlaps(geom) elif predicate == 'within': res = tmpGeom.within(geom) elif predicate == 'crosses': res = tmpGeom.crosses(geom) if res: selectedSet.append(feat.id()) break progress.setPercentage(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)