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 saveLineGeometry(shapePath, geodata, spatialRef, geoFormat): """ :param shapePath: Location of shape file :param geodata: x, y and z coordinate of line :param spatialRef: current spatial reference of qgis project :param geoFormat: Geodata export format """ # Define fields for feature attributes. A QgsFields object is needed fields = QgsFields() writer = QgsVectorFileWriter(shapePath, 'UTF-8', fields, QgsWkbTypes.LineStringZ, spatialRef, geoFormat) if writer.hasError() != QgsVectorFileWriter.NoError: # TODO raise Exception('Vector Writer') lineVertices = [] for coords in geodata: lineVertices.append(QgsPoint(coords[0], coords[1], coords[2])) feature = QgsFeature() feature.setGeometry(QgsGeometry.fromPolyline(lineVertices)) feature.setId(1) writer.addFeatures([feature]) del feature # Delete the writer to flush features to disk del writer
def check_if_export_file_in_use(self): """ Attempts to write to export file, to check if in use. Warns if so. This check only works in Windows. :return: boolean """ if config.DEBUG_MODE: print('DEBUG_MODE: Checking if output file in use.') field_map = QgsFields() for field in self.fields: field_map.append(field) writer = QgsVectorFileWriter(str(self.export_path), "utf-8", field_map, QGis.WKBMultiLineString, None, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: file_open_msg_box = QMessageBox( QMessageBox.Warning, " ", "The file {} is already open " "(possibly in another application).\n" "Close the file and try again".format(str(self.export_path)), QMessageBox.Ok, None) file_open_msg_box.setWindowFlags(Qt.CustomizeWindowHint | Qt.WindowTitleHint) file_open_msg_box.exec_() return True return False
def to_shp(path, any_features_list, layer_fields, crs, name, encoding, geom_type): if path is None: if geom_type == 0: network = QgsVectorLayer('Point?crs=' + crs.toWkt(), name, "memory") else: network = QgsVectorLayer('LineString?crs=' + crs.toWkt(), name, "memory") else: fields = QgsFields() for field in layer_fields: fields.append(field) file_writer = QgsVectorFileWriter(path, encoding, fields, geom_type, crs, "ESRI Shapefile") if file_writer.hasError() != QgsVectorFileWriter.NoError: print "Error when creating shapefile: ", file_writer.errorMessage() del file_writer network = QgsVectorLayer(path, name, "ogr") pr = network.dataProvider() if path is None: pr.addAttributes(layer_fields) new_features = [] for i in any_features_list: new_feat = QgsFeature() new_feat.setFeatureId(i[0]) new_feat.setAttributes([attr[0] for attr in i[1]]) new_feat.setGeometry(QgsGeometry(QgsGeometry.fromWkt(str(i[2])))) #QgsGeometry() new_features.append(new_feat) network.startEditing() pr.addFeatures(new_features) network.commitChanges() return network
def fileHanddler(self, alayer, alist, filedirectory, name): crsSrc = alayer.crs() crsDes = QgsCoordinateReferenceSystem(crsSrc.authid()) fieldz = QgsFields() fieldz.append(QgsField("Id", QVariant.Int)) fieldz.append(QgsField("Ré", QVariant.String)) fieldz.append(QgsField("Norte", QVariant.Double, "double", 23, 2)) fieldz.append(QgsField("Este", QVariant.Double, "double", 23, 2)) fieldz.append(QgsField("Longitude", QVariant.String)) fieldz.append(QgsField("Latitude", QVariant.String)) fieldz.append(QgsField("Vante", QVariant.String)) fieldz.append(QgsField("Azimute", QVariant.String)) fieldz.append(QgsField("Distancia", QVariant.Double, "double", 23, 2)) writer = QgsVectorFileWriter(filedirectory+'/'+name, "UTF-8", fieldz, QgsWkbTypes.Point, crsDes, driverName="ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: print("Error when creating shapefile:", writer.errorMessage()) writer.addFeatures(alist) del writer nwLayer = self.iface.addVectorLayer(filedirectory+'/'+name, "", "ogr") if not nwLayer: print("Layer failed to load!") return
def to_shp(self, path, name, crs, encoding, geom_type, features, graph='primal'): if graph == 'primal': flds = self.edge_qflds elif graph == 'dual': flds = [ QgsField('source', QVariant.String), QgsField('target', QVariant.String), QgsField('cost', QVariant.Int) ] if path is None: network = QgsVectorLayer('MultiLineString?crs=' + crs.toWkt(), name, "memory") else: file_writer = QgsVectorFileWriter(path, encoding, flds, geom_type, crs, "ESRI Shapefile") if file_writer.hasError() != QgsVectorFileWriter.NoError: print "Error when creating shapefile: ", file_writer.errorMessage( ) del file_writer network = QgsVectorLayer(path, name, "ogr") # QgsMapLayerRegistry.instance().addMapLayer(network) pr = network.dataProvider() network.startEditing() if path is None: pr.addAttributes(flds) pr.addFeatures(features) network.commitChanges() return network
def create_datasource_from_template(self, datasource): fieldSet = QgsFields() for fieldDef in FIELDS_TEMPLATE: fieldSet.append(self.getFieldFromDefinition(fieldDef)) writer = QgsVectorFileWriter(datasource, 'UTF-8', fieldSet, QgsWkbTypes.Point, QgsCoordinateReferenceSystem(4326),"ESRI Shapefile") if writer.hasError(): print ("error",writer.errorMessage()) del writer
def createShapefile(filePath, name, wkbType, crs, fields, styleURI=None, symbology=None): # WARNING This will overwrite existing files writer = QgsVectorFileWriter(filePath, 'System', fields, wkbType, crs) if writer.hasError(): utils.debug(writer.errorMessage()) del writer layer = QgsVectorLayer(filePath, name, 'ogr') loadStyle(layer, styleURI, symbology) return layer
def create_reservoirs_shp(shp_file_path, crs=None): fields = QgsFields() fields.append(QgsField(Reservoir.field_name_eid, QVariant.String)) fields.append(QgsField(Reservoir.field_name_elev, QVariant.Double)) fields.append(QgsField(Reservoir.field_name_delta_z, QVariant.Double)) # fields.append(QgsField(Reservoir.field_name_head, QVariant.Double)) writer = QgsVectorFileWriter(shp_file_path, "CP1250", fields, QgsWkbTypes.Point, crs, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: raise Exception(writer.errorMessage())
def create_pumps_shp(shp_file_path, crs=None): fields = QgsFields() fields.append(QgsField(QgsField(Pump.field_name_eid, QVariant.String))) # fields.append(QgsField(QgsField(Pump.field_name_from_node, QVariant.String))) # fields.append(QgsField(QgsField(Pump.field_name_to_node, QVariant.String))) fields.append( QgsField(QgsField(Pump.field_name_param, QVariant.String))) fields.append( QgsField(QgsField(Pump.field_name_value, QVariant.String))) writer = QgsVectorFileWriter(shp_file_path, "CP1250", fields, QGis.WKBLineString, crs, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: raise Exception(writer.errorMessage())
def createEmptyVectorLayer(path, formatDriver, fields=None, srcCrs=QgsCoordinateReferenceSystem( 4326, QgsCoordinateReferenceSystem.EpsgCrsId), shape=QgsWkbTypes.Polygon, encoding="UTF-8"): """ Create empty vector layer. """ validDriver = False drivers = QgsVectorFileWriter.ogrDriverList() for driver in drivers: validDriver = driver.longName == formatDriver if not formatDriver: print("Not applicable formatDriver" + str(drivers)) return False writer = QgsVectorFileWriter(path, encoding, fields, shape, srcCrs, formatDriver) if writer.hasError() != QgsVectorFileWriter.NoError: print("Error when creating shapefile: ", writer.hasError()) del writer return False return writer
def open_shapefile_writer(vlayer, shapefile_path): # Prepare inputs fields = vlayer.fields() # Create writer writer = QgsVectorFileWriter( shapefile_path, "utf-8", fields, QGis.WKBMultiPolygon, QgsCoordinateReferenceSystem(27700, QgsCoordinateReferenceSystem.EpsgCrsId), 'ESRI Shapefile') if writer.hasError() != QgsVectorFileWriter.NoError: msg = "Error when creating shapefile: {}".format(writer.errorMessage()) raise rn_except.CannotOpenShapefilePopupError(msg) return writer
def create_junctions_shp(shp_file_path, crs=None): fields = QgsFields() fields.append( QgsField(QgsField(Junction.field_name_eid, QVariant.String))) fields.append( QgsField(QgsField(Junction.field_name_demand, QVariant.Double))) fields.append(QgsField(Junction.field_name_elev, QVariant.Double)) fields.append(QgsField(Junction.field_name_delta_z, QVariant.Double)) fields.append(QgsField(Junction.field_name_pattern, QVariant.String)) fields.append( QgsField(Junction.field_name_emitter_coeff, QVariant.Double)) writer = QgsVectorFileWriter(shp_file_path, "CP1250", fields, QgsWkbTypes.Point, crs, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: raise Exception(writer.errorMessage())
def create_tanks_shp(shp_file_path, crs=None): fields = QgsFields() fields.append(QgsField(Tank.field_name_eid, QVariant.String)) fields.append(QgsField(Tank.field_name_curve, QVariant.Int)) fields.append(QgsField(Tank.field_name_diameter, QVariant.Double)) fields.append(QgsField(Tank.field_name_elev, QVariant.Double)) fields.append(QgsField(Tank.field_name_delta_z, QVariant.Double)) fields.append(QgsField(Tank.field_name_level_init, QVariant.Double)) fields.append(QgsField(Tank.field_name_level_max, QVariant.Double)) fields.append(QgsField(Tank.field_name_level_min, QVariant.Double)) fields.append(QgsField(Tank.field_name_vol_min, QVariant.Double)) writer = QgsVectorFileWriter(shp_file_path, "CP1250", fields, QgsWkbTypes.Point, crs, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: raise Exception(writer.errorMessage())
def _createLayer(self, filename, crs, geometries): if len(geometries) < 1: raise AerogenError(self.tr("No features to write")) geom_type = geometries[0].wkbType() writer = QgsVectorFileWriter(filename, "UTF-8", QgsFields(), geom_type, crs, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: raise AerogenError( 'Failed creating Shapefile: {}'.format(writer.errorMessage()) ) for geom in geometries: fet = QgsFeature() fet.setGeometry(geom) writer.addFeature(fet)
def create_shplayer_from_template(template, legend=True): #print "creating",template['datasource'] fieldSet = QgsFields() for fieldDef in template['fields']: fieldSet.append(getFieldFromDefinition(fieldDef)) writer = QgsVectorFileWriter(template['datasource'], 'UTF-8', fieldSet, template['geomtype'], QgsCoordinateReferenceSystem(template['srs'])) if writer.hasError(): print writer.errorMessage() del writer lyr = QgsVectorLayer(template['datasource'], template['name'], 'ogr') if template['style']: lyr.loadNamedStyle(template['style']) if legend: QgsMapLayerRegistry.instance().addMapLayer(lyr) return lyr
def create_valves_shp(shp_file_path, crs=None): fields = QgsFields() fields.append(QgsField(QgsField(Valve.field_name_eid, QVariant.String))) fields.append( QgsField(QgsField(Valve.field_name_diameter, QVariant.Double))) fields.append( QgsField(QgsField(Valve.field_name_minor_loss, QVariant.Double))) fields.append( QgsField(QgsField(Valve.field_name_setting, QVariant.Double))) fields.append( QgsField(QgsField(Valve.field_name_type, QVariant.String))) writer = QgsVectorFileWriter(shp_file_path, "CP1250", fields, QGis.WKBLineString, crs, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: raise Exception(writer.errorMessage())
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 create_shp(self): fields = QgsFields() fields.append(QgsField("setting_id", QVariant.String)) fields.append(QgsField("raster", QVariant.String)) fields.append(QgsField("x centre", QVariant.String)) fields.append(QgsField("y centre", QVariant.String)) self.shape_path = self.results.log_path.split(".log")[0] + ".shp" writer = QgsVectorFileWriter( self.shape_path, "CP1250", fields, QgsWkbTypes.Point, QgsCoordinateReferenceSystem(), "ESRI Shapefile", ) try: if writer.hasError() != QgsVectorFileWriter.NoError: msg = "Error while creating shapefile: " + str(writer.errorMessage()) logger.error(msg) raise Exception(msg) else: for pixel_check_dict in self.input_data_shp: raster = pixel_check_dict.get("raster") setting_id = pixel_check_dict.get("setting_id") coords = pixel_check_dict.get("coords") for row in coords: for point in row: point_y = point[0] point_x = point[1] feat = QgsFeature() feat.setGeometry( QgsGeometry.fromPointXY(QgsPointXY(point_x, point_y)) ) feat.setAttributes([setting_id, raster, point_x, point_y]) writer.addFeature(feat) except Exception: # TODO: there's a "raise" inside the try, there's a raise # below. What's the intention? logger.exception("Error creating shapefile") raise AssertionError("could not write XY point to shp file") # delete the writer to flush features to disk 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 create_pipes_shp(shp_file_path, crs=None): fields = QgsFields() fields.append(QgsField(QgsField(Pipe.field_name_eid, QVariant.String))) # fields.append(QgsField(QgsField(Pipe.field_name_demand, QVariant.Double))) fields.append( QgsField(QgsField(Pipe.field_name_diameter, QVariant.Double))) fields.append( QgsField(QgsField(Pipe.field_name_length, QVariant.Double))) fields.append( QgsField(QgsField(Pipe.field_name_roughness, QVariant.Double))) fields.append( QgsField(QgsField(Pipe.field_name_status, QVariant.String))) fields.append( QgsField(QgsField(Pipe.field_name_minor_loss, QVariant.Double))) writer = QgsVectorFileWriter(shp_file_path, "CP1250", fields, QgsWkbTypes.LineString, crs, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: raise Exception(writer.errorMessage())
def savePointGeometry(path, geodata, label, spatialRef, geoFormat): """ :param label: Name of poles :param path: Location of shape file :param geodata: x, y and z coordinate of poles :param spatialRef: current spatial reference of qgis project :param geoFormat: Geodata export format """ # Define fields for feature attributes. A QgsFields object is needed stueNrName = tr('bezeichnung') fields = QgsFields() fields.append(QgsField(stueNrName, QVariant.String, 'text', 254)) fields.append(QgsField('x', QVariant.Double)) fields.append(QgsField('y', QVariant.Double)) fields.append(QgsField('z', QVariant.Double)) fields.append(QgsField('h', QVariant.Double)) writer = QgsVectorFileWriter(path, 'UTF-8', fields, QgsWkbTypes.PointZ, spatialRef, geoFormat) if writer.hasError() != QgsVectorFileWriter.NoError: # TODO raise Exception('Vector Writer') features = [] for idx, coords in enumerate(geodata): feature = QgsFeature() feature.setFields(fields) feature.setGeometry(QgsPoint(coords[0], coords[1], coords[2])) feature.setId(idx) feature.setAttribute(stueNrName, label[idx]) feature.setAttribute('x', float(coords[0])) feature.setAttribute('y', float(coords[1])) feature.setAttribute('z', float(coords[2])) feature.setAttribute('h', float(coords[3])) features.append(feature) writer.addFeatures(features) # Delete the writer to flush features to disk del writer
def save2LineShape(shapePath, geodata, spatialRef): # define fields for feature attributes. A QgsFields object is needed fields = QgsFields() writer = QgsVectorFileWriter(shapePath, "UTF8", fields, QgsWkbTypes.LineStringZ, spatialRef, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: # TODO raise Exception("Vector Writer") lineVertices = [] for idx, coords in enumerate(geodata): lineVertices.append(QgsPoint(coords[0], coords[1], coords[2])) feature = QgsFeature() feature.setGeometry(QgsGeometry.fromPolyline(lineVertices)) feature.setId(1) writer.addFeature(feature) del feature # delete the writer to flush features to disk del writer
def _newShapefile(self): fields = QgsFields() fields.append(QgsField('filepath', QVariant.String, '', 254)) fields.append(QgsField('filename', QVariant.String, '', 254)) fields.append(QgsField('longitude', QVariant.Double, '', 20, 7)) fields.append(QgsField('latitude', QVariant.Double, '', 20, 7)) fields.append(QgsField('altitude', QVariant.Double, '', 20, 7)) fields.append(QgsField('north', QVariant.String, '', 1)) fields.append(QgsField('azimuth', QVariant.Double, '', 20, 7)) fields.append(QgsField('gps_date', QVariant.String, '', 254)) fields.append(QgsField('img_date', QVariant.String, '', 254)) crs = QgsCoordinateReferenceSystem(4326) writer = QgsVectorFileWriter( self.shapePath, self.encoding, fields, QGis.WKBPoint, crs) if writer.hasError() != QgsVectorFileWriter.NoError: return None del writer layer = QgsVectorLayer( self.shapePath, QFileInfo(self.shapePath).baseName(), 'ogr') return layer
def to_shp(self, path, name, crs, encoding, geom_type, features, graph='primal'): if graph == 'primal': flds = self.edge_qflds elif graph == 'dual': flds = [QgsField('source', QVariant.String), QgsField('target', QVariant.String), QgsField('cost', QVariant.Int)] if path is None: network = QgsVectorLayer('MultiLineString?crs=' + crs.toWkt(), name, "memory") else: file_writer = QgsVectorFileWriter(path, encoding, flds, geom_type, crs, "ESRI Shapefile") if file_writer.hasError() != QgsVectorFileWriter.NoError: print "Error when creating shapefile: ", file_writer.errorMessage() del file_writer network = QgsVectorLayer(path, name, "ogr") # QgsMapLayerRegistry.instance().addMapLayer(network) pr = network.dataProvider() network.startEditing() if path is None: pr.addAttributes(flds) pr.addFeatures(features) network.commitChanges() return network
def _clipVectorLayer(theLayer, theExtent, extraKeywords=None): """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 - 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. Returns: Path to the output clipped layer (placed in the system temp dir). Raises: None """ if not theLayer or not theExtent: msg = tr('Layer or Extent passed to clip is None.') raise InvalidParameterException(msg) if theLayer.type() != QgsMapLayer.VectorLayer: msg = tr('Expected a vector layer but received a %s.' % str(theLayer.type())) raise InvalidParameterException(msg) myHandle, myFilename = tempfile.mkstemp('.shp', 'clip_', getTempDir()) # 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()) myRect = QgsRectangle(theExtent[0], theExtent[1], theExtent[2], theExtent[3]) myProjectedExtent = myXForm.transformBoundingBox(myRect) # Get vector layer myProvider = theLayer.dataProvider() if myProvider is None: msg = tr('Could not obtain data provider from ' 'layer "%s"' % theLayer.source()) raise Exception(msg) # 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, 'ESRI Shapefile') if myWriter.hasError() != QgsVectorFileWriter.NoError: msg = tr('Error when creating shapefile: <br>Filename:' '%s<br>Error: %s' % (myFilename, myWriter.hasError())) raise Exception(msg) # 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() myGeometry.transform(myXForm) myFeature.setGeometry(myGeometry) 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.') raise NoFeaturesInExtentException(myMessage) copyKeywords(theLayer.source(), myFilename, extraKeywords=extraKeywords) return myFilename # Filename of created file
def _preparePolygonLayer(self, theQgisLayer): """Create a new layer with no intersecting features to self.layer. A helper function to align the polygons to the postprocLayer polygons. If one input polygon is in two or more postprocLayer polygons then it is divided so that each part is within only one of the postprocLayer polygons. this allows to aggregate in postrocessing using centroid in polygon. The function assumes EPSG:4326 but no checks are enforced Args: theQgisLayer of the file to be processed Returns: QgisLayer of the processed file Raises: Any exceptions raised by the InaSAFE library will be propagated. """ # import time # startTime = time.clock() myMessage = m.Message( m.Heading(self.tr('Preclipping input data...')), m.Paragraph(self.tr( 'Modifying %1 to avoid intersections with the aggregation ' 'layer' ).arg(theQgisLayer.name()))) self._sendMessage(myMessage) theLayerFilename = str(theQgisLayer.source()) myPostprocPolygons = self.safeLayer.get_geometry() myPolygonsLayer = safe_read_layer(theLayerFilename) myRemainingPolygons = numpy.array(myPolygonsLayer.get_geometry()) # myRemainingAttributes = numpy.array(myPolygonsLayer.get_data()) myRemainingIndexes = numpy.array(range(len(myRemainingPolygons))) #used for unit tests only self.preprocessedFeatureCount = 0 # FIXME (MB) the intersecting array is used only for debugging and # could be safely removed myIntersectingPolygons = [] myInsidePolygons = [] # FIXME (MB) maybe do raw geos without qgis #select all postproc polygons with no attributes aggregationProvider = self.layer.dataProvider() aggregationProvider.select([]) # copy polygons to a memory layer myQgisMemoryLayer = create_memory_layer(theQgisLayer) polygonsProvider = myQgisMemoryLayer.dataProvider() allPolygonAttrs = polygonsProvider.attributeIndexes() polygonsProvider.select(allPolygonAttrs) myQgisPostprocPoly = QgsFeature() myQgisFeat = QgsFeature() myInsideFeat = QgsFeature() fields = polygonsProvider.fields() myTempdir = temp_dir(sub_dir='preprocess') myOutFilename = unique_filename(suffix='.shp', dir=myTempdir) self.keywordIO.copy_keywords(theQgisLayer, myOutFilename) mySHPWriter = QgsVectorFileWriter(myOutFilename, 'UTF-8', fields, polygonsProvider.geometryType(), polygonsProvider.crs()) if mySHPWriter.hasError(): raise InvalidParameterError(mySHPWriter.errorMessage()) # end FIXME for (myPostprocPolygonIndex, myPostprocPolygon) in enumerate(myPostprocPolygons): LOGGER.debug('PostprocPolygon %s' % myPostprocPolygonIndex) myPolygonsCount = len(myRemainingPolygons) aggregationProvider.featureAtId( myPostprocPolygonIndex, myQgisPostprocPoly, True, []) myQgisPostprocGeom = QgsGeometry(myQgisPostprocPoly.geometry()) # myPostprocPolygon bounding box values A = numpy.array(myPostprocPolygon) minx = miny = sys.maxint maxx = maxy = -minx myPostprocPolygonMinx = min(minx, min(A[:, 0])) myPostprocPolygonMaxx = max(maxx, max(A[:, 0])) myPostprocPolygonMiny = min(miny, min(A[:, 1])) myPostprocPolygonMaxy = max(maxy, max(A[:, 1])) # create an array full of False to store if a BB vertex is inside # or outside the myPostprocPolygon myAreVerticesInside = numpy.zeros(myPolygonsCount * 4, dtype=numpy.bool) # Create Nx2 vector of vertices of bounding boxes myBBVertices = [] # Compute bounding box for each geometry type for myPoly in myRemainingPolygons: minx = miny = sys.maxint maxx = maxy = -minx # Do outer ring only as the BB is outside anyway A = numpy.array(myPoly) minx = min(minx, numpy.min(A[:, 0])) maxx = max(maxx, numpy.max(A[:, 0])) miny = min(miny, numpy.min(A[:, 1])) maxy = max(maxy, numpy.max(A[:, 1])) myBBVertices.extend([(minx, miny), (minx, maxy), (maxx, maxy), (maxx, miny)]) # see if BB vertices are in myPostprocPolygon myBBVertices = numpy.array(myBBVertices) inside, _ = points_in_and_outside_polygon(myBBVertices, myPostprocPolygon) # make True if the vertice was in myPostprocPolygon myAreVerticesInside[inside] = True # myNextIterPolygons has the 0:count indexes # myOutsidePolygons has the mapped to original indexes # and is overwritten at every iteration because we care only of # the outside polygons remaining after the last iteration myNextIterPolygons = [] myOutsidePolygons = [] for i in range(myPolygonsCount): k = i * 4 myMappedIndex = myRemainingIndexes[i] # memory layers counting starts at 1 instead of 0 as in our # indexes myFeatId = myMappedIndex + 1 doIntersection = False # summ the isInside bool for each of the boundingbox vertices # of each poygon. for example True + True + False + True is 3 myPolygonLocation = numpy.sum(myAreVerticesInside[k:k + 4]) if myPolygonLocation == 4: # all vertices are inside -> polygon is inside #ignore this polygon from further analysis myInsidePolygons.append(myMappedIndex) polygonsProvider.featureAtId(myFeatId, myQgisFeat, True, allPolygonAttrs) mySHPWriter.addFeature(myQgisFeat) self.preprocessedFeatureCount += 1 # LOGGER.debug('Polygon %s is fully inside' %myMappedIndex) # tmpWriter.addFeature(myQgisFeat) elif myPolygonLocation == 0: # all vertices are outside # check if the polygon BB is completely outside of the # myPostprocPolygon BB. myPolyMinx = numpy.min(myBBVertices[k:k + 4, 0]) myPolyMaxx = numpy.max(myBBVertices[k:k + 4, 0]) myPolyMiny = numpy.min(myBBVertices[k:k + 4, 1]) myPolyMaxy = numpy.max(myBBVertices[k:k + 4, 1]) # check if myPoly is all E,W,N,S of myPostprocPolygon if ((myPolyMinx > myPostprocPolygonMaxx) or (myPolyMaxx < myPostprocPolygonMinx) or (myPolyMiny > myPostprocPolygonMaxy) or (myPolyMaxy < myPostprocPolygonMiny)): #polygon is surely outside myOutsidePolygons.append(myMappedIndex) # we need this polygon in the next iteration myNextIterPolygons.append(i) else: # polygon might be outside or intersecting. consider # it intersecting so it goes into further analysis doIntersection = True else: # some vertices are outside some inside -> polygon is # intersecting doIntersection = True #intersect using qgis if doIntersection: # LOGGER.debug('Intersecting polygon %s' % myMappedIndex) myIntersectingPolygons.append(myMappedIndex) ok = polygonsProvider.featureAtId(myFeatId, myQgisFeat, True, allPolygonAttrs) if not ok: LOGGER.debug('Couldn\'t fetch feature: %s' % myFeatId) LOGGER.debug([str(error) for error in polygonsProvider.errors()]) myQgisPolyGeom = QgsGeometry(myQgisFeat.geometry()) myAtMap = myQgisFeat.attributeMap() # for (k, attr) in myAtMap.iteritems(): # LOGGER.debug( "%d: %s" % (k, attr.toString())) # make intersection of the myQgisFeat and the postprocPoly # write the inside part to a shp file and the outside part # back to the original QGIS layer try: myIntersec = myQgisPostprocGeom.intersection( myQgisPolyGeom) # if myIntersec is not None: myIntersecGeom = QgsGeometry(myIntersec) #from ftools myUnknownGeomType = 0 if myIntersecGeom.wkbType() == myUnknownGeomType: int_com = myQgisPostprocGeom.combine( myQgisPolyGeom) int_sym = myQgisPostprocGeom.symDifference( myQgisPolyGeom) myIntersecGeom = QgsGeometry( int_com.difference(int_sym)) # LOGGER.debug('wkbType type of intersection: %s' % # myIntersecGeom.wkbType()) polygonTypesList = [QGis.WKBPolygon, QGis.WKBMultiPolygon] if myIntersecGeom.wkbType() in polygonTypesList: myInsideFeat.setGeometry(myIntersecGeom) myInsideFeat.setAttributeMap(myAtMap) mySHPWriter.addFeature(myInsideFeat) self.preprocessedFeatureCount += 1 else: pass # LOGGER.debug('Intersection not a polygon so ' # 'the two polygons either touch ' # 'only or do not intersect. Not ' # 'adding this to the inside list') #Part of the polygon that is outside the postprocpoly myOutside = myQgisPolyGeom.difference(myIntersecGeom) # if myOutside is not None: myOutsideGeom = QgsGeometry(myOutside) if myOutsideGeom.wkbType() in polygonTypesList: # modifiy the original geometry to the part # outside of the postproc polygon polygonsProvider.changeGeometryValues( {myFeatId: myOutsideGeom}) # we need this polygon in the next iteration myOutsidePolygons.append(myMappedIndex) myNextIterPolygons.append(i) except TypeError: LOGGER.debug('ERROR with FID %s', myMappedIndex) # LOGGER.debug('Inside %s' % myInsidePolygons) # LOGGER.debug('Outside %s' % myOutsidePolygons) # LOGGER.debug('Intersec %s' % myIntersectingPolygons) if len(myNextIterPolygons) > 0: #some polygons are still completely outside of the postprocPoly #so go on and reiterate using only these nextIterPolygonsIndex = numpy.array(myNextIterPolygons) myRemainingPolygons = myRemainingPolygons[ nextIterPolygonsIndex] # myRemainingAttributes = myRemainingAttributes[ # nextIterPolygonsIndex] myRemainingIndexes = myRemainingIndexes[nextIterPolygonsIndex] LOGGER.debug('Remaining: %s' % len(myRemainingPolygons)) else: print 'no more polygons to be checked' break # del tmpWriter # here the full polygon set is represented by: # myInsidePolygons + myIntersectingPolygons + myNextIterPolygons # the a polygon intersecting multiple postproc polygons appears # multiple times in the array # noinspection PyUnboundLocalVariable LOGGER.debug('Results:\nInside: %s\nIntersect: %s\nOutside: %s' % ( myInsidePolygons, myIntersectingPolygons, myOutsidePolygons)) #add in- and outside polygons for i in myOutsidePolygons: myFeatId = i + 1 polygonsProvider.featureAtId(myFeatId, myQgisFeat, True, allPolygonAttrs) mySHPWriter.addFeature(myQgisFeat) self.preprocessedFeatureCount += 1 del mySHPWriter # LOGGER.debug('Created: %s' % self.preprocessedFeatureCount) myName = '%s %s' % (theQgisLayer.name(), self.tr('preprocessed')) myOutLayer = QgsVectorLayer(myOutFilename, myName, 'ogr') if not myOutLayer.isValid(): #TODO (MB) use a better exception raise Exception('Invalid qgis Layer') if self.showIntermediateLayers: self.keywordIO.update_keywords(myOutLayer, {'title': myName}) QgsMapLayerRegistry.instance().addMapLayer(myOutLayer) return myOutLayer
# Export a vector layer directly from features # define fields for feature attributes. A QgsFields object is needed fields = QgsFields() fields.append(QgsField("first", QVariant.Int)) fields.append(QgsField("second", QVariant.String)) # Create an instance of vector file writer, which will create the vector file. # Arguments: # 1. path to new file (will fail if exists already) # 2. encoding of the attributes # 3. field map # 4. geometry type - from WKBTYPE enum # 5. layer's spatial reference (instance of # QgsCoordinateReferenceSystem) - optional # 6. driver name for the output file writer = QgsVectorFileWriter("my_shapes.shp", "CP1250", fields, QGis.WKBPoint, None, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: print("Error when creating shapefile: ", writer.errorMessage()) # Add a feature fet = QgsFeature() fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10))) fet.setAttributes([1, "text"]) writer.addFeature(fet) # Delete the writer to flush features to disk del writer
def _clipVectorLayer(theLayer, theExtent, theExtraKeywords=None, explodeMultipart=True): """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 - 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. * theExtraKeywords - any additional keywords over and above the original keywords that should be associated with the cliplayer. * explodeMultipart - a bool describing if to convert multipart features into singleparts 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 InvalidParameterException(myMessage) if theLayer.type() != QgsMapLayer.VectorLayer: myMessage = tr("Expected a vector layer but received a %s." % str(theLayer.type())) raise InvalidParameterException(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()) myRect = QgsRectangle(theExtent[0], theExtent[1], theExtent[2], theExtent[3]) 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 explodeMultipart is False if explodeMultipart: myGeometryList = explodeMultiPartGeometry(myGeometry) else: myGeometryList = [myGeometry] for myPart in myGeometryList: myPart.transform(myXForm) 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." ) raise NoFeaturesInExtentException(myMessage) myKeywordIO = KeywordIO() myKeywordIO.copyKeywords(theLayer, myFilename, theExtraKeywords=theExtraKeywords) return myFilename # Filename of created file
def _clipVectorLayer(theLayer, theExtent, theExtraKeywords=None, explodeMultipart=True): """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 - 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. * theExtraKeywords - any additional keywords over and above the original keywords that should be associated with the cliplayer. * explodeMultipart - a bool describing if to convert multipart features into singleparts 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 InvalidParameterException(myMessage) if theLayer.type() != QgsMapLayer.VectorLayer: myMessage = tr('Expected a vector layer but received a %s.' % str(theLayer.type())) raise InvalidParameterException(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()) myRect = QgsRectangle(theExtent[0], theExtent[1], theExtent[2], theExtent[3]) 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 explodeMultipart is False if explodeMultipart: myGeometryList = explodeMultiPartGeometry(myGeometry) else: myGeometryList = [myGeometry] for myPart in myGeometryList: myPart.transform(myXForm) 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.') raise NoFeaturesInExtentException(myMessage) myKeywordIO = KeywordIO() myKeywordIO.copyKeywords(theLayer, myFilename, theExtraKeywords=theExtraKeywords) return myFilename # Filename of created file
def processSampleRasterAlgorithm(self, pointSpacing, INPUT_EXTENT, SAMPLE_FILE, OUTPUT_FILE, feedback): if (os.path.isfile(OUTPUT_FILE)): return 0 fields = QgsFields() fields.append(QgsField("slope", QVariant.Double)) sampleLayer = QgsRasterLayer(SAMPLE_FILE, 'Reclassified Slope', 'gdal') #pointLayerPath = quote(INPUT_POINTS) #pointLayer = QgsVectorLayer(pointLayerPath, 'points', 'ogr') QgsMessageLog.logMessage( 'Now generate points: extent={} crs={}'.format( INPUT_EXTENT.toString(), sampleLayer.crs().description())) pointLayer = processing.run('qgis:regularpoints', { 'EXTENT': INPUT_EXTENT, 'SPACING': pointSpacing, 'INSET': 0, 'IS_SPACING': True, 'RANDOMIZE': False, 'CRS': sampleLayer.crs().description(), 'OUTPUT': 'memory:' }, feedback=feedback)['OUTPUT'] #QgsMessageLog.logMessage("Points done!") #QgsMessageLog.logMessage("Now build sample points destination") sampledPointsLayerPath = OUTPUT_FILE sampledPointsLayer = QgsVectorFileWriter(sampledPointsLayerPath, "utf-8", fields, QgsWkbTypes.Point, sampleLayer.crs(), "ESRI Shapefile") result = sampledPointsLayer.hasError() QgsMessageLog.logMessage( "INITIAL ERROR CHECK, CODE: {}, MSG: {}".format( result, sampledPointsLayer.errorMessage())) if result > 0: return result #QgsMessageLog.logMessage("Does writer have error? {}, {}".format(sampledPointsLayer.hasError(), sampledPointsLayer.errorMessage())) #QgsMessageLog.logMessage("Will sample {} points".format(pointLayer.featureCount())) count = pointLayer.featureCount() total = 100.0 / count if count else 0 features = pointLayer.getFeatures(QgsFeatureRequest()) current = 0 featureGroups = chunks(features, count, 100) QgsMessageLog.logMessage("FEATURE COUNT: {}".format(count)) for group in featureGroups: for feature in group: # Stop the algorithm if cancel button has been clicked #QgsMessageLog.logMessage("Current: {}".format(current)) #QgsMessageLog.logMessage("Feature: {}".format(feature)) if feedback.isCanceled(): break current = current + 1 ident = sampleLayer.dataProvider().identify( feature.geometry().asPoint(), QgsRaster.IdentifyFormatValue) if (ident.results()[1]) is not None and int( ident.results()[1]) == 1: out_point = QgsFeature(fields) out_point.setGeometry(feature.geometry()) out_point.setAttribute('slope', ident.results()[1]) sampledPointsLayer.addFeature(out_point, QgsFeatureSink.FastInsert) # Update the progress bar feedback.setProgress(int(current * total)) result = sampledPointsLayer.hasError() del sampledPointsLayer return result
def points_along_line(layerout, startpoint, endpoint, distance, label, layer, selected_only=True, force=False, fo_fila=False, divide=0, decimal=2): """Adding Points along the line """ crs = layer.crs().authid() # TODO check for virtual or shapelayer and set virt_layer according to it shape = False if shape: # define fields for feature attributes. A list of QgsField objects is needed fields = [ QgsField("first", QVariant.Int), QgsField("second", QVariant.String) ] # create an instance of vector file writer, which will create the vector file. # Arguments: # 1. path to new file (will fail if exists already) # 2. encoding of the attributes # 3. field map # 4. geometry type - from WKBTYPE enum # 5. layer's spatial reference (instance of # QgsCoordinateReferenceSystem) - optional # 6. driver name for the output file writer = QgsVectorFileWriter("my_shapes.shp", "CP1250", fields, Qgis.WKBPoint, crs, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: # fix_print_with_import print("Error when creating shapefile: ", writer.hasError()) # add a feature fet = QgsFeature() fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10))) fet.setAttributes([1, "text"]) writer.addFeature(fet) # delete the writer to flush features to disk (optional) del writer layer_type = "Shapefile" # TODO Add Shapefile functionality here else: layer_type = "memory" virt_layer = QgsVectorLayer("Point?crs=%s" % crs, layerout, layer_type) provider = virt_layer.dataProvider() virt_layer.startEditing() # actually writes attributes units = layer.crs().mapUnits() unitname = QgsUnitTypes.toString(units) provider.addAttributes([ QgsField("fid", QVariant.Int), QgsField("cng" + unitname, QVariant.Double) ]) def get_features(): """Getting the features """ if selected_only: return layer.selectedFeatures() else: return layer.getFeatures() # Loop through all (selected) features for feature in get_features(): geom = feature.geometry() # Add feature ID of selected feature fid = feature.id() if not geom: QgsMessageLog.logMessage("No geometry", "QChainage") continue features = create_points_at(startpoint, endpoint, distance, geom, fid, force, fo_fila, divide) provider.addFeatures(features) virt_layer.updateExtents() proj = QgsProject.instance() proj.addMapLayers([virt_layer]) virt_layer.commitChanges() virt_layer.reload() # generic labeling properties if label: virt_layer.setCustomProperty("labeling", "pal") virt_layer.setCustomProperty("labeling/enabled", "true") virt_layer.setCustomProperty("labeling/fieldName", "cng") virt_layer.setCustomProperty("labeling/fontSize", "10") virt_layer.setCustomProperty("labeling/multiLineLabels", "true") virt_layer.setCustomProperty("labeling/formatNumbers", "true") virt_layer.setCustomProperty("labeling/decimals", decimal) virt_layer.setCustomProperty("labeling/Size", "5") # symbol = QgsMarkerSymbol.createSimple({"name": "capital"}) # virt_layer.setRenderer(QgsSingleSymbolRenderer(symbol)) virt_layer.triggerRepaint() return
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 _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: myMessage = tr('Layer or Extent passed to clip is None.') raise InvalidParameterError(myMessage) if layer.type() != QgsMapLayer.VectorLayer: myMessage = tr('Expected a vector layer but received a %s.' % str(layer.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.createFromSrid(4326) myXForm = QgsCoordinateTransform(myGeoCrs, layer.crs()) myAllowedClipTypes = [QGis.WKBPolygon, QGis.WKBPolygon25D] if type(extent) is list: myRect = QgsRectangle( extent[0], extent[1], extent[2], extent[3]) # noinspection PyCallByClass myClipPolygon = QgsGeometry.fromRect(myRect) elif (type(extent) is QgsGeometry and extent.wkbType in myAllowedClipTypes): myRect = extent.boundingBox().toRectF() myClipPolygon = extent 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 = layer.dataProvider() if myProvider is None: myMessage = tr('Could not obtain data provider from ' 'layer "%s"' % layer.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 myRequest = QgsFeatureRequest() if not myProjectedExtent.isEmpty(): myRequest.setFilterRect(myProjectedExtent) myRequest.setFlags(QgsFeatureRequest.ExactIntersect) myFieldList = myProvider.fields() myWriter = QgsVectorFileWriter( myFilename, 'UTF-8', myFieldList, layer.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(layer.crs(), myGeoCrs) # Retrieve every feature with its geometry and attributes myCount = 0 myHasMultipart = False for myFeature in myProvider.getFeatures(myRequest): myGeometry = myFeature.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: myGeometryList = explode_multipart_geometry(myGeometry) else: myGeometryList = [myGeometry] for myPartIndex, myPart in enumerate(myGeometryList): myPart.transform(myXForm) if hard_clip_flag: # Remove any dangling bits so only intersecting area is # kept. myPart = clip_geometry(myClipPolygon, myPart) if myPart is None: continue myFeature.setGeometry(myPart) # There are multiple parts and we want to show it in the # explode_attribute if myPartIndex > 0 and explode_attribute is not None: myHasMultipart = True 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 disjointed. If this is the ' 'case, try to turn on reproject on-the-fly in QGIS.') raise NoFeaturesInExtentError(myMessage) myKeywordIO = KeywordIO() if extra_keywords is None: extra_keywords = {} extra_keywords['had multipart polygon'] = myHasMultipart myKeywordIO.copy_keywords( layer, myFilename, extra_keywords=extra_keywords) myBaseName = '%s clipped' % layer.name() myLayer = QgsVectorLayer(myFilename, myBaseName, 'ogr') return myLayer
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 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 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 _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 points_along_line(layerout, startpoint, endpoint, distance, label, layer, selected_only=True, force=False, fo_fila=False, divide=0, decimal=2): """Adding Points along the line """ crs = layer.crs().authid() # TODO check for virtual or shapelayer and set virt_layer according to it shape = False if shape: # define fields for feature attributes. A list of QgsField objects is needed fields = [QgsField("first", QVariant.Int), QgsField("second", QVariant.String)] # create an instance of vector file writer, which will create the vector file. # Arguments: # 1. path to new file (will fail if exists already) # 2. encoding of the attributes # 3. field map # 4. geometry type - from WKBTYPE enum # 5. layer's spatial reference (instance of # QgsCoordinateReferenceSystem) - optional # 6. driver name for the output file writer = QgsVectorFileWriter("my_shapes.shp", "CP1250", fields, QGis.WKBPoint, crs, "ESRI Shapefile") if writer.hasError() != QgsVectorFileWriter.NoError: print "Error when creating shapefile: ", writer.hasError() # add a feature fet = QgsFeature() fet.setGeometry(QgsGeometry.fromPoint(QgsPoint(10, 10))) fet.setAttributes([1, "text"]) writer.addFeature(fet) # delete the writer to flush features to disk (optional) del writer layer_type = "Shapefile" # TODO Add Shapefile functionality here else: layer_type = "memory" virt_layer = QgsVectorLayer("Point?crs=%s" % crs, layerout, layer_type) provider = virt_layer.dataProvider() virt_layer.startEditing() # actually writes attributes units = layer.crs().mapUnits() unit_dic = { QGis.Degrees: 'Degrees', QGis.Meters: 'Meters', QGis.Feet: 'Feet', QGis.UnknownUnit: 'Unknown'} unit = unit_dic.get(units, 'Unknown') provider.addAttributes([QgsField("fid", QVariant.Int), QgsField("cng_("+unit+")", QVariant.Double)]) def get_features(): """Getting the features """ if selected_only: return layer.selectedFeatures() else: return layer.getFeatures() # Loop through all (selected) features for feature in get_features(): geom = feature.geometry() # Add feature ID of selected feature fid = feature.id() if not geom: QgsMessageLog.logMessage("No geometry", "QChainage") continue features = create_points_at(startpoint, endpoint, distance, geom, fid, force, fo_fila, divide) provider.addFeatures(features) virt_layer.updateExtents() QgsMapLayerRegistry.instance().addMapLayers([virt_layer]) virt_layer.commitChanges() virt_layer.reload() # from here Add labeling # generic labeling properties if label: virt_layer.setCustomProperty("labeling", "pal") virt_layer.setCustomProperty("labeling/enabled", "true") virt_layer.setCustomProperty("labeling/fieldName", "cng_("+unit+")") virt_layer.setCustomProperty("labeling/fontSize", "10") virt_layer.setCustomProperty("labeling/multiLineLabels", "true") virt_layer.setCustomProperty("labeling/formatNumbers", "true") virt_layer.setCustomProperty("labeling/decimals", decimal) # virt_layer.setCustomProperty("labeling/Size", "5") # symbol = QgsMarkerSymbolV2.createSimple({"name": "capital"}) # virt_layer.setRendererV2(QgsSingleSymbolRendererV2(symbol)) virt_layer.triggerRepaint() return
def run_blur(self): self.progressBar_blur.setValue(0) self.label_progress.setText('') # Get all the fields. layer_to_blur = self.comboBox_layerToBlur.currentLayer() radius = self.spinBox_radius.value() display = self.checkBox_addToMap.isChecked() selected_features_only = self.checkBox_selectedOnlyFeatures.isChecked() file_name = self.lineEdit_outputFile.text() export_radius = self.checkBox_exportRadius.isChecked() export_centroid = self.checkBox_exportCentroid.isChecked() if self.checkBox_envelope.isChecked(): layer_envelope = self.comboBox_envelope.currentLayer() else: layer_envelope = None # Test values try: if not layer_to_blur: raise NoLayerProvidedException if not file_name and not display: raise NoFileNoDisplayException if layer_to_blur.crs().mapUnits() != 0: msg = tr('The projection of the map or of the layer is not ' 'in meters. These parameters should be in meters.') display_message_bar(msg, level=Qgis.Warning, duration=5) #https://github.com/qgis/QGIS/commit/9302613f28207910608fe538a03e0bff82ca5629 if not file_name: file_name = getTempFilename('blurring.shp') pass if layer_envelope: if layer_to_blur.crs() != layer_envelope.crs(): raise DifferentCrsException( epsg1=layer_to_blur.crs().authid(), epsg2=layer_envelope.crs().authid()) self.label_progress.setText('Creating index ...') layer_envelope = LayerIndex(layer_envelope) self.progressBar_blur.setValue(0) self.label_progress.setText('Blurring ...') if selected_features_only: features = layer_to_blur.selectedFeatures() nb_features = layer_to_blur.selectedFeatureCount() else: features = layer_to_blur.getFeatures() nb_features = layer_to_blur.featureCount() # Fields fields = layer_to_blur.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)) # Creating the output shapefile file_writer = QgsVectorFileWriter(file_name, 'utf-8', fields, Qgis.WKBPolygon, layer_to_blur.crs(), 'ESRI Shapefile') if file_writer.hasError() != QgsVectorFileWriter.NoError: raise CreatingShapeFileException(suffix=file_writer.hasError()) # Creating the algorithm with radius algo = Blur(radius, layer_envelope, export_radius, export_centroid) for j, feature in enumerate(features): feature = algo.blur(feature) file_writer.addFeature(feature) # Update progress bar percent = int((j + 1) * 100 / nb_features) self.progressBar_blur.setValue(percent) # Write all features in the file del file_writer if display: old_default_projection = self.settings.value( '/Projections/defaultBehaviour') self.settings.setValue('/Projections/defaultBehaviour', 'useProject') layer_name = basename(file_name) new_layer = QgsVectorLayer(file_name, layer_name, 'ogr') new_layer.commitChanges() new_layer.clearCacheImage() # noinspection PyArgumentList QgsProject.instance().addMapLayers([new_layer]) self.settings.setValue('/Projections/defaultBehaviour', old_default_projection) msg = tr('Successful export in %s' % file_name) iface.messageBar().pushMessage(msg, level=Qgis.Info, duration=5) self.signalAskCloseWindow.emit() except GeoPublicHealthException as e: self.label_progress.setText('') display_message_bar(msg=e.msg, level=e.level, duration=e.duration) finally: # noinspection PyArgumentList QApplication.restoreOverrideCursor() # noinspection PyArgumentList QApplication.processEvents()
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 run_blur(self): self.progressBar_blur.setValue(0) self.label_progress.setText('') # Get all the fields. layer_to_blur = self.comboBox_layerToBlur.currentLayer() radius = self.spinBox_radius.value() display = self.checkBox_addToMap.isChecked() selected_features_only = self.checkBox_selectedOnlyFeatures.isChecked() file_name = self.lineEdit_outputFile.text() export_radius = self.checkBox_exportRadius.isChecked() export_centroid = self.checkBox_exportCentroid.isChecked() if self.checkBox_envelope.isChecked(): layer_envelope = self.comboBox_envelope.currentLayer() else: layer_envelope = None # Test values try: if not layer_to_blur: raise NoLayerProvidedException if not file_name and not display: raise NoFileNoDisplayException if layer_to_blur.crs().mapUnits() != 0: msg = tr('The projection of the map or of the layer is not ' 'in meters. These parameters should be in meters.') display_message_bar( msg, level=QgsMessageBar.WARNING, duration=5) if not file_name: file_name = getTempFilenameInTempFolder('blurring.shp') pass if layer_envelope: if layer_to_blur.crs() != layer_envelope.crs(): raise DifferentCrsException( epsg1=layer_to_blur.crs().authid(), epsg2=layer_envelope.crs().authid()) self.label_progress.setText('Creating index ...') layer_envelope = LayerIndex(layer_envelope) self.progressBar_blur.setValue(0) self.label_progress.setText('Blurring ...') if selected_features_only: features = layer_to_blur.selectedFeatures() nb_features = layer_to_blur.selectedFeatureCount() else: features = layer_to_blur.getFeatures() nb_features = layer_to_blur.featureCount() # Fields fields = layer_to_blur.pendingFields() 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)) # Creating the output shapefile file_writer = QgsVectorFileWriter( file_name, 'utf-8', fields, QGis.WKBPolygon, layer_to_blur.crs(), 'ESRI Shapefile') if file_writer.hasError() != QgsVectorFileWriter.NoError: raise CreatingShapeFileException(suffix=file_writer.hasError()) # Creating the algorithm with radius algo = Blur(radius, layer_envelope, export_radius, export_centroid) for j, feature in enumerate(features): feature = algo.blur(feature) file_writer.addFeature(feature) # Update progress bar percent = int((j + 1) * 100 / nb_features) self.progressBar_blur.setValue(percent) # Write all features in the file del file_writer if display: old_default_projection = self.settings.value( '/Projections/defaultBehaviour') self.settings.setValue( '/Projections/defaultBehaviour', 'useProject') layer_name = basename(file_name) new_layer = QgsVectorLayer(file_name, layer_name, 'ogr') new_layer.commitChanges() new_layer.clearCacheImage() # noinspection PyArgumentList QgsMapLayerRegistry.instance().addMapLayers([new_layer]) self.settings.setValue( '/Projections/defaultBehaviour', old_default_projection) msg = tr('Successful export in %s' % file_name) iface.messageBar().pushMessage( msg, level=QgsMessageBar.INFO, duration=5) self.signalAskCloseWindow.emit() except GeoPublicHealthException, e: self.label_progress.setText('') display_message_bar(msg=e.msg, level=e.level, duration=e.duration)