def save2PointShape(shapePath, geodata, attribName, attribData, label, spatialRef): """ :param label: :param shapePath: Pfad wo Shapefile agespeichert wird :param geodata: Koordinaten der Punkte :param attribName: Attributname (Feldname) von zusätzlichen Werten :param attribData: Werte für Attribute :param spatialRef: Räumliche Referenz """ # define fields for feature attributes. A QgsFields object is needed fields = QgsFields() fields.append(QgsField("StuetzenNr", QVariant.String)) fields.append(QgsField(attribName, QVariant.Int)) writer = QgsVectorFileWriter(shapePath, "UTF8", fields, QgsWkbTypes.PointZ, spatialRef, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: # TODO raise Exception("Vector Writer") for idx, (coords, attrib) in enumerate(zip(geodata, attribData)): feature = QgsFeature() feature.setFields(fields) # TODO: Nicht 3D weil Methode fromPoint() nicht existiert. Wird evtl. in der Zukunft implementiert feature.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(coords[0], coords[1]))) feature.setId(idx) feature.setAttribute("StuetzenNr", label[idx]) feature.setAttribute(attribName, attrib) writer.addFeature(feature) del feature # delete the writer to flush features to disk del writer
def _create_grid(self, grid_name, grid_file, x_min, y_min, x_max, y_max, x_off, y_off): x_off2, y_off2 = x_off / 2.0, y_off / 2.0 x_min = floor(x_min / x_off) * x_off x_max = ceil(x_max / x_off) * x_off y_min = floor(y_min / y_off) * y_off y_max = ceil(y_max / y_off) * y_off xtotal = int((x_max - x_min) / x_off) + 1 ytotal = int((y_max - y_min) / y_off) + 1 logAPICall.log( "x_min %f x_max %f y_min %f y_max %f x_off %f y_off %f xtotal %d, ytotal %d" % (x_min, x_max, y_min, y_max, x_off, y_off, xtotal, ytotal), logAPICall.DEBUG_L2, ) fields = {0: QgsField("GRID_GID", QVariant.String)} writer = QgsVectorFileWriter(grid_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile") f = QgsFeature() for x in range(xtotal): for y in range(ytotal): lon = x_min + (x * x_off) + (x_off2) lat = y_min + (y * y_off) + (y_off2) # out_geom = QgsGeometry.fromRect(QgsRectangle(lon-x_off2, lat-y_off2, # lon+x_off2, lat+y_off2)) f.setGeometry(self._outputGeometryFromLatLon(lat, lon)) f.addAttribute(0, QVariant(latlon_to_grid(lat, lon))) writer.addFeature(f) del writer return load_shapefile(grid_file, grid_name)
def multi_to_single( self ): vprovider = self.vlayer.dataProvider() geomType = self.multiToSingleGeom( vprovider.geometryType() ) writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(), geomType, vprovider.crs() ) inFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() nFeat = vprovider.featureCount() nElement = 0 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0 ) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) ) fit = vprovider.getFeatures() while fit.nextFeature( inFeat ): nElement += 1 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement ) inGeom = inFeat.geometry() atMap = inFeat.attributes() featList = self.extractAsSingle( inGeom ) outFeat.setAttributes( atMap ) for i in featList: outFeat.setGeometry( i ) writer.addFeature( outFeat ) del writer return True
def _write_grid_shapefile(self, path, x_min, y_min, x_max, y_max, x_off, y_off): x_off = self._x_off y_off = self._y_off x_min = floor(x_min / x_off) * x_off x_max = ceil(x_max / x_off) * x_off y_min = floor(y_min / y_off) * y_off y_max = ceil(y_max / y_off) * y_off xtotal = int((x_max - x_min) / x_off) ytotal = int((y_max - y_min) / y_off) logAPICall.log('x_min %f x_max %f y_min %f y_max %f x_off %f y_off %f xtotal %d, ytotal %d' % (x_min, x_max, y_min, y_max, x_off, y_off, xtotal, ytotal), logAPICall.DEBUG_L2) writer = QgsVectorFileWriter(path, "utf-8", self._fields, QGis.WKBPoint, self._crs, "ESRI Shapefile") f = QgsFeature() for x in range(xtotal): for y in range(ytotal): lon = x_min + (x * x_off) + (x_off/2.0) lat = y_min + (y * y_off) + (y_off/2.0) f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat))) f.addAttribute(0, QVariant(lon)) f.addAttribute(1, QVariant(lat)) writer.addFeature(f) del writer
def extract_nodes( self ): vprovider = self.vlayer.dataProvider() writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(), QGis.WKBPoint, vprovider.crs() ) inFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() nFeat = vprovider.featureCount() nElement = 0 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0 ) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) ) fit = vprovider.getFeatures() while fit.nextFeature( inFeat ): nElement += 1 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement ) inGeom = inFeat.geometry() atMap = inFeat.attributes() pointList = ftools_utils.extractPoints( inGeom ) outFeat.setAttributes( atMap ) for i in pointList: outFeat.setGeometry( outGeom.fromPoint( i ) ) writer.addFeature( outFeat ) del writer return True
def polygons_to_lines( self ): vprovider = self.vlayer.dataProvider() writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(), QGis.WKBLineString, vprovider.crs() ) inFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() nFeat = vprovider.featureCount() nElement = 0 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) ) fit = vprovider.getFeatures() while fit.nextFeature( inFeat ): nElement += 1 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement ) inGeom = inFeat.geometry() atMap = inFeat.attributes() lineList = self.extractAsLine( inGeom ) outFeat.setAttributes( atMap ) for h in lineList: outFeat.setGeometry( outGeom.fromPolyline( h ) ) writer.addFeature( outFeat ) del writer return True
def lines_to_polygons( self ): vprovider = self.vlayer.dataProvider() writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(), QGis.WKBPolygon, vprovider.crs() ) inFeat = QgsFeature() outFeat = QgsFeature() nFeat = vprovider.featureCount() nElement = 0 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) ) fit = vprovider.getFeatures() while fit.nextFeature( inFeat ): outGeomList = [] nElement += 1 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement ) if inFeat.geometry().isMultipart(): outGeomList = inFeat.geometry().asMultiPolyline() else: outGeomList.append( inFeat.geometry().asPolyline() ) polyGeom = self.remove_bad_lines( outGeomList ) if len( polyGeom ) != 0: outFeat.setGeometry( QgsGeometry.fromPolygon( polyGeom ) ) atMap = inFeat.attributes() outFeat.setAttributes( atMap ) writer.addFeature( outFeat ) del writer return True
def do_operation(self): """ perform create mapping scheme operation """ # input/output verification already performed during set input/ouput zone_layer = self.inputs[0].value zone_field = self.inputs[1].value fp_layer = self.inputs[2].value # merge with zone to get assignment tmp_join = 'joined_%s' % get_unique_filename() tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join) analyzer = QgsOverlayAnalyzer() try: analyzer.intersection(fp_layer, zone_layer, tmp_join_file) tmp_join_layer = load_shapefile_verify(tmp_join_file, tmp_join,[zone_field]) except AssertionError as err: raise OperatorError(str(err), self.__class__) except Exception as err: raise OperatorError(str(err), self.__class__) fields = { 0 : QgsField(self._lon_field, QVariant.Double), 1 : QgsField(self._lat_field, QVariant.Double), 2 : QgsField(zone_field, QVariant.String), } zone_idx = layer_field_index(tmp_join_layer, zone_field) fp_layername = 'fpc_%s' % get_unique_filename() fp_file = '%s%s.shp' % (self._tmp_dir, fp_layername) try: writer = QgsVectorFileWriter(fp_file, "utf-8", fields, QGis.WKBPoint, self._crs, "ESRI Shapefile") f = QgsFeature() for _f in layer_features(tmp_join_layer): centroid = _f.geometry().centroid().asPoint() lon = centroid.x() lat = centroid.y() zone_str = str(_f.attributeMap()[zone_idx].toString()).upper() f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat))) f.addAttribute(0, QVariant(lon)) f.addAttribute(1, QVariant(lat)) f.addAttribute(2, QVariant(zone_str)) writer.addFeature(f) del writer except Exception as err: logAPICall.log(err, logAPICall.ERROR) remove_shapefile(fp_file) raise OperatorError("error creating joined grid: %s" % err, self.__class__) # load shapefile as layer fp_layer = load_shapefile(fp_file, fp_layername) if not fp_layer: raise OperatorError('Error loading footprint centroid file' % (fp_file), self.__class__) # clean up del tmp_join_layer remove_shapefile(tmp_join_file) self.outputs[0].value = fp_layer self.outputs[1].value = fp_file
def processAlgorithm(self, progress): """Here is where the processing itself takes place.""" # The first thing to do is retrieve the values of the parameters # entered by the user inputFilename = self.getParameterValue(self.INPUT_LAYER) output = self.getOutputValue(self.OUTPUT_LAYER) # Input layers vales are always a string with its location. # That string can be converted into a QGIS object (a # QgsVectorLayer in this case) using the # processing.getObjectFromUri() method. vectorLayer = dataobjects.getObjectFromUri(inputFilename) # And now we can process # First we create the output layer. The output value entered by # the user is a string containing a filename, so we can use it # directly settings = QSettings() systemEncoding = settings.value('/UI/encoding', 'System') writer = QgsVectorFileWriter(output, systemEncoding, vectorLayer.fields(), vectorLayer.wkbType(), vectorLayer.crs()) # Now we take the features from input layer and add them to the # output. Method features() returns an iterator, considering the # selection that might exist in layer and the configuration that # indicates should algorithm use only selected features or all # of them features = vector.features(vectorLayer) for f in features: writer.addFeature(f)
def exportVectorLayer(layer, supported=None): """Takes a QgsVectorLayer and returns the filename to refer to it, which allows external apps which support only file-based layers to use it. It performs the necessary export in case the input layer is not in a standard format suitable for most applications, it is a remote one or db-based (non-file based) one, or if there is a selection and it should be used, exporting just the selected features. Currently, the output is restricted to shapefiles, so anything that is not in a shapefile will get exported. It also export to a new file if the original one contains non-ascii characters. """ supported = supported or ["shp"] settings = QSettings() systemEncoding = settings.value('/UI/encoding', 'System') filename = os.path.basename(unicode(layer.source())) idx = filename.rfind('.') if idx != -1: filename = filename[:idx] filename = unicode(layer.name()) validChars = \ 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789:' filename = ''.join(c for c in filename if c in validChars) if len(filename) == 0: filename = 'layer' output = getTempFilenameInTempFolder(filename + '.shp') provider = layer.dataProvider() useSelection = ProcessingConfig.getSetting(ProcessingConfig.USE_SELECTED) if useSelection and layer.selectedFeatureCount() != 0: writer = QgsVectorFileWriter(output, systemEncoding, layer.pendingFields(), provider.geometryType(), layer.crs()) selection = layer.selectedFeatures() for feat in selection: writer.addFeature(feat) del writer return output else: isASCII = True try: unicode(layer.source()).decode('ascii') except UnicodeEncodeError: isASCII = False if not os.path.splitext()[1].lower() in supported or not isASCII: writer = QgsVectorFileWriter( output, systemEncoding, layer.pendingFields(), provider.geometryType(), layer.crs() ) for feat in layer.getFeatures(): writer.addFeature(feat) del writer return output else: return unicode(layer.source())
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 run(self): self.mutex.lock() self.stopMe = 0 self.mutex.unlock() interrupted = False outPath = self.outDir if outPath.find("\\") != -1: outPath.replace("\\", "/") if not outPath.endswith("/"): outPath = outPath + "/" provider = self.layer.dataProvider() index = provider.fieldNameIndex(self.field) unique = ftools_utils.getUniqueValues(provider, int(index)) baseName = unicode( outPath + self.layer.name() + "_" + self.field + "_" ) fieldList = ftools_utils.getFieldList(self.layer) sRs = provider.crs() geom = self.layer.wkbType() inFeat = QgsFeature() self.emit(SIGNAL("rangeCalculated(PyQt_PyObject)"), len(unique)) for i in unique: check = QFile(baseName + "_" + unicode(i).strip() + ".shp") fName = check.fileName() if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(fName): self.errors.append( fName ) continue writer = QgsVectorFileWriter(fName, self.encoding, fieldList, geom, sRs) fit = provider.getFeatures() while fit.nextFeature(inFeat): atMap = inFeat.attributes() if atMap[index] == i: writer.addFeature(inFeat) del writer self.emit(SIGNAL("valueProcessed()")) self.mutex.lock() s = self.stopMe self.mutex.unlock() if s == 1: interrupted = True break if not interrupted: self.emit(SIGNAL("processFinished( PyQt_PyObject )"), self.errors) else: self.emit(SIGNAL("processInterrupted()"))
class VectorWriter: MEMORY_LAYER_PREFIX = 'memory:' def __init__(self, fileName, encoding, fields, geometryType, crs, options=None): self.fileName = fileName self.isMemory = False self.memLayer = None self.writer = None if encoding is None: settings = QSettings() encoding = settings.value('/Processing/encoding', 'System', type=str) if self.fileName.startswith(self.MEMORY_LAYER_PREFIX): self.isMemory = True uri = GEOM_TYPE_MAP[geometryType] + "?uuid=" + unicode(uuid.uuid4()) if crs.isValid(): uri += '&crs=' + crs.authid() fieldsdesc = [] for f in fields: qgsfield = _toQgsField(f) fieldsdesc.append('field=%s:%s' %(qgsfield.name(), TYPE_MAP_MEMORY_LAYER.get(qgsfield.type(), "string"))) if fieldsdesc: uri += '&' + '&'.join(fieldsdesc) self.memLayer = QgsVectorLayer(uri, self.fileName, 'memory') self.writer = self.memLayer.dataProvider() else: formats = QgsVectorFileWriter.supportedFiltersAndFormats() OGRCodes = {} for (key, value) in formats.items(): extension = unicode(key) extension = extension[extension.find('*.') + 2:] extension = extension[:extension.find(' ')] OGRCodes[extension] = value extension = self.fileName[self.fileName.rfind('.') + 1:] if extension not in OGRCodes: extension = 'shp' self.filename = self.filename + 'shp' qgsfields = QgsFields() for field in fields: qgsfields.append(_toQgsField(field)) self.writer = QgsVectorFileWriter( self.fileName, encoding, qgsfields, geometryType, crs, OGRCodes[extension]) def addFeature(self, feature): if self.isMemory: self.writer.addFeatures([feature]) else: self.writer.addFeature(feature)
def randomize(self, inLayer, outPath, minimum, design, value): outFeat = QgsFeature() outFeat.initAttributes(1) if design == self.tr("unstratified"): ext = inLayer.extent() if inLayer.type() == QgsMapLayer.RasterLayer: points = self.simpleRandom( int(value), ext, ext.xMinimum(), ext.xMaximum(), ext.yMinimum(), ext.yMaximum()) else: points = self.vectorRandom( int(value), inLayer, ext.xMinimum(), ext.xMaximum(), ext.yMinimum(), ext.yMaximum()) else: points, featErrors = self.loopThruPolygons(inLayer, value, design) if featErrors: if len(featErrors) >= 10: err_msg = "Too many features couldn't be calculated due to conversion error. " err_msg += "Please check out message log for more info." msgLogInstance = QgsMessageLog.instance() msgLogInstance.logMessage("WARNING - fTools: " + self.tr("Random Points")) msgLogInstance.logMessage("The following feature ids should be checked.") for feat in featErrors: msgLogInstance.logMessage("Feature id: %d" % feat.id()) msgLogInstance.logMessage("End of features to be checked.") else: features_ids = [] for feat in featErrors: features_ids.append(unicode(feat.id())) erroneous_ids = ', '.join(features_ids) err_msg = "The following features IDs couldn't be calculated due to conversion error: %s" % erroneous_ids self.iface.messageBar().pushMessage("Errors", err_msg) if len(points): crs = self.iface.mapCanvas().mapRenderer().destinationCrs() if not crs.isValid(): crs = None fields = QgsFields() fields.append(QgsField("ID", QVariant.Int)) outFeat.setFields(fields) check = QFile(self.shapefileName) if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName): return writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fields, QGis.WKBPoint, crs) idVar = 0 count = 70.00 add = (100.00 - 70.00) / len(points) for i in points: outFeat.setGeometry(i) outFeat.setAttribute(0, idVar) writer.addFeature(outFeat) idVar = idVar + 1 count = count + add self.progressBar.setValue(count) del writer return True return False
def exportVectorLayer(layer, supported=None): """Takes a QgsVectorLayer and returns the filename to refer to it, which allows external apps which support only file-based layers to use it. It performs the necessary export in case the input layer is not in a standard format suitable for most applications, it is a remote one or db-based (non-file based) one, or if there is a selection and it should be used, exporting just the selected features. Currently, the output is restricted to shapefiles, so anything that is not in a shapefile will get exported. It also export to a new file if the original one contains non-ascii characters. """ supported = supported or ["shp"] settings = QSettings() systemEncoding = settings.value('/UI/encoding', 'System') output = getTempFilename('shp') basename = removeInvalidChars(os.path.basename(layer.source())) if basename: if not basename.endswith("shp"): basename = basename + ".shp" output = getTempFilenameInTempFolder(basename) else: output = getTempFilename("shp") provider = layer.dataProvider() useSelection = ProcessingConfig.getSetting(ProcessingConfig.USE_SELECTED) if useSelection and layer.selectedFeatureCount() != 0: writer = QgsVectorFileWriter(output, systemEncoding, layer.fields(), layer.wkbType(), layer.crs()) selection = layer.selectedFeatures() for feat in selection: writer.addFeature(feat) del writer return output else: isASCII = True try: str(layer.source()).decode('ascii') except UnicodeEncodeError: isASCII = False if not os.path.splitext(layer.source())[1].lower() in supported or not isASCII: writer = QgsVectorFileWriter( output, systemEncoding, layer.fields(), layer.wkbType(), layer.crs() ) for feat in layer.getFeatures(): writer.addFeature(feat) del writer return output else: return str(layer.source())
def physiocap_moyenne_vers_point( crs, EPSG_NUMBER, nom_point, nom_prj, les_geom_point_feat, les_GID, les_dates, les_vitesses, les_sarments, les_diametres, les_biom, les_biomgm2, les_biomgcep, les_biomm2, les_nbsarmm2, les_nbsarcep, details = "NO"): """ Creation d'un shape de points se trouvant dans le contour """ # Prepare les attributs les_champs = QgsFields() les_champs.append( QgsField( "GID", QVariant.Int, "integer", 10)) les_champs.append( QgsField( "DATE", QVariant.String, "string", 25)) les_champs.append( QgsField("VITESSE", QVariant.Double, "double", 10,2)) les_champs.append(QgsField( "NBSARM", QVariant.Double, "double", 10,2)) les_champs.append(QgsField( "DIAM", QVariant.Double, "double", 10,2)) les_champs.append(QgsField("BIOM", QVariant.Double,"double", 10,2)) if details == "YES": # Niveau de detail demandé les_champs.append(QgsField("BIOMGM2", QVariant.Double,"double", 10,2)) les_champs.append( QgsField( "BIOMGCEP", QVariant.Double,"double", 10,2)) les_champs.append( QgsField( "BIOMM2", QVariant.Double,"double", 10,2)) les_champs.append( QgsField( "NBSARMM2", QVariant.Double,"double", 10,2)) les_champs.append( QgsField( "NBSARCEP", QVariant.Double,"double", 10,2)) # Creation du Shape writer = QgsVectorFileWriter( nom_point, "utf-8", les_champs, QGis.WKBPoint, crs , "ESRI Shapefile") i = -1 for gid in les_GID: i = i+1 feat = QgsFeature() feat.setGeometry( QgsGeometry.fromPoint( les_geom_point_feat[ i])) #écrit la géométrie tel que lu dans shape contour if details == "YES": # Ecrit tous les attributs feat.setAttributes( [ les_GID[ i], les_dates[ i], les_vitesses[ i], les_sarments[ i], les_diametres[ i], les_biom[ i], les_biomgm2[ i], les_biomgcep[ i], les_biomm2[ i], les_nbsarmm2[ i], les_nbsarcep[ i] ]) else: # Ecrit les premiers attributs feat.setAttributes( [ les_GID[ i], les_dates[ i], les_vitesses[ i], les_sarments[ i], les_diametres[ i], les_biom[ i] ]) # Ecrit le feature writer.addFeature( feat) # Create the PRJ file prj = open(nom_prj, "w") epsg = 'inconnu' if ( EPSG_NUMBER == EPSG_NUMBER_L93): epsg = EPSG_TEXT_L93 if (EPSG_NUMBER == EPSG_NUMBER_GPS): epsg = EPSG_TEXT_GPS prj.write(epsg) prj.close() #physiocap_log( "Fin point :") return 0
def check_geometry(self, vlayer): lstErrors = [] if self.mySelection: layer = vlayer.selectedFeatures() nFeat = len(layer) else: layer = [] ft = QgsFeature() fit = vlayer.getFeatures(QgsFeatureRequest().setSubsetOfAttributes([])) while fit.nextFeature(ft): layer.append(QgsFeature(ft)) nFeat = len(layer) nElement = 0 if nFeat > 0: self.emit(SIGNAL("runStatus(PyQt_PyObject)"), 0) self.emit(SIGNAL("runRange(PyQt_PyObject)"), (0, nFeat)) for feat in layer: if not self.running: return list() geom = QgsGeometry(feat.geometry()) # ger reference to geometry self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nElement) nElement += 1 # Check Add error if not geom.isGeosEmpty(): lstErrors.append((feat.id(), list(geom.validateGeometry()))) self.emit(SIGNAL("runStatus(PyQt_PyObject)"), nFeat) if self.writeShape: fields = QgsFields() fields.append(QgsField("FEAT_ID", QVariant.Int)) fields.append(QgsField("ERROR", QVariant.String)) writer = QgsVectorFileWriter(self.myName, self.myEncoding, fields, QGis.WKBPoint, vlayer.crs()) for rec in lstErrors: if len(rec[1]) < 1: continue for err in rec[1]: fidItem = unicode(rec[0]) message = err.what() if err.hasWhere(): locErr = err.where() xP = locErr.x() yP = locErr.y() myPoint = QgsPoint(xP, yP) geometry = QgsGeometry().fromPoint(myPoint) ft = QgsFeature() ft.setGeometry(geometry) ft.setAttributes([fidItem, message]) writer.addFeature(ft) del writer return "writeShape" else: return lstErrors
def layer_extent( self ): self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0 ) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, 0 ) ) fields = QgsFields() fields.append( QgsField( "MINX", QVariant.Double ) ) fields.append( QgsField( "MINY", QVariant.Double ) ) fields.append( QgsField( "MAXX", QVariant.Double ) ) fields.append( QgsField( "MAXY", QVariant.Double ) ) fields.append( QgsField( "CNTX", QVariant.Double ) ) fields.append( QgsField( "CNTY", QVariant.Double ) ) fields.append( QgsField( "AREA", QVariant.Double ) ) fields.append( QgsField( "PERIM", QVariant.Double ) ) fields.append( QgsField( "HEIGHT", QVariant.Double ) ) fields.append( QgsField( "WIDTH", QVariant.Double ) ) writer = QgsVectorFileWriter( self.myName, self.myEncoding, fields, QGis.WKBPolygon, self.vlayer.crs() ) rect = self.vlayer.extent() minx = rect.xMinimum() miny = rect.yMinimum() maxx = rect.xMaximum() maxy = rect.yMaximum() height = rect.height() width = rect.width() cntx = minx + ( width / 2.0 ) cnty = miny + ( height / 2.0 ) area = width * height perim = ( 2 * width ) + (2 * height ) rect = [ QgsPoint( minx, miny ), QgsPoint( minx, maxy ), QgsPoint( maxx, maxy ), QgsPoint( maxx, miny ), QgsPoint( minx, miny ) ] geometry = QgsGeometry().fromPolygon( [ rect ] ) feat = QgsFeature() feat.setGeometry( geometry ) feat.setAttributes( [ minx, miny, maxx, maxy, cntx, cnty, area, perim, height, width ] ) writer.addFeature( feat ) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, 100 ) ) self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0 ) del writer return True
def processAlgorithm(self, progress): """Here is where the processing itself takes place.""" # The first thing to do is retrieve the values of the parameters # entered by the user inputFilename = self.getParameterValue(self.INPUT_LAYER) azimuthField = self.getParameterValue(self.AZIMUTH_FIELD) wedgeAngleField = self.getParameterValue(self.WEDGE_ANGLE_FIELD) radiusField = self.getParameterValue(self.RADIUS_FIELD) innerRadiusField = self.getParameterValue(self.INNER_RADIUS_FIELD) output = self.getOutputValue(self.OUTPUT_LAYER) # Input layers vales are always a string with its location. # That string can be converted into a QGIS object (a # QgsVectorLayer in this case) using the # processing.getObjectFromUri() method. vectorLayer = dataobjects.getObjectFromUri(inputFilename) # And now we can process # First we create the output layer. The output value entered by # the user is a string containing a filename, so we can use it # directly settings = QSettings() systemEncoding = settings.value('/UI/encoding', 'System') provider = vectorLayer.dataProvider() writer = QgsVectorFileWriter(output, systemEncoding, provider.fields(), QGis.WKBPolygon, provider.crs()) # Now we take the features from input layer and add them to the # output. Method features() returns an iterator, considering the # selection that might exist in layer and the configuration that # indicates should algorithm use only selected features or all # of them features = vector.features(vectorLayer) for f in features: azimuth = float(f[azimuthField]) wedgeAngle = float(f[wedgeAngleField]) radius = float(f[radiusField]) innerRadius = float( f[innerRadiusField] if innerRadiusField else 0 ) centre = f.geometry().asPoint() wedge = wedge_buffer_implementation.wedge_buffer(centre, radius, azimuth, wedgeAngle, innerRadius) qgisPoly = QgsGeometry.fromPolygon( [[QgsPoint(*p) for p in wedge]] ) outFeat = QgsFeature() outFeat.setAttributes( f.attributes() ) outFeat.setGeometry( qgisPoly ) writer.addFeature( outFeat )
def compute(self, inPoly, inLns, inField, outPath, progressBar): polyLayer = ftools_utils.getVectorLayerByName(inPoly) lineLayer = ftools_utils.getVectorLayerByName(inLns) polyProvider = polyLayer.dataProvider() lineProvider = lineLayer.dataProvider() if polyProvider.crs() != lineProvider.crs(): QMessageBox.warning(self, self.tr("CRS warning!"), self.tr("Warning: Input layers have non-matching CRS.\nThis may cause unexpected results.")) fieldList = ftools_utils.getFieldList(polyLayer) index = polyProvider.fieldNameIndex(unicode(inField)) if index == -1: index = polyProvider.fields().count() fieldList.append(QgsField(unicode(inField), QVariant.Double, "real", 24, 15, self.tr("length field"))) sRs = polyProvider.crs() inFeat = QgsFeature() inFeatB = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() distArea = QgsDistanceArea() start = 0.00 add = 100.00 / polyProvider.featureCount() check = QFile(self.shapefileName) if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName): return writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fieldList, polyProvider.geometryType(), sRs) spatialIndex = ftools_utils.createIndex(lineProvider) polyFit = polyProvider.getFeatures() while polyFit.nextFeature(inFeat): inGeom = QgsGeometry(inFeat.geometry()) atMap = inFeat.attributes() lineList = [] length = 0 lineList = spatialIndex.intersects(inGeom.boundingBox()) if len(lineList) > 0: check = 0 else: check = 1 if check == 0: for i in lineList: lineProvider.getFeatures(QgsFeatureRequest().setFilterFid(int(i))).nextFeature(inFeatB) tmpGeom = QgsGeometry(inFeatB.geometry()) if inGeom.intersects(tmpGeom): outGeom = inGeom.intersection(tmpGeom) length = length + distArea.measure(outGeom) outFeat.setGeometry(inGeom) atMap.append(length) outFeat.setAttributes(atMap) writer.addFeature(outFeat) start = start + 1 progressBar.setValue(start * (add)) del writer
def generate(self): """ generate points on surface """ vlayer = self.dlg.layerBox.currentLayer() vprovider = vlayer.dataProvider() writer = QgsVectorFileWriter(self.dlg.pointEdit.text(), \ self.dlg.encoding, vprovider.fields(), QgsWkbTypes.Point, \ vprovider.crs(), "ESRI Shapefile") outFeat = QgsFeature() if self.dlg.selectedBox.isChecked(): features = vlayer.selectedFeatures() else: features = vlayer.getFeatures() nElement = 0 nError = 0 for inFeat in features: nElement += 1 inGeom = inFeat.geometry() if inGeom is None or not inFeat.hasGeometry() or \ not inGeom.isGeosValid(): QgsMessageLog.logMessage("Feature %d skipped (empty or invalid geometry)" % nElement, 'realcentroid') nError += 1 continue if inGeom.isMultipart(): # find largest part in case of multipart maxarea = 0 #tmpGeom = QgsGeometry() for part in inGeom.asGeometryCollection(): area = part.area() if area > maxarea: tmpGeom = part maxarea = area inGeom = tmpGeom atMap = inFeat.attributes() outGeom = inGeom.pointOnSurface() outFeat.setAttributes(atMap) outFeat.setGeometry(outGeom) writer.addFeature(outFeat) del writer if nError > 0: QMessageBox.warning(None, "RealCentroid", \ tr("Invalid or empty geometries found, see log messages")) # add centroid shape to canvas if self.dlg.addBox.checkState() == Qt.Checked: p, name = os.path.split(self.dlg.pointEdit.text()) w = QgsVectorLayer(self.dlg.pointEdit.text(), name, 'ogr') if w.isValid(): QgsProject.instance().addMapLayer(w) else: QMessageBox.warning(None, "RealCentroid", \ tr("Error loading shapefile\n") + self.dlg.pointEdit.text())
def do_operation(self): """ perform export operation """ # input/output data checking already done during property set input_file = self.inputs[0].value output_file = self.inputs[1].value output_dbf = '%s_attr.dbf' % output_file[:-3] try: exp_layer = load_shapefile(input_file, 'exposure_%s' % get_unique_filename()) # store id of distinct features total_features = exp_layer.dataProvider().featureCount() if total_features > MAX_FEATURES_IN_MEMORY: # use bsddb to store id in case number of features is too large tmp_db_file = '%sdb_%s.db' % (self._tmp_dir, get_unique_filename()) db = bsddb.btopen(tmp_db_file, 'c') use_db = True else: # in memory dictionary, should be much faster, but could fail # if memory is limited db = {} use_db = False # get field index for GID gid_idx = layer_field_index(exp_layer, GID_FIELD_NAME) fields = { 0: QgsField(GID_FIELD_NAME, QVariant.Int), } writer = QgsVectorFileWriter(output_file, "utf-8", fields, exp_layer.dataProvider().geometryType(), exp_layer.crs(), "ESRI Shapefile") out_feature = QgsFeature() for feature in layer_features(exp_layer): gid = str(feature.attributeMap()[gid_idx].toString()) # only write out once if not db.has_key(gid): db[gid]= '1' # bsddb only accepts string out_feature.addAttribute(0, gid) out_feature.setGeometry(feature.geometry()) writer.addFeature(out_feature) # clean up del writer if use_db: db.close() os.remove(tmp_db_file) # copy associated attribute file copy_shapefile(input_file, output_dbf, extensions=['.dbf']) except Exception as err: raise OperatorError("error creating shapefile: %s" % err, self.__class__)
def voronoi_polygons( self ): vprovider = self.vlayer.dataProvider() writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(), QGis.WKBPolygon, vprovider.crs() ) inFeat = QgsFeature() outFeat = QgsFeature() extent = self.vlayer.extent() extraX = extent.height() * ( self.myParam / 100.00 ) extraY = extent.width() * ( self.myParam / 100.00 ) height = extent.height() width = extent.width() c = voronoi.Context() pts = [] ptDict = {} ptNdx = -1 fit = vprovider.getFeatures() while fit.nextFeature( inFeat ): geom = QgsGeometry( inFeat.geometry() ) point = geom.asPoint() x = point.x() - extent.xMinimum() y = point.y() - extent.yMinimum() pts.append( ( x, y ) ) ptNdx +=1 ptDict[ ptNdx ] = inFeat.id() self.vlayer = None if len( pts ) < 3: return False uniqueSet = Set( item for item in pts ) ids = [ pts.index( item ) for item in uniqueSet ] sl = voronoi.SiteList( [ voronoi.Site( i[ 0 ], i[ 1 ], sitenum=j ) for j, i in enumerate( uniqueSet ) ] ) voronoi.voronoi( sl, c ) inFeat = QgsFeature() nFeat = len( c.polygons ) nElement = 0 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0 ) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) ) for site, edges in c.polygons.iteritems(): vprovider.getFeatures( QgsFeatureRequest().setFilterFid( ptDict[ ids[ site ] ] ) ).nextFeature( inFeat ) lines = self.clip_voronoi( edges, c, width, height, extent, extraX, extraY ) geom = QgsGeometry.fromMultiPoint( lines ) geom = QgsGeometry( geom.convexHull() ) outFeat.setGeometry( geom ) outFeat.setAttributes( inFeat.attributes() ) writer.addFeature( outFeat ) nElement += 1 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement ) del writer return True
def processAlgorithm(self, progress): # Get parameters input_filename = self.getParameterValue(self.INPUT_LAYER) radius = self.getParameterValue(self.RADIUS_FIELD) export_radius = self.getParameterValue(self.RADIUS_EXPORT) export_centroid = self.getParameterValue(self.CENTROID_EXPORT) envelope_layer_field = self.getParameterValue(self.ENVELOPE_LAYER) output = self.getOutputValue(self.OUTPUT_LAYER) vector_layer = dataobjects.getObjectFromUri(input_filename) # If we use a mask, envelope vector_layer_envelope_index = None if envelope_layer_field is not None: vector_layer_envelope = dataobjects.getObjectFromUri( envelope_layer_field) vector_layer_envelope_index = LayerIndex(vector_layer_envelope) settings = QSettings() system_encoding = settings.value('/UI/encoding', 'System') provider = vector_layer.dataProvider() fields = provider.fields() if export_radius: fields.append(QgsField(u"Radius", QVariant.Int)) if export_centroid: fields.append(QgsField(u"X centroid", QVariant.Int)) fields.append(QgsField(u"Y centroid", QVariant.Int)) writer = QgsVectorFileWriter( output, system_encoding, fields, QGis.WKBPolygon, provider.crs()) # Creating a algorithm with all these parameters. algorithm = Blur( radius, vector_layer_envelope_index, export_radius, export_centroid) for feature in features(vector_layer): feature = algorithm.blur(feature) writer.addFeature(feature)
def storyDescriptionLinkClicked(self, url): url = url.toString() if url == "search": dlg = SearchDialog() dlg.exec_() if dlg.mapstory is not None: story = Story.storyFromNumberId(dlg.mapstory) if story is None: QMessageBox.warning(iface.mainWindow(), "MapStory", "Cannot get MapStory data.\nCheck that the provided ID is correct.") else: self.updateCurrentStory(story) elif url == "download": outDir = QFileDialog.getExistingDirectory(self, self.tr("Select output directory"), "." ) if not outDir: return QDir().mkpath(outDir) settings = QSettings() systemEncoding = settings.value('/UI/encoding', 'System') startProgressBar(len(self.story.storyLayers()), "Download layers for off-line use:") for i, layer in enumerate(self.story.storyLayers()): filename = os.path.join(outDir, layer.name() + ".shp") uri = "%s?srsname=%s&typename=geonode:%s&version=1.0.0&request=GetFeature&service=WFS" % (layer.wfsUrl(), layer.crs(), layer.name()) qgslayer = QgsVectorLayer(uri, layer.name(), "WFS") writer = QgsVectorFileWriter(filename, systemEncoding, qgslayer.pendingFields(), qgslayer.dataProvider().geometryType(), qgslayer.crs()) for feat in qgslayer.getFeatures(): writer.addFeature(feat) del writer fieldname = self._getTimeField(qgslayer) if fieldname is not None: filename = os.path.join(outDir, layer.name() + ".timefield") with open(filename, "w") as f: f.write(fieldname) setProgress(i+1) closeProgressBar() iface.messageBar().pushMessage("MapStory", "Layers have been correctly saved as QGIS project.", level=QgsMessageBar.INFO, duration=3)
def saveAsFile(self, polygons, progress): ''' save output polygon layer as Shapefile polygons: list of polygons created by Polygonize function progress: progress bar value ''' global polyCount outFeat = QgsFeature() setGeometry = outFeat.setGeometry setAttributeMap = outFeat.setAttributeMap if self.ui.cbTable.isChecked(): fields = self.parent.layer.dataProvider().fields() else: fields = {} polyCount = len(polygons) step = 50. / polyCount new_path = self.ui.eOutput.text() if self.ui.cbGeometry.isChecked(): fields[len(fields)] = QgsField("area",QVariant.Double,"double",16,2) fields[len(fields)] = QgsField("perimeter",QVariant.Double,"double",16,2) nrArea = len(fields)-2 nrPerimeter = len(fields)-1 writer = QgsVectorFileWriter(new_path,self.parent.layer.dataProvider().encoding(),fields,QGis.WKBPolygon,self.parent.layer.srs() ) for polygon in polygons: setGeometry( QgsGeometry.fromWkt( polygon.wkt ) ) setAttributeMap({ nrArea:QVariant(polygon.area), nrPerimeter:QVariant(polygon.length) }) writer.addFeature( outFeat ) progress += step self.emit(SIGNAL('progress'), progress) else: writer = QgsVectorFileWriter(new_path,self.parent.layer.dataProvider().encoding(),fields,QGis.WKBPolygon,self.parent.layer.srs() ) for polygon in polygons: setGeometry( QgsGeometry.fromWkt( polygon.wkt ) ) writer.addFeature( outFeat ) progress += step self.emit(SIGNAL('progress'), progress) del writer self.emit(SIGNAL('progress'), 100)
def processAlgorithm(self, progress): """Here is where the processing itself takes place.""" # The first thing to do is retrieve the values of the parameters # entered by the user inputFilename = self.getParameterValue(self.INPUT_LAYER) grid_size = float(self.getParameterValue(self.GRID_SIZE)) x_offset = float(self.getParameterValue(self.X_OFFSET)) y_offset = float(self.getParameterValue(self.Y_OFFSET)) output = self.getOutputValue(self.OUTPUT_LAYER) # Input layers vales are always a string with its location. # That string can be converted into a QGIS object (a # QgsVectorLayer in this case) using the # processing.getObjectFromUri() method. vectorLayer = dataobjects.getObjectFromUri(inputFilename) # And now we can process # First we create the output layer. The output value entered by # the user is a string containing a filename, so we can use it # directly settings = QSettings() systemEncoding = settings.value('/UI/encoding', 'System') provider = vectorLayer.dataProvider() writer = QgsVectorFileWriter(output, systemEncoding, provider.fields(), provider.geometryType(), provider.crs()) # Now we take the features from input layer and add them to the # output. Method features() returns an iterator, considering the # selection that might exist in layer and the configuration that # indicates should algorithm use only selected features or all # of them features = vector.features(vectorLayer) for f in features: g = f.geometryAndOwnership() new_point = self.round_to_grid( g.asPoint(), grid_size, x_offset, y_offset) f.setGeometry(QgsGeometry.fromPoint(new_point)) writer.addFeature(f)
def run(self): """ Do the job """ # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result and len(self.dlg.LayerCombo.currentText()) and len(self.dlg.ColumnCombo.currentText()): vlayer = util.getMapLayerByName(self.dlg.LayerCombo.currentText()) vprovider = vlayer.dataProvider() field = self.dlg.ColumnCombo.currentText() fields = vprovider.fields() id = fields.indexFromName(field) # unique values of selected field uniquevalues = vprovider.uniqueValues(id) if len(uniquevalues) > 25: if ( QMessageBox.warning( None, QApplication.translate("@default", "Warning"), str(len(uniquevalues)) + " " + QApplication.translate("@default", " unique values! Continue?"), QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Cancel, ) == QMessageBox.Cancel ): return base = os.path.join(self.dlg.DirectoryEdit.text(), self.dlg.BaseEdit.text()) for uniquevalue in uniquevalues: # create new shape file for each unique value writer = QgsVectorFileWriter( base + str(uniquevalue), vprovider.encoding(), fields, vprovider.geometryType(), vprovider.crs() ) # set up filter expression exptext = field + " = '" + str(uniquevalue) + "'" exp = QgsExpression(exptext) request = QgsFeatureRequest(exp) # pyqtRemoveInputHook() # pdb.set_trace() for feature in vlayer.getFeatures(request): writer.addFeature(feature) # flush and close del writer
def _toVectorLayer_geojson (self): crs = QgsCoordinateReferenceSystem() crs.createFromUserInput(self.provider.srsName) fileName = self.xmlFile.replace(".xml", ".geojson") fields = QgsFields () map (fields.append, self.provider.fields) writer = QgsVectorFileWriter (fileName, "utf-8", fields, QGis.WKBPoint, crs, "GeoJSON") if writer.hasError() != QgsVectorFileWriter.NoError: raise Exception (writer.errorMessage()) for feature in self.provider.getFeatures(): self.features.append(feature) writer.addFeature(feature) del writer #Forzar escritura a disco return QgsVectorLayer( fileName, self.name, "ogr")
def regularize(self, bound, outPath, offset, value, gridType, inset, crs): area = bound.width() * bound.height() if offset: seed() if gridType: pointSpacing = value else: # Calculate grid spacing pointSpacing = sqrt(area / value) outFeat = QgsFeature() outFeat.initAttributes(1) fields = QgsFields() fields.append( QgsField("ID", QVariant.Int) ) outFeat.setFields( fields ) check = QFile(self.shapefileName) if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName): return writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fields, QGis.WKBPoint, crs) idVar = 0 count = 10.00 add = 90.00 / (area / pointSpacing) y = bound.yMaximum() - inset while y >= bound.yMinimum(): x = bound.xMinimum() + inset while x <= bound.xMaximum(): if offset: pGeom = QgsGeometry().fromPoint( QgsPoint( uniform(x - (pointSpacing / 2.0), x + (pointSpacing / 2.0)), uniform(y - (pointSpacing / 2.0), y + (pointSpacing / 2.0)) )) else: pGeom = QgsGeometry().fromPoint(QgsPoint(x, y)) if pGeom.intersects(bound): outFeat.setGeometry(pGeom) outFeat.setAttribute(0, idVar) writer.addFeature(outFeat) idVar = idVar + 1 x = x + pointSpacing count = count + add self.progressBar.setValue(count) y = y - pointSpacing del writer
def processAlgorithm(self, parameters, context, feedback): """Here is where the processing itself takes place. :param parameters: :param context: """ # The first thing to do is retrieve the values of the parameters # entered by the user inputFilename = self.getParameterValue(self.INPUT_LAYER) output = self.getOutputValue(self.OUTPUT_LAYER) # Input layers vales are always a string with its location. # That string can be converted into a QGIS layer (a # QgsVectorLayer in this case) using the # QgsProcessingUtils.mapLayerFromString() method. vectorLayer = QgsProcessingUtils.mapLayerFromString( inputFilename, context) # And now we can process # First we create the output layer. The output value entered by # the user is a string containing a filename, so we can use it # directly settings = QgsSettings() systemEncoding = settings.value('/UI/encoding', 'System') writer = QgsVectorFileWriter(output, systemEncoding, vectorLayer.fields(), vectorLayer.wkbType(), vectorLayer.crs()) # Now we take the features from input layer and add them to the # output. Method features() returns an iterator, considering the # selection that might exist in layer and the configuration that # indicates should algorithm use only selected features or all # of them features = QgsProcessingUtils.getFeatures(vectorLayer, context) for f in features: writer.addFeature(f)
def exportTable(table): """Takes a QgsVectorLayer and returns the filename to refer to its attributes table, which allows external apps which support only file-based layers to use it. It performs the necessary export in case the input layer is not in a standard format suitable for most applications, it isa remote one or db-based (non-file based) one. Currently, the output is restricted to DBF. It also export to a new file if the original one contains non-ascii characters. """ settings = QgsSettings() systemEncoding = settings.value('/UI/encoding', 'System') output = getTempFilename() isASCII = True try: str(table.source()).decode('ascii') except UnicodeEncodeError: isASCII = False isDbf = str(table.source()).endswith('dbf') \ or str(table.source()).endswith('shp') if not isDbf or not isASCII: writer = QgsVectorFileWriter(output, systemEncoding, table.fields(), QgsWkbTypes.NullGeometry, QgsCoordinateReferenceSystem('4326')) for feat in table.getFeatures(): writer.addFeature(feat) del writer return output + '.dbf' else: filename = str(table.source()) if str(table.source()).endswith('shp'): return filename[:-3] + 'dbf' else: return filename
def polygon_centroids(self): vprovider = self.vlayer.dataProvider() writer = QgsVectorFileWriter(self.myName, self.myEncoding, vprovider.fields(), QGis.WKBPoint, vprovider.crs()) inFeat = QgsFeature() outFeat = QgsFeature() nFeat = vprovider.featureCount() nElement = 0 self.emit(SIGNAL("runStatus( PyQt_PyObject )"), 0) self.emit(SIGNAL("runRange( PyQt_PyObject )"), (0, nFeat)) fit = vprovider.getFeatures() while fit.nextFeature(inFeat): nElement += 1 self.emit(SIGNAL("runStatus( PyQt_PyObject )"), nElement) inGeom = inFeat.geometry() atMap = inFeat.attributes() outGeom = inGeom.centroid() if outGeom is None: return "math_error" outFeat.setAttributes(atMap) outFeat.setGeometry(QgsGeometry(outGeom)) writer.addFeature(outFeat) del writer return True
def makeBaseDistributionMapShapefile(setupObject, distShapeFilePathName): puLayer = QgsVectorLayer(setupObject.puPath, 'Planning units', 'ogr') puIDField = puLayer.fields().indexFromName('Unit_ID') newFields = QgsFields() newFields.append(QgsField('Unit_ID', QVariant.Int)) writer = QgsVectorFileWriter(distShapeFilePathName, "System", newFields, QgsWkbTypes.MultiPolygon, puLayer.dataProvider().crs(), "ESRI Shapefile") puFeatures = puLayer.getFeatures() #Make distribution shapefile copying PU polygons and ID field for puFeature in puFeatures: puGeom = puFeature.geometry() puAttributes = puFeature.attributes() puID = puAttributes[puIDField] featAttribList = [puID] distFeat = QgsFeature() distFeat.setGeometry(puGeom) distFeat.setAttributes(featAttribList) writer.addFeature(distFeat) del writer
def physiocap_segment_vers_vecteur(self, chemin_session, nom_repertoire, nom_session, segment, info_segment, version_3="NO", segment_simplifie="YES"): """ Creation de shape file à partir des données de segment """ distancearea, EXT_CRS_SHP, EXT_CRS_PRJ, EXT_CRS_RASTER, \ laProjectionCRS, laProjectionTXT, EPSG_NUMBER = \ physiocap_quelle_projection_et_lib_demandee( self) nom_court_vecteur_segment = None nom_court_prj_segment = None nom_vecteur_segment = None nom_prj = None #nom_gpkg = None quel_vecteur_demande = self.fieldComboFormats.currentText() if segment_simplifie == "YES": nom_court_vecteur = nom_session + NOM_SEGMENTS else: nom_court_vecteur = nom_session + NOM_SEGMENTS + NOM_SEGMENTS_SUITE_DETAILS if quel_vecteur_demande == SHAPEFILE_NOM: nom_court_vecteur_segment = nom_court_vecteur + EXT_CRS_SHP nom_court_prj_segment = nom_court_vecteur + EXT_CRS_PRJ nom_vecteur_segment = os.path.join(nom_repertoire, nom_court_vecteur_segment) nom_prj = os.path.join(nom_repertoire, nom_court_prj_segment) # Si le shape existe dejà il faut le détruire if os.path.isfile(nom_vecteur_segment): # A_TESTER: je doute que ca marche physiocap_log( self.tr("Le shape file existant déjà, il est détruit."), TRACE_TOOLS) os.remove(nom_vecteur_segment) elif quel_vecteur_demande == GEOPACKAGE_NOM and version_3 == "YES": # Assert GPKG existe : nom_gpkg = physiocap_vecteur_vers_gpkg(self, chemin_session, nom_session) nom_court_gpkg_extension = nom_court_vecteur + EXTENSION_GPKG nom_gpkg_intermediaire = os.path.join(chemin_session, nom_court_gpkg_extension) else: # Assert type vecteur supporté raise physiocap_exception_vecteur_type_inconnu(quel_vecteur_demande) # Assert GPKG existe # Prepare les attributs les_champs = QgsFields() if quel_vecteur_demande == GEOPACKAGE_NOM and version_3 == "YES": les_champs.append(QgsField("fid", QVariant.Int, "integer", 10)) else: les_champs.append(QgsField("GID", QVariant.Int, "integer", 10)) les_champs.append(QgsField("GID_10", QVariant.Int, "integer", 10)) les_champs.append(QgsField("NB_POINTS", QVariant.Int, "integer", 10)) les_champs.append(QgsField("DATE_DEB", QVariant.String, "string", 25)) les_champs.append(QgsField("DATE_FIN", QVariant.String, "string", 25)) les_champs.append(QgsField("DERIVE", QVariant.Double, "double", 10, 2)) les_champs.append(QgsField("GID_GARDE", QVariant.String, "varchar", 100)) les_champs.append(QgsField("GID_TROU", QVariant.String, "varchar", 100)) # Creation du vecteur if quel_vecteur_demande == GEOPACKAGE_NOM and version_3 == "YES": # CAS Géopackage writer = QgsVectorFileWriter(nom_gpkg_intermediaire, "utf-8", les_champs, QgsWkbTypes.MultiLineString, laProjectionCRS, GEOPACKAGE_DRIVER) else: writer = QgsVectorFileWriter(nom_vecteur_segment, "utf-8", les_champs, QgsWkbTypes.MultiLineString, laProjectionCRS, SHAPEFILE_DRIVER) # Ecriture du shp numero_ligne = 0 for un_segment in segment: feat = QgsFeature() le_gid = info_segment[numero_ligne][NUM_SEG] gid_modulo_10 = le_gid % 10 nombre = info_segment[numero_ligne][NOMBRE] # GID gardé gid_points_gardes = info_segment[numero_ligne][GID_GARDE] nb_points_gardes = len(gid_points_gardes) if nb_points_gardes > 30: str_gid_points_gardes = str( gid_points_gardes[0:2]) + "... " + \ str(nb_points_gardes) + " points gardés ..." + \ str( gid_points_gardes[nb_points_gardes-2:]) else: str_gid_points_gardes = str(gid_points_gardes) # GID manquants gid_points_manquants = info_segment[numero_ligne][GID_TROU] nb_points_manquants = len(gid_points_manquants) if nb_points_manquants > 30: str_gid_points_manquants = str( gid_points_manquants[0:2]) + "... " + \ str(nb_points_manquants) + " points manquants ..." + \ str( gid_points_manquants[nb_points_manquants-2:]) else: str_gid_points_manquants = str(gid_points_manquants) if (segment_simplifie == "YES"): # Premier et dernier feat.setGeometry( QgsGeometry.fromPolylineXY( [un_segment[0], un_segment[nombre - 1]])) #écrit la géométrie else: # Tous les poins feat.setGeometry( QgsGeometry.fromPolylineXY(un_segment)) #écrit la géométrie feat.setAttributes([ le_gid, gid_modulo_10, nombre, info_segment[numero_ligne][DATE_DEBUT], info_segment[numero_ligne][DATE_FIN], round(float(info_segment[numero_ligne][DERIVE]), 2), str_gid_points_gardes, str_gid_points_manquants ]) numero_ligne = numero_ligne + 1 # Ecrit le feature writer.addFeature(feat) writer = None # PRJ file physiocap_create_projection_file(nom_prj, laProjectionTXT) nom_layer_cree = nom_vecteur_segment # Cas geopackage if quel_vecteur_demande == GEOPACKAGE_NOM and version_3 == "YES": nom_layer_cree = physiocap_vecteur_vers_gpkg(self, chemin_session, nom_session, nom_court_vecteur, nom_gpkg_intermediaire) return nom_layer_cree
def run(self): # index = 0 arrmat = np.empty((1, 8)) # #Check OS and dep # if sys.platform == 'darwin': # gdalwarp_os_dep = '/Library/Frameworks/GDAL.framework/Versions/Current/Programs/gdalwarp' # else: # gdalwarp_os_dep = 'gdalwarp' ret = 0 imp_point = 0 # Allt arbete en trad ska utforas maste goras i en try-sats try: # j = 0 # Loop som utfor det arbete som annars hade "hangt" anvandargranssnittet i Qgis pre = self.dlg.textOutput_prefix.text() header = ' Wd pai fai zH zHmax zHstd zd z0' numformat = '%3d %4.3f %4.3f %5.3f %5.3f %5.3f %5.3f %5.3f' header2 = ' id pai fai zH zHmax zHstd zd z0' numformat2 = '%3d %4.3f %4.3f %5.3f %5.3f %5.3f %5.3f %5.3f' # temporary fix for mac, ISSUE #15 pf = sys.platform if pf == 'darwin' or pf == 'linux2': if not os.path.exists(self.folderPath[0] + '/' + pre): os.makedirs(self.folderPath[0] + '/' + pre) for f in self.vlayer.getFeatures( ): # looping through each grid polygon # Kollar sa att traden inte har avbrutits, ifall den har det sa slutar loopning. if self.killed is True: break # pydevd.settrace('localhost', port=53100, stdoutToServer=True, stderrToServer=True) #used for debugging attributes = f.attributes() geometry = f.geometry() feature = QgsFeature() feature.setAttributes(attributes) feature.setGeometry(geometry) if self.imid == 1: # use center point r = self.radius y = f.geometry().centroid().asPoint().y() x = f.geometry().centroid().asPoint().x() else: r = 0 # Uses as info to separate from IMP point to grid writer = QgsVectorFileWriter(self.dir_poly, "CP1250", self.fields, self.prov.geometryType(), self.prov.crs(), "ESRI shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: self.iface.messageBar().pushMessage( "Error when creating shapefile: ", str(writer.hasError())) writer.addFeature(feature) del writer if self.dlg.checkBoxOnlyBuilding.isChecked( ): # Only building heights provider = self.dsm_build.dataProvider() filePath_dsm_build = str(provider.dataSourceUri()) if self.imid == 1: bbox = (x - r, y + r, x + r, y - r) # gdalruntextdsm_build = gdalwarp_os_dep + ' -dstnodata -9999 -q -overwrite -te ' + str(x - r) + ' ' + str(y - r) + \ # ' ' + str(x + r) + ' ' + str(y + r) + ' -of GTiff "' + \ # filePath_dsm_build + '" "' + self.plugin_dir + '/data/clipdsm.tif"' else: # Remove gdalwarp cuttoline with gdal.Translate. Cut to envelope of polygon feature VectorDriver = ogr.GetDriverByName("ESRI Shapefile") Vector = VectorDriver.Open(self.dir_poly, 0) layer = Vector.GetLayer() feature = layer.GetFeature(0) geom = feature.GetGeometryRef() minX, maxX, minY, maxY = geom.GetEnvelope() bbox = (minX, maxY, maxX, minY ) # Reorder bbox to use with gdal_translate Vector.Destroy() # gdalruntextdsm_build = gdalwarp_os_dep + ' -dstnodata -9999 -q -overwrite -cutline ' + self.dir_poly + \ # ' -crop_to_cutline -of GTiff "' + filePath_dsm_build + '" "' + \ # self.plugin_dir + '/data/clipdsm.tif"' # if sys.platform == 'win32': # si = subprocess.STARTUPINFO() # si.dwFlags |= subprocess.STARTF_USESHOWWINDOW # subprocess.call(gdalruntextdsm_build, startupinfo=si) # else: # os.system(gdalruntextdsm_build) # Remove gdalwarp with gdal.Translate bigraster = gdal.Open(filePath_dsm_build) gdal.Translate(self.plugin_dir + '/data/clipdsm.tif', bigraster, projWin=bbox) bigraster = None # os.system(gdalruntextdsm_build) dataset = gdal.Open(self.plugin_dir + '/data/clipdsm.tif') dsm_array = dataset.ReadAsArray().astype(np.float) sizex = dsm_array.shape[0] sizey = dsm_array.shape[1] dem_array = np.zeros((sizex, sizey)) else: # Both building ground heights provider = self.dsm.dataProvider() filePath_dsm = str(provider.dataSourceUri()) provider = self.dem.dataProvider() filePath_dem = str(provider.dataSourceUri()) # # get raster source - gdalwarp if self.imid == 1: bbox = (x - r, y + r, x + r, y - r) # gdalruntextdsm = gdalwarp_os_dep + ' -dstnodata -9999 -q -overwrite -te ' + str(x - r) + ' ' + str(y - r) + \ # ' ' + str(x + r) + ' ' + str(y + r) + ' -of GTiff "' + \ # filePath_dsm + '" "' + self.plugin_dir + '/data/clipdsm.tif"' # gdalruntextdem = gdalwarp_os_dep + ' -dstnodata -9999 -q -overwrite -te ' + str(x - r) + ' ' + str(y - r) + \ # ' ' + str(x + r) + ' ' + str(y + r) + ' -of GTiff "' + \ # filePath_dem + '" "' + self.plugin_dir + '/data/clipdem.tif"' else: # Remove gdalwarp cuttoline with gdal.Translate. Cut to envelope of polygon feature VectorDriver = ogr.GetDriverByName("ESRI Shapefile") Vector = VectorDriver.Open(self.dir_poly, 0) layer = Vector.GetLayer() feature = layer.GetFeature(0) geom = feature.GetGeometryRef() minX, maxX, minY, maxY = geom.GetEnvelope() bbox = (minX, maxY, maxX, minY ) # Reorder bbox to use with gdal_translate Vector.Destroy() # gdalruntextdsm = gdalwarp_os_dep + ' -dstnodata -9999 -q -overwrite -cutline ' + self.dir_poly + \ # ' -crop_to_cutline -of GTiff "' + filePath_dsm + \ # '" "' + self.plugin_dir + '/data/clipdsm.tif"' # gdalruntextdem = gdalwarp_os_dep + ' -dstnodata -9999 -q -overwrite -cutline ' + self.dir_poly + \ # ' -crop_to_cutline -of GTiff "' + filePath_dem + \ # '" "' + self.plugin_dir + '/data/clipdem.tif"' # if sys.platform == 'win32': # si = subprocess.STARTUPINFO() # si.dwFlags |= subprocess.STARTF_USESHOWWINDOW # subprocess.call(gdalruntextdsm, startupinfo=si) # subprocess.call(gdalruntextdem, startupinfo=si) # else: # os.system(gdalruntextdsm) # os.system(gdalruntextdem) # Remove gdalwarp with gdal.Translate bigraster = gdal.Open(filePath_dsm) gdal.Translate(self.plugin_dir + '/data/clipdsm.tif', bigraster, projWin=bbox) bigraster = None bigraster = gdal.Open(filePath_dem) gdal.Translate(self.plugin_dir + '/data/clipdem.tif', bigraster, projWin=bbox) bigraster = None time.sleep(0.05) dataset = gdal.Open(self.plugin_dir + '/data/clipdsm.tif') dsm_array = dataset.ReadAsArray().astype(np.float) dataset2 = gdal.Open(self.plugin_dir + '/data/clipdem.tif') dem_array = dataset2.ReadAsArray().astype(np.float) if not (dsm_array.shape[0] == dem_array.shape[0]) & ( dsm_array.shape[1] == dem_array.shape[1]): QMessageBox.critical( None, "Error", "All grids must be of same pixel resolution") return geotransform = dataset.GetGeoTransform() scale = 1 / geotransform[1] nd = dataset.GetRasterBand(1).GetNoDataValue() nodata_test = (dsm_array == nd) if self.dlg.checkBoxNoData.isChecked(): if np.sum(dsm_array) == (dsm_array.shape[0] * dsm_array.shape[1] * nd): QgsMessageLog.logMessage( "Grid " + str(f.attributes()[self.idx]) + " not calculated. Includes Only NoData Pixels", level=QgsMessageLog.CRITICAL) cal = 0 else: dsm_array[dsm_array == nd] = np.mean(dem_array) dem_array[dem_array == nd] = np.mean(dem_array) cal = 1 else: if nodata_test.any(): # == True QgsMessageLog.logMessage( "Grid " + str(f.attributes()[self.idx]) + " not calculated. Includes NoData Pixels", level=QgsMessageLog.CRITICAL) cal = 0 else: cal = 1 if cal == 1: # arr = np.array([f.attributes()[self.idx], -99, -99, -99, -99, -99, -99, -99]) # arrmat = np.vstack([arrmat, arr]) # else: immorphresult = imagemorphparam_v2(dsm_array, dem_array, scale, self.imid, self.degree, self.dlg, imp_point) zH = immorphresult["zH"] fai = immorphresult["fai"] pai = immorphresult["pai"] zMax = immorphresult["zHmax"] zSdev = immorphresult["zH_sd"] zd, z0 = rg.RoughnessCalcMany(self.rm, zH, fai, pai, zMax, zSdev) # save to file # header = ' Wd pai fai zH zHmax zHstd zd z0' # numformat = '%3d %4.3f %4.3f %5.3f %5.3f %5.3f %5.3f %5.3f' arr = np.concatenate( (immorphresult["deg"], immorphresult["pai"], immorphresult["fai"], immorphresult["zH"], immorphresult["zHmax"], immorphresult["zH_sd"], zd, z0), axis=1) np.savetxt(self.folderPath[0] + '/' + pre + '_' + 'IMPGrid_anisotropic_' + str(f.attributes()[self.idx]) + '.txt', arr, fmt=numformat, delimiter=' ', header=header, comments='') del arr zHall = immorphresult["zH_all"] faiall = immorphresult["fai_all"] paiall = immorphresult["pai_all"] zMaxall = immorphresult["zHmax_all"] zSdevall = immorphresult["zH_sd_all"] zdall, z0all = rg.RoughnessCalc(self.rm, zHall, faiall, paiall, zMaxall, zSdevall) # If zd and z0 are lower than open country, set to open country if zdall == 0.0: zdall = 0.1 if z0all == 0.0: z0all = 0.03 arr2 = np.array([[ f.attributes()[self.idx], immorphresult["pai_all"], immorphresult["fai_all"], immorphresult["zH_all"], immorphresult["zHmax_all"], immorphresult["zH_sd_all"], zdall, z0all ]]) arrmat = np.vstack([arrmat, arr2]) dataset = None dataset2 = None dataset3 = None self.progress.emit() # header2 = ' id pai fai zH zHmax zHstd zd z0' # numformat2 = '%3d %4.3f %4.3f %5.3f %5.3f %5.3f %5.3f %5.3f' arrmatsave = arrmat[1:arrmat.shape[0], :] np.savetxt(self.folderPath[0] + '/' + pre + '_' + 'IMPGrid_isotropic.txt', arrmatsave, fmt=numformat2, delimiter=' ', header=header2, comments='') if self.dlg.addResultToGrid.isChecked(): self.addattributes(self.vlayer, arrmatsave, header, pre) # Nas om hela loopen utforts, kan anvandas for att tilldela ret-variabeln resultatet av arbetet som ska # ska skickas tillbaka till image_morph_param.py if self.killed is False: self.progress.emit() ret = 1 except Exception: # forward the exception upstream ret = 0 errorstring = self.print_exception() #self.error.emit(e, traceback.format_exc()) self.error.emit(errorstring) self.finished.emit(ret)
def do_operation(self): """ perform create mappin """ # validate inputs popgrid_layer = self.inputs[0].value zone_layer = self.inputs[1].value zone_field = self.inputs[2].value pop_to_bldg = float(self.inputs[3].value) # make sure input is correct # NOTE: these checks cannot be performed at set input time # because the data layer maybe is not loaded yet self._test_layer_loaded(popgrid_layer) self._test_layer_field_exists(popgrid_layer, CNT_FIELD_NAME) self._test_layer_loaded(zone_layer) self._test_layer_field_exists(zone_layer, zone_field) # count_field is not required # if count field is not defined, then generate building count from footprints # local variables analyzer = QgsOverlayAnalyzer() # intersect grids and zones to obtain polygons with # - population and zone_id # - apply ratio to population to obtain building count tmp_join = 'joined_%s' % get_unique_filename() tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join) try: # do intersection analyzer.intersection(popgrid_layer, zone_layer, tmp_join_file) tmp_join_layer = load_shapefile(tmp_join_file, tmp_join) except AssertionError as err: raise OperatorError(str(err), self.__class__) except Exception as err: raise OperatorError(str(err), self.__class__) # generate grid with building counts fields = { 0 : QgsField(GID_FIELD_NAME, QVariant.String), 1 : QgsField(zone_field, QVariant.String), 2 : QgsField(CNT_FIELD_NAME, QVariant.Double), } output_layername = 'grid_%s' % get_unique_filename() output_file = '%s%s.shp' % (self._tmp_dir, output_layername) writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile") f = QgsFeature() pop_idx = layer_field_index(tmp_join_layer, CNT_FIELD_NAME) zone_idx = layer_field_index(tmp_join_layer, zone_field) for _f in layer_features(tmp_join_layer): pop_count = _f.attributeMap()[pop_idx].toDouble()[0] zone = _f.attributeMap()[zone_idx].toString() # 1. get geometry geom = _f.geometry() # 2. get original centroid point and project is required centroid = geom.centroid().asPoint() grid_gid = latlon_to_grid(centroid.y(), centroid.x()) f.setGeometry(self._outputGeometryFromGridId(grid_gid)) f.addAttribute(0, grid_gid) f.addAttribute(1, zone) f.addAttribute(2, pop_count / pop_to_bldg) writer.addFeature(f) del writer # clean up del tmp_join_layer remove_shapefile(tmp_join_file) # store data in output self._load_output(output_file, output_layername)
def do_operation(self): # validate inputs zone_layer = self.inputs[0].value zone_field = self.inputs[1].value count_field = self.inputs[2].value area_field = self.inputs[3].value # make sure input is correct # NOTE: these checks cannot be performed at set input time # because the data layer maybe is not loaded yet self._test_layer_loaded(zone_layer) self._test_layer_field_exists(zone_layer, GID_FIELD_NAME) self._test_layer_field_exists(zone_layer, zone_field) self._test_layer_field_exists(zone_layer, count_field) # local variables analyzer = QgsOverlayAnalyzer() area_idx = ToGrid.STAT_AREA_IDX #cnt_idx = ToGrid.STAT_COUNT_IDX # 1. find building count and total area for each zone zone_names, zone_stat= {}, {} try: self._create_zone_statistics(zone_layer, zone_field, count_field, zone_stat, zone_names) except Exception as err: raise OperatorError(str(err), self.__class__) # 2. create grids around extent of zone tmp_grid1 = 'grid_' + get_unique_filename() tmp_grid1_file = self._tmp_dir + tmp_grid1 + '.shp' try: extent = zone_layer.extent() [x_min, y_min, x_max, y_max] = [extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum()] tmp_grid_lyr1 = self._create_grid(tmp_grid1, tmp_grid1_file, \ x_min, y_min, x_max, y_max, \ DEFAULT_GRID_SIZE, DEFAULT_GRID_SIZE) except Exception as err: raise OperatorError(str(err), self.__class__) # 3. intersect grids and zones to obtain polygons with # - grid_id and zone_id # - ratio of grid covered by zone (polygon area / zone area) # apply ratio to zone building count to obtain count assigned to polygon tmp_join = 'joined_%s' % get_unique_filename() tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join) try: # do intersection analyzer.intersection(tmp_grid_lyr1, zone_layer, tmp_join_file) tmp_join_layer = load_shapefile(tmp_join_file, tmp_join) except AssertionError as err: raise OperatorError(str(err), self.__class__) except Exception as err: raise OperatorError(str(err), self.__class__) # do tally zone_gid_idx = layer_field_index(tmp_join_layer, GID_FIELD_NAME) grid_gid_idx = layer_field_index(tmp_join_layer, "GRID_GID") bldg_cnt_idx = layer_field_index(tmp_join_layer, count_field) bldg_area_idx = layer_field_index(tmp_join_layer, area_field) mercator_transform = QgsCoordinateTransform(tmp_join_layer.crs(), self.mercator_crs) fields = { 0 : QgsField(GID_FIELD_NAME, QVariant.String), 1 : QgsField(zone_field, QVariant.String), 2 : QgsField(CNT_FIELD_NAME, QVariant.Double), 3 : QgsField(AREA_FIELD_NAME, QVariant.Double), } output_layername = 'grid_%s' % get_unique_filename() output_file = '%s%s.shp' % (self._tmp_dir, output_layername) writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile") f = QgsFeature() for _f in layer_features(tmp_join_layer): # get area of polygon geom = _f.geometry() geom.transform(mercator_transform) area = geom.area() # generate all stats of interest zone_gid = _f.attributeMap()[zone_gid_idx].toString() grid_gid = _f.attributeMap()[grid_gid_idx].toString() stat = zone_stat[zone_gid] # calculate count/area as proportion of total zone area bldg_cnt = _f.attributeMap()[bldg_cnt_idx].toDouble()[0] * (area/stat[area_idx]) if bldg_area_idx> 0: bldg_area = _f.attributeMap()[bldg_area_idx].toDouble()[0] * (area/stat[area_idx]) else: bldg_area = 0 # create output record f.setGeometry(self._outputGeometryFromGridId(grid_gid)) f.addAttribute(0, grid_gid) f.addAttribute(1, zone_names[QString(zone_gid)]) f.addAttribute(2, bldg_cnt) f.addAttribute(3, bldg_area) writer.addFeature(f) del writer # clean up del tmp_grid_lyr1 del tmp_join_layer remove_shapefile(tmp_grid1_file) remove_shapefile(tmp_join_file) # store data in output self._load_output(output_file, output_layername)
def loadCsv(self): Input_Table = self.lnEditCsvPath.text( ) # set the filepath for the input CSV lon_field = 'origin_lon' # set the name for the field containing the longitude lat_field = 'origin_lat' # set the name for the field containing the latitude lon_dest = 'dest_lon' lat_dest = 'dest_lat' crs = 4326 # WGS 84 (GPS data) strCRS = "EPSG" + str(4326) directory = os.path.dirname(Input_Table) + "/output/dbscan" import time # timestamp = time.time() ts = time.gmtime() ts = time.strftime("%Y%m%dT%H%M%S", ts) filename = ntpath.basename(self.lnEditCsvPath.text()).replace( ".csv", "") + "_" + ts + "_" + strCRS + ".shp" if not os.path.exists(directory): os.makedirs(directory) outputLayerPath = directory + "//" + filename # set the filepath for the output shapefile #print (outputLayerPath) spatRef = QgsCoordinateReferenceSystem( crs, QgsCoordinateReferenceSystem.EpsgCrsId) inp_tab = QgsVectorLayer(Input_Table, 'Input_Table', 'ogr') prov = inp_tab.dataProvider() fields = inp_tab.fields() outLayer = QgsVectorFileWriter(outputLayerPath, None, fields, QgsWkbTypes.Point, spatRef, "ESRI Shapefile") # outLayer = QgsVectorFileWriter(Output_Layer, None, fields, QGis.WKBPoint, spatRef) # reprojecting to metric datum system for k-means clustering purposes pt = QgsPointXY() pt_dest = QgsPointXY() outFeature = QgsFeature() outFeature_dest = QgsFeature() for feat in inp_tab.getFeatures(): attrs = feat.attributes() pt.setX(float(feat[lon_field])) pt.setY(float(feat[lat_field])) outFeature.setAttributes(attrs) outFeature.setGeometry(QgsGeometry.fromPointXY(pt)) outLayer.addFeature(outFeature) pt_dest.setX(float(feat[lon_dest])) pt_dest.setY(float(feat[lat_dest])) outFeature_dest.setAttributes(attrs) outFeature_dest.setGeometry(QgsGeometry.fromPointXY(pt_dest)) outLayer.addFeature(outFeature_dest) del outLayer return outputLayerPath
def physiocap_csv_vers_vecteur(self, chemin_session, Nom_Session, progress_barre, extension_point, csv_name, chemin_shapes, nom_court_vecteur, nom_fichier_synthese="NO", details="NO", version_3="NO"): """ Creation de shape file à partir des données des CSV Si nom_fichier_synthese n'est pas "NO", on produit les moyennes dans le fichier qui se nomme nom_fichier_synthese Selon la valeur de détails , on crée les 5 premiers ("NO") ou tous les attibuts ("YES") """ leModeDeTrace = self.fieldComboModeTrace.currentText() # Recuperer le CRS choisi, les extensions et le calculateur de distance distancearea, EXT_CRS_SHP, EXT_CRS_PRJ, EXT_CRS_RASTER, \ laProjectionCRS, laProjectionTXT, EPSG_NUMBER = \ physiocap_quelle_projection_et_lib_demandee( self) # Initialisation nom_vecteur = None prj_name = None #nom_gpkg = None quel_vecteur_demande = self.fieldComboFormats.currentText() if quel_vecteur_demande == SHAPEFILE_NOM: nom_court_shapefile = nom_court_vecteur + EXT_CRS_SHP nom_court_projection = nom_court_vecteur + EXT_CRS_PRJ nom_vecteur = os.path.join(chemin_shapes, nom_court_shapefile) prj_name = os.path.join(chemin_shapes, nom_court_projection) # Si le shape existe dejà il faut le détruire if os.path.isfile(nom_vecteur): # A_TESTER: je doute que ca marche : detruire plutot par une option de creation os.remove(nom_vecteur) elif quel_vecteur_demande == GEOPACKAGE_NOM and version_3 == "YES": # Creer seulement le geopackage #nom_gpkg = <<< Inutile physiocap_vecteur_vers_gpkg(self, chemin_session, Nom_Session) nom_court_gpkg = NOM_POINTS[1:] + extension_point nom_court_gpkg_extension = nom_court_gpkg + EXTENSION_GPKG nom_gpkg_intermediaire = os.path.join(chemin_session, nom_court_gpkg_extension) #nom_gpkg_final = nom_gpkg + SEPARATEUR_GPKG + nom_court_gpkg else: # Assert type vecteur supporté raise physiocap_exception_vecteur_type_inconnu(quel_vecteur_demande) # Préparation de la liste d'arguments gid, x,y,nbsarm,diam,biom,date_capture,vitesse= [],[],[],[],[],[],[],[] altitude, pdop, distance, derive = [], [], [], [] azimuth, nbsart = [], [] nbsarmm2, nbsarcep, biommm2, biomgm2, biomgcep = [], [], [], [], [] un_fic = open(csv_name, "r") lignes = un_fic.readlines() nombre_mesures = len(lignes) un_fic.close() progress_step = int(nombre_mesures / 19) barre = 1 nom_layer_cree = None #Lecture des data dans le csv et stockage dans une liste with open(csv_name, "rt") as csvfile: try: r = csv.reader(csvfile, delimiter=";") except NameError: uText = "Erreur bloquante : module csv n'est pas accessible." # TODO: ?V3.12 LTR tester les exceptions ou passer à Panda raise physiocap_exception_csv(csv_name) for numrow, row in enumerate(r): #skip header if numrow > 0: # Aavancer la barre de progression de 19 points if (numrow > progress_step * barre): barre = barre + 1 progress_barre = progress_barre + 1 self.progressBar.setValue(progress_barre) if version_3 == "NO": if (laProjectionTXT == "L93"): x.append(float(row[2])) y.append(float(row[3])) if (laProjectionTXT == "GPS"): x.append(float(row[0])) y.append(float(row[1])) nbsarm.append(float(row[4])) diam.append(float(row[5])) biom.append(float(row[6])) # A_TESTER : sans str date_capture.append(str(row[7])) vitesse.append(float(row[8])) else: # Changement de position dans cvs gid.append(float(row[0])) if (laProjectionTXT == "L93"): x.append(float(row[3])) y.append(float(row[4])) if (laProjectionTXT == "GPS"): x.append(float(row[1])) y.append(float(row[2])) altitude.append(float(row[5])) pdop.append(float(row[6])) distance.append(float(row[7])) derive.append(float(row[8])) azimuth.append(float(row[9])) nbsart.append(int(row[10])) nbsarm.append(float(row[11])) diam.append(float(row[12])) biom.append(float(row[13])) date_capture.append(str(row[14])) vitesse.append(float(row[15])) if details == "YES": if version_3 == "NO": # Niveau de detail demandé # assert sur len row if len(row) != 14: uText = "Le nombre de colonnes : {0} du cvs ne permet pas le calcul détaillé - lors création du shape {1}".\ format( len(row), nom_court_vecteur) raise physiocap_exception_err_csv(uText) nbsarmm2.append(float(row[9])) nbsarcep.append(float(row[10])) biommm2.append(float(row[11])) biomgm2.append(float(row[12])) biomgcep.append(float(row[13])) else: if len(row) != 21: uText = "Le nombre de colonnes : {0} du cvs ne permet pas le calcul détaillé - lors création dushape {1}".\ format( len(row), nom_court_vecteur) raise physiocap_exception_err_csv(uText) nbsarmm2.append(float(row[16])) nbsarcep.append(float(row[17])) biommm2.append(float(row[18])) biomgm2.append(float(row[19])) biomgcep.append(float(row[20])) # Prepare les attributs les_champs = QgsFields() # V1.0 Ajout du GID puis V3.1.8 pas fid si GPKG if quel_vecteur_demande == GEOPACKAGE_NOM and version_3 == "YES": les_champs.append(QgsField("fid", QVariant.Int, "integer", 10)) else: les_champs.append(QgsField("GID", QVariant.Int, "integer", 10)) les_champs.append(QgsField("DATE", QVariant.String, "string", 25)) les_champs.append(QgsField("VITESSE", QVariant.Double, "double", 10, 2)) if version_3 == "YES": les_champs.append( QgsField("ALTITUDE", QVariant.Double, "double", 10, 2)) les_champs.append(QgsField("PDOP", QVariant.Double, "double", 10, 2)) les_champs.append( QgsField("DISTANCE", QVariant.Double, "double", 10, 2)) les_champs.append(QgsField("DERIVE", QVariant.Double, "double", 10, 1)) les_champs.append(QgsField("AZIMUTH", QVariant.Double, "double", 10, 1)) les_champs.append(QgsField("NBSART", QVariant.Int, "integer", 10)) les_champs.append(QgsField("NBSARM", QVariant.Double, "double", 10, 2)) les_champs.append(QgsField("DIAM", QVariant.Double, "double", 10, 2)) les_champs.append(QgsField("BIOM", QVariant.Double, "double", 10, 2)) if details == "YES": # Niveau de detail demandé les_champs.append( QgsField("NBSARMM2", QVariant.Double, "double", 10, 2)) les_champs.append( QgsField("NBSARCEP", QVariant.Double, "double", 10, 2)) les_champs.append(QgsField("BIOMM2", QVariant.Double, "double", 10, 2)) les_champs.append(QgsField("BIOMGM2", QVariant.Double, "double", 10, 2)) les_champs.append( QgsField("BIOMGCEP", QVariant.Double, "double", 10, 2)) # Creation du vecteur if quel_vecteur_demande == GEOPACKAGE_NOM and version_3 == "YES": # CAS Géopackage writer = QgsVectorFileWriter(nom_gpkg_intermediaire, "utf-8", les_champs, QgsWkbTypes.PointZM, laProjectionCRS, GEOPACKAGE_DRIVER) else: if version_3 == "YES": # Cas V3 writer = QgsVectorFileWriter(nom_vecteur, "utf-8", les_champs, QgsWkbTypes.PointZM, laProjectionCRS, SHAPEFILE_DRIVER) else: writer = QgsVectorFileWriter(nom_vecteur, "utf-8", les_champs, QgsWkbTypes.Point, laProjectionCRS, SHAPEFILE_DRIVER) ### CAS Géopackage BAD ne n'a pas creer de vecteur, mais un tuple ### if self.fieldComboFormats.currentText() == GEOPACKAGE_NOM and version_3 == "YES": ### # Copie dans geopackage ### nom_court_gpkg = NOM_POINTS[1:] + extension_point ### layer_modele = QgsVectorLayer( nom_vecteur, "INUTILE", 'ogr') ### options = QgsVectorFileWriter.SaveVectorOptions() ### options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer ### options.layerName = nom_court_gpkg ### # BAD BAD ==> ### writer_gpkg = QgsVectorFileWriter.writeAsVectorFormat( layer_modele, nom_gpkg, options) ### nom_gpkg_cree = nom_gpkg + SEPARATEUR_GPKG + nom_court_gpkg ### # BAD BAD ==> writer_gpkg = QgsVectorLayerExporter.exportLayer( layer_modele, nom_layer_cree, ### #GEOPACKAGE_DRIVER, laProjectionCRS) for numPoint, Xpoint in enumerate(x): feat = QgsFeature() if version_3 == "YES": # choix de la données dans Z val_Z = 0.0 val_M = altitude[numPoint] if extension_point == EXTENSION_SANS_ZERO: val_Z = diam[numPoint] if extension_point == EXTENSION_AVEC_ZERO: val_Z = derive[numPoint] if extension_point == EXTENSION_ZERO_SEUL: val_Z = vitesse[numPoint] #écrit la géométrie avec le Z = diametre (ou altitude ou vitesse) et M feat.setGeometry( QgsGeometry(QgsPoint(Xpoint, y[numPoint], val_Z, val_M))) else: # A_TESTER: test sans fromPointXY feat.setGeometry( QgsGeometry.fromPointXY(QgsPointXY( Xpoint, y[numPoint]))) #écrit la géométrie if details == "YES": if version_3 == "NO": # Ecrit tous les attributs feat.setAttributes([ numPoint, date_capture[numPoint], vitesse[numPoint], nbsarm[numPoint], diam[numPoint], biom[numPoint], nbsarmm2[numPoint], nbsarcep[numPoint], biommm2[numPoint], biomgm2[numPoint], biomgcep[numPoint] ]) else: feat.setAttributes([ gid[numPoint], date_capture[numPoint], vitesse[numPoint], altitude[numPoint], pdop[numPoint], distance[numPoint], derive[numPoint], azimuth[numPoint], nbsart[numPoint], nbsarm[numPoint], diam[numPoint], biom[numPoint], nbsarmm2[numPoint], nbsarcep[numPoint], biommm2[numPoint], biomgm2[numPoint], biomgcep[numPoint] ]) else: # sans les détails if version_3 == "NO": # Ecrit les 5 premiers attributs feat.setAttributes([ numPoint, date_capture[numPoint], vitesse[numPoint], nbsarm[numPoint], diam[numPoint], biom[numPoint] ]) else: # Ecrit les 10 premiers attributs feat.setAttributes([ gid[numPoint], date_capture[numPoint], vitesse[numPoint], altitude[numPoint], pdop[numPoint], distance[numPoint], derive[numPoint], azimuth[numPoint], nbsart[numPoint], nbsarm[numPoint], diam[numPoint], biom[numPoint] ]) # Ecrit le feature writer.addFeature(feat) # Fermer le vecteur writer = None # Create the PRJ file physiocap_create_projection_file(prj_name, laProjectionTXT) # Progress BAR + 5 % progress_barre = progress_barre + 5 self.progressBar.setValue(progress_barre) nom_layer_cree = None # Cas geopackage il faut faire une copie du gpkg intermediaire if quel_vecteur_demande == GEOPACKAGE_NOM and version_3 == "YES": nom_layer_cree = physiocap_vecteur_vers_gpkg(self, chemin_session, Nom_Session, nom_court_gpkg, nom_gpkg_intermediaire) else: nom_layer_cree = nom_vecteur # Création de la synthese if nom_fichier_synthese != "NO": # ASSERT Le fichier de synthese existe if not os.path.isfile(nom_fichier_synthese): uMsg = "Le fichier de synthese " + nom_fichier_synthese + "n'existe pas" physiocap_log(uMsg, leModeDeTrace) return physiocap_error(self, uMsg) # Ecriture des resulats fichier_synthese = open(nom_fichier_synthese, "a") try: fichier_synthese.write("\n\nVECTEURS FORMAT : {0}\n".format( self.fieldComboFormats.currentText())) fichier_synthese.write("\n\nSTATISTIQUES\n") fichier_synthese.write( "Vitesse moyenne d'avancement km/h \n mean : %0.1f \n" % np.mean(vitesse)) if version_3 == "YES": fichier_synthese.write("Altitude moyenne GPS en m \n mean : %0.1f\t std : %0.1f\n" \ %(np.mean(altitude), np.std(altitude))) fichier_synthese.write("Pdop moyen du GPS \n mean : %0.1f\t std : %0.1f\n" \ %(np.mean(pdop), np.std(pdop))) fichier_synthese.write("Distance moyenne entre point m \n mean : %0.1f\t std : %0.1f\n" \ %(np.mean(distance), np.std(distance))) # fichier_synthese.write("Dérive moyenne entre point % \n mean : %0.1f\t std : %0.1f\n" \ # %(np.mean(derive), np.std(derive))) except: msg = "Erreur bloquante durant premiers calculs de moyennes\n" physiocap_error(self, msg) raise physiocap_exception_fic(nom_fichier_synthese) try: fichier_synthese.write( "Section moyenne mm\n mean : %0.1f \t std : %0.1f\n" % (np.mean(diam), np.std(diam))) fichier_synthese.write( "Nombre de sarments au m \n mean : %0.1f \t std : %0.1f\n" % (np.mean(nbsarm), np.std(nbsarm))) fichier_synthese.write( "Biomasse en mm²/m linéaire \n mean : %0.1f\t std : %0.1f\n" % (np.mean(biom), np.std(biom))) if details == "YES": fichier_synthese.write( "Nombre de sarments au m² \n mean : %0.1f \t std : %0.1f\n" % (np.mean(nbsarmm2), np.std(nbsarmm2))) fichier_synthese.write( "Nombre de sarments par cep \n mean : %0.1f \t\t std : %0.1f\n" % (np.mean(nbsarcep), np.std(nbsarcep))) fichier_synthese.write( "Biomasse en mm²/m² \n mean : %0.1f\t std : %0.1f\n" % (np.mean(biommm2), np.std(biommm2))) fichier_synthese.write( "Biomasse en gramme/m² \n mean : %0.1f\t std : %0.1f\n" % (np.mean(biomgm2), np.std(biomgm2))) fichier_synthese.write( "Biomasse en gramme/cep \n mean : %0.1f\t std : %0.1f\n" % (np.mean(biomgcep), np.std(biomgcep))) except: msg = "Erreur bloquante durant deuxièmes calculs de moyennes\n" raise physiocap_exception_fic(msg) fichier_synthese.close() # Rendre la memoire x,y,nbsarm,diam,biom,date_capture,vitesse= [],[],[],[],[],[],[] azimuth, nbsart = [], [] altitude, pdop, distance, derive = [], [], [], [] nbsarmm2, nbsarcep, biommm2, biomgm2, biomgcep = [], [], [], [], [] # on rend le nom du shapefile ou du geopackage return nom_layer_cree
def _clipVectorLayer(theLayer, theExtent, theExtraKeywords=None, theExplodeFlag=True, theHardClipFlag=False): """Clip a Hazard or Exposure layer to the extents of the current view frame. The layer must be a vector layer or an exception will be thrown. The output layer will always be in WGS84/Geographic. Args: * theLayer - a valid QGIS vector layer in EPSG:4326 * theExtent either: an array representing the exposure layer extents in the form [xmin, ymin, xmax, ymax]. It is assumed that the coordinates are in EPSG:4326 although currently no checks are made to enforce this. or: A QgsGeometry of type polygon. **Polygon clipping is currently only supported for vector datasets.** * theExtraKeywords - any additional keywords over and above the original keywords that should be associated with the cliplayer. * theExplodeFlag - a bool specifying whether multipart features should be 'exploded' into singleparts. * theHardClipFlag - a bool specifying whether line and polygon features that extend beyond the extents should be clipped such that they are reduced in size to the part of the geometry that intersects the extent only. Default is False. Returns: Path to the output clipped layer (placed in the system temp dir). Raises: None """ if not theLayer or not theExtent: myMessage = tr('Layer or Extent passed to clip is None.') raise InvalidParameterError(myMessage) if theLayer.type() != QgsMapLayer.VectorLayer: myMessage = tr('Expected a vector layer but received a %s.' % str(theLayer.type())) raise InvalidParameterError(myMessage) #myHandle, myFilename = tempfile.mkstemp('.sqlite', 'clip_', # temp_dir()) myHandle, myFilename = tempfile.mkstemp('.shp', 'clip_', temp_dir()) # Ensure the file is deleted before we try to write to it # fixes windows specific issue where you get a message like this # ERROR 1: c:\temp\inasafe\clip_jpxjnt.shp is not a directory. # This is because mkstemp creates the file handle and leaves # the file open. os.close(myHandle) os.remove(myFilename) # Get the clip extents in the layer's native CRS myGeoCrs = QgsCoordinateReferenceSystem() myGeoCrs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) myXForm = QgsCoordinateTransform(myGeoCrs, theLayer.crs()) myAllowedClipTypes = [QGis.WKBPolygon, QGis.WKBPolygon25D] if type(theExtent) is list: myRect = QgsRectangle(theExtent[0], theExtent[1], theExtent[2], theExtent[3]) # noinspection PyCallByClass myClipPolygon = QgsGeometry.fromRect(myRect) elif (type(theExtent) is QgsGeometry and theExtent.wkbType in myAllowedClipTypes): myRect = theExtent.boundingBox().toRectF() myClipPolygon = theExtent else: raise InvalidClipGeometryError( tr('Clip geometry must be an extent or a single part' 'polygon based geometry.')) myProjectedExtent = myXForm.transformBoundingBox(myRect) # Get vector layer myProvider = theLayer.dataProvider() if myProvider is None: myMessage = tr('Could not obtain data provider from ' 'layer "%s"' % theLayer.source()) raise Exception(myMessage) # Get the layer field list, select by our extent then write to disk # .. todo:: FIXME - for different geometry types we should implement # different clipping behaviour e.g. reject polygons that # intersect the edge of the bbox. Tim myAttributes = myProvider.attributeIndexes() myFetchGeometryFlag = True myUseIntersectFlag = True myProvider.select(myAttributes, myProjectedExtent, myFetchGeometryFlag, myUseIntersectFlag) myFieldList = myProvider.fields() myWriter = QgsVectorFileWriter( myFilename, 'UTF-8', myFieldList, theLayer.wkbType(), myGeoCrs, #'SQLite') # FIXME (Ole): This works but is far too slow 'ESRI Shapefile') if myWriter.hasError() != QgsVectorFileWriter.NoError: myMessage = tr('Error when creating shapefile: <br>Filename:' '%s<br>Error: %s' % (myFilename, myWriter.hasError())) raise Exception(myMessage) # Reverse the coordinate xform now so that we can convert # geometries from layer crs to geocrs. myXForm = QgsCoordinateTransform(theLayer.crs(), myGeoCrs) # Retrieve every feature with its geometry and attributes myFeature = QgsFeature() myCount = 0 while myProvider.nextFeature(myFeature): myGeometry = myFeature.geometry() # Loop through the parts adding them to the output file # we write out single part features unless theExplodeFlag is False if theExplodeFlag: myGeometryList = explodeMultiPartGeometry(myGeometry) else: myGeometryList = [myGeometry] for myPart in myGeometryList: myPart.transform(myXForm) if theHardClipFlag: # Remove any dangling bits so only intersecting area is # kept. myPart = clipGeometry(myClipPolygon, myPart) if myPart is None: continue myFeature.setGeometry(myPart) myWriter.addFeature(myFeature) myCount += 1 del myWriter # Flush to disk if myCount < 1: myMessage = tr('No features fall within the clip extents. ' 'Try panning / zooming to an area containing data ' 'and then try to run your analysis again.' 'If hazard and exposure data doesn\'t overlap ' 'at all, it is not possible to do an analysis.' 'Another possibility is that the layers do overlap ' 'but because they may have different spatial ' 'references, they appear to be disjoint. ' 'If this is the case, try to turn on reproject ' 'on-the-fly in QGIS.') raise NoFeaturesInExtentError(myMessage) myKeywordIO = KeywordIO() myKeywordIO.copyKeywords(theLayer, myFilename, theExtraKeywords=theExtraKeywords) return myFilename # Filename of created file
def indexing(self,parameters): ggg=np.zeros(np.shape(parameters['INPUT3'][0]),dtype='float32') ggg[:]=parameters['INPUT3'][0][:] ggg[(ggg==-9999)]=np.nan numbb=parameters['INPUT']*2+1 row,col=np.where(parameters['INPUT3'][1]==1) #del parameters['INPUT4'] geo=parameters['INPUT1'].GetGeoTransform() xsize=geo[1] ysize=geo[5] OOx=geo[0] OOy=geo[3] XYcoord=np.array([0,0]) attributi={} print('filtering...') for ix in range(7): g={} lll=['real','max','min','std','sum','average','mean'] print(ix*15, '%') if ix == 0: g[ix] = ggg[:] #print(g[ix]) if ix == 1: g[ix] = scipy.ndimage.generic_filter(ggg, np.nanmax, size=(numbb,numbb)) #print(g[ix]) if ix == 2: g[ix] = scipy.ndimage.generic_filter(ggg, np.nanmin, size=(numbb,numbb)) #print(g[ix]) if ix == 3: g[ix] = scipy.ndimage.generic_filter(ggg, np.std, size=(numbb,numbb)) #print(g[ix]) if ix == 4: g[ix] = scipy.ndimage.generic_filter(ggg, np.sum, size=(numbb,numbb)) #print(g[ix]) if ix == 5: g[ix] = scipy.ndimage.generic_filter(ggg, np.average, size=(numbb,numbb)) #print(g[ix]) if ix == 6: g[ix] = scipy.ndimage.generic_filter(ggg, np.mean, size=(numbb,numbb)) #print(g[ix]) #g[ix][(ggg==-9999)]=-9999 #g[ix][(parameters['INPUT3'][1]==0)]=-9999 count=0 for i in range(len(col)): xmin=OOx+(xsize*col[i]) xmax=OOx+(xsize*col[i])+(xsize) ymax=OOy+(ysize*row[i]) ymin=OOy+(ysize*row[i])+(ysize) for ii in range(len(parameters['INPUT2'])): if (parameters['INPUT2'][ii,0]>=xmin and parameters['INPUT2'][ii,0]<=xmax and parameters['INPUT2'][ii,1]>=ymin and parameters['INPUT2'][ii,1]<=ymax): if ix==0: XYcoord=np.vstack((XYcoord,parameters['INPUT2'][ii,:])) try: attributi[count]=attributi[count]+[float(g[ix][row[i],col[i]])] except: attributi[count]=[float(g[ix][row[i],col[i]])] count+=1 g = {} fn = '/tmp/stat'+str(lll[ix])+'.shp' if os.path.isfile(fn): os.remove(fn) layerFields = QgsFields() layerFields.append(QgsField('ID', QVariant.Int)) layerFields.append(QgsField(lll[ix], QVariant.Double)) writer = QgsVectorFileWriter(fn, 'UTF-8', layerFields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem('EPSG:3857'), 'ESRI Shapefile') XYcoords=XYcoord[1:,:] for i in range(len(XYcoords)): feat = QgsFeature() feat.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(float(XYcoords[i,0]) , float(XYcoords[i,1])))) l=[] l=[i] #print(parameters['INPUT3'],'input3') #print(l+parameters['INPUT3'][i],'MIO') feat.setAttributes(l+[attributi[i][ix]]) writer.addFeature(feat) del(writer) #iface.addVectorLayer(fn, 'layer', 'ogr') print('100 %...end filtering') del parameters['INPUT2'] #print(XYcoord) XYcoord=XYcoord[1:,:] del ggg del parameters['INPUT3'] #print(attributi) #print(attributi[0][0]) return XYcoord,attributi
class VectorWriter(object): MEMORY_LAYER_PREFIX = 'memory:' POSTGIS_LAYER_PREFIX = 'postgis:' SPATIALITE_LAYER_PREFIX = 'spatialite:' nogeometry_extensions = [ u'csv', u'dbf', u'ods', u'xlsx', ] def __init__(self, destination, encoding, fields, geometryType, crs, options=None): self.destination = destination self.isNotFileBased = False self.layer = None self.writer = None if encoding is None: settings = QSettings() encoding = settings.value('/Processing/encoding', 'System', type=str) if self.destination.startswith(self.MEMORY_LAYER_PREFIX): self.isNotFileBased = True uri = QgsWkbTypes.displayString(geometryType) + "?uuid=" + str( uuid.uuid4()) if crs.isValid(): uri += '&crs=' + crs.authid() fieldsdesc = [] for f in fields: qgsfield = _toQgsField(f) fieldsdesc.append( 'field=%s:%s' % (qgsfield.name(), TYPE_MAP_MEMORY_LAYER.get(qgsfield.type(), "string"))) if fieldsdesc: uri += '&' + '&'.join(fieldsdesc) self.layer = QgsVectorLayer(uri, self.destination, 'memory') self.writer = self.layer.dataProvider() elif self.destination.startswith(self.POSTGIS_LAYER_PREFIX): self.isNotFileBased = True uri = QgsDataSourceUri( self.destination[len(self.POSTGIS_LAYER_PREFIX):]) connInfo = uri.connectionInfo() (success, user, passwd) = QgsCredentials.instance().get(connInfo, None, None) if success: QgsCredentials.instance().put(connInfo, user, passwd) else: raise GeoAlgorithmExecutionException( "Couldn't connect to database") # fix_print_with_import print(uri.uri()) try: db = postgis.GeoDB(host=uri.host(), port=int(uri.port()), dbname=uri.database(), user=user, passwd=passwd) except postgis.DbError as e: raise GeoAlgorithmExecutionException( "Couldn't connect to database:\n%s" % e.message) def _runSQL(sql): try: db._exec_sql_and_commit(str(sql)) except postgis.DbError as e: raise GeoAlgorithmExecutionException( 'Error creating output PostGIS table:\n%s' % e.message) fields = [_toQgsField(f) for f in fields] fieldsdesc = ",".join( '%s %s' % (f.name(), TYPE_MAP_POSTGIS_LAYER.get(f.type(), "VARCHAR")) for f in fields) _runSQL("CREATE TABLE %s.%s (%s)" % (uri.schema(), uri.table().lower(), fieldsdesc)) if geometryType != QgsWkbTypes.NullGeometry: _runSQL( "SELECT AddGeometryColumn('{schema}', '{table}', 'the_geom', {srid}, '{typmod}', 2)" .format(table=uri.table().lower(), schema=uri.schema(), srid=crs.authid().split(":")[-1], typmod=QgsWkbTypes.displayString( geometryType).upper())) self.layer = QgsVectorLayer(uri.uri(), uri.table(), "postgres") self.writer = self.layer.dataProvider() elif self.destination.startswith(self.SPATIALITE_LAYER_PREFIX): self.isNotFileBased = True uri = QgsDataSourceUri( self.destination[len(self.SPATIALITE_LAYER_PREFIX):]) # fix_print_with_import print(uri.uri()) try: db = spatialite.GeoDB(uri=uri) except spatialite.DbError as e: raise GeoAlgorithmExecutionException( "Couldn't connect to database:\n%s" % e.message) def _runSQL(sql): try: db._exec_sql_and_commit(str(sql)) except spatialite.DbError as e: raise GeoAlgorithmExecutionException( 'Error creating output Spatialite table:\n%s' % str(e)) fields = [_toQgsField(f) for f in fields] fieldsdesc = ",".join( '%s %s' % (f.name(), TYPE_MAP_SPATIALITE_LAYER.get(f.type(), "VARCHAR")) for f in fields) _runSQL("DROP TABLE IF EXISTS %s" % uri.table().lower()) _runSQL("CREATE TABLE %s (%s)" % (uri.table().lower(), fieldsdesc)) if geometryType != QgsWkbTypes.NullGeometry: _runSQL( "SELECT AddGeometryColumn('{table}', 'the_geom', {srid}, '{typmod}', 2)" .format(table=uri.table().lower(), srid=crs.authid().split(":")[-1], typmod=QgsWkbTypes.displayString( geometryType).upper())) self.layer = QgsVectorLayer(uri.uri(), uri.table(), "spatialite") self.writer = self.layer.dataProvider() else: formats = QgsVectorFileWriter.supportedFiltersAndFormats() OGRCodes = {} for (key, value) in list(formats.items()): extension = str(key) extension = extension[extension.find('*.') + 2:] extension = extension[:extension.find(' ')] OGRCodes[extension] = value OGRCodes['dbf'] = "DBF file" extension = self.destination[self.destination.rfind('.') + 1:] if extension not in OGRCodes: extension = 'shp' self.destination = self.destination + '.shp' if geometryType == QgsWkbTypes.NoGeometry: if extension == 'shp': extension = 'dbf' self.destination = self.destination[:self.destination. rfind('.')] + '.dbf' if extension not in self.nogeometry_extensions: raise GeoAlgorithmExecutionException( "Unsupported format for tables with no geometry") qgsfields = QgsFields() for field in fields: qgsfields.append(_toQgsField(field)) # use default dataset/layer options dataset_options = QgsVectorFileWriter.defaultDatasetOptions( OGRCodes[extension]) layer_options = QgsVectorFileWriter.defaultLayerOptions( OGRCodes[extension]) self.writer = QgsVectorFileWriter(self.destination, encoding, qgsfields, geometryType, crs, OGRCodes[extension], dataset_options, layer_options) def addFeature(self, feature): if self.isNotFileBased: self.writer.addFeatures([feature]) else: self.writer.addFeature(feature)
def run(self): self.mutex.lock() self.stopMe = 0 self.mutex.unlock() interrupted = False polyProvider = self.layerPoly.dataProvider() pointProvider = self.layerPoints.dataProvider() fieldList = ftools_utils.getFieldList(self.layerPoly) index = polyProvider.fieldNameIndex(unicode(self.fieldName)) if index == -1: index = polyProvider.fields().count() fieldList.append( QgsField(unicode(self.fieldName), QVariant.Int, "int", 10, 0, self.tr("point count field"))) # Add the selected vector fields to the output polygon vector layer selectedItems = self.attributeList.selectedItems() for item in selectedItems: global typeDouble columnName = unicode(item.text() + "_" + self.statistics) index = polyProvider.fieldNameIndex(unicode(columnName)) if index == -1: if item.type( ) == typeDouble or self.statistics == "mean" or self.statistics == "stddev": fieldList.append( QgsField(columnName, QVariant.Double, "double", 24, 15, "Value")) else: fieldList.append( QgsField(columnName, QVariant.Int, "int", 10, 0, "Value")) sRs = polyProvider.crs() if QFile(self.outPath).exists(): if not QgsVectorFileWriter.deleteShapeFile(self.outPath): return writer = QgsVectorFileWriter(self.outPath, self.encoding, fieldList, polyProvider.geometryType(), sRs) spatialIndex = ftools_utils.createIndex(pointProvider) self.emit(SIGNAL("rangeChanged(int)"), polyProvider.featureCount()) polyFeat = QgsFeature() pntFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() polyFit = polyProvider.getFeatures() while polyFit.nextFeature(polyFeat): inGeom = polyFeat.geometry() atMap = polyFeat.attributes() outFeat.setAttributes(atMap) outFeat.setGeometry(inGeom) count = 0 pointList = [] hasIntersection = True pointList = spatialIndex.intersects(inGeom.boundingBox()) if len(pointList) > 0: hasIntersection = True else: hasIntersection = False if hasIntersection: valueList = {} for item in selectedItems: valueList[item.text()] = [] for p in pointList: pointProvider.getFeatures(QgsFeatureRequest().setFilterFid( p)).nextFeature(pntFeat) tmpGeom = QgsGeometry(pntFeat.geometry()) if inGeom.intersects(tmpGeom): count += 1 for item in selectedItems: valueList[item.text()].append( pntFeat.attribute(item.text())) self.mutex.lock() s = self.stopMe self.mutex.unlock() if s == 1: interrupted = True break atMap.append(count) # Compute the statistical values for selected vector attributes for item in selectedItems: values = valueList[item.text()] # Check if the input contains non-numeric values non_numeric_values = False for value in values: if not isinstance(value, type( float())) and not isinstance( value, type(int())): non_numeric_values = True break # Jump over invalid values if non_numeric_values is True: continue if values and len(values) > 0: if self.statistics == "sum": value = reduce(myAdder, values) elif self.statistics == "mean": value = reduce(myAdder, values) / float( len(values)) elif self.statistics == "min": values.sort() value = values[0] elif self.statistics == "max": values.sort() value = values[-1] elif self.statistics == "stddev": value = two_pass_variance(values) value = math.sqrt(value) atMap.append(value) outFeat.setAttributes(atMap) writer.addFeature(outFeat) self.emit(SIGNAL("updateProgress()")) self.mutex.lock() s = self.stopMe self.mutex.unlock() if s == 1: interrupted = True break del writer if not interrupted: self.emit(SIGNAL("processingFinished()")) else: self.emit(SIGNAL("processingInterrupted()"))
def do_operation(self): """ perform create mapping scheme operation """ # input/output verification already performed during set input/ouput fp_layer = self.inputs[0].value zone_field = self.inputs[1].value # aggregate footprint into grids logAPICall.log('aggregate statistic for grid ...', logAPICall.DEBUG) total_features = fp_layer.dataProvider().featureCount() if total_features > MAX_FEATURES_IN_MEMORY: # use bsddb to store temporary lat/lon tmp_db_file = '%sdb_%s.db' % (self._tmp_dir, get_unique_filename()) db = bsddb.btopen(tmp_db_file, 'c') use_db = True else: db = {} use_db = False zone_idx = layer_field_index(fp_layer, zone_field) for f in layer_features(fp_layer): geom = f.geometry() zone_str = str(f.attributeMap()[zone_idx].toString()) centroid = geom.centroid().asPoint() # use floor, this truncates all points within grid to grid's # bottom-left corner x = math.floor(centroid.x() / DEFAULT_GRID_SIZE) y = math.floor(centroid.y() / DEFAULT_GRID_SIZE) key = '%s %d %d' % (zone_str, x,y) if db.has_key(key): db[key] = str(int(db[key]) + 1) else: db[key] = '1' # output grid logAPICall.log('create grid ...', logAPICall.DEBUG) fields = { 0 : QgsField(self._lon_field, QVariant.Double), 1 : QgsField(self._lat_field, QVariant.Double), 2 : QgsField(CNT_FIELD_NAME, QVariant.Double), 3 : QgsField(zone_field, QVariant.String), } grid_layername = 'grid_%s' % get_unique_filename() grid_file = '%s%s.shp' % (self._tmp_dir, grid_layername) try: writer = QgsVectorFileWriter(grid_file, "utf-8", fields, QGis.WKBPoint , self._crs, "ESRI Shapefile") f = QgsFeature() for key, val in db.iteritems(): (zone_str, x, y) = key.split(' ') # point were aggregated to grid's bottom-left corner # add half grid size to place point at center of grid point = QgsPoint(int(x)*DEFAULT_GRID_SIZE+(DEFAULT_GRID_SIZE/2.0), int(y)*DEFAULT_GRID_SIZE+(DEFAULT_GRID_SIZE/2.0)) f.setGeometry(QgsGeometry.fromPoint(point)) f.addAttribute(0, QVariant(point.x())) f.addAttribute(1, QVariant(point.y())) f.addAttribute(2, QVariant(val)) f.addAttribute(3, QVariant(zone_str)) writer.addFeature(f) del writer except Exception as err: remove_shapefile(grid_file) raise OperatorError("error creating joined grid: " % err, self.__class__) grid_layer = load_shapefile(grid_file, grid_layername) if not grid_layer: raise OperatorError('Error loading created grid file' % (grid_file), self.__class__) # clean up if use_db: db.close() os.remove(tmp_db_file) # done self.outputs[0].value = grid_layer self.outputs[1].value = grid_file
def read2dm(self): try: crs = self.crs except(AttributeError): crs = QgsCoordinateReferenceSystem( 3826, QgsCoordinateReferenceSystem.EpsgCrsId) meshFile = self.dlg.meshFileEdit.text() f = open(meshFile, 'r') nodeFields = QgsFields() nodeFields.append(QgsField("id", QVariant.Int)) nodeFields.append(QgsField("z", QVariant.Double)) nodePath = os.path.join(self.dlg.folderLineEdit.text(), 'Nodes.shp') nodeWriter = QgsVectorFileWriter(nodePath, 'UTF-8', nodeFields, QGis.WKBPoint, crs, 'ESRI Shapefile') data = f.readlines() NodeDict = dict() Regions = list() NodeStrings = list() oneString = list() for line in data: line = line.split() if line[0] == 'ND': NodeDict.update( {int(line[1]): (float(line[2]), float(line[3]), float(line[4]))}) geoString = ('POINT (' + line[2] + ' ' + line[3] + ')') feature = QgsFeature() feature.setGeometry(QgsGeometry.fromWkt(geoString)) feature.setAttributes([int(line[1]), float(line[4])]) nodeWriter.addFeature(feature) elif line[0] in meshType.keys(): Regions.append(int(line[-1])) elif line[0] == 'NS': for i in range(1, len(line)): oneString.append(fabs(int(line[i]))) if int(line[-1]) < 0: NodeStrings.append(oneString) oneString = list() del nodeWriter Regions = list(set(Regions)) Regions.sort() group = QgsProject.instance().layerTreeRoot().addGroup( os.path.basename(meshFile)) regionWriters = list() fields = QgsFields() fields.append(QgsField("id", QVariant.Int)) layerList = list() layerList.append(nodePath) for i in range(0, len(Regions)): layerName = 'Material' + str(Regions[i]) path = os.path.join(self.dlg.folderLineEdit.text(), layerName + '.shp') self.iface.messageBar().pushMessage(path) regionWriters.append( QgsVectorFileWriter(path, 'UTF-8', fields, QGis.WKBPolygon, crs, 'ESRI Shapefile')) layerList.append(path) for line in data: line = line.split() if line[0] in meshType.keys(): n = meshType[line[0]] geoString = 'POLYGON ((' for k in range(2, 2+n): Coor = NodeDict[int(line[k])] geoString += (str(Coor[0]) + ' ' + str(Coor[1]) + ', ') Coor = NodeDict[int(line[2])] geoString += (str(Coor[0]) + ' ' + str(Coor[1])) geoString += '))' writer = regionWriters[int(line[-1])-1] feature = QgsFeature() feature.setGeometry(QgsGeometry().fromWkt(geoString)) feature.setAttributes([int(line[1])]) writer.addFeature(feature) if writer.hasError() != QgsVectorFileWriter.NoError: self.iface.messageBar().pushMessage( "Error when creating shapefile: ", writer.errorMessage()) for writer in regionWriters: del writer counter = 1 for lineString in NodeStrings: path = os.path.join(self.dlg.folderLineEdit.text(), 'NodeString' + str(counter) + '.shp') writer = QgsVectorFileWriter(path, 'UTF-8', fields, QGis.WKBLineString, crs, 'ESRI Shapefile') layerList.append(path) geoString = 'LINESTRING (' for i in range(0, len(lineString)): nodeCoor = NodeDict[lineString[i]] geoString += (str(nodeCoor[0]) + " " + str(nodeCoor[1]) + ", ") geoString = geoString[:-2] + ')' feature = QgsFeature() feature.setGeometry(QgsGeometry().fromWkt(geoString)) feature.setAttributes([counter]) writer.addFeature(feature) del writer counter += 1 for i in range(0, len(layerList)): layer = QgsVectorLayer( layerList[i], QFileInfo(layerList[i]).baseName(), 'ogr') QgsMapLayerRegistry.instance().addMapLayer(layer, False) group.addLayer(layer) layer.reload()
def processAlgorithm(self, progress): """Here is where the processing itself takes place.""" # The first thing to do is retrieve the values of the parameters # entered by the user inputFilename = self.getParameterValue(self.INPUT_LAYER) output = self.getOutputValue(self.OUTPUT_LAYER) # Input layers vales are always a string with its location. # That string can be converted into a QGIS object (a # QgsVectorLayer in this case) using the # processing.getObjectFromUri() method. vectorLayer = dataobjects.getObjectFromUri(inputFilename) # And now we can process # First we create the output layer. The output value entered by # the user is a string containing a filename, so we can use it # directly provider = vectorLayer.dataProvider() settings = QSettings() systemEncoding = settings.value('/UI/encoding', 'System') writer = QgsVectorFileWriter(output, systemEncoding, provider.fields(), provider.geometryType(), provider.crs()) # Do the transform QgsMessageLog.logMessage("Start processing ...", 'WGS2GCJ', QgsMessageLog.INFO) # engine = OffsetWGS84Engine() features = vector.features(vectorLayer) total_cnt = len(features) cnt = 0 step = int(total_cnt / 100) if step == 0: step = 1 for f in features: attrs = f.attributes() geom = f.geometry() geom_type = geom.wkbType() new_f = QgsFeature() if geom_type == QGis.WKBPoint: vertices = geom.asPoint() new_vert = bd2wgs(vertices[0], vertices[1]) new_f.setGeometry(QgsGeometry.fromPoint(QgsPoint(new_vert[0], new_vert[1]))) elif geom_type == QGis.WKBMultiPoint: vertices = geom.asMultiPoint() new_vert = [] for pt in vertices: new_pt = bd2wgs(pt[0], pt[1]) new_vert.append(QgsPoint(new_pt[0], new_pt[1])) new_f.setGeometry(QgsGeometry.fromMultiPoint(new_vert)) elif geom_type == QGis.WKBLineString: vertices = geom.asPolyline() new_vert = [] for pt in vertices: new_pt = bd2wgs(pt[0], pt[1]) new_vert.append(QgsPoint(new_pt[0], new_pt[1])) new_f.setGeometry(QgsGeometry.fromPolyline(new_vert)) elif geom_type == QGis.WKBMultiLineString: vertices = geom.asMultiPolyline() new_vert = [] for part in vertices: linestring = [] for pt in part: new_pt = bd2wgs(pt[0], pt[1]) linestring.append(QgsPoint(new_pt[0], new_pt[1])) new_vert.append(linestring) new_f.setGeometry(QgsGeometry.fromMultiPolyline(new_vert)) elif geom_type == QGis.WKBPolygon: vertices = geom.asPolygon() new_vert = [] for ring in vertices: ring_vert = [] for pt in ring: new_pt = bd2wgs(pt[0], pt[1]) ring_vert.append(QgsPoint(new_pt[0], new_pt[1])) new_vert.append(ring_vert) new_f.setGeometry(QgsGeometry.fromPolygon(new_vert)) elif geom_type == QGis.WKBMultiPolygon: vertices = geom.asMultiPolygon() new_vert = [] for part in vertices: ply = [] for ring in part: ring_vert = [] for pt in ring: new_pt = bd2wgs(pt[0], pt[1]) ring_vert.append(QgsPoint(new_pt[0], new_pt[1])) ply.append(ring_vert) new_vert.append(ply) new_f.setGeometry(QgsGeometry.fromMultiPolygon(new_vert)) else: continue new_f.setAttributes(attrs) writer.addFeature(new_f) cnt = cnt + 1 if (cnt % step == 0): progress.setPercentage((float(cnt) / float(total_cnt) * 100)) QgsMessageLog.logMessage("Successful finished.", 'BD2WGS', QgsMessageLog.INFO)
def _clip_vector_layer( layer, extent, extra_keywords=None, explode_flag=True, hard_clip_flag=False, explode_attribute=None): """Clip a Hazard or Exposure layer to the extents provided. The layer must be a vector layer or an exception will be thrown. The output layer will always be in WGS84/Geographic. :param layer: A valid QGIS vector or raster layer :type layer: :param extent: Either an array representing the exposure layer extents in the form [xmin, ymin, xmax, ymax]. It is assumed that the coordinates are in EPSG:4326 although currently no checks are made to enforce this. or: A QgsGeometry of type polygon. **Polygon clipping is currently only supported for vector datasets.** :type extent: list(float, float, float, float) :param extra_keywords: Optional keywords dictionary to be added to output layer. :type extra_keywords: dict :param explode_flag: A bool specifying whether multipart features should be 'exploded' into singleparts. **This parameter is ignored for raster layer clipping.** :type explode_flag: bool :param hard_clip_flag: A bool specifying whether line and polygon features that extend beyond the extents should be clipped such that they are reduced in size to the part of the geometry that intersects the extent only. Default is False. **This parameter is ignored for raster layer clipping.** :type hard_clip_flag: bool :param explode_attribute: A str specifying to which attribute #1, #2 and so on will be added in case of explode_flag being true. The attribute is modified only if there are at least 2 parts. :type explode_attribute: str :returns: Clipped layer (placed in the system temp dir). The output layer will be reprojected to EPSG:4326 if needed. :rtype: QgsVectorLayer """ if not layer or not extent: message = tr('Layer or Extent passed to clip is None.') raise InvalidParameterError(message) if layer.type() != QgsMapLayer.VectorLayer: message = tr( 'Expected a vector layer but received a %s.' % str(layer.type())) raise InvalidParameterError(message) # handle, file_name = tempfile.mkstemp('.sqlite', 'clip_', # temp_dir()) handle, file_name = tempfile.mkstemp( '.shp', 'clip_', temp_dir()) # Ensure the file is deleted before we try to write to it # fixes windows specific issue where you get a message like this # ERROR 1: c:\temp\inasafe\clip_jpxjnt.shp is not a directory. # This is because mkstemp creates the file handle and leaves # the file open. os.close(handle) os.remove(file_name) # Get the clip extents in the layer's native CRS geo_crs = QgsCoordinateReferenceSystem() geo_crs.createFromSrid(4326) transform = QgsCoordinateTransform(geo_crs, layer.crs()) allowed_clip_values = [QGis.WKBPolygon, QGis.WKBPolygon25D] if isinstance(extent, list): rectangle = QgsRectangle( extent[0], extent[1], extent[2], extent[3]) # noinspection PyCallByClass # noinspection PyTypeChecker polygon = QgsGeometry.fromRect(rectangle) elif (isinstance(extent, QgsGeometry) and extent.wkbType in allowed_clip_values): rectangle = extent.boundingBox().toRectF() polygon = extent else: raise InvalidClipGeometryError( tr( 'Clip geometry must be an extent or a single part' 'polygon based geometry.')) projected_extent = transform.transformBoundingBox(rectangle) # Get vector layer provider = layer.dataProvider() if provider is None: message = tr( 'Could not obtain data provider from ' 'layer "%s"' % layer.source()) raise Exception(message) # Get the layer field list, select by our extent then write to disk # .. todo:: FIXME - for different geometry types we should implement # different clipping behaviour e.g. reject polygons that # intersect the edge of the bbox. Tim request = QgsFeatureRequest() if not projected_extent.isEmpty(): request.setFilterRect(projected_extent) request.setFlags(QgsFeatureRequest.ExactIntersect) field_list = provider.fields() writer = QgsVectorFileWriter( file_name, 'UTF-8', field_list, layer.wkbType(), geo_crs, # 'SQLite') # FIXME (Ole): This works but is far too slow 'ESRI Shapefile') if writer.hasError() != QgsVectorFileWriter.NoError: message = tr( 'Error when creating shapefile: <br>Filename:' '%s<br>Error: %s' % (file_name, writer.hasError())) raise Exception(message) # Reverse the coordinate xform now so that we can convert # geometries from layer crs to geocrs. transform = QgsCoordinateTransform(layer.crs(), geo_crs) # Retrieve every feature with its geometry and attributes count = 0 has_multipart = False for feature in provider.getFeatures(request): geometry = feature.geometry() # Loop through the parts adding them to the output file # we write out single part features unless explode_flag is False if explode_flag: geometry_list = explode_multipart_geometry(geometry) else: geometry_list = [geometry] for part_index, part in enumerate(geometry_list): part.transform(transform) if hard_clip_flag: # Remove any dangling bits so only intersecting area is # kept. part = clip_geometry(polygon, part) if part is None: continue feature.setGeometry(part) # There are multiple parts and we want to show it in the # explode_attribute if part_index > 0 and explode_attribute is not None: has_multipart = True writer.addFeature(feature) count += 1 del writer # Flush to disk if count < 1: message = tr( 'No features fall within the clip extents. Try panning / zooming ' 'to an area containing data and then try to run your analysis ' 'again. If hazard and exposure data doesn\'t overlap at all, it ' 'is not possible to do an analysis. Another possibility is that ' 'the layers do overlap but because they may have different ' 'spatial references, they appear to be disjointed. If this is the ' 'case, try to turn on reproject on-the-fly in QGIS.') raise NoFeaturesInExtentError(message) keyword_io = KeywordIO() if extra_keywords is None: extra_keywords = {} extra_keywords['had multipart polygon'] = has_multipart keyword_io.copy_keywords( layer, file_name, extra_keywords=extra_keywords) base_name = '%s clipped' % layer.name() layer = QgsVectorLayer(file_name, base_name, 'ogr') return layer
def do_operation(self): """ perform create mapping scheme operation """ # validate inputs fp_layer = self.inputs[0].value zone_layer = self.inputs[1].value zone_field = self.inputs[2].value count_field = self.inputs[3].value area_field = self.inputs[4].value # make sure input is correct # NOTE: these checks cannot be performed at set input time # because the data layer maybe is not loaded yet self._test_layer_loaded(fp_layer) self._test_layer_loaded(zone_layer) self._test_layer_field_exists(zone_layer, GID_FIELD_NAME) self._test_layer_field_exists(zone_layer, zone_field) # count_field is not required # if count field is not defined, then generate building count from footprints # area_field is not required # local variables analyzer = QgsOverlayAnalyzer() area_idx = ToGrid.STAT_AREA_IDX cnt_idx = ToGrid.STAT_COUNT_IDX zone_names, zone_stat, zone_stat2, zone_totals = {}, {}, {}, {} # 1. find building count and total area for each zone # project geometry into mercator and get area in m2 mercator_crs = QgsCoordinateReferenceSystem() mercator_crs.createFromEpsg(3395) mercator_transform = QgsCoordinateTransform(zone_layer.crs(), mercator_crs) try: # use zone geometry area self._create_zone_statistics(zone_layer, zone_field, count_field, zone_stat, zone_names) except Exception as err: raise OperatorError(str(err), self.__class__) # 2. create grids around extent of zone tmp_grid1 = 'grid_' + get_unique_filename() tmp_grid1_file = self._tmp_dir + tmp_grid1 + '.shp' extent = zone_layer.extent() [x_min, y_min, x_max, y_max] = [extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum()] tmp_grid_lyr1 = self._create_grid(tmp_grid1, tmp_grid1_file, \ x_min, y_min, x_max, y_max, \ DEFAULT_GRID_SIZE, DEFAULT_GRID_SIZE) # tally total building area if there is defined bldg_area_idx = layer_field_index(zone_layer, area_field) zone_area = {} zone_has_area = False if bldg_area_idx > 0: zone_has_area = True zone_gid_idx = layer_field_index(zone_layer, GID_FIELD_NAME) for _f in layer_features(zone_layer): gid = _f.attributeMap()[zone_gid_idx].toString() area = _f.attributeMap()[bldg_area_idx].toDouble()[0] if zone_area.has_key(gid): zone_area[gid] = str(float(zone_area[gid]))+area else: zone_area[gid] = area # 3. intersect grids and zones to obtain polygons with # - grid_id and zone_id # - ratio of grid covered by zone (polygon area / zone area) # apply ratio to zone building count to obtain count assigned to polygon tmp_join = 'joined_%s' % get_unique_filename() tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join) try: # do intersection analyzer.intersection(tmp_grid_lyr1, zone_layer, tmp_join_file) tmp_join_layer = load_shapefile(tmp_join_file, tmp_join) except AssertionError as err: raise OperatorError(str(err), self.__class__) except Exception as err: raise OperatorError(str(err), self.__class__) # do tally zone_gid_idx = layer_field_index(tmp_join_layer, GID_FIELD_NAME) grid_gid_idx = layer_field_index(tmp_join_layer, "GRID_GID") bldg_cnt_idx = layer_field_index(tmp_join_layer, count_field) for _f in layer_features(tmp_join_layer): geom = _f.geometry() geom.transform(mercator_transform) area = geom.area() # generate all stats of interest zone_gid = _f.attributeMap()[zone_gid_idx].toString() grid_gid = _f.attributeMap()[grid_gid_idx].toString() stat = zone_stat[zone_gid] # calculate count/area as proportion of total zone area area_ratio = (area/stat[area_idx]) if bldg_cnt_idx > 0: bldg_cnt = _f.attributeMap()[bldg_cnt_idx].toDouble()[0] * area_ratio else: bldg_cnt = 0 if zone_has_area: area = zone_area[zone_gid] * area_ratio else: area = stat[area_idx] * area_ratio self._update_stat(zone_stat2, '%s|%s'%(grid_gid, zone_gid), bldg_cnt, area) # 4. find total buildings in each zone based on footprint # - simply join the files and tally count and total area tmp_join1 = 'joined_%s' % get_unique_filename() tmp_join1_file = '%s%s.shp' % (self._tmp_dir, tmp_join1) try: # do intersection analyzer.intersection(fp_layer, tmp_join_layer, tmp_join1_file) tmp_join1_layer = load_shapefile(tmp_join1_file, tmp_join1) except AssertionError as err: raise OperatorError(str(err), self.__class__) except Exception as err: raise OperatorError(str(err), self.__class__) # do tally zone_fp_stat = {} zone_gid_idx = layer_field_index(tmp_join1_layer, '%s_'% GID_FIELD_NAME) grid_gid_idx = layer_field_index(tmp_join1_layer, "GRID_GID") fp_area_idx = layer_field_index(tmp_join1_layer, AREA_FIELD_NAME) fp_ht_idx = layer_field_index(tmp_join1_layer, HT_FIELD_NAME) fp_has_height = False for _f in layer_features(tmp_join1_layer): zone_gid = _f.attributeMap()[zone_gid_idx].toString() grid_gid = _f.attributeMap()[grid_gid_idx].toString() area = _f.attributeMap()[fp_area_idx].toDouble()[0] # area comes from geometry, always exists ht = _f.attributeMap()[fp_ht_idx].toDouble()[0] if ht > 0: fp_has_height = True area *= ht # this is actual area to be aggregated at the end self._update_stat(zone_fp_stat, '%s|%s'%(grid_gid, zone_gid), 1, area) self._update_stat(zone_totals, zone_gid, 1, area) # 5. generate grid with adjusted building counts fields = { 0 : QgsField(GID_FIELD_NAME, QVariant.String), 1 : QgsField(zone_field, QVariant.String), 2 : QgsField(CNT_FIELD_NAME, QVariant.Double), 3 : QgsField(AREA_FIELD_NAME, QVariant.Double), } output_layername = 'grid_%s' % get_unique_filename() output_file = '%s%s.shp' % (self._tmp_dir, output_layername) writer = QgsVectorFileWriter(output_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile") f = QgsFeature() for key in zone_stat2.keys(): (grid_gid, zone_gid) = str(key).split("|") s_zone = zone_stat[QString(zone_gid)] # overall statistics for the zone from zone file (always exists) s_zone_grid = zone_stat2[key] # grid specific statistic from from zone file (always exists) if zone_totals.has_key(QString(zone_gid)): # overall statistics for the zone from footprints s_total = zone_totals[QString(zone_gid)] else: s_total = [0,0] # set to zero if missing if zone_fp_stat.has_key(key): # grid specific statistic from from footprint s_fp = zone_fp_stat[key] else: s_fp = [0, 0] # set to zero if missing zone_leftover_count = s_zone[cnt_idx] - s_total[cnt_idx] if zone_has_area: zone_leftover_area = zone_area[QString(zone_gid)] - s_total[area_idx] else: zone_leftover_area = s_zone[area_idx] - s_total[area_idx] if zone_leftover_count > 0: # there are still building not accounted for # distribute to grid based on ratio of grid leftover area over zone leftover area # (leftover area is area of zone after subtracting footprint areas grid_leftover_count = zone_leftover_count * ((s_zone_grid[area_idx]-s_fp[area_idx])/zone_leftover_area) grid_count = s_fp[cnt_idx] + grid_leftover_count else: grid_count = s_fp[cnt_idx] if fp_has_height: # area can be actual area based on footprint area * height area = s_fp[area_idx] elif zone_has_area: area = s_zone_grid[area_idx] else: # no area defined area = 0 # max(s_zone_grid[area_idx], s_fp[area_idx]) f.setGeometry(self._outputGeometryFromGridId(grid_gid)) f.addAttribute(0, grid_gid) f.addAttribute(1, zone_names[QString(zone_gid)]) f.addAttribute(2, grid_count) f.addAttribute(3, area) writer.addFeature(f) del writer # clean up del tmp_grid_lyr1 del tmp_join_layer del tmp_join1_layer remove_shapefile(tmp_grid1_file) remove_shapefile(tmp_join_file) remove_shapefile(tmp_join1_file) # store data in output self._load_output(output_file, output_layername)
def parse(self): """ Start parsing the osm file """ # Configuration for OGR gdal.SetConfigOption('OSM_CONFIG_FILE', self._osm_conf) gdal.SetConfigOption('OSM_USE_CUSTOM_INDEXING', 'NO') if not isfile(self.__osmFile): raise GeoAlgorithmExecutionException("File doesn't exist") uri = self.__osmFile + "|layername=" layers = {} # If loadOnly, no parsing required: # It's used only when we ask to open an osm file if self.__loadOnly: file_name = basename(self.__osmFile) for layer in self.__layers: layers[layer] = QgsVectorLayer( uri + layer, file_name + " " + layer, "ogr") if not layers[layer].isValid(): print "Error on the layer", layers[layer].lastError() return layers # Check if the order is node before way,relation # We don't check way before relation, # because we can have only nodes and relations with open(self.__osmFile) as f: for line in f: if re.search(r'node', line): break if re.search(r'(way|relation)', line): raise WrongOrderOSMException # Foreach layers for layer in self.__layers: self.signalText.emit(tr("QuickOSM", u"Parsing layer : " + layer)) layers[layer] = {} # Reading it with a QgsVectorLayer layers[layer]['vectorLayer'] = QgsVectorLayer( uri + layer, "test_" + layer, "ogr") if not layers[layer]['vectorLayer'].isValid(): msg = "Error on the layer : " + \ layers[layer]['vectorLayer'].lastError() raise GeoAlgorithmExecutionException(msg) # Set some default tags layers[layer]['tags'] = ['full_id', 'osm_id', 'osm_type'] # Save the geometry type of the layer layers[layer]['geomType'] = layers[layer]['vectorLayer'].wkbType() # Set a featureCount layers[layer]['featureCount'] = 0 # Get the other_tags fields = layers[layer]['vectorLayer'].pendingFields() field_names = [field.name() for field in fields] other_tags_index = field_names.index('other_tags') features = layers[layer]['vectorLayer'].getFeatures() for i, feature in enumerate(features): layers[layer]['featureCount'] += 1 # Improve the parsing if comma in whitelist, # we skip the parsing of tags, but featureCount is needed if self.__whiteListColumn[layer] == ',': continue # Get the "others_tags" field attributes = feature.attributes()[other_tags_index] if attributes: h_store = pghstore.loads(attributes) for key in h_store: if key not in layers[layer]['tags']: # If the key in OSM is not already in the table if self.__whiteListColumn[layer]: if key in self.__whiteListColumn[layer]: layers[layer]['tags'].append(key) else: layers[layer]['tags'].append(key) percent = int(100 / len(self.__layers) * (i + 1)) self.signalPercentage.emit(percent) # Delete empty layers if this option is set to True if self.__deleteEmptyLayers: delete_layers = [] for keys, values in layers.iteritems(): if values['featureCount'] < 1: delete_layers.append(keys) for layer in delete_layers: del layers[layer] # Creating GeoJSON files for each layers for layer in self.__layers: msg = tr("QuickOSM", u"Creating GeoJSON file : " + layer) self.signalText.emit(msg) self.signalPercentage.emit(0) # Creating the temp file tf = tempfile.NamedTemporaryFile( delete=False, suffix="_" + layer + ".geojson") layers[layer]['geojsonFile'] = tf.name tf.flush() tf.close() # Adding the attribute table fields = QgsFields() for key in layers[layer]['tags']: fields.append(QgsField(key, QVariant.String)) encoding = get_default_encoding() file_writer = QgsVectorFileWriter( layers[layer]['geojsonFile'], encoding, fields, layers[layer]['geomType'], layers[layer]['vectorLayer'].crs(), 'GeoJSON') # Foreach feature in the layer features = layers[layer]['vectorLayer'].getFeatures() for i, feature in enumerate(features): fet = QgsFeature() fet.setGeometry(feature.geometry()) new_attributes = [] attributes = feature.attributes() if layer in ['points', 'lines', 'multilinestrings']: if layer == 'points': osm_type = "node" elif layer == 'lines': osm_type = "way" elif layer == 'multilinestrings': osm_type = 'relation' new_attributes.append( self.DIC_OSM_TYPE[osm_type] + str(attributes[0])) new_attributes.append(attributes[0]) new_attributes.append(osm_type) if attributes[1]: h_store = pghstore.loads(attributes[1]) for tag in layers[layer]['tags'][3:]: if unicode(tag) in h_store: new_attributes.append(h_store[tag]) else: new_attributes.append("") fet.setAttributes(new_attributes) file_writer.addFeature(fet) elif layer == 'multipolygons': if attributes[0]: osm_type = "relation" new_attributes.append( self.DIC_OSM_TYPE[osm_type] + str(attributes[0])) new_attributes.append(str(attributes[0])) else: osm_type = "way" new_attributes.append( self.DIC_OSM_TYPE[osm_type] + str(attributes[1])) new_attributes.append(attributes[1]) new_attributes.append(osm_type) h_store = pghstore.loads(attributes[2]) for tag in layers[layer]['tags'][3:]: if unicode(tag) in h_store: new_attributes.append(h_store[tag]) else: new_attributes.append("") fet.setAttributes(new_attributes) file_writer.addFeature(fet) percentage = int( 100 / layers[layer]['featureCount'] * (i + 1)) self.signalPercentage.emit(percentage) del file_writer return layers
class VectorWriter: MEMORY_LAYER_PREFIX = 'memory:' def __init__(self, fileName, encoding, fields, geometryType, crs, options=None): self.fileName = fileName self.isMemory = False self.memLayer = None self.writer = None if encoding is None: settings = QSettings() encoding = settings.value('/Processing/encoding', 'System', type=str) if self.fileName.startswith(self.MEMORY_LAYER_PREFIX): self.isMemory = True uri = GEOM_TYPE_MAP[geometryType] + "?uuid=" + str(uuid.uuid4()) if crs.isValid(): uri += '&crs=' + crs.authid() fieldsdesc = [] for f in fields: qgsfield = _toQgsField(f) fieldsdesc.append( 'field=%s:%s' % (qgsfield.name(), TYPE_MAP_MEMORY_LAYER.get(qgsfield.type(), "string"))) if fieldsdesc: uri += '&' + '&'.join(fieldsdesc) self.memLayer = QgsVectorLayer(uri, self.fileName, 'memory') self.writer = self.memLayer.dataProvider() else: formats = QgsVectorFileWriter.supportedFiltersAndFormats() OGRCodes = {} for (key, value) in formats.items(): extension = unicode(key) extension = extension[extension.find('*.') + 2:] extension = extension[:extension.find(' ')] OGRCodes[extension] = value extension = self.fileName[self.fileName.rfind('.') + 1:] if extension not in OGRCodes: extension = 'shp' self.filename = self.filename + 'shp' qgsfields = QgsFields() for field in fields: qgsfields.append(_toQgsField(field)) self.writer = QgsVectorFileWriter(self.fileName, encoding, qgsfields, geometryType, crs, OGRCodes[extension]) def addFeature(self, feature): if self.isMemory: self.writer.addFeatures([feature]) else: self.writer.addFeature(feature)
def processAlgorithm(self, parameters, context, feedback): # extract input parameters alg = self.parameterAsEnum(parameters, self.INPUT_ALG_NAME, context) extent = self.parameterAsVectorLayer(parameters, self.INPUT_EXTENT, context) raster_1_id = self.parameterAsString(parameters, self.INPUT_RASTER_1, context) raster_1 = QgsProject.instance().mapLayer(raster_1_id) raster_2_id = self.parameterAsString(parameters, self.INPUT_RASTER_2, context) raster_2 = QgsProject.instance().mapLayer(raster_2_id) (sink, self.dest_id) = self.parameterAsSink( parameters, self.OUTPUT_BUFFER, context, QgsFields(), extent.wkbType(), extent.sourceCrs(), ) outputFile = self.parameterAsRasterLayer( parameters, self.OUTPUT_CHANGES, context ) # create a temporary vector layer tmp = tempfile.mkdtemp() path_roi = os.path.join(tmp, "roi.shp") writer = QgsVectorFileWriter( path_roi, "UTF-8", QgsFields(), QgsWkbTypes.Polygon, extent.sourceCrs(), "ESRI Shapefile", ) # create buffered extent and update temporary shp for detector for feature in extent.getFeatures(): geom = feature.geometry() buffer = geom.buffer( 10, 100, QgsGeometry.CapFlat, QgsGeometry.JoinStyleMiter, 100 ) feature.setGeometry(buffer) feature.setFields(QgsFields()) sink.addFeature(feature) writer.addFeature(feature) del writer # run change detector path1 = raster_1.source() path2 = raster_2.source() detector = LittoDynChangeDetectorPca(path1, path2, path_roi) if alg == 1: detector = LittoDynChangeDetectorEvi(path1, path2, path_roi) elif alg == 2: detector = LittoDynChangeDetectorNdvi(path1, path2, path_roi) elif alg == 3: detector = LittoDynChangeDetectorNgrdi(path1, path2, path_roi) elif alg == 4: detector = LittoDynChangeDetectorNormEuclid(path1, path2, path_roi) elif alg == 5: detector = LittoDynChangeDetectorNormCorr(path1, path2, path_roi) elif alg == 6: detector = LittoDynChangeDetectorNormCos(path1, path2, path_roi) detector.detect() # store output layers in group alg_name = self.options[alg].lower().replace(" ", "_") if Qgis.QGIS_VERSION_INT >= 31500: name = "{}_{}_{}".format(raster_1.name(), raster_2.name(), alg_name) ProcessingConfig.setSettingValue(ProcessingConfig.RESULTS_GROUP_NAME, name) # save result in temporary file tmp = tempfile.mkdtemp() path_changes = os.path.join(tmp, "{}_changes.tif".format(alg_name)) detector.save(path_changes) rl = QgsRasterLayer(path_changes, "{}_changes".format(alg_name), "gdal") context.temporaryLayerStore().addMapLayer(rl) context.addLayerToLoadOnCompletion( rl.id(), QgsProcessingContext.LayerDetails( "{}_changes".format(alg_name), context.project(), self.OUTPUT_CHANGES ), ) return { self.OUTPUT_CHANGES: rl.id(), self.OUTPUT_BUFFER: self.dest_id, self.OUTPUT_CHANGES: rl.id(), }
def calc(progress_bars, receiver_layer, source_pts_layer, source_roads_layer, settings, level_field_index, obstacles_layer, rays_writer, diff_rays_writer): research_ray = int(settings['research_ray']) temperature = int(settings['temperature']) humidity = int(settings['humidity']) time = datetime.now() ## create diffraction points if obstacles_layer is not None: bar = progress_bars['create_dif']['bar'] diffraction_points_layer_path = os.path.abspath( os.path.join(temp_dir + os.sep + "diffraction_pts.shp")) on_CreateDiffractionPoints.run(bar, obstacles_layer.source(), diffraction_points_layer_path) diffraction_layer_name = 'diff' diffraction_layer = QgsVectorLayer(diffraction_points_layer_path, diffraction_layer_name, "ogr") progress_bars['create_dif']['label'].setText( 'Done in ' + duration(time, datetime.now())) # print 'crea diffraction points ',datetime.now() - time time = datetime.now() # Create emission layer that will contain all the emission pts from source_pts and source_roads emission_pts_layer_path = os.path.abspath( os.path.join(temp_dir + os.sep + "emission_pts.shp")) # emission_pts_fields = [QgsField("type", QVariant.String), # QgsField("id_source", QVariant.Int), # QgsField("segment", QVariant.String),] emission_pts_fields = QgsFields() emission_pts_fields.append(QgsField("type", QVariant.String)) emission_pts_fields.append(QgsField("id_source", QVariant.Int)) emission_pts_fields.append(QgsField("segment", QVariant.String)) emission_pts_writer = QgsVectorFileWriter(emission_pts_layer_path, "System", emission_pts_fields, QgsWkbTypes.Point, receiver_layer.crs(), "ESRI Shapefile") bar = progress_bars['prepare_emi']['bar'] bar.setValue(1) source_feat_all_dict = {} # pts source layer to emission pts layer if source_pts_layer is not None: # get emission levels and add feat to emission pts layer source_pts_levels_dict = {} source_pts_feat_all = source_pts_layer.dataProvider().getFeatures() for source_feat in source_pts_feat_all: # get emission values levels = get_levels(settings, source_pts_layer, source_feat) source_pts_levels_dict[source_feat.id()] = levels # add feat to emission pts layer source_feat.setAttributes(['pt', source_feat.id(), None]) emission_pts_writer.addFeature(source_feat) # roads source layer to emission pts layer if source_roads_layer is not None: ## create emission points from roads source emission_pts_roads_layer_path = os.path.abspath( os.path.join(temp_dir + os.sep + "emission_pts_roads.shp")) on_CreateEmissionPoints.run(source_roads_layer.source(), receiver_layer.source(), emission_pts_roads_layer_path, research_ray) emission_pts_roads_layer = QgsVectorLayer( emission_pts_roads_layer_path, 'emission_pts_roads', "ogr") # get levels from the road source source_roads_levels_dict = {} source_roads_feat_all = source_roads_layer.dataProvider().getFeatures() for source_feat in source_roads_feat_all: levels = get_levels(settings, source_roads_layer, source_feat) source_roads_levels_dict[source_feat.id()] = levels # add roads pts to emission pts layer source_pts_roads_feat_all = emission_pts_roads_layer.dataProvider( ).getFeatures() for source_feat in source_pts_roads_feat_all: id_source = source_feat['id_source'] segment_source = source_feat[ 'd_rTOe'] # Pierluigi -- corretto perchè chiamava segment # add feat to emission pts layer source_feat.setAttributes(['road', id_source, segment_source]) emission_pts_writer.addFeature(source_feat) del emission_pts_writer # Create dict with all the data source_feat_all_dict = {} source_layer = QgsVectorLayer(emission_pts_layer_path, 'emission pts', "ogr") source_feat_all = source_layer.dataProvider().getFeatures() source_feat_total = source_layer.dataProvider().featureCount() source_feat_number = 0 for source_feat in source_feat_all: source_feat_number = source_feat_number + 1 barValue = source_feat_number / float(source_feat_total) * 100 bar.setValue(barValue) type_source = source_feat['type'] id_source = source_feat['id_source'] segment = source_feat['segment'] if type_source == 'pt': levels = source_pts_levels_dict[id_source] if type_source == 'road': levels = source_roads_levels_dict[id_source] value = {} value['type'] = type_source value['feat'] = source_feat value['global'] = levels['global'] value['bands'] = levels['bands'] value['segment'] = segment source_feat_all_dict[source_feat.id()] = value ## get data # receiver layer receiver_feat_all = receiver_layer.dataProvider().getFeatures() receiver_feat_total = receiver_layer.dataProvider().featureCount() receiver_feat_number = 0 # obstacles layer if obstacles_layer is not None: obstacles_feat_all = obstacles_layer.dataProvider().getFeatures() obstacles_feat_all_dict = {} for obstacles_feat in obstacles_feat_all: obstacles_feat_all_dict[obstacles_feat.id()] = obstacles_feat # diffraction layer diff_feat_all = diffraction_layer.dataProvider().getFeatures() diff_feat_all_dict = {} for diff_feat in diff_feat_all: diff_feat_all_dict[diff_feat.id()] = diff_feat progress_bars['prepare_emi']['label'].setText( 'Done in ' + duration(time, datetime.now())) # fix_print_with_import print('get acoustic data', datetime.now() - time) time = datetime.now() if obstacles_layer is None: bar = progress_bars['recTOsou']['bar'] recTOsource_dict = on_RaysSearch.run(bar, receiver_layer.source(), source_layer.source(), None, research_ray) progress_bars['recTOsou']['label'].setText( 'Done in ' + duration(time, datetime.now())) # fix_print_with_import print('find connections receivers sources ', datetime.now() - time) time = datetime.now() diffTOsource_dict = {} recTOdiff_dict = {} else: ### recTOsou bar = progress_bars['recTOsou']['bar'] recTOsource_dict = on_RaysSearch.run(bar, receiver_layer.source(), source_layer.source(), obstacles_layer.source(), research_ray) progress_bars['recTOsou']['label'].setText( 'Done in ' + duration(time, datetime.now())) # fix_print_with_import print('find connections receceivers sources ', datetime.now() - time) time = datetime.now() ### difTOsou bar = progress_bars['difTOsou']['bar'] diffTOsource_dict = on_RaysSearch.run(bar, diffraction_layer.source(), source_layer.source(), obstacles_layer.source(), research_ray) progress_bars['difTOsou']['label'].setText( 'Done in ' + duration(time, datetime.now())) # fix_print_with_import print('find connections diffraction points sources', datetime.now() - time) time = datetime.now() ### recTOdif bar = progress_bars['recTOdif']['bar'] # recTOdiff_dict = on_RaysSearch.run_selection_distance(bar,receiver_layer.source(),diffraction_layer.source(),obstacles_layer.source(),research_ray,diffTOsource_dict,source_layer.source()) recTOdiff_dict = on_RaysSearch.run_selection( bar, receiver_layer.source(), diffraction_layer.source(), obstacles_layer.source(), research_ray, diffTOsource_dict) progress_bars['recTOdif']['label'].setText( 'Done in ' + duration(time, datetime.now())) # fix_print_with_import print('find connectino receivers diffraction points', datetime.now() - time) time = datetime.now() ray_id = 0 diff_ray_id = 0 receiver_feat_all_new_fields = {} bar = progress_bars['calculate']['bar'] for receiver_feat in receiver_feat_all: receiver_feat_number = receiver_feat_number + 1 barValue = receiver_feat_number / float(receiver_feat_total) * 100 bar.setValue(barValue) receiver_feat_new_fields = {} # initializes the receiver point lin level receiver_point_lin_level = {} receiver_point_lin_level['gen'] = 0 receiver_point_lin_level['day'] = 0 receiver_point_lin_level['eve'] = 0 receiver_point_lin_level['nig'] = 0 if receiver_feat.id() in recTOsource_dict: source_ids = recTOsource_dict[receiver_feat.id()] for source_id in source_ids: source_feat_value = source_feat_all_dict[source_id] source_feat = source_feat_value['feat'] ray_geometry = QgsGeometry.fromPolylineXY([ receiver_feat.geometry().asPoint(), source_feat.geometry().asPoint() ]) d_recTOsource = compute_distance( receiver_feat.geometry().asPoint(), source_feat.geometry().asPoint()) # length with receiver points height fixed to 4 m d_recTOsource_4m = sqrt(d_recTOsource**2 + 16) feat_type = source_feat_value['type'] level_emi = source_feat_value['global'] level_emi_bands = source_feat_value['bands'] segment = source_feat_value['segment'] level_dir = {} level_atm_bands = {} geo_attenuation = on_Acoustics.GeometricalAttenuation( 'spherical', d_recTOsource_4m) print("d_recTOsource_4m", d_recTOsource_4m) print("geo_attenuation", geo_attenuation) for key in list(level_emi.keys()): if level_emi[key] > 0: level_atm_bands[ key] = on_Acoustics.AtmosphericAbsorption( d_recTOsource, temperature, humidity, level_emi_bands[key]).level() #level_dir[key] = on_Acoustics.OctaveBandsToGlobal(level_atm_bands[key]) - geo_attenuation print("level_atm_bands[key]", level_atm_bands[key]) if settings['implementation_roads'] == 'CNOSSOS': level_dir[key] = on_Acoustics.OctaveBandsToGlobalA( level_atm_bands[key]) - geo_attenuation else: level_dir[key] = on_Acoustics.OctaveBandsToGlobal( level_atm_bands[key]) - geo_attenuation print("level_dir[key]", level_dir[key]) # correction for the segment lenght if feat_type == 'road': if (settings['implementation_roads'] == 'POWER_R' or settings['implementation_roads'] == 'NMPB'): level_dir[key] = level_dir[ key] + 20 + 10 * log10(float(segment)) + 3 if settings['implementation_roads'] == 'CNOSSOS': level_dir[key] = level_dir[key] + 10 * log10( float(segment)) + 3 receiver_point_lin_level[ key] = receiver_point_lin_level[key] + 10**( level_dir[key] / float(10)) else: # level_dir[key] = -1 if rays_writer is not None: ray = QgsFeature() ray.setGeometry(ray_geometry) attributes = [ ray_id, receiver_feat.id(), source_feat.id(), d_recTOsource, d_recTOsource_4m ] if settings['period_pts_gen'] == "True" or settings[ 'period_roads_gen'] == "True": if 'gen' in level_emi: attributes.append(level_emi['gen']) attributes.append(level_dir['gen']) else: attributes.append(None) attributes.append(None) if settings['period_pts_day'] == "True" or settings[ 'period_roads_day'] == "True": if 'day' in level_emi: attributes.append(level_emi['day']) attributes.append(level_dir['day']) else: attributes.append(None) attributes.append(None) if settings['period_pts_eve'] == "True" or settings[ 'period_roads_eve'] == "True": if 'eve' in level_emi: attributes.append(level_emi['eve']) attributes.append(level_dir['eve']) else: attributes.append(None) attributes.append(None) if settings['period_pts_nig'] == "True" or settings[ 'period_roads_nig'] == "True": if 'nig' in level_emi: attributes.append(level_emi['nig']) attributes.append(level_dir['nig']) else: attributes.append(None) attributes.append(None) ray.setAttributes(attributes) rays_writer.addFeature(ray) ray_id = ray_id + 1 if receiver_feat.id() in recTOdiff_dict: diff_ids = recTOdiff_dict[receiver_feat.id()] for diff_id in diff_ids: diff_feat = diff_feat_all_dict[diff_id] if diff_feat.id() in diffTOsource_dict: source_ids = diffTOsource_dict[diff_feat.id()] for source_id in source_ids: source_feat_value = source_feat_all_dict[source_id] source_feat = source_feat_value['feat'] if receiver_feat.id() in recTOsource_dict: source_ids = recTOsource_dict[receiver_feat.id()] if source_feat.id() in source_ids: shadow = 0 else: shadow = 1 else: shadow = 1 if shadow == 1: ray_geometry = QgsGeometry.fromPolylineXY([ receiver_feat.geometry().asPoint(), diff_feat.geometry().asPoint(), source_feat.geometry().asPoint() ]) d_recTOdiff = compute_distance( receiver_feat.geometry().asPoint(), diff_feat.geometry().asPoint()) d_diffTOsource = compute_distance( diff_feat.geometry().asPoint(), source_feat.geometry().asPoint()) d_recTOsource = compute_distance( receiver_feat.geometry().asPoint(), source_feat.geometry().asPoint()) d_recPLUSsource = d_recTOdiff + d_diffTOsource if d_recPLUSsource <= research_ray: feat_type = source_feat_value['type'] level_emi = source_feat_value['global'] level_emi_bands = source_feat_value['bands'] segment = source_feat_value['segment'] level_dif = {} level_dif_bands = {} level_atm_bands = {} for key in list(level_emi_bands.keys()): if level_emi[key] > 0: level_dif_bands[ key] = on_Acoustics.Diffraction( 'CNOSSOS', level_emi_bands[key], d_diffTOsource, d_recTOsource, d_recTOdiff).level() level_atm_bands[ key] = on_Acoustics.AtmosphericAbsorption( d_recPLUSsource, temperature, humidity, level_emi_bands[key] ).attenuation() level_dif_bands[ key] = on_Acoustics.DiffBands( level_dif_bands[key], level_atm_bands[key]) #level_dif[key] = on_Acoustics.OctaveBandsToGlobal(level_dif_bands[key]) #print("settings: ", settings['implementation_roads']) if settings[ 'implementation_roads'] == 'CNOSSOS': level_dif[ key] = on_Acoustics.OctaveBandsToGlobalA( level_dif_bands[key]) else: level_dif[ key] = on_Acoustics.OctaveBandsToGlobal( level_dif_bands[key]) # correction for the segment lenght if feat_type == 'road': if (settings['implementation_roads'] == 'POWER_R' or settings[ 'implementation_roads'] == 'NMPB'): level_dif[key] = level_dif[ key] + 20 + 10 * log10( float(segment)) + 3 if settings[ 'implementation_roads'] == 'CNOSSOS': level_dif[key] = level_dif[ key] + 10 * log10( float(segment)) + 3 receiver_point_lin_level[ key] = receiver_point_lin_level[ key] + 10**(level_dif[key] / float(10)) else: level_dif[key] = -1 if diff_rays_writer is not None: ray = QgsFeature() ray.setGeometry(ray_geometry) attributes = [ diff_ray_id, receiver_feat.id(), diff_feat.id(), source_feat.id(), d_recTOdiff, d_diffTOsource, d_recTOsource ] if settings[ 'period_pts_gen'] == "True" or settings[ 'period_roads_gen'] == "True": if 'gen' in level_emi: attributes.append(level_emi['gen']) attributes.append(level_dif['gen']) else: attributes.append(None) attributes.append(None) if settings[ 'period_pts_day'] == "True" or settings[ 'period_roads_day'] == "True": if 'day' in level_emi: attributes.append(level_emi['day']) attributes.append(level_dif['day']) else: attributes.append(None) attributes.append(None) if settings[ 'period_pts_eve'] == "True" or settings[ 'period_roads_eve'] == "True": if 'eve' in level_emi: attributes.append(level_emi['eve']) attributes.append(level_dif['eve']) else: attributes.append(None) attributes.append(None) if settings[ 'period_pts_nig'] == "True" or settings[ 'period_roads_nig'] == "True": if 'nig' in level_emi: attributes.append(level_emi['nig']) attributes.append(level_dif['nig']) else: attributes.append(None) attributes.append(None) ray.setAttributes(attributes) diff_rays_writer.addFeature(ray) diff_ray_id = diff_ray_id + 1 if settings['period_pts_gen'] == "True" or settings[ 'period_roads_gen'] == "True": if receiver_point_lin_level['gen'] > 0: Lgen = 10 * log10(receiver_point_lin_level['gen']) if Lgen < 0: Lgen = 0 receiver_feat_new_fields[level_field_index['gen']] = Lgen else: receiver_feat_new_fields[level_field_index['gen']] = -99 Lday = 0 Leve = 0 Lnig = 0 #addec contron on final data if negative set to zero if settings['period_pts_day'] == "True" or settings[ 'period_roads_day'] == "True": if receiver_point_lin_level['day'] > 0: Lday = 10 * log10(receiver_point_lin_level['day']) if Lday < 0: Lday = 0 receiver_feat_new_fields[level_field_index['day']] = Lday else: receiver_feat_new_fields[level_field_index['day']] = -99 if settings['period_pts_eve'] == "True" or settings[ 'period_roads_eve'] == "True": if receiver_point_lin_level['eve'] > 0: Leve = 10 * log10(receiver_point_lin_level['eve']) if Leve < 0: Leve = 0 receiver_feat_new_fields[level_field_index['eve']] = Leve else: receiver_feat_new_fields[level_field_index['eve']] = -99 if settings['period_pts_nig'] == "True" or settings[ 'period_roads_nig'] == "True": if receiver_point_lin_level['nig'] > 0: Lnig = 10 * log10(receiver_point_lin_level['nig']) if Lnig < 0: Lnig = 0 receiver_feat_new_fields[level_field_index['nig']] = Lnig else: receiver_feat_new_fields[level_field_index['nig']] = -99 if settings['period_den'] == "True": receiver_feat_new_fields[ level_field_index['den']] = on_Acoustics.Lden( Lday, Leve, Lnig, int(settings['day_hours']), int(settings['eve_hours']), int(settings['nig_hours']), int(settings['day_penalty']), int(settings['eve_penalty']), int(settings['nig_penalty'])) receiver_feat_all_new_fields[ receiver_feat.id()] = receiver_feat_new_fields progress_bars['calculate']['label'].setText('Done in ' + duration(time, datetime.now())) # fix_print_with_import print('calculate levels and, if selected, draw rays', datetime.now() - time) time = datetime.now() return receiver_feat_all_new_fields
def buffer_points(point_layer, radii, hazard_zone_attribute, output_crs): """Buffer points for each point with defined radii. This function is used for making buffer of volcano point hazard. :param point_layer: A point layer to buffer. :type point_layer: QgsVectorLayer :param radii: Desired approximate radii in kilometers (must be monotonically ascending). Can be either one number or list of numbers :type radii: int, list :param hazard_zone_attribute: The name of the attributes representing hazard zone. :type hazard_zone_attribute: str :param output_crs: The output CRS. :type output_crs: QgsCoordinateReferenceSystem :return: Vector polygon layer representing circle in point layer CRS. :rtype: QgsVectorLayer """ if not isinstance(radii, list): radii = [radii] if not is_point_layer(point_layer): message = ('Input hazard must be a vector point layer. I got %s ' 'with layer type %s' % (point_layer.name(), point_layer.type())) raise Exception(message) # Check that radii are monotonically increasing monotonically_increasing_flag = all(x < y for x, y in zip(radii, radii[1:])) if not monotonically_increasing_flag: raise RadiiException(RadiiException.suggestion) hazard_file_path = unique_filename(suffix='-polygon-volcano.shp') fields = point_layer.pendingFields() fields.append(QgsField(hazard_zone_attribute, QVariant.Double)) writer = QgsVectorFileWriter(hazard_file_path, 'utf-8', fields, QGis.WKBPolygon, output_crs, 'ESRI Shapefile') input_crs = point_layer.crs() center = point_layer.extent().center() utm = None if output_crs.authid() == 'EPSG:4326': utm = QgsCoordinateReferenceSystem( get_utm_epsg(center.x(), center.y(), input_crs)) transform = QgsCoordinateTransform(point_layer.crs(), utm) else: transform = QgsCoordinateTransform(point_layer.crs(), output_crs) for point in point_layer.getFeatures(): geom = point.geometry() geom.transform(transform) inner_rings = None for radius in radii: attributes = point.attributes() # Generate circle polygon circle = geom.buffer(radius * 1000.0, 30) if inner_rings: circle.addRing(inner_rings) inner_rings = circle.asPolygon()[0] new_buffer = QgsFeature() if output_crs.authid() == 'EPSG:4326': circle.transform(QgsCoordinateTransform(utm, output_crs)) new_buffer.setGeometry(circle) attributes.append(radius) new_buffer.setAttributes(attributes) writer.addFeature(new_buffer) del writer vector_layer = QgsVectorLayer(hazard_file_path, 'Polygons', 'ogr') keyword_io = KeywordIO() try: keywords = keyword_io.read_keywords(point_layer) keyword_io.write_keywords(vector_layer, keywords) except NoKeywordsFoundError: pass return vector_layer
def run_stats(self): """Main function which do the process.""" # Get the common fields. self.admin_layer = self.cbx_aggregation_layer.currentLayer() selected_indicators = self.indicators_list() if not self.name_field: self.name_field = self.le_new_column.placeholderText() # Output. self.output_file_path = self.le_output_filepath.text() try: self.button_box_ok.setDisabled(True) # noinspection PyArgumentList QApplication.setOverrideCursor(Qt.WaitCursor) # noinspection PyArgumentList QApplication.processEvents() if not self.admin_layer: raise NoLayerProvidedException if not self.admin_layer and self.use_point_layer: raise NoLayerProvidedException crs_admin_layer = self.admin_layer.crs() if not self.use_point_layer and not self.use_area: if not self.cbx_list_indicators: raise FieldException( field_1='List Indicators should not empty') # Output if not self.output_file_path: temp_file = NamedTemporaryFile(delete=False, suffix='-geopublichealth.shp') self.output_file_path = temp_file.name temp_file.flush() temp_file.close() admin_layer_provider = self.admin_layer.dataProvider() fields = self.admin_layer.fields() if admin_layer_provider.fields().indexFromName( self.name_field) != -1: raise FieldExistingException(field=self.name_field) for indicator_selected in selected_indicators: fields.append( QgsField("Z" + indicator_selected[0], QVariant.Double)) fields.append(QgsField(self.name_field, QVariant.Double)) file_writer = QgsVectorFileWriter(self.output_file_path, 'utf-8', fields, QgsWkbTypes.Polygon, self.admin_layer.crs(), 'ESRI Shapefile') count = self.admin_layer.featureCount() stats = {} for indicator_selected in selected_indicators: values = [] indicator_selected_name = str(indicator_selected[0]) for i, feature in enumerate(self.admin_layer.getFeatures()): index = self.admin_layer.fields().indexFromName( indicator_selected_name) if feature[index]: value = float(feature[index]) else: value = 0.0 values.append(value) stats[indicator_selected_name] = Stats(values) for i, feature in enumerate(self.admin_layer.getFeatures()): attributes = feature.attributes() composite_index_value = 0.0 for indicator_selected in selected_indicators: indicator_selected_name = str(indicator_selected[0]) index = self.admin_layer.fields().indexFromName( indicator_selected_name) if feature[index]: value = float(feature[index]) else: value = 0.0 zscore = (value - stats[indicator_selected_name].average( )) / stats[indicator_selected_name].standard_deviation() attributes.append(float(zscore)) if indicator_selected[1] == '+': composite_index_value -= zscore else: composite_index_value += zscore attributes.append(float(composite_index_value)) new_feature = QgsFeature() new_geom = QgsGeometry(feature.geometry()) new_feature.setAttributes(attributes) new_feature.setGeometry(new_geom) file_writer.addFeature(new_feature) del file_writer self.output_layer = QgsVectorLayer(self.output_file_path, self.name_field, 'ogr') QgsProject.instance().addMapLayer(self.output_layer) if self.symbology.isChecked(): self.add_symbology() self.signalStatus.emit(3, tr('Successful process')) except GeoPublicHealthException as e: display_message_bar(msg=e.msg, level=e.level, duration=e.duration) finally: self.button_box_ok.setDisabled(False) # noinspection PyArgumentList QApplication.restoreOverrideCursor() # noinspection PyArgumentList QApplication.processEvents()
def processAlgorithm(self, parameters, context, model_feedback): # variables propres à Processing feedback = QgsProcessingMultiStepFeedback(2, model_feedback) results = {} # entrées lignes = self.parameterAsVectorLayer(parameters, 'lignes', context) rasters = parameters['rasters'] # sorties output = self.parameterAsOutputLayer(parameters, 'OUTPUT', context) profils = [] # paramètres echantillons_nb = parameters['echantillons_nb'] # traitement if len(rasters) == 0: feedback.pushInfo( "⚠ Il est nécessaire de fournir au moins un raster en entrée.\n" ) return {} for ligne_f in lignes.getFeatures(): ligne_g = ligne_f.geometry() freq = ligne_g.length() / (echantillons_nb - 1) echantillons_g = [ QgsGeometry().fromPointXY(ligne_g.asMultiPolyline()[0][0]) ] for i in range(1, echantillons_nb - 1): echantillons_g.append(ligne_g.interpolate(freq * i)) echantillons_g.append(QgsGeometry().fromPointXY( ligne_g.asMultiPolyline()[0][-1])) feedback.pushInfo(str(echantillons_g)) for raster in rasters: elevations = [] for echantillon_g in echantillons_g: elevation = raster.dataProvider().sample( echantillon_g.asPoint(), 1)[0] elevations.append(elevation) profils.append([ echantillons_g, ligne_f.attributes(), raster.name(), elevations ]) feedback.setCurrentStep(1) if feedback.isCanceled(): return {} # écriture des données en sortie fields = lignes.fields() fields.append(QgsField("ordre", QVariant.Int)) fields.append(QgsField("raster", QVariant.String)) fields.append(QgsField("elevation", QVariant.Double)) writer = QgsVectorFileWriter(output, "System", fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem(2154), "ESRI Shapefile") for echantillons_g, attributes, raster_name, elevations in profils: ordre = 0 for echantillon_g, elevation in zip(echantillons_g, elevations): f = QgsFeature() f.setGeometry(echantillon_g) echantillon_att = attributes.copy() echantillon_att.append(ordre) echantillon_att.append(raster_name) echantillon_att.append(elevation) f.setAttributes(echantillon_att) feedback.pushInfo(str(f.attributes())) writer.addFeature(f) ordre += 1 feedback.setCurrentStep(2) results['OUTPUT'] = output return results
def createGis(self) -> None: """ Create TUFLOW GIS Layer(s) Use input GIS feature for data :return: None """ if self.inputs['gis feature'] is not None: if self.inputs['output gis'] is not None: for gisOutput in self.inputs['output gis']: fields = QgsFields() feat = QgsFeature() feat.setGeometry(self.inputs['gis feature'].geometry()) name = os.path.splitext( os.path.basename(self.inputs['output file']))[0] if gisOutput == Refh2.RF: outfile = os.path.join( os.path.dirname(self.inputs['output file']), '2d_rf_{0}_R.shp'.format(name)) fields.append( QgsField("Name", QVariant.String, len=100)) fields.append( QgsField("f1", QVariant.Double, len=15, prec=5)) fields.append( QgsField("f2", QVariant.Double, len=15, prec=5)) feat.setAttributes( [self.inputs['rainfall name'], 1, 1]) elif gisOutput == Refh2.SA_RF: outfile = os.path.join( os.path.dirname(self.inputs['output file']), '2d_sa_rf_{0}_R.shp'.format(name)) fields.append( QgsField("Name", QVariant.String, len=100)) fields.append( QgsField("Catchment_", QVariant.Double, len=15, prec=5)) fields.append( QgsField("Rain_Gauge", QVariant.Double, len=15, prec=5)) fields.append( QgsField("IL", QVariant.Double, len=15, prec=5)) fields.append( QgsField("CL", QVariant.Double, len=15, prec=5)) feat.setAttributes([ self.inputs['rainfall name'], self.inputs['area'], NULL, NULL, NULL ]) elif gisOutput == Refh2.SA: outfile = os.path.join( os.path.dirname(self.inputs['output file']), '2d_sa_{0}_R.shp'.format(name)) fields.append( QgsField("Name", QVariant.String, len=100)) feat.setAttributes([self.inputs['inflow name']]) elif gisOutput == Refh2.BC_2d: outfile = os.path.join( os.path.dirname(self.inputs['output file']), '2d_rf_{0}_L.shp'.format(name)) fields.append(QgsField("Type", QVariant.String, len=2)) fields.append(QgsField("Flags", QVariant.String, len=3)) fields.append( QgsField("Name", QVariant.String, len=100)) fields.append( QgsField("f", QVariant.Double, len=15, prec=5)) fields.append( QgsField("d", QVariant.Double, len=15, prec=5)) fields.append( QgsField("td", QVariant.Double, len=15, prec=5)) fields.append( QgsField("a", QVariant.Double, len=15, prec=5)) fields.append( QgsField("b", QVariant.Double, len=15, prec=5)) feat.setAttributes([ 'QT', NULL, self.inputs['inflow name'], NULL, NULL, NULL, NULL, NULL ]) elif gisOutput == Refh2.BC_1d: if self.inputs[ 'gis geometry'] == QgsWkbTypes.PointGeometry: outfile = os.path.join( os.path.dirname(self.inputs['output file']), '1d_bc_{0}_P.shp'.format(name)) else: outfile = os.path.join( os.path.dirname(self.inputs['output file']), '1d_bc_{0}_R.shp'.format(name)) fields.append(QgsField("Type", QVariant.String, len=2)) fields.append(QgsField("Flags", QVariant.String, len=6)) fields.append(QgsField("Name", QVariant.String, len=50)) fields.append( QgsField("Descriptio", QVariant.String, len=250)) feat.setAttributes( ['QT', NULL, self.inputs['inflow name'], NULL]) writer = QgsVectorFileWriter(outfile, "UTF-8", fields, self.inputs['gis geometry'], self.inputs['crs'], driverName="ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: self.finished.emit(writer.errorMessage()) return writer.addFeature(feat) del writer
def compute(self, inName, joinName, outName, summary, sumList, keep, progressBar): layer1 = ftools_utils.getVectorLayerByName(inName) provider1 = layer1.dataProvider() fieldList1 = ftools_utils.getFieldList(layer1) layer2 = ftools_utils.getVectorLayerByName(joinName) provider2 = layer2.dataProvider() fieldList2 = ftools_utils.getFieldList(layer2) fieldList = QgsFields() if provider1.crs() != provider2.crs(): QMessageBox.warning( self, self.tr("CRS warning!"), self. tr("Warning: Input layers have non-matching CRS.\nThis may cause unexpected results." )) if not summary: fieldList2 = ftools_utils.testForUniqueness(fieldList1, fieldList2) seq = range(0, len(fieldList1) + len(fieldList2)) fieldList1.extend(fieldList2) fieldList1 = dict(zip(seq, fieldList1)) else: numFields = {} for j in xrange(len(fieldList2)): if fieldList2[j].type() == QVariant.Int or fieldList2[j].type( ) == QVariant.Double: numFields[j] = [] for i in sumList: field = QgsField(i + unicode(fieldList2[j].name()), QVariant.Double, "real", 24, 16, self.tr("Summary field")) fieldList.append(field) field = QgsField("COUNT", QVariant.Double, "real", 24, 16, self.tr("Summary field")) fieldList.append(field) fieldList2 = ftools_utils.testForUniqueness(fieldList1, fieldList) fieldList1.extend(fieldList) seq = range(0, len(fieldList1)) fieldList1 = dict(zip(seq, fieldList1)) sRs = provider1.crs() progressBar.setValue(13) check = QFile(self.shapefileName) if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName): QMessageBox.warning( self, self.tr('Error deleting shapefile'), self.tr("Can't delete existing shapefile\n%s") % (self.shapefileName)) return False fields = QgsFields() for f in fieldList1.values(): fields.append(f) writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fields, provider1.geometryType(), sRs) #writer = QgsVectorFileWriter(outName, "UTF-8", fieldList1, provider1.geometryType(), sRs) inFeat = QgsFeature() outFeat = QgsFeature() inFeatB = QgsFeature() inGeom = QgsGeometry() progressBar.setValue(15) start = 15.00 add = 85.00 / provider1.featureCount() index = ftools_utils.createIndex(provider2) # cache all features from provider2 to avoid huge number of feature requests in the inner loop mapP2 = {} for f in provider2.getFeatures(): mapP2[f.id()] = QgsFeature(f) fit1 = provider1.getFeatures() while fit1.nextFeature(inFeat): inGeom = inFeat.geometry() atMap1 = inFeat.attributes() outFeat.setGeometry(inGeom) none = True joinList = [] if inGeom.type() == QGis.Point: #(check, joinList) = layer2.featuresInRectangle(inGeom.buffer(10,2).boundingBox(), True, True) #layer2.select(inGeom.buffer(10,2).boundingBox(), False) #joinList = layer2.selectedFeatures() joinList = index.intersects(inGeom.buffer(10, 2).boundingBox()) if len(joinList) > 0: check = 0 else: check = 1 else: #(check, joinList) = layer2.featuresInRectangle(inGeom.boundingBox(), True, True) #layer2.select(inGeom.boundingBox(), False) #joinList = layer2.selectedFeatures() joinList = index.intersects(inGeom.boundingBox()) if len(joinList) > 0: check = 0 else: check = 1 if check == 0: count = 0 for i in joinList: inFeatB = mapP2[i] # cached feature from provider2 if inGeom.intersects(inFeatB.geometry()): count = count + 1 none = False atMap2 = inFeatB.attributes() if not summary: atMap = atMap1 atMap2 = atMap2 atMap.extend(atMap2) atMap = dict(zip(seq, atMap)) break else: for j in numFields.keys(): numFields[j].append(atMap2[j]) if summary and not none: atMap = atMap1 for j in numFields.keys(): for k in sumList: if k == "SUM": atMap.append(sum(filter_null(numFields[j]))) elif k == "MEAN": try: nn_count = sum( 1 for _ in filter_null(numFields[j])) atMap.append( sum(filter_null(numFields[j])) / nn_count) except ZeroDivisionError: atMap.append(NULL) elif k == "MIN": try: atMap.append(min(filter_null( numFields[j]))) except ValueError: atMap.append(NULL) elif k == "MED": atMap.append(myself(numFields[j])) else: try: atMap.append(max(filter_null( numFields[j]))) except ValueError: atMap.append(NULL) numFields[j] = [] atMap.append(count) atMap = dict(zip(seq, atMap)) if none: outFeat.setAttributes(atMap1) else: outFeat.setAttributes(atMap.values()) if keep: # keep all records writer.addFeature(outFeat) else: # keep only matching records if not none: writer.addFeature(outFeat) start = start + add progressBar.setValue(start) del writer return True
def run(self): """Run method that performs all the real work""" # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. filename = os.path.abspath("Sample_Data/sample_data.shp") iface.messageBar().pushMessage("Shapefile loaded ...", QgsMessageBar.INFO) source_layer = iface.addVectorLayer(filename, "sample_data", "ogr") centroid = QgsVectorLayer('Point', 'Centroid', 'memory') fields = QgsFields() fields.append(QgsField("code", QVariant.String)) fields.append(QgsField("x", QVariant.Double)) fields.append(QgsField("y", QVariant.Double)) # Define additional attributes already on the layer level centroid_layer = QgsVectorFileWriter( centroid, "UTF8", fields, QGis.WKBPoint, QgsCoordinateReferenceSystem(4326), "ESRI Shapefile") if centroid_layer.hasError() != QgsVectorFileWriter.NoError: print("Error when creating centroid: ", centroid_layer.errorMessage()) iface.messageBar().pushMessage("Feature addition failed.", QgsMessageBar.CRITICAL) centroid_layer.startEditing() # Loop over all features for source_feature in source_layer.getFeatures(): geometry = source_feature.geometry() centroid = geometry.centroid().asPoint() pts = [Centroid] name = source_feature["code"] # Create the new feature with the fields of the ogr layer # And set geometry and attribute before adding it to the target layer centroid_feature = QgsFeature(source_layer.fields()) centroid_feature = source_feature.attributes() centroid_feature.setAttributes(centroid_feature) centroid_feature.setGeometry(centroid) centroid_feature['code'] = name centroid_layer.addFeature(centroid_feature) # Loop centroids to shapefile for x, y in pts: centroid_feature = QgsFeature() point = QgsPoint(x, y) centroid_feature.setGeometry(QgsGeometry.fromPoint(point)) centroid_feature.setAttributes(attrs) prov.addFeatures([centroid_feature]) centroid_layer.commitChanges() # Add the layer to the registry QgsMapLayerRegistry.instance().addMapLayer(centroid_layer) # Save centroid layer as csv format QgsVectorFileWriter.writeAsVectorFormat( centroid_layer, r'extract_centroid', "utf-8", None, "CSV", layerOptions='GEOMETRY=AS_XYZ') iface.messageBar().pushMessage("Extract centroid saved as csv ...", QgsMessageBar.INFO)
def processAlgorithm(self, parameters, context, model_feedback): # variables propres à Processing feedback = QgsProcessingMultiStepFeedback(2, model_feedback) results = {} # entrées profils = self.parameterAsVectorLayer(parameters, 'profils', context) mnt = self.parameterAsRasterLayer(parameters, 'mnt', context) # sorties output = self.parameterAsOutputLayer(parameters, 'OUTPUT', context) # paramètres echantillons_nb = parameters[ 'echantillons_nb'] # nombre d'échantillons profils_pt = [] # géométries des points profils_sp = [] # valeur des points # les deux listes sont à deux dimension : chaque ligne correspond à un profil # traitement # discrétisation des points sur chaque profil for profil_f in profils.getFeatures(): profil_g = profil_f.geometry() freq = profil_g.length() / (echantillons_nb - 1) echantillons_g = [ QgsGeometry().fromPointXY(profil_g.asMultiPolyline()[0][0]) ] for i in range(1, echantillons_nb - 1): echantillons_g.append(profil_g.interpolate(freq * i)) echantillons_g.append(QgsGeometry().fromPointXY( profil_g.asMultiPolyline()[0][-1])) # note pour ci-dessus : l'interpolation des premiers et derniers points sur une ligne peut parfois planter, on les place à la main pour lever le risque profils_pt.append(echantillons_g) elevations = [] for echantillon_g in echantillons_g: elevation = mnt.dataProvider().sample(echantillon_g.asPoint(), 1)[0] elevations.append(elevation) profils_sp.append(elevations) # interpolation linéaire : calcul des valeurs des points entre le premier et le dernier profil de point à point steps = [] nb_profils = len(profils_sp) for i in range(0, echantillons_nb): # on récupère la valeur du point sur le premier et le dernier profil v1 = profils_sp[0][i] v2 = profils_sp[-1][i] # on détermine le pas de l'interpolation steps.append((v2 - v1) / nb_profils) for i in range(1, nb_profils - 1): for j in range(0, echantillons_nb): profils_sp[i][j] = profils_sp[i - 1][j] + steps[j] feedback.setCurrentStep(1) if feedback.isCanceled(): return {} # écriture des données en sortie fields = QgsFields() fields.append(QgsField("elevation", QVariant.Double)) writer = QgsVectorFileWriter(output, "System", fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem(2154), "ESRI Shapefile") for i in range(0, nb_profils): for j in range(0, echantillons_nb): f = QgsFeature() f.setGeometry(profils_pt[i][j]) f.setAttributes([profils_sp[i][j]]) writer.addFeature(f) feedback.setCurrentStep(2) results['OUTPUT'] = output return results