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 extract_nodes( self ): vprovider = self.vlayer.dataProvider() writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(), QGis.WKBPoint, vprovider.crs() ) inFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() nFeat = vprovider.featureCount() nElement = 0 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0 ) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) ) fit = vprovider.getFeatures() while fit.nextFeature( inFeat ): nElement += 1 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement ) inGeom = inFeat.geometry() atMap = inFeat.attributes() pointList = ftools_utils.extractPoints( inGeom ) outFeat.setAttributes( atMap ) for i in pointList: outFeat.setGeometry( outGeom.fromPoint( i ) ) writer.addFeature( outFeat ) del writer return True
def polygons_to_lines( self ): vprovider = self.vlayer.dataProvider() writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(), QGis.WKBLineString, vprovider.crs() ) inFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() outGeom = QgsGeometry() nFeat = vprovider.featureCount() nElement = 0 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) ) fit = vprovider.getFeatures() while fit.nextFeature( inFeat ): nElement += 1 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement ) inGeom = inFeat.geometry() atMap = inFeat.attributes() lineList = self.extractAsLine( inGeom ) outFeat.setAttributes( atMap ) for h in lineList: outFeat.setGeometry( outGeom.fromPolyline( h ) ) writer.addFeature( outFeat ) del writer return True
def lines_to_polygons( self ): vprovider = self.vlayer.dataProvider() writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(), QGis.WKBPolygon, vprovider.crs() ) inFeat = QgsFeature() outFeat = QgsFeature() nFeat = vprovider.featureCount() nElement = 0 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) ) fit = vprovider.getFeatures() while fit.nextFeature( inFeat ): outGeomList = [] nElement += 1 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement ) if inFeat.geometry().isMultipart(): outGeomList = inFeat.geometry().asMultiPolyline() else: outGeomList.append( inFeat.geometry().asPolyline() ) polyGeom = self.remove_bad_lines( outGeomList ) if len( polyGeom ) != 0: outFeat.setGeometry( QgsGeometry.fromPolygon( polyGeom ) ) atMap = inFeat.attributes() outFeat.setAttributes( atMap ) writer.addFeature( outFeat ) del writer return True
def _create_grid(self, grid_name, grid_file, x_min, y_min, x_max, y_max, x_off, y_off): x_off2, y_off2 = x_off / 2.0, y_off / 2.0 x_min = floor(x_min / x_off) * x_off x_max = ceil(x_max / x_off) * x_off y_min = floor(y_min / y_off) * y_off y_max = ceil(y_max / y_off) * y_off xtotal = int((x_max - x_min) / x_off) + 1 ytotal = int((y_max - y_min) / y_off) + 1 logAPICall.log( "x_min %f x_max %f y_min %f y_max %f x_off %f y_off %f xtotal %d, ytotal %d" % (x_min, x_max, y_min, y_max, x_off, y_off, xtotal, ytotal), logAPICall.DEBUG_L2, ) fields = {0: QgsField("GRID_GID", QVariant.String)} writer = QgsVectorFileWriter(grid_file, "utf-8", fields, QGis.WKBPolygon, self._crs, "ESRI Shapefile") f = QgsFeature() for x in range(xtotal): for y in range(ytotal): lon = x_min + (x * x_off) + (x_off2) lat = y_min + (y * y_off) + (y_off2) # out_geom = QgsGeometry.fromRect(QgsRectangle(lon-x_off2, lat-y_off2, # lon+x_off2, lat+y_off2)) f.setGeometry(self._outputGeometryFromLatLon(lat, lon)) f.addAttribute(0, QVariant(latlon_to_grid(lat, lon))) writer.addFeature(f) del writer return load_shapefile(grid_file, grid_name)
def do_operation(self): """ perform create mapping scheme operation """ # input/output verification already performed during set input/ouput zone_layer = self.inputs[0].value zone_field = self.inputs[1].value fp_layer = self.inputs[2].value # merge with zone to get assignment tmp_join = 'joined_%s' % get_unique_filename() tmp_join_file = '%s%s.shp' % (self._tmp_dir, tmp_join) analyzer = QgsOverlayAnalyzer() try: analyzer.intersection(fp_layer, zone_layer, tmp_join_file) tmp_join_layer = load_shapefile_verify(tmp_join_file, tmp_join,[zone_field]) except AssertionError as err: raise OperatorError(str(err), self.__class__) except Exception as err: raise OperatorError(str(err), self.__class__) fields = { 0 : QgsField(self._lon_field, QVariant.Double), 1 : QgsField(self._lat_field, QVariant.Double), 2 : QgsField(zone_field, QVariant.String), } zone_idx = layer_field_index(tmp_join_layer, zone_field) fp_layername = 'fpc_%s' % get_unique_filename() fp_file = '%s%s.shp' % (self._tmp_dir, fp_layername) try: writer = QgsVectorFileWriter(fp_file, "utf-8", fields, QGis.WKBPoint, self._crs, "ESRI Shapefile") f = QgsFeature() for _f in layer_features(tmp_join_layer): centroid = _f.geometry().centroid().asPoint() lon = centroid.x() lat = centroid.y() zone_str = str(_f.attributeMap()[zone_idx].toString()).upper() f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat))) f.addAttribute(0, QVariant(lon)) f.addAttribute(1, QVariant(lat)) f.addAttribute(2, QVariant(zone_str)) writer.addFeature(f) del writer except Exception as err: logAPICall.log(err, logAPICall.ERROR) remove_shapefile(fp_file) raise OperatorError("error creating joined grid: %s" % err, self.__class__) # load shapefile as layer fp_layer = load_shapefile(fp_file, fp_layername) if not fp_layer: raise OperatorError('Error loading footprint centroid file' % (fp_file), self.__class__) # clean up del tmp_join_layer remove_shapefile(tmp_join_file) self.outputs[0].value = fp_layer self.outputs[1].value = fp_file
def _write_grid_shapefile(self, path, x_min, y_min, x_max, y_max, x_off, y_off): x_off = self._x_off y_off = self._y_off x_min = floor(x_min / x_off) * x_off x_max = ceil(x_max / x_off) * x_off y_min = floor(y_min / y_off) * y_off y_max = ceil(y_max / y_off) * y_off xtotal = int((x_max - x_min) / x_off) ytotal = int((y_max - y_min) / y_off) logAPICall.log('x_min %f x_max %f y_min %f y_max %f x_off %f y_off %f xtotal %d, ytotal %d' % (x_min, x_max, y_min, y_max, x_off, y_off, xtotal, ytotal), logAPICall.DEBUG_L2) writer = QgsVectorFileWriter(path, "utf-8", self._fields, QGis.WKBPoint, self._crs, "ESRI Shapefile") f = QgsFeature() for x in range(xtotal): for y in range(ytotal): lon = x_min + (x * x_off) + (x_off/2.0) lat = y_min + (y * y_off) + (y_off/2.0) f.setGeometry(QgsGeometry.fromPoint(QgsPoint(lon, lat))) f.addAttribute(0, QVariant(lon)) f.addAttribute(1, QVariant(lat)) writer.addFeature(f) del writer
def getOgrCompatibleSource(self, parameter_name, parameters, context, feedback): """ Interprets a parameter as an OGR compatible source and layer name """ input_layer = self.parameterAsVectorLayer(parameters, parameter_name, context) ogr_data_path = None ogr_layer_name = None if input_layer is None: # parameter is not a vector layer - try to convert to a source compatible with OGR # and extract selection if required ogr_data_path = self.parameterAsCompatibleSourceLayerPath(parameters, parameter_name, context, QgsVectorFileWriter.supportedFormatExtensions(), feedback=feedback) ogr_layer_name = GdalUtils.ogrLayerName(ogr_data_path) elif input_layer.dataProvider().name() == 'ogr': # parameter is a vector layer, with OGR data provider # so extract selection if required ogr_data_path = self.parameterAsCompatibleSourceLayerPath(parameters, parameter_name, context, QgsVectorFileWriter.supportedFormatExtensions(), feedback=feedback) ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri()) else: # vector layer, but not OGR - get OGR compatible path # TODO - handle "selected features only" mode!! ogr_data_path = GdalUtils.ogrConnectionString(input_layer.dataProvider().dataSourceUri(), context)[1:-1] ogr_layer_name = GdalUtils.ogrLayerName(input_layer.dataProvider().dataSourceUri()) return ogr_data_path, ogr_layer_name
def processAlgorithm(self, progress): """Here is where the processing itself takes place.""" # The first thing to do is retrieve the values of the parameters # entered by the user inputFilename = self.getParameterValue(self.INPUT_LAYER) output = self.getOutputValue(self.OUTPUT_LAYER) # Input layers vales are always a string with its location. # That string can be converted into a QGIS object (a # QgsVectorLayer in this case) using the # processing.getObjectFromUri() method. vectorLayer = dataobjects.getObjectFromUri(inputFilename) # And now we can process # First we create the output layer. The output value entered by # the user is a string containing a filename, so we can use it # directly settings = QSettings() systemEncoding = settings.value('/UI/encoding', 'System') writer = QgsVectorFileWriter(output, systemEncoding, vectorLayer.fields(), vectorLayer.wkbType(), vectorLayer.crs()) # Now we take the features from input layer and add them to the # output. Method features() returns an iterator, considering the # selection that might exist in layer and the configuration that # indicates should algorithm use only selected features or all # of them features = vector.features(vectorLayer) for f in features: writer.addFeature(f)
def 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 testOgrDriverList(self): # test with drivers in recommended order drivers = QgsVectorFileWriter.ogrDriverList(QgsVectorFileWriter.SortRecommended) self.assertEqual(drivers[0].longName, 'GeoPackage') self.assertEqual(drivers[0].driverName, 'GPKG') self.assertEqual(drivers[1].longName, 'ESRI Shapefile') self.assertEqual(drivers[1].driverName, 'ESRI Shapefile') self.assertTrue('ODS' in [f.driverName for f in drivers]) # ensure that XLSX comes before SQLite, because we should sort on longName, not driverName! ms_xlsx_index = next(i for i, v in enumerate(drivers) if v.driverName == 'XLSX') sqlite_index = next(i for i, v in enumerate(drivers) if v.driverName == 'SQLite') self.assertLess(ms_xlsx_index, sqlite_index) self.assertIn('[XLSX]', drivers[ms_xlsx_index].longName) # alphabetical sorting drivers2 = QgsVectorFileWriter.ogrDriverList(QgsVectorFileWriter.VectorFormatOptions()) self.assertTrue(drivers2[0].longName < drivers2[1].longName) self.assertCountEqual([d.driverName for d in drivers], [d.driverName for d in drivers2]) self.assertNotEqual(drivers2[0].driverName, 'GPKG') # skip non-spatial formats = QgsVectorFileWriter.ogrDriverList(QgsVectorFileWriter.SkipNonSpatialFormats) self.assertFalse('ODS' in [f.driverName for f in formats])
def export_filter_layer(self, ext='xlsx'): ''' export a filter-layer (opens user-input) to excel or kml ''' try: res = self.get_filterlayer() except: traceback.print_exc() return if not res: return category, layer = res file_filter = EXCEL_FILTER if ext == 'xlsx' else KML_FILTER filepath = browse_file(None, 'Export', file_filter, save=True, parent=self) if not filepath: return driver = 'XLSX' if ext == 'xlsx'else 'KML' #fields = [] #for i, f in enumerate(layer.fields()): #if layer.editorWidgetV2(i) == 'Hidden': #continue #fields.append(f.name()) try: QgsVectorFileWriter.writeAsVectorFormat( layer, filepath, "utf-8", None, driver, False) #attributes=fields) title = 'Speicherung erfolgreich' msg = 'Die Daten wurden erfolgreich exportiert.' except Exception as e: title = 'Fehler' msg = 'Fehler bei der Speicherung: \n {}'.format(str(e)) QtGui.QMessageBox.information( self, title, msg)
def _add_tabular_layer(self, tabular_layer, layer_name, save_style=False): """Add a tabular layer to the folder. :param tabular_layer: The layer to add. :type tabular_layer: QgsVectorLayer :param layer_name: The name of the layer in the datastore. :type layer_name: str :param save_style: If we have to save a QML too. Default to False. :type save_style: bool :returns: A two-tuple. The first element will be True if we could add the layer to the datastore. The second element will be the layer name which has been used or the error message. :rtype: (bool, str) .. versionadded:: 4.0 """ output = QFileInfo( self.uri.filePath(layer_name + '.csv')) QgsVectorFileWriter.writeAsVectorFormat( tabular_layer, output.absoluteFilePath(), 'utf-8', QgsCoordinateTransform(), 'CSV') if save_style: style_path = QFileInfo(self.uri.filePath(layer_name + '.qml')) tabular_layer.saveNamedStyle(style_path.absoluteFilePath()) assert output.exists() return True, output.baseName()
def convert_geojson_to_shapefile(geojson_path): """Convert geojson file to shapefile. It will create a necessary file next to the geojson file. It will not affect another files (e.g. .xml, .qml, etc). :param geojson_path: The path to geojson file. :type geojson_path: basestring :returns: True if shapefile layer created, False otherwise. :rtype: bool """ layer = QgsVectorLayer(geojson_path, 'vector layer', 'ogr') if not layer.isValid(): return False # Construct shapefile path shapefile_path = os.path.splitext(geojson_path)[0] + '.shp' QgsVectorFileWriter.writeAsVectorFormat( layer, shapefile_path, 'utf-8', layer.crs(), 'ESRI Shapefile') if os.path.exists(shapefile_path): return True return False
def multi_to_single( self ): vprovider = self.vlayer.dataProvider() geomType = self.multiToSingleGeom( vprovider.geometryType() ) writer = QgsVectorFileWriter( self.myName, self.myEncoding, vprovider.fields(), geomType, vprovider.crs() ) inFeat = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() nFeat = vprovider.featureCount() nElement = 0 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), 0 ) self.emit( SIGNAL( "runRange( PyQt_PyObject )" ), ( 0, nFeat ) ) fit = vprovider.getFeatures() while fit.nextFeature( inFeat ): nElement += 1 self.emit( SIGNAL( "runStatus( PyQt_PyObject )" ), nElement ) inGeom = inFeat.geometry() atMap = inFeat.attributes() featList = self.extractAsSingle( inGeom ) outFeat.setAttributes( atMap ) for i in featList: outFeat.setGeometry( i ) writer.addFeature( outFeat ) del writer return True
def _add_tabular_layer(self, tabular_layer, layer_name): """Add a tabular layer to the folder. :param tabular_layer: The layer to add. :type tabular_layer: QgsVectorLayer :param layer_name: The name of the layer in the datastore. :type layer_name: str :returns: A two-tuple. The first element will be True if we could add the layer to the datastore. The second element will be the layer name which has been used or the error message. :rtype: (bool, str) .. versionadded:: 4.0 """ output = QFileInfo( self.uri.filePath(layer_name + '.csv')) QgsVectorFileWriter.writeAsVectorFormat( tabular_layer, output.absoluteFilePath(), 'utf-8', None, 'CSV') assert output.exists() return True, output.baseName()
def exportVector(layer, sln, layersFolder, restrictToExtent, iface, extent, precision, crs, minify): canvas = iface.mapCanvas() cleanLayer = writeTmpLayer(layer, restrictToExtent, iface, extent) if is25d(layer, canvas, restrictToExtent, extent): add25dAttributes(cleanLayer, layer, canvas) tmpPath = os.path.join(layersFolder, sln + ".json") path = os.path.join(layersFolder, sln + ".js") options = [] if precision != "maintain": options.append("COORDINATE_PRECISION=" + unicode(precision)) QgsVectorFileWriter.writeAsVectorFormat(cleanLayer, tmpPath, "utf-8", crs, 'GeoJson', 0, layerOptions=options) with open(path, mode="w", encoding="utf8") as f: f.write("var %s = " % ("json_" + sln)) with open(tmpPath, encoding="utf8") as tmpFile: for line in tmpFile: if minify: line = line.strip("\n\t ") line = removeSpaces(line) f.write(line) os.remove(tmpPath) fields = layer.fields() for field in fields: exportImages(layer, field.name(), layersFolder + "/tmp.tmp")
def writeVectorLayerToShape(vlayer, outputPath, encoding): mCodec = QTextCodec.codecForName(encoding) if not mCodec: return False #Here we should check that the output path is valid QgsVectorFileWriter.writeAsVectorFormat(vlayer, outputPath, encoding, vlayer.dataProvider().crs(), "ESRI Shapefile", False) return True
def TussenTelling(selectie_gebouwen, outputTable, outputFeatures): if outputTable: statistics_fields = ["AZ_T","PZ_T","PVT_T","WZC_T","SOM_T"] MaakOverzichtstabel(selectie_gebouwen, statistics_fields, outputTable) if outputFeatures: flType = findOGRtype(outputFeatures) QgsVectorFileWriter.writeAsVectorFormat(selectie_gebouwen , outputFeatures, "utf-8", None, flType )
def run(self): tempLayer = self.createGridLayer('temp', 'Multipolygon', self.crs.geographicCRSAuthId()) self.populateQgsLayer(self.index, self.stopScale, tempLayer, self.mi) useMemory = True if not self.layer: useMemory = False self.layer = self.createGridLayer('Grid Zones', 'Multipolygon', self.crs.authid()) for feature in tempLayer.getFeatures(): if self.stopped: del tempLayer tempLayer = None self.aux.userCanceled.emit() return geom = feature.geometry() reprojected = self.reprojectGridZone(geom) self.insertGridZoneIntoQgsLayer(self.layer, reprojected, feature.attributes()) self.aux.stepProcessed.emit() del tempLayer tempLayer = None self.aux.stepProcessed.emit() if not useMemory: QgsVectorFileWriter.writeAsVectorFormat(self.layer, self.output, "utf-8", None, "ESRI Shapefile") self.aux.processFinished.emit()
def getFileFilter(param): """ Returns a suitable file filter pattern for the specified parameter definition :param param: :return: """ if param.type() == 'multilayer': if param.layerType() == QgsProcessingParameterDefinition.TypeRaster: exts = dataobjects.getSupportedOutputRasterLayerExtensions() elif param.layerType() == QgsProcessingParameterDefinition.TypeFile: return tr('All files (*.*)', 'QgsProcessingParameterMultipleLayers') else: exts = QgsVectorFileWriter.supportedFormatExtensions() for i in range(len(exts)): exts[i] = tr('{0} files (*.{1})', 'QgsProcessingParameterMultipleLayers').format(exts[i].upper(), exts[i].lower()) return ';;'.join(exts) elif param.type() in ('raster', 'rasterOut'): exts = dataobjects.getSupportedOutputRasterLayerExtensions() for i in range(len(exts)): exts[i] = tr('{0} files (*.{1})', 'QgsProcessingParameterRasterOutput').format(exts[i].upper(), exts[i].lower()) return ';;'.join(exts) elif param.type() == 'table': exts = ['csv', 'dbf'] for i in range(len(exts)): exts[i] = tr('{0} files (*.{1})', 'ParameterTable').format(exts[i].upper(), exts[i].lower()) return ';;'.join(exts) elif param.type() == 'sink': exts = QgsVectorFileWriter.supportedFormatExtensions() for i in range(len(exts)): exts[i] = tr('{0} files (*.{1})', 'ParameterVector').format(exts[i].upper(), exts[i].lower()) return ';;'.join(exts) return ''
class VectorWriter: MEMORY_LAYER_PREFIX = 'memory:' def __init__(self, fileName, encoding, fields, geometryType, crs, options=None): self.fileName = fileName self.isMemory = False self.memLayer = None self.writer = None if encoding is None: settings = QSettings() encoding = settings.value('/Processing/encoding', 'System', type=str) if self.fileName.startswith(self.MEMORY_LAYER_PREFIX): self.isMemory = True uri = GEOM_TYPE_MAP[geometryType] + "?uuid=" + unicode(uuid.uuid4()) if crs.isValid(): uri += '&crs=' + crs.authid() fieldsdesc = [] for f in fields: qgsfield = _toQgsField(f) fieldsdesc.append('field=%s:%s' %(qgsfield.name(), TYPE_MAP_MEMORY_LAYER.get(qgsfield.type(), "string"))) if fieldsdesc: uri += '&' + '&'.join(fieldsdesc) self.memLayer = QgsVectorLayer(uri, self.fileName, 'memory') self.writer = self.memLayer.dataProvider() else: formats = QgsVectorFileWriter.supportedFiltersAndFormats() OGRCodes = {} for (key, value) in formats.items(): extension = unicode(key) extension = extension[extension.find('*.') + 2:] extension = extension[:extension.find(' ')] OGRCodes[extension] = value extension = self.fileName[self.fileName.rfind('.') + 1:] if extension not in OGRCodes: extension = 'shp' self.filename = self.filename + 'shp' qgsfields = QgsFields() for field in fields: qgsfields.append(_toQgsField(field)) self.writer = QgsVectorFileWriter( self.fileName, encoding, qgsfields, geometryType, crs, OGRCodes[extension]) def addFeature(self, feature): if self.isMemory: self.writer.addFeatures([feature]) else: self.writer.addFeature(feature)
def run(self): self.mutex.lock() self.stopMe = 0 self.mutex.unlock() interrupted = False outPath = self.outDir if outPath.find("\\") != -1: outPath.replace("\\", "/") if not outPath.endswith("/"): outPath = outPath + "/" provider = self.layer.dataProvider() index = provider.fieldNameIndex(self.field) unique = ftools_utils.getUniqueValues(provider, int(index)) baseName = unicode( outPath + self.layer.name() + "_" + self.field + "_" ) fieldList = ftools_utils.getFieldList(self.layer) sRs = provider.crs() geom = self.layer.wkbType() inFeat = QgsFeature() self.emit(SIGNAL("rangeCalculated(PyQt_PyObject)"), len(unique)) for i in unique: check = QFile(baseName + "_" + unicode(i).strip() + ".shp") fName = check.fileName() if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(fName): self.errors.append( fName ) continue writer = QgsVectorFileWriter(fName, self.encoding, fieldList, geom, sRs) fit = provider.getFeatures() while fit.nextFeature(inFeat): atMap = inFeat.attributes() if atMap[index] == i: writer.addFeature(inFeat) del writer self.emit(SIGNAL("valueProcessed()")) self.mutex.lock() s = self.stopMe self.mutex.unlock() if s == 1: interrupted = True break if not interrupted: self.emit(SIGNAL("processFinished( PyQt_PyObject )"), self.errors) else: self.emit(SIGNAL("processInterrupted()"))
def on_file_browse(self): settings = QSettings() # look for directory path = QgsProject.instance().homePath() if path == '': path = settings.value("mask/file_dir", '') if path == '': path = QDir.homePath() drivers = QgsVectorFileWriter.ogrDriverList() filterList = [] filterMap = {} for ln, n in drivers.items(): # grrr, driverMetadata is not really consistent if n == "ESRI Shapefile": ext = "shp" glob = "*.shp" else: md = QgsVectorFileWriter.MetaData() if QgsVectorFileWriter.driverMetadata(n, md): ext = md.ext glob = md.glob else: continue fn = "%s (%s)" % (ln, glob) filterMap[fn] = (n, ext, glob) filterList += [fn] fileFilters = ';;'.join(filterList) fd = QFileDialog(None, self.tr("Select a filename to save the mask layer to"), path, fileFilters) save_format_name = self.parameters.file_format self.save_format = None for k, v in filterMap.items(): if v[0] == save_format_name: self.save_format = v fd.selectNameFilter(k) break def on_filter_selected(ff): self.save_format = filterMap[ff] fd.filterSelected.connect(on_filter_selected) fd.setAcceptMode(QFileDialog.AcceptSave) r = fd.exec_() if r == 1: fn = fd.selectedFiles()[0] driver, ext, glob = self.save_format if not fn.endswith("." + ext): fn += "." + ext self.ui.filePath.setText(fn) self.ui.formatLbl.setText(self.save_format[0]) self.parameters.file_format = self.save_format[0] self.parameters.file_path = fn
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 test03_SaveAsCSV(self): """Save layer to a CSV file""" self._testAvailable() or self.skipTest("Not available") layer = self._testLayer(self.fileName) outfile = self.testDataPath(u"{}.csv".format(self.layerName), output=True) QgsVectorFileWriter.writeAsVectorFormat(layer, outfile, "UTF-8", layer.crs(), "CSV", layerOptions=["LINEFORMAT=LF", "GEOMETRY=AS_XY"]) expfile = unitTestDataPath("{}.csv".format(TC01_Attribute.layerName), own=True) assert compareFile(outfile, expfile, delimiter=",") == 0, "unexpected csv output"
def randomize(self, inLayer, outPath, minimum, design, value): outFeat = QgsFeature() outFeat.initAttributes(1) if design == self.tr("unstratified"): ext = inLayer.extent() if inLayer.type() == QgsMapLayer.RasterLayer: points = self.simpleRandom( int(value), ext, ext.xMinimum(), ext.xMaximum(), ext.yMinimum(), ext.yMaximum()) else: points = self.vectorRandom( int(value), inLayer, ext.xMinimum(), ext.xMaximum(), ext.yMinimum(), ext.yMaximum()) else: points, featErrors = self.loopThruPolygons(inLayer, value, design) if featErrors: if len(featErrors) >= 10: err_msg = "Too many features couldn't be calculated due to conversion error. " err_msg += "Please check out message log for more info." msgLogInstance = QgsMessageLog.instance() msgLogInstance.logMessage("WARNING - fTools: " + self.tr("Random Points")) msgLogInstance.logMessage("The following feature ids should be checked.") for feat in featErrors: msgLogInstance.logMessage("Feature id: %d" % feat.id()) msgLogInstance.logMessage("End of features to be checked.") else: features_ids = [] for feat in featErrors: features_ids.append(unicode(feat.id())) erroneous_ids = ', '.join(features_ids) err_msg = "The following features IDs couldn't be calculated due to conversion error: %s" % erroneous_ids self.iface.messageBar().pushMessage("Errors", err_msg) if len(points): crs = self.iface.mapCanvas().mapRenderer().destinationCrs() if not crs.isValid(): crs = None fields = QgsFields() fields.append(QgsField("ID", QVariant.Int)) outFeat.setFields(fields) check = QFile(self.shapefileName) if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName): return writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fields, QGis.WKBPoint, crs) idVar = 0 count = 70.00 add = (100.00 - 70.00) / len(points) for i in points: outFeat.setGeometry(i) outFeat.setAttribute(0, idVar) writer.addFeature(outFeat) idVar = idVar + 1 count = count + add self.progressBar.setValue(count) del writer return True return False
def testDefaultLayerOptions(self): """ Test retrieving default layer options for a format """ # NOTE - feel free to adapt these if the defaults change! options = QgsVectorFileWriter.defaultLayerOptions('not a format') self.assertEqual(options, []) options = QgsVectorFileWriter.defaultLayerOptions('ESRI Shapefile') self.assertEqual(options, ['RESIZE=NO']) options = QgsVectorFileWriter.defaultLayerOptions('GML') self.assertEqual(options, [])
def testGeoPackage(self): '''Test GeoPackage''' layer = QgsVectorLayer(os.path.join(os.path.dirname(__file__), "data","airports.gpkg"), "test", "ogr") self.assertTrue(layer.isValid()) filepath = os.path.join(tempfile.mkdtemp(), str(time.time()) + ".gpkg") QgsVectorFileWriter.writeAsVectorFormat(layer, filepath, 'utf-8', layer.crs(), 'GPKG') layer = QgsVectorLayer(filepath, "test", "ogr") self.assertTrue(layer.isValid())
def conversion(input_name,output_name,input_json,output_json): vlayer = QgsVectorLayer(input_name,'shp','ogr') error=QW.writeAsVectorFormat(vlayer, input_json,'utf-8',None,'GeoJSON') if error == QW.NoError: print "succeed in json conversion" convert(input_json+'.geojson',output_json+'.geojson') jlayer = QgsVectorLayer(output_json+'.geojson','json','ogr') err_shp = QW.writeAsVectorFormat(jlayer, output_name, "utf-8", None, "ESRI Shapefile") if error == QW.NoError: print "succeed in shp conversion"
def getOgrCompatibleSource(self, parameter_name, parameters, context, feedback, executing): """ Interprets a parameter as an OGR compatible source and layer name :param executing: """ if not executing and parameter_name in parameters and isinstance( parameters[parameter_name], QgsProcessingFeatureSourceDefinition): # if not executing, then we throw away all 'selected features only' settings # since these have no meaning for command line gdal use, and we don't want to force # an export of selected features only to a temporary file just to show the command! parameters = {parameter_name: parameters[parameter_name].source} input_layer = self.parameterAsVectorLayer(parameters, parameter_name, context) ogr_data_path = None ogr_layer_name = None if input_layer is None or input_layer.dataProvider().name( ) == 'memory': if executing: # parameter is not a vector layer - try to convert to a source compatible with OGR # and extract selection if required ogr_data_path = self.parameterAsCompatibleSourceLayerPath( parameters, parameter_name, context, QgsVectorFileWriter.supportedFormatExtensions(), feedback=feedback) ogr_layer_name = GdalUtils.ogrLayerName(ogr_data_path) else: #not executing - don't waste time converting incompatible sources, just return dummy strings #for the command preview (since the source isn't compatible with OGR, it has no meaning anyway and can't #be run directly in the command line) ogr_data_path = 'path_to_data_file' ogr_layer_name = 'layer_name' elif input_layer.dataProvider().name() == 'ogr': if executing and isinstance( parameters[parameter_name], QgsProcessingFeatureSourceDefinition ) and parameters[parameter_name].selectedFeaturesOnly: # parameter is a vector layer, with OGR data provider # so extract selection if required ogr_data_path = self.parameterAsCompatibleSourceLayerPath( parameters, parameter_name, context, QgsVectorFileWriter.supportedFormatExtensions(), feedback=feedback) parts = QgsProviderRegistry.instance().decodeUri( 'ogr', ogr_data_path) ogr_data_path = parts['path'] if 'layerName' in parts and parts['layerName']: ogr_layer_name = parts['layerName'] else: ogr_layer_name = GdalUtils.ogrLayerName(ogr_data_path) else: #either not using the selection, or #not executing - don't worry about 'selected features only' handling. It has no meaning #for the command line preview since it has no meaning outside of a QGIS session! ogr_data_path = GdalUtils.ogrConnectionStringAndFormatFromLayer( input_layer)[0] ogr_layer_name = GdalUtils.ogrLayerName( input_layer.dataProvider().dataSourceUri()) else: # vector layer, but not OGR - get OGR compatible path # TODO - handle "selected features only" mode!! ogr_data_path = GdalUtils.ogrConnectionStringFromLayer(input_layer) ogr_layer_name = GdalUtils.ogrLayerName( input_layer.dataProvider().dataSourceUri()) return ogr_data_path, ogr_layer_name
def create_preview_group( group_name: str, images: List[dict], footprints_filename=None, catalog_layer_name=None, tile_service: str = "xyz", search_query: str = None, sort_order: Tuple[str, str] = None, ) -> None: if tile_service.lower() not in ["wmts", "xyz"]: log.debug("Incorrect tile service passed for preview group: " f"{tile_service} (must be wmts or xyz)") return item_ids = [f"{img['properties'][ITEM_TYPE]}:{img[ID]}" for img in images] uri = tile_service_data_src_uri(item_ids, service=tile_service) if uri: log.debug(f"Tile datasource URI:\n{uri}") rlayer = QgsRasterLayer(uri, "Image previews", "wms") rlayer.setCustomProperty(PLANET_PREVIEW_ITEM_IDS, json.dumps(item_ids)) if tile_service == "xyz" and catalog_layer_name is not None: url = uri.split("url=")[-1] s = QSettings() s.setValue(f"qgis/connections-xyz/{catalog_layer_name}/username", "") s.setValue(f"qgis/connections-xyz/{catalog_layer_name}/password", "") s.setValue(f"qgis/connections-xyz/{catalog_layer_name}/authcfg", "") s.setValue( f"qgis/connections-xyz/{catalog_layer_name}/url", url.replace(PlanetClient.getInstance().api_key(), ""), ) else: log.debug("No tile URI for preview group") return vlayer = None if images: vlayer = create_preview_vector_layer(images[0]) vlayer.startEditing() dp = vlayer.dataProvider() fields: List[QgsField] = vlayer.fields() for img in images: feat = QgsFeature() feat.setFields(fields) qgs_geom = qgsgeometry_from_geojson(img["geometry"]) feat.setGeometry(qgs_geom) f_names = [f.name() for f in fields] if "item_id" in f_names: feat["item_id"] = img[ID] if search_query and "search_query" in f_names: feat["search_query"] = json.dumps(search_query) if sort_order and "sort_order" in f_names and len(sort_order) > 1: feat["sort_order"] = " ".join(sort_order) props: dict = img["properties"] for k, v in props.items(): if k in f_names: feat[k] = v dp.addFeature(feat) vlayer.commitChanges() if footprints_filename: QgsVectorFileWriter.writeAsVectorFormat(vlayer, footprints_filename, "UTF-8") gpkglayer = QgsVectorLayer(footprints_filename, "Footprints") gpkglayer.setRenderer(vlayer.renderer().clone()) vlayer = gpkglayer QgsProject.instance().addMapLayer(vlayer, False) # noinspection PyArgumentList QgsProject.instance().addMapLayer(rlayer, False) # noinspection PyArgumentList root: QgsLayerTree = QgsProject.instance().layerTreeRoot() group = root.insertGroup(0, f"{group_name} {tile_service.upper()} preview") if vlayer: group.addLayer(vlayer) group.addLayer(rlayer) if vlayer: iface.setActiveLayer(vlayer)
def runAndCreateLayer(parent): geomDialog = QgsNewVectorLayerDialog(parent) if (geomDialog.exec_() == QDialog.Rejected): return "" geometrytype = geomDialog.selectedType() fileformat = geomDialog.selectedFileFormat() enc = geomDialog.selectedFileEncoding() crsId = geomDialog.selectedCrsId() print(QString("New file format will be: %1").arg(fileformat)) attributes = dict() geomDialog.attributes(attributes) settings = QSettings() lastUsedDir = settings.value("/UI/lastVectorFileFilterDir", QDir.homePath()).toString() filterString = QgsVectorFileWriter.filterForDriver(fileformat) fileName = QFileDialog.getSaveFileName(parent, "Save layer as...", lastUsedDir, filterString) if (fileName.isNull()): return "" if (fileformat == "ESRI Shapefile" and not fileName.endsWith(".shp", Qt.CaseInsensitive)): fileName += ".shp" settings.setValue("/UI/lastVectorFileFilterDir", QFileInfo(fileName).absolutePath()) settings.setValue("/UI/encoding", enc) #try to create the new layer with OGRProvider instead of QgsVectorFileWriter pReg = QgsProviderRegistry.instance() ogrlib = pReg.library("ogr") # load the data provider myLib = QLibrary(ogrlib) loaded = myLib.load() constructionLineLayer = None mapUnits = define._canvas.mapUnits() layerName = String.QString2Str(fileName).split("\\")[-1] path = "memory" selectedCrs = geomDialog.selectedCrs() if geometrytype == QGis.Line: # if mapUnits == QGis.Meters: constructionLineLayer = QgsVectorLayer( "linestring?crs=%s" % selectedCrs.authid(), layerName, path) # else: # constructionLineLayer = QgsVectorLayer("linestring?crs=%s"%define._latLonCrs.authid (), layerName, path) elif geometrytype == QGis.Polygon: # if mapUnits == QGis.Meters: constructionLineLayer = QgsVectorLayer( "polygon?crs=%s" % selectedCrs.authid(), layerName, path) # else: # constructionLineLayer = QgsVectorLayer("polygon?crs=%s"%define._latLonCrs.authid (), layerName, path) elif geometrytype == QGis.Point: # if mapUnits == QGis.Meters: constructionLineLayer = QgsVectorLayer( "Point?crs=%s" % selectedCrs.authid(), layerName, path) # else: # constructionLineLayer = QgsVectorLayer("Point?crs=%s"%define._latLonCrs.authid (), layerName, path) fieldList = [] for key in attributes.iterkeys(): fieldList.append(QgsField(key, attributes[key][0])) constructionLineLayer.startEditing() constructionLineLayer.dataProvider().addAttributes(fieldList) constructionLineLayer.commitChanges() er = QgsVectorFileWriter.writeAsVectorFormat( constructionLineLayer, fileName, "utf-8", constructionLineLayer.crs()) constructionLineLayer = QgsVectorLayer(fileName, layerName, "ogr") QgisHelper.appendToCanvas(define._canvas, [constructionLineLayer], "NewLayers") # if ( loaded ): # print( "ogr provider loaded" ) # # typedef bool ( *createEmptyDataSourceProc )( const QString&, const QString&, const QString&, QGis::WkbType, # const QList< QPair<QString, QString> >&, const QgsCoordinateReferenceSystem * ) # createEmptyDataSourceProc createEmptyDataSource = ( createEmptyDataSourceProc ) cast_to_fptr( myLib.resolve( "createEmptyDataSource" ) ) # if ( createEmptyDataSource ) # { # if ( geometrytype not = QGis::WKBUnknown ) # { # QgsCoordinateReferenceSystem srs = QgsCRSCache::instance().crsBySrsId( crsId ) # if ( not createEmptyDataSource( fileName, fileformat, enc, geometrytype, attributes, &srs ) ) # { # return QString::null # } # } # else # { # QgsDebugMsg( "geometry type not recognised" ) # return QString::null # } # } # else # { # QgsDebugMsg( "Resolving newEmptyDataSource(...) failed" ) # return QString::null # } # } # # if ( pEnc ) # *pEnc = enc return fileName
def ogrConnectionStringAndFormat(uri, context): """Generates OGR connection string and format string from layer source Returned values are a tuple of the connection string and format string """ ogrstr = None format = None layer = QgsProcessingUtils.mapLayerFromString(uri, context, False) if layer is None: path, ext = os.path.splitext(uri) format = QgsVectorFileWriter.driverForExtension(ext) return '"' + uri + '"', '"' + format + '"' provider = layer.dataProvider().name() if provider == 'spatialite': # dbname='/geodata/osm_ch.sqlite' table="places" (Geometry) sql= regex = re.compile("dbname='(.+)'") r = regex.search(str(layer.source())) ogrstr = r.groups()[0] format = 'SQLite' elif provider == 'postgres': # dbname='ktryjh_iuuqef' host=spacialdb.com port=9999 # user='******' password='******' sslmode=disable # key='gid' estimatedmetadata=true srid=4326 type=MULTIPOLYGON # table="t4" (geom) sql= dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri()) conninfo = dsUri.connectionInfo() conn = None ok = False while not conn: try: conn = psycopg2.connect(dsUri.connectionInfo()) except psycopg2.OperationalError: (ok, user, passwd) = QgsCredentials.instance().get( conninfo, dsUri.username(), dsUri.password()) if not ok: break dsUri.setUsername(user) dsUri.setPassword(passwd) if not conn: raise RuntimeError( 'Could not connect to PostgreSQL database - check connection info' ) if ok: QgsCredentials.instance().put(conninfo, user, passwd) ogrstr = "PG:%s" % dsUri.connectionInfo() format = 'PostgreSQL' elif provider == "oracle": # OCI:user/password@host:port/service:table dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri()) ogrstr = "OCI:" if dsUri.username() != "": ogrstr += dsUri.username() if dsUri.password() != "": ogrstr += "/" + dsUri.password() delim = "@" if dsUri.host() != "": ogrstr += delim + dsUri.host() delim = "" if dsUri.port() != "" and dsUri.port() != '1521': ogrstr += ":" + dsUri.port() ogrstr += "/" if dsUri.database() != "": ogrstr += dsUri.database() elif dsUri.database() != "": ogrstr += delim + dsUri.database() if ogrstr == "OCI:": raise RuntimeError( 'Invalid oracle data source - check connection info') ogrstr += ":" if dsUri.schema() != "": ogrstr += dsUri.schema() + "." ogrstr += dsUri.table() format = 'OCI' else: ogrstr = str(layer.source()).split("|")[0] path, ext = os.path.splitext(ogrstr) format = QgsVectorFileWriter.driverForExtension(ext) return '"' + ogrstr + '"', '"' + format + '"'
def accept(self, *args, **kwargs): if not self.validate(): return False try: # disable form via a frame, this will still allow interaction with the message bar self.stackedWidget.setDisabled(True) # clean gui and Qgis messagebars self.cleanMessageBars(True) # self.iface.messageBar().clearWidgets() # Change cursor to Wait cursor QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) self.iface.mainWindow().statusBar().showMessage('Processing {}'.format(self.windowTitle())) self.send_to_messagebar("Please wait.. QGIS will be locked... See log panel for progress.", level=Qgis.Warning, duration=0, addToLog=False, core_QGIS=False, showLogPanel=True) gp_layer_name = '' LOGGER.info('{st}\nProcessing {}'.format(self.windowTitle(), st='*' * 50)) # Add settings to log settingsStr = 'Parameters:---------------------------------------' if self.optFile.isChecked(): settingsStr += '\n {:30}\t{}'.format('File:', self.lneInCSVFile.text()) settingsStr += '\n {:30}\t{}, {}'.format('Geometry Fields:', self.cboXField.currentText(), self.cboYField.currentText()) settingsStr += '\n {:30}\t{} - {}'.format('CSV Coordinate System:', self.qgsCRScsv.crs().authid(), self.qgsCRScsv.crs().description()) else: if self.chkUseSelected.isChecked(): settingsStr += '\n {:30}\t{} with {} selected features'.format('Layer:', self.mcboTargetLayer.currentLayer().name(), self.mcboTargetLayer.currentLayer().selectedFeatureCount()) else: settingsStr += '\n {:30}\t{}'.format('Layer:', self.mcboTargetLayer.currentLayer().name()) crs_units = QgsUnitTypes.toString(self.mCRSoutput.crs().mapUnits()) settingsStr += '\n {:30}\t{} {}'.format('Thinning Distance:', self.dsbThinDist.value(),crs_units) settingsStr += '\n {:30}\t{} {}'.format("Aggregate Distance:", self.dsbAggregateDist.value(),crs_units) settingsStr += '\n {:30}\t{} {}'.format("Buffer Distance:", self.dsbBufferDist.value(),crs_units) settingsStr += '\n {:30}\t{} {}'.format("Shrink Distance:", self.dsbShrinkDist.value(),crs_units) settingsStr += '\n {:30}\t{}'.format('Output Polygon Shapefile:', self.lneSavePolyFile.text()) if self.lneSavePointsFile.text() == '': settingsStr += '\n {:30}\t{}'.format('Saved Points Shapefile:', self.lneSavePointsFile.text()) settingsStr += '\n {:30}\t{} - {}\n\n'.format('Output Projected Coordinate System:', self.mCRSoutput.crs().authid(), self.mCRSoutput.crs().description()) LOGGER.info(settingsStr) stepTime = time.time() if self.optFile.isChecked(): in_epsg = int(self.qgsCRScsv.crs().authid().replace('EPSG:','')) in_crs = self.qgsCRScsv.crs() else: in_epsg =self.mcboTargetLayer.currentLayer().crs().authid().replace('EPSG:','') in_crs = self.mcboTargetLayer.currentLayer().crs() out_epsg = int(self.mCRSoutput.crs().authid().replace('EPSG:','')) filePoly = None gdfPoints = None filePoints = None if self.optFile.isChecked(): if self.DEBUG: filePoints = os.path.join(TEMPDIR, os.path.splitext(os.path.basename(self.lneSavePolyFile.text()))[0] + '_table2pts.shp') if os.path.splitext(self.lneInCSVFile.text())[-1] == '.csv': gdfPoints, gdfPtsCrs = convert.convert_csv_to_points(self.lneInCSVFile.text() , out_shapefilename=filePoints, coord_columns=[self.cboXField.currentText(), self.cboYField.currentText()], coord_columns_epsg=in_epsg) elif os.path.splitext(self.lneInCSVFile.text())[-1] in ['.xls', '.xlsx', '.ods']: xls_file = pd.ExcelFile(self.lneInCSVFile.text()) pdfxls = xls_file.parse(self.sheet(), skiprows=self.linesToIgnore() - 1) del xls_file gdfPoints, gdfPtsCrs = convert.add_point_geometry_to_dataframe(pdfxls, coord_columns=[ self.cboXField.currentText(), self.cboYField.currentText()], coord_columns_epsg=in_epsg) del pdfxls LOGGER.info('{:<30} {d:<15} {}'.format('Add Geometry to Table','', d=str(timedelta(seconds=time.time() - stepTime)))) stepTime = time.time() if filePoints is not None: describe.save_geopandas_tofile(gdfPoints, filePoints) #, file_encoding=self.file_encoding) if self.DISP_TEMP_LAYERS and filePoints is not None: addVectorFileToQGIS(filePoints, layer_name=os.path.splitext(os.path.basename(filePoints))[0], group_layer_name='DEBUG', atTop=True) else: layerPts = self.mcboTargetLayer.currentLayer() if layerPts.providerType() == 'delimitedtext' or \ os.path.splitext(get_layer_source(layerPts))[-1] == '.vrt' or \ self.chkUseSelected.isChecked() or self.optFile.isChecked(): filePoints = os.path.join(TEMPDIR, "{}_points.shp".format(layerPts.name())) if self.chkUseSelected.isChecked(): filePoints = os.path.join(TEMPDIR, "{}_selected_points.shp".format(layerPts.name())) if os.path.exists(filePoints): removeFileFromQGIS(filePoints) ptsLayer = copyLayerToMemory(layerPts, layerPts.name() + "_memory", bAddUFI=True, bOnlySelectedFeat=self.chkUseSelected.isChecked()) _writer = QgsVectorFileWriter.writeAsVectorFormat(ptsLayer, filePoints, "utf-8", self.mCRSoutput.crs(), driverName="ESRI Shapefile") LOGGER.info('{:<30} {d:<15} {}'.format('Save layer/selection to file',filePoints, d=str(timedelta(seconds=time.time() - stepTime) ))) stepTime = time.time() del ptsLayer if self.DISP_TEMP_LAYERS: addVectorFileToQGIS(filePoints, layer_name=os.path.splitext(os.path.basename(filePoints))[0], group_layer_name='DEBUG', atTop=True) else: filePoints = get_layer_source(layerPts) if gdfPoints is None: ptsDesc = describe.VectorDescribe(filePoints) gdfPtsCrs = ptsDesc.crs gdfPoints = ptsDesc.open_geo_dataframe() if in_crs.authid() != self.mCRSoutput.crs().authid(): gdfPoints = gdfPoints.to_crs(epsg=out_epsg) gdfPtsCrs = pyprecag_crs.crs() gdfPtsCrs.getFromEPSG(out_epsg) LOGGER.info('{:<30} {d:<15} {} to {}'.format('Reproject points', in_crs.authid(), self.mCRSoutput.crs().authid(), d=str(timedelta(seconds=time.time() - stepTime)))) if self.DEBUG: filePoints = os.path.join(TEMPDIR, os.path.basename(self.lneSavePolyFile.text().replace('.csv', '_ptsprj.shp'))) removeFileFromQGIS(filePoints) describe.save_geopandas_tofile(gdfPoints, filePoints) if self.DISP_TEMP_LAYERS: if self.DEBUG: addVectorFileToQGIS(filePoints, layer_name=os.path.splitext(os.path.basename(filePoints))[0], group_layer_name='DEBUG', atTop=True) else: addVectorFileToQGIS(filePoints, layer_name=os.path.splitext(os.path.basename(filePoints))[0], atTop=True) stepTime = time.time() result = processing.create_polygon_from_point_trail(gdfPoints, gdfPtsCrs, out_filename=self.lneSavePolyFile.text(), thin_dist_m=self.dsbThinDist.value(), aggregate_dist_m=self.dsbAggregateDist.value(), buffer_dist_m=self.dsbBufferDist.value(), shrink_dist_m=self.dsbShrinkDist.value()) addVectorFileToQGIS(self.lneSavePolyFile.text(), atTop=True) self.cleanMessageBars(True) self.stackedWidget.setDisabled(False) QApplication.restoreOverrideCursor() self.iface.messageBar().popWidget() self.iface.mainWindow().statusBar().clearMessage() if result is not None: self.fraMain.setDisabled(False) self.send_to_messagebar(result, level=Qgis.Warning, duration=0, addToLog=False) return False # leave dialog open return super(PointTrailToPolygonDialog, self).accept(*args, **kwargs) except Exception as err: QApplication.restoreOverrideCursor() self.iface.mainWindow().statusBar().clearMessage() self.cleanMessageBars(True) self.stackedWidget.setDisabled(False) self.send_to_messagebar(str(err), level=Qgis.Critical, duration=0, addToLog=True, core_QGIS=False, showLogPanel=True, exc_info=sys.exc_info()) return False # leave dialog open
def create_conv_runoff(self): QSWATMOD_path_dict = self.dirs_and_paths() # Create swatmf_results tree inside root = QgsProject.instance().layerTreeRoot() if root.findGroup("SWAT-MODFLOW"): SM = root.findGroup("SWAT-MODFLOW") SM.insertGroup(0, "Scenarios") scenario_tree = root.findGroup("Scenarios") scenario_tree.addGroup("Pumping from MODFLOW") input1 = QgsProject.instance().mapLayersByName("sub (SWAT)")[0] # Copy sub shapefile to be under "p from mf" name = "conv_runoff" name_ext = "conv_runoff.shp" output_dir = QSWATMOD_path_dict['Scenarios'] # Check if there is an exsting mf_head shapefile # if not any(lyr.name() == ("conv_runoff") for lyr in QgsProject.instance().mapLayers().values()): conv_runoff_shapfile = os.path.join(output_dir, name_ext) QgsVectorFileWriter.writeAsVectorFormat( input1, conv_runoff_shapfile, "utf-8", input1.crs(), "ESRI Shapefile") layer = QgsVectorLayer(conv_runoff_shapfile, '{0}'.format("conv_runoff"), 'ogr') # Put in the group # root = QgsProject.instance().layerTreeRoot() # conv_runoff = root.findGroup("Pumping from MODFLOW") QgsProject.instance().addMapLayer(layer, False) p_mf_tree = root.findGroup("Pumping from MODFLOW") p_mf_tree.insertChildNode(0, QgsLayerTreeLayer(layer)) input2 = QgsProject.instance().mapLayersByName("conv_runoff")[0] fields = input2.dataProvider() # DEBUG: fixed: AttributeError: 'QgsVectorDataProvider' object has no attribute 'indexFromName' fdname = [ fields.fields().indexFromName(field.name()) for field in fields.fields() if not field.name() == 'Subbasin' ] fields.deleteAttributes(fdname) input2.updateFields() cvy = QgsField('Conveyance', QVariant.Double, 'double', 20, 5) runoff = QgsField('Runoff', QVariant.Double, 'double', 20, 5) fields.addAttributes([cvy, runoff]) input2.updateFields() cvy_idx = fields.fields().indexFromName('Conveyance') runoff_idx = fields.fields().indexFromName('Runoff') feats = input2.getFeatures() input2.startEditing() for feat in feats: # attr = feat.attributes() # this can be used for changing value based on value from other column input2.changeAttributeValue(feat.id(), cvy_idx, 1) input2.changeAttributeValue(feat.id(), runoff_idx, 0.05) input2.commitChanges() # msgBox = QMessageBox() # msgBox.setWindowIcon(QtGui.QIcon(':/QSWATMOD2/pics/sm_icon.png')) msgBox.setWindowTitle("Created!") msgBox.setText("'conv_runoff.shp' file has been created!") msgBox.exec_() # FIXME, TODO: require escapting code to check *.wel file. # Find *.wel file and read number of grid cells and set maximum grid cells try: for filename in glob.glob(str(QSWATMOD_path_dict['SMfolder'])+"/*.wel"): with open(filename, "r") as f: data = [] for line in f.readlines(): if not line.startswith("#"): data.append(line.replace('\n', '').split()) wel_max = int(data[0][0]) self.dlg.spinBox_irrig_mf.setMaximum(wel_max) except: msgBox.setWindowTitle("No Well package found!") msgBox.setText("Please, provide a well package to your MODFLOW model first!") self.dlg.spinBox_irrig_mf.setEnabled(False) msgBox.exec_() else: msgBox.setWindowTitle("Error!") msgBox.setText("Your project couldn't be read.\nPlease, go back to the linking process!") msgBox.exec_()
def getFileFilter(param): """ Returns a suitable file filter pattern for the specified parameter definition :param param: :return: """ if param.type() == 'layer': vectors = QgsProviderRegistry.instance().fileVectorFilters().split( ';;') vectors.pop(0) rasters = QgsProviderRegistry.instance().fileRasterFilters().split( ';;') rasters.pop(0) filters = set(vectors + rasters) filters = sorted(filters) return tr('All files (*.*)') + ';;' + ";;".join(filters) elif param.type() == 'multilayer': if param.layerType() == QgsProcessing.TypeRaster: exts = QgsRasterFileWriter.supportedFormatExtensions() elif param.layerType() == QgsProcessing.TypeFile: return tr('All files (*.*)', 'QgsProcessingParameterMultipleLayers') else: exts = QgsVectorFileWriter.supportedFormatExtensions() for i in range(len(exts)): exts[i] = tr('{0} files (*.{1})', 'QgsProcessingParameterMultipleLayers').format( exts[i].upper(), exts[i].lower()) return tr('All files (*.*)') + ';;' + ';;'.join(exts) elif param.type() == 'raster': return QgsProviderRegistry.instance().fileRasterFilters() elif param.type() == 'rasterDestination': if param.provider() is not None: exts = param.provider().supportedOutputRasterLayerExtensions() else: exts = QgsRasterFileWriter.supportedFormatExtensions() for i in range(len(exts)): exts[i] = tr('{0} files (*.{1})', 'ParameterRaster').format(exts[i].upper(), exts[i].lower()) return ';;'.join(exts) + ';;' + tr('All files (*.*)') elif param.type() in ('sink', 'vectorDestination'): if param.provider() is not None: exts = param.provider().supportedOutputVectorLayerExtensions() else: exts = QgsVectorFileWriter.supportedFormatExtensions() for i in range(len(exts)): exts[i] = tr('{0} files (*.{1})', 'ParameterVector').format(exts[i].upper(), exts[i].lower()) return ';;'.join(exts) + ';;' + tr('All files (*.*)') elif param.type() == 'source': return QgsProviderRegistry.instance().fileVectorFilters() elif param.type() == 'vector': return QgsProviderRegistry.instance().fileVectorFilters() elif param.type() == 'fileDestination': return param.fileFilter() + ';;' + tr('All files (*.*)') if param.defaultFileExtension(): return tr( 'Default extension') + ' (*.' + param.defaultFileExtension() + ')' else: return ''
def testWriteWithBinaryField(self): """ Test writing with a binary field :return: """ basetestpath = tempfile.mkdtemp() tmpfile = os.path.join(basetestpath, 'binaryfield.sqlite') ds = ogr.GetDriverByName('SQLite').CreateDataSource(tmpfile) lyr = ds.CreateLayer('test', geom_type=ogr.wkbPoint, options=['FID=fid']) lyr.CreateField(ogr.FieldDefn('strfield', ogr.OFTString)) lyr.CreateField(ogr.FieldDefn('intfield', ogr.OFTInteger)) lyr.CreateField(ogr.FieldDefn('binfield', ogr.OFTBinary)) lyr.CreateField(ogr.FieldDefn('binfield2', ogr.OFTBinary)) f = None ds = None vl = QgsVectorLayer(tmpfile) self.assertTrue(vl.isValid()) # check that 1 of its fields is a bool fields = vl.fields() self.assertEqual( fields.at(fields.indexFromName('binfield')).type(), QVariant.ByteArray) dp = vl.dataProvider() f = QgsFeature(fields) bin_1 = b'xxx' bin_2 = b'yyy' bin_val1 = QByteArray(bin_1) bin_val2 = QByteArray(bin_2) f.setAttributes([1, 'str', 100, bin_val1, bin_val2]) self.assertTrue(dp.addFeature(f)) # write a gpkg package with a binary field filename = os.path.join(str(QDir.tempPath()), 'with_bin_field') rc, errmsg = QgsVectorFileWriter.writeAsVectorFormat( vl, filename, 'utf-8', vl.crs(), 'GPKG') self.assertEqual(rc, QgsVectorFileWriter.NoError) # open the resulting geopackage vl = QgsVectorLayer(filename + '.gpkg', '', 'ogr') self.assertTrue(vl.isValid()) fields = vl.fields() # test type of converted field idx = fields.indexFromName('binfield') self.assertEqual(fields.at(idx).type(), QVariant.ByteArray) idx2 = fields.indexFromName('binfield2') self.assertEqual(fields.at(idx2).type(), QVariant.ByteArray) # test values self.assertEqual(vl.getFeature(1).attributes()[idx], bin_val1) self.assertEqual(vl.getFeature(1).attributes()[idx2], bin_val2) del vl os.unlink(filename + '.gpkg')
def initialize(): icon = QgsApplication.getThemeIcon("/processingAlgorithm.svg") ProcessingConfig.settingIcons['General'] = icon ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.SHOW_DEBUG_IN_DIALOG, ProcessingConfig.tr('Show extra info in Log panel'), True)) ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.KEEP_DIALOG_OPEN, ProcessingConfig.tr( 'Keep dialog open after running an algorithm'), True)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.USE_FILENAME_AS_LAYER_NAME, ProcessingConfig.tr('Use filename as layer name'), False)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.SHOW_RECENT_ALGORITHMS, ProcessingConfig.tr('Show recently executed algorithms'), True)) ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.SHOW_PROVIDERS_TOOLTIP, ProcessingConfig.tr( 'Show tooltip when there are disabled providers'), True)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.OUTPUT_FOLDER, ProcessingConfig.tr('Output folder'), defaultOutputFolder(), valuetype=Setting.FOLDER)) ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.SHOW_CRS_DEF, ProcessingConfig.tr( 'Show layer CRS definition in selection boxes'), True)) ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.WARN_UNMATCHING_CRS, ProcessingConfig.tr( "Warn before executing if layer CRS's do not match"), True)) ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.WARN_UNMATCHING_EXTENT_CRS, ProcessingConfig. tr("Warn before executing if extent CRS might not match layers CRS" ), True)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.RASTER_STYLE, ProcessingConfig.tr('Style for raster layers'), '', valuetype=Setting.FILE)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.VECTOR_POINT_STYLE, ProcessingConfig.tr('Style for point layers'), '', valuetype=Setting.FILE)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.VECTOR_LINE_STYLE, ProcessingConfig.tr('Style for line layers'), '', valuetype=Setting.FILE)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.VECTOR_POLYGON_STYLE, ProcessingConfig.tr('Style for polygon layers'), '', valuetype=Setting.FILE)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.PRE_EXECUTION_SCRIPT, ProcessingConfig.tr('Pre-execution script'), '', valuetype=Setting.FILE)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.POST_EXECUTION_SCRIPT, ProcessingConfig.tr('Post-execution script'), '', valuetype=Setting.FILE)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.RECENT_ALGORITHMS, ProcessingConfig.tr('Recent algorithms'), '', hidden=True)) ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.MODELS_SCRIPTS_REPO, ProcessingConfig.tr('Scripts and models repository'), 'https://raw.githubusercontent.com/qgis/QGIS-Processing/master' )) invalidFeaturesOptions = [ ProcessingConfig.tr('Do not filter (better performance)'), ProcessingConfig.tr('Ignore features with invalid geometries'), ProcessingConfig.tr( 'Stop algorithm execution when a geometry is invalid') ] ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.FILTER_INVALID_GEOMETRIES, ProcessingConfig.tr('Invalid features filtering'), invalidFeaturesOptions[2], valuetype=Setting.SELECTION, options=invalidFeaturesOptions)) extensions = QgsVectorFileWriter.supportedFormatExtensions() ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.DEFAULT_OUTPUT_VECTOR_LAYER_EXT, ProcessingConfig.tr('Default output vector layer extension'), extensions[0], valuetype=Setting.SELECTION, options=extensions)) extensions = QgsRasterFileWriter.supportedFormatExtensions() ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.DEFAULT_OUTPUT_RASTER_LAYER_EXT, ProcessingConfig.tr('Default output raster layer extension'), extensions[0], valuetype=Setting.SELECTION, options=extensions))
def processAlgorithm(self, parameters, context, feedback): """ Here is where the processing itself takes place. """ outflowPoints = self.parameterAsVectorLayer(parameters, self.INPUT_POINTS, context) input_dem = self.parameterAsRasterLayer(parameters, self.INPUT_DEM, context) out_folder = self.parameterAsString(parameters, self.OUTPUT_FOLDER, context) total_points = outflowPoints.featureCount() # Iterate over point features for i, pnt in enumerate(outflowPoints.getFeatures()): # Get x and y coordinate from point feature geom = pnt.geometry() p = geom.asPoint() x = p.x() y = p.y() feedback.pushInfo( 'Creating upslope area for point ({:.2f}, {:.2f}) - {} of {}'. format(x, y, i + 1, total_points)) feedback.setProgress(i / total_points * 100.) # Calculate catchment raster from point feature catchraster = processing.run( "saga:upslopearea", { 'TARGET': None, 'TARGET_PT_X': x, 'TARGET_PT_Y': y, 'ELEVATION': input_dem, 'SINKROUTE': None, 'METHOD': 0, 'CONVERGE': 1.1, 'AREA': 'TEMPORARY_OUTPUT' }) # Polygonize raster catchment catchpoly = processing.run( "gdal:polygonize", { 'INPUT': catchraster['AREA'], 'BAND': 1, 'FIELD': 'DN', 'EIGHT_CONNECTEDNESS': False, 'OUTPUT': 'TEMPORARY_OUTPUT' }) # Select features having DN = 100 and export them to a SHP file catch_lyr = QgsVectorLayer(catchpoly['OUTPUT'], 'catchmments', 'ogr') catch_lyr.selectByExpression('"DN"=100') catch_filename = os.path.join(out_folder, 'area_{}'.format(i + 1)) # Save only selected features (last argument is onlySelected = True) QgsVectorFileWriter.writeAsVectorFormat(catch_lyr, catch_filename, 'UTF-8', outflowPoints.crs(), 'ESRI Shapefile', True) feedback.setProgress(100) return {self.OUTPUT_FOLDER: out_folder}
def testSupportedFormatExtensions(self): formats = QgsVectorFileWriter.supportedFormatExtensions() self.assertTrue('gpkg' in formats) self.assertFalse('exe' in formats) self.assertEqual(formats[0], 'shp')
def testOverwriteLayer(self): """Tests writing a layer with a field value converter.""" ml = QgsVectorLayer('Point?field=firstfield:int', 'test', 'memory') provider = ml.dataProvider() ft = QgsFeature() ft.setAttributes([1]) provider.addFeatures([ft]) options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = 'GPKG' options.layerName = 'test' filename = '/vsimem/out.gpkg' write_result = QgsVectorFileWriter.writeAsVectorFormat( ml, filename, options) self.assertEqual(write_result, QgsVectorFileWriter.NoError) ds = ogr.Open(filename, update=1) lyr = ds.GetLayerByName('test') self.assertIsNotNone(lyr) f = lyr.GetNextFeature() self.assertEqual(f['firstfield'], 1) ds.CreateLayer('another_layer') del f del lyr del ds caps = QgsVectorFileWriter.editionCapabilities(filename) self.assertTrue((caps & QgsVectorFileWriter.CanAddNewLayer)) self.assertTrue((caps & QgsVectorFileWriter.CanAppendToExistingLayer)) self.assertTrue( (caps & QgsVectorFileWriter.CanAddNewFieldsToExistingLayer)) self.assertTrue((caps & QgsVectorFileWriter.CanDeleteLayer)) self.assertTrue(QgsVectorFileWriter.targetLayerExists( filename, 'test')) self.assertFalse( QgsVectorFileWriter.areThereNewFieldsToCreate( filename, 'test', ml, [0])) # Test CreateOrOverwriteLayer ml = QgsVectorLayer('Point?field=firstfield:int', 'test', 'memory') provider = ml.dataProvider() ft = QgsFeature() ft.setAttributes([2]) provider.addFeatures([ft]) options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = 'GPKG' options.layerName = 'test' options.actionOnExistingFile = QgsVectorFileWriter.CreateOrOverwriteLayer filename = '/vsimem/out.gpkg' write_result = QgsVectorFileWriter.writeAsVectorFormat( ml, filename, options) self.assertEqual(write_result, QgsVectorFileWriter.NoError) ds = ogr.Open(filename) lyr = ds.GetLayerByName('test') self.assertIsNotNone(lyr) f = lyr.GetNextFeature() self.assertEqual(f['firstfield'], 2) # another_layer should still exist self.assertIsNotNone(ds.GetLayerByName('another_layer')) del f del lyr del ds # Test CreateOrOverwriteFile ml = QgsVectorLayer('Point?field=firstfield:int', 'test', 'memory') provider = ml.dataProvider() ft = QgsFeature() ft.setAttributes([3]) provider.addFeatures([ft]) options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = 'GPKG' options.layerName = 'test' filename = '/vsimem/out.gpkg' write_result = QgsVectorFileWriter.writeAsVectorFormat( ml, filename, options) self.assertEqual(write_result, QgsVectorFileWriter.NoError) ds = ogr.Open(filename) lyr = ds.GetLayerByName('test') self.assertIsNotNone(lyr) f = lyr.GetNextFeature() self.assertEqual(f['firstfield'], 3) # another_layer should no longer exist self.assertIsNone(ds.GetLayerByName('another_layer')) del f del lyr del ds # Test AppendToLayerNoNewFields ml = QgsVectorLayer('Point?field=firstfield:int&field=secondfield:int', 'test', 'memory') provider = ml.dataProvider() ft = QgsFeature() ft.setAttributes([4, -10]) provider.addFeatures([ft]) self.assertTrue( QgsVectorFileWriter.areThereNewFieldsToCreate( filename, 'test', ml, [0, 1])) options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = 'GPKG' options.layerName = 'test' options.actionOnExistingFile = QgsVectorFileWriter.AppendToLayerNoNewFields filename = '/vsimem/out.gpkg' write_result = QgsVectorFileWriter.writeAsVectorFormat( ml, filename, options) self.assertEqual(write_result, QgsVectorFileWriter.NoError) ds = ogr.Open(filename) lyr = ds.GetLayerByName('test') self.assertEqual(lyr.GetLayerDefn().GetFieldCount(), 1) self.assertIsNotNone(lyr) f = lyr.GetNextFeature() self.assertEqual(f['firstfield'], 3) f = lyr.GetNextFeature() self.assertEqual(f['firstfield'], 4) del f del lyr del ds # Test AppendToLayerAddFields ml = QgsVectorLayer('Point?field=firstfield:int&field=secondfield:int', 'test', 'memory') provider = ml.dataProvider() ft = QgsFeature() ft.setAttributes([5, -1]) provider.addFeatures([ft]) self.assertTrue( QgsVectorFileWriter.areThereNewFieldsToCreate( filename, 'test', ml, [0, 1])) options = QgsVectorFileWriter.SaveVectorOptions() options.driverName = 'GPKG' options.layerName = 'test' options.actionOnExistingFile = QgsVectorFileWriter.AppendToLayerAddFields filename = '/vsimem/out.gpkg' write_result = QgsVectorFileWriter.writeAsVectorFormat( ml, filename, options) self.assertEqual(write_result, QgsVectorFileWriter.NoError) ds = ogr.Open(filename) lyr = ds.GetLayerByName('test') self.assertEqual(lyr.GetLayerDefn().GetFieldCount(), 2) self.assertIsNotNone(lyr) f = lyr.GetNextFeature() self.assertEqual(f['firstfield'], 3) self.assertFalse(f.IsFieldSet('secondfield')) f = lyr.GetNextFeature() self.assertEqual(f['firstfield'], 4) self.assertFalse(f.IsFieldSet('secondfield')) f = lyr.GetNextFeature() self.assertEqual(f['firstfield'], 5) self.assertEqual(f['secondfield'], -1) del f del lyr del ds gdal.Unlink(filename)
def testWriteShapefileWithAttributeSubsets(self): """Tests writing subsets of attributes to files.""" ml = QgsVectorLayer(( 'Point?crs=epsg:4326&field=id:int&field=field1:int&field=field2:int&field=field3:int' ), 'test', 'memory') self.assertIsNotNone(ml, 'Provider not initialized') self.assertTrue(ml.isValid(), 'Source layer not valid') provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setGeometry(QgsGeometry.fromWkt('Point (1 2)')) ft.setAttributes([1, 11, 12, 13]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) # first write out with all attributes dest_file_name = os.path.join(str(QDir.tempPath()), 'all_attributes.shp') crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', attributes=[]) self.assertEqual(write_result, QgsVectorFileWriter.NoError) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') self.assertEqual(created_layer.fields().count(), 4) f = next(created_layer.getFeatures(QgsFeatureRequest())) self.assertEqual(f['id'], 1) self.assertEqual(f['field1'], 11) self.assertEqual(f['field2'], 12) self.assertEqual(f['field3'], 13) # now test writing out only a subset of attributes dest_file_name = os.path.join(str(QDir.tempPath()), 'subset_attributes.shp') write_result = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', attributes=[1, 3]) self.assertEqual(write_result, QgsVectorFileWriter.NoError) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') self.assertEqual(created_layer.fields().count(), 2) f = next(created_layer.getFeatures(QgsFeatureRequest())) self.assertEqual(f['field1'], 11) self.assertEqual(f['field3'], 13) # finally test writing no attributes dest_file_name = os.path.join(str(QDir.tempPath()), 'no_attributes.shp') write_result = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', skipAttributeCreation=True) self.assertEqual(write_result, QgsVectorFileWriter.NoError) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') # expect only a default 'FID' field for shapefiles self.assertEqual(created_layer.fields().count(), 1) self.assertEqual(created_layer.fields()[0].name(), 'FID') # in this case we also check that the geometry exists, to make sure feature has been correctly written # even without attributes f = next(created_layer.getFeatures(QgsFeatureRequest())) g = f.geometry() wkt = g.exportToWkt() expWkt = 'Point (1 2)' self.assertTrue( compareWkt(expWkt, wkt), "geometry not saved correctly when saving without attributes : mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)) self.assertEqual(f['FID'], 0)
def __init__(self, destination, encoding, fields, geometryType, crs, options=None): self.destination = destination self.isNotFileBased = False self.layer = None self.writer = None if encoding is None: settings = QSettings() encoding = settings.value('/Processing/encoding', 'System', type=str) if self.destination.startswith(self.MEMORY_LAYER_PREFIX): self.isNotFileBased = True uri = GEOM_TYPE_MAP[geometryType] + "?uuid=" + unicode( uuid.uuid4()) if crs.isValid(): uri += '&crs=' + crs.authid() fieldsdesc = [] for f in fields: qgsfield = _toQgsField(f) fieldsdesc.append( 'field=%s:%s' % (qgsfield.name(), TYPE_MAP_MEMORY_LAYER.get(qgsfield.type(), "string"))) if fieldsdesc: uri += '&' + '&'.join(fieldsdesc) self.layer = QgsVectorLayer(uri, self.destination, 'memory') self.writer = self.layer.dataProvider() elif self.destination.startswith(self.POSTGIS_LAYER_PREFIX): self.isNotFileBased = True uri = QgsDataSourceURI( self.destination[len(self.POSTGIS_LAYER_PREFIX):]) connInfo = uri.connectionInfo() (success, user, passwd) = QgsCredentials.instance().get(connInfo, None, None) if success: QgsCredentials.instance().put(connInfo, user, passwd) else: raise GeoAlgorithmExecutionException( "Couldn't connect to database") print uri.uri() try: db = postgis_utils.GeoDB(host=uri.host(), port=int(uri.port()), dbname=uri.database(), user=user, passwd=passwd) except postgis_utils.DbError as e: raise GeoAlgorithmExecutionException( "Couldn't connect to database:\n%s" % e.message) def _runSQL(sql): try: db._exec_sql_and_commit(unicode(sql)) except postgis_utils.DbError as e: raise GeoAlgorithmExecutionException( 'Error creating output PostGIS table:\n%s' % e.message) fields = [_toQgsField(f) for f in fields] fieldsdesc = ",".join( '%s %s' % (f.name(), TYPE_MAP_POSTGIS_LAYER.get(f.type(), "VARCHAR")) for f in fields) _runSQL("CREATE TABLE %s.%s (%s)" % (uri.schema(), uri.table().lower(), fieldsdesc)) if geometryType != QGis.WKBNoGeometry: _runSQL( "SELECT AddGeometryColumn('{schema}', '{table}', 'the_geom', {srid}, '{typmod}', 2)" .format(table=uri.table().lower(), schema=uri.schema(), srid=crs.authid().split(":")[-1], typmod=GEOM_TYPE_MAP[geometryType].upper())) self.layer = QgsVectorLayer(uri.uri(), uri.table(), "postgres") self.writer = self.layer.dataProvider() elif self.destination.startswith(self.SPATIALITE_LAYER_PREFIX): self.isNotFileBased = True uri = QgsDataSourceURI( self.destination[len(self.SPATIALITE_LAYER_PREFIX):]) print uri.uri() try: db = spatialite_utils.GeoDB(uri=uri) except spatialite_utils.DbError as e: raise GeoAlgorithmExecutionException( "Couldn't connect to database:\n%s" % e.message) def _runSQL(sql): try: db._exec_sql_and_commit(unicode(sql)) except spatialite_utils.DbError as e: raise GeoAlgorithmExecutionException( 'Error creating output Spatialite table:\n%s' % unicode(e)) fields = [_toQgsField(f) for f in fields] fieldsdesc = ",".join( '%s %s' % (f.name(), TYPE_MAP_SPATIALITE_LAYER.get(f.type(), "VARCHAR")) for f in fields) _runSQL("DROP TABLE IF EXISTS %s" % uri.table().lower()) _runSQL("CREATE TABLE %s (%s)" % (uri.table().lower(), fieldsdesc)) if geometryType != QGis.WKBNoGeometry: _runSQL( "SELECT AddGeometryColumn('{table}', 'the_geom', {srid}, '{typmod}', 2)" .format(table=uri.table().lower(), srid=crs.authid().split(":")[-1], typmod=GEOM_TYPE_MAP[geometryType].upper())) self.layer = QgsVectorLayer(uri.uri(), uri.table(), "spatialite") self.writer = self.layer.dataProvider() else: formats = QgsVectorFileWriter.supportedFiltersAndFormats() OGRCodes = {} for (key, value) in formats.items(): extension = unicode(key) extension = extension[extension.find('*.') + 2:] extension = extension[:extension.find(' ')] OGRCodes[extension] = value OGRCodes['dbf'] = "DBF file" extension = self.destination[self.destination.rfind('.') + 1:] if extension not in OGRCodes: extension = 'shp' self.destination = self.destination + '.shp' if geometryType == QGis.WKBNoGeometry: if extension == 'shp': extension = 'dbf' self.destination = self.destination[:self.destination. rfind('.')] + '.dbf' if extension not in self.nogeometry_extensions: raise GeoAlgorithmExecutionException( "Unsupported format for tables with no geometry") qgsfields = QgsFields() for field in fields: qgsfields.append(_toQgsField(field)) self.writer = QgsVectorFileWriter(self.destination, encoding, qgsfields, geometryType, crs, OGRCodes[extension])
def compute(self, bound, xOffset, yOffset, polygon): crs = None layer = ftools_utils.getMapLayerByName( unicode(self.inShape.currentText())) if self.angle.value() != 0.0: bound = self.initRotation(bound) if layer is None: crs = self.iface.mapCanvas().mapRenderer().destinationCrs() else: crs = layer.crs() if not crs.isValid(): crs = None fields = QgsFields() fields.append(QgsField("ID", QVariant.Int)) fieldCount = 1 if polygon: fields.append(QgsField("X_MIN", QVariant.Double)) fields.append(QgsField("X_MAX", QVariant.Double)) fields.append(QgsField("Y_MIN", QVariant.Double)) fields.append(QgsField("Y_MAX", QVariant.Double)) fieldCount = 5 check = QFile(self.shapefileName) if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName): return writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fields, QGis.WKBPolygon, crs) else: fields.append(QgsField("COORD", QVariant.Double)) fieldCount = 2 check = QFile(self.shapefileName) if check.exists(): if not QgsVectorFileWriter.deleteShapeFile(self.shapefileName): return writer = QgsVectorFileWriter(self.shapefileName, self.encoding, fields, QGis.WKBLineString, crs) outFeat = QgsFeature() outFeat.initAttributes(fieldCount) outFeat.setFields(fields) outGeom = QgsGeometry() idVar = 0 self.progressBar.setValue(0) if not polygon: # counters for progressbar - update every 5% count = 0 count_max = (bound.yMaximum() - bound.yMinimum()) / yOffset count_update = count_max * 0.10 y = bound.yMaximum() while y >= bound.yMinimum(): pt1 = QgsPoint(bound.xMinimum(), y) pt2 = QgsPoint(bound.xMaximum(), y) if self.angle.value() != 0.0: self.rotatePoint(pt1) self.rotatePoint(pt2) line = [pt1, pt2] outFeat.setGeometry(outGeom.fromPolyline(line)) outFeat.setAttribute(0, idVar) outFeat.setAttribute(1, y) writer.addFeature(outFeat) y = y - yOffset idVar = idVar + 1 count += 1 if int(math.fmod(count, count_update)) == 0: prog = int(count / count_max * 50) self.progressBar.setValue(prog) self.progressBar.setValue(50) # counters for progressbar - update every 5% count = 0 count_max = (bound.xMaximum() - bound.xMinimum()) / xOffset count_update = count_max * 0.10 x = bound.xMinimum() while x <= bound.xMaximum(): pt1 = QgsPoint(x, bound.yMaximum()) pt2 = QgsPoint(x, bound.yMinimum()) if self.angle.value() != 0.0: self.rotatePoint(pt1) self.rotatePoint(pt2) line = [pt1, pt2] outFeat.setGeometry(outGeom.fromPolyline(line)) outFeat.setAttribute(0, idVar) outFeat.setAttribute(1, x) writer.addFeature(outFeat) x = x + xOffset idVar = idVar + 1 count += 1 if int(math.fmod(count, count_update)) == 0: prog = 50 + int(count / count_max * 50) self.progressBar.setValue(prog) else: # counters for progressbar - update every 5% count = 0 count_max = (bound.yMaximum() - bound.yMinimum()) / yOffset count_update = count_max * 0.05 y = bound.yMaximum() while y >= bound.yMinimum(): x = bound.xMinimum() while x <= bound.xMaximum(): pt1 = QgsPoint(x, y) pt2 = QgsPoint(x + xOffset, y) pt3 = QgsPoint(x + xOffset, y - yOffset) pt4 = QgsPoint(x, y - yOffset) pt5 = QgsPoint(x, y) if self.angle.value() != 0.0: self.rotatePoint(pt1) self.rotatePoint(pt2) self.rotatePoint(pt3) self.rotatePoint(pt4) self.rotatePoint(pt5) polygon = [[pt1, pt2, pt3, pt4, pt5]] outFeat.setGeometry(outGeom.fromPolygon(polygon)) outFeat.setAttribute(0, idVar) outFeat.setAttribute(1, x) outFeat.setAttribute(2, x + xOffset) outFeat.setAttribute(3, y - yOffset) outFeat.setAttribute(4, y) writer.addFeature(outFeat) idVar = idVar + 1 x = x + xOffset y = y - yOffset count += 1 if int(math.fmod(count, count_update)) == 0: prog = int(count / count_max * 100) self.progressBar.setValue(100) del writer
def getSupportedOutputVectorLayerExtensions(self): exts = QgsVectorFileWriter.supportedFormatExtensions() if not self.hasGeometry(): exts = ['dbf'] + [ext for ext in exts if ext in NOGEOMETRY_EXTENSIONS] return exts
def link_drain(self): # Create Scenarios tree inside root = QgsProject.instance().layerTreeRoot() if not root.findGroup("Scenarios"): sm_tree = root.findGroup("SWAT-MODFLOW") sm_tree.addGroup("Scenarios") if not root.findGroup("Drains to SWAT Channels"): scenario_tree = root.findGroup("Scenarios") scenario_tree.addGroup("Drains to SWAT Channels") try: QSWATMOD_path_dict = self.dirs_and_paths() self.layer = QgsProject.instance().mapLayersByName("mf_grid (MODFLOW)")[0] input1 = QgsProject.instance().mapLayersByName("mf_grid (MODFLOW)")[0] provider = self.layer.dataProvider() # Find *.drn file and read number of grid cells for filename in glob.glob(str(QSWATMOD_path_dict['SMfolder'])+"/*.drn"): with open(filename, "r") as f: data = [] for line in f.readlines(): if not line.startswith("#"): data.append(line.replace('\n', '').split()) nDrain = int(data[0][0]) drn_lyr = [] drn_row = [] drn_col = [] # Skip two lines in Riv package and get row and col for i in range(2, nDrain+2): drn_lyr.append(int(data[i][0])) drn_row.append(int(data[i][1])) drn_col.append(int(data[i][2])) # Find grid cells according to the drnl package feats = self.layer.getFeatures() drn_matched = [] for f in feats: rowNo = f.attribute("row") colNo = f.attribute("col") for i in range(len(drn_row)): if ((rowNo == drn_row[i]) and (colNo == drn_col[i])): drn_matched.append(f.id()) self.layer.selectByIds(drn_matched) name_ext = "drain2sub.shp" output_dir = QSWATMOD_path_dict['Scenarios'] # Save just the selected features of the target layer drn_chn = os.path.join(output_dir, name_ext) QgsVectorFileWriter.writeAsVectorFormat( input1, drn_chn, "utf-8", input1.crs(), "ESRI Shapefile", 1) # Deselect the features self.layer.removeSelection() # Join sub and drn n2_ext = "drain2sub_f.shp" drn_chn_f = os.path.join(output_dir, n2_ext) # QgsVectorFileWriter.deleteShapeFile(irrig_mf_s) sub_shp = QgsProject.instance().mapLayersByName("sub (SWAT)")[0] processing.run( "qgis:joinattributesbylocation", drn_chn, sub_shp, ['intersects'],0,0,"sum,mean,min,max,median",0, drn_chn_f) # delete unnecessary fields layer_drn = QgsVectorLayer(drn_chn_f, '{0}'.format("drain2sub"), 'ogr') QgsProject.instance().addMapLayer(layer_drn, False) root = QgsProject.instance().layerTreeRoot() p_mf_tree = root.findGroup("Drains to SWAT Channels") p_mf_tree.insertChildNode(0, QgsLayerTreeLayer(layer_drn)) input2 = QgsProject.instance().mapLayersByName("drain2sub")[0] fields = input2.dataProvider() fdname = [ fields.indexFromName(field.name()) for field in fields.fields() if not ( field.name() == 'Subbasin' or field.name() == 'row' or field.name() == 'col' or field.name() == 'layer')] fields.deleteAttributes(fdname) input2.updateFields() msgBox.setWindowTitle("Created!") msgBox.setText("'drain2sub.shp' file has been created!") msgBox.exec_() except: msgBox.setWindowTitle("No Drain package found!") msgBox.setText("Please, provide a drain package to your MODFLOW model first!") self.dlg.spinBox_irrig_mf.setEnabled(False) self.dlg.pushButton_irrig_mf.setEnabled(False) self.dlg.pushButton_irrig_mf_create.setEnabled(False) msgBox.exec_()
def processCommand(self, parameters, context, feedback, delOutputs=False): """ Prepare the GRASS algorithm command :param parameters: :param context: :param delOutputs: do not add outputs to commands. """ noOutputs = [o for o in self.parameterDefinitions() if o not in self.destinationParameterDefinitions()] command = '{} '.format(self.grass7Name) command += '{}'.join(self.hardcodedStrings) # Add algorithm command for param in noOutputs: paramName = param.name() value = None # Exclude default GRASS parameters if paramName in [self.GRASS_REGION_CELLSIZE_PARAMETER, self.GRASS_REGION_EXTENT_PARAMETER, self.GRASS_MIN_AREA_PARAMETER, self.GRASS_SNAP_TOLERANCE_PARAMETER, self.GRASS_OUTPUT_TYPE_PARAMETER, self.GRASS_REGION_ALIGN_TO_RESOLUTION, self.GRASS_RASTER_FORMAT_OPT, self.GRASS_RASTER_FORMAT_META]: continue # Raster and vector layers if isinstance(param, (QgsProcessingParameterRasterLayer, QgsProcessingParameterVectorLayer, QgsProcessingParameterFeatureSource)): if paramName in self.exportedLayers: value = self.exportedLayers[paramName] else: value = self.parameterAsCompatibleSourceLayerPath( parameters, paramName, context, QgsVectorFileWriter.supportedFormatExtensions() ) # MultipleLayers elif isinstance(param, QgsProcessingParameterMultipleLayers): layers = self.parameterAsLayerList(parameters, paramName, context) values = [] for idx in range(len(layers)): layerName = '{}_{}'.format(paramName, idx) values.append(self.exportedLayers[layerName]) value = ','.join(values) # For booleans, we just add the parameter name elif isinstance(param, QgsProcessingParameterBoolean): if self.parameterAsBool(parameters, paramName, context): command += ' {}'.format(paramName) # For Extents, remove if the value is null elif isinstance(param, QgsProcessingParameterExtent): if self.parameterAsExtent(parameters, paramName, context): value = self.parameterAsString(parameters, paramName, context) # For enumeration, we need to grab the string value elif isinstance(param, QgsProcessingParameterEnum): # Handle multiple values if param.allowMultiple(): indexes = self.parameterAsEnums(parameters, paramName, context) else: indexes = [self.parameterAsEnum(parameters, paramName, context)] if indexes: value = '"{}"'.format(','.join([param.options()[i] for i in indexes])) # For strings, we just translate as string elif isinstance(param, QgsProcessingParameterString): data = self.parameterAsString(parameters, paramName, context) # if string is empty, we don't add it if len(data) > 0: value = '"{}"'.format( self.parameterAsString(parameters, paramName, context) ) # For fields, we just translate as string elif isinstance(param, QgsProcessingParameterField): value = ','.join( self.parameterAsFields(parameters, paramName, context) ) elif isinstance(param, QgsProcessingParameterFile): if self.parameterAsString(parameters, paramName, context): value = '"{}"'.format( self.parameterAsString(parameters, paramName, context) ) elif isinstance(param, QgsProcessingParameterPoint): if self.parameterAsString(parameters, paramName, context): # parameter specified, evaluate as point # TODO - handle CRS transform point = self.parameterAsPoint(parameters, paramName, context) value = '{},{}'.format(point.x(), point.y()) # For numbers, we translate as a string elif isinstance(param, (QgsProcessingParameterNumber, QgsProcessingParameterPoint)): value = self.parameterAsString(parameters, paramName, context) # For everything else, we assume that it is a string else: value = '"{}"'.format( self.parameterAsString(parameters, paramName, context) ) if value: command += ' {}={}'.format(paramName.replace('~', ''), value) # Handle outputs if not delOutputs: for out in self.destinationParameterDefinitions(): # We exclude hidden parameters if out.flags() & QgsProcessingParameterDefinition.FlagHidden: continue outName = out.name() # For File destination if isinstance(out, QgsProcessingParameterFileDestination): # for HTML reports, we need to redirect stdout if out.defaultFileExtension().lower() == 'html': command += ' > "{}"'.format( self.parameterAsFileOutput( parameters, outName, context) ) else: command += ' {}="{}"'.format( outName, self.parameterAsFileOutput( parameters, outName, context)) # For folders destination elif isinstance(out, QgsProcessingParameterFolderDestination): # We need to add a unique temporary basename uniqueBasename = outName + self.uniqueSuffix command += ' {}={}'.format(outName, uniqueBasename) else: # We add an output name to make sure it is unique if the session # uses this algorithm several times. #value = self.parameterAsOutputLayer(parameters, outName, context) uniqueOutputName = outName + self.uniqueSuffix command += ' {}={}'.format(outName, uniqueOutputName) # Add output file to exported layers, to indicate that # they are present in GRASS self.exportedLayers[outName] = uniqueOutputName command += ' --overwrite' self.commands.append(command) QgsMessageLog.logMessage(self.tr('processCommands end. Commands: {}').format(self.commands), 'Grass7', Qgis.Info)
def link_irrig_mf(self): QSWATMOD_path_dict = self.dirs_and_paths() self.layer = QgsProject.instance().mapLayersByName("mf_grid (MODFLOW)")[0] input1 = QgsProject.instance().mapLayersByName("mf_grid (MODFLOW)")[0] provider = self.layer.dataProvider() welnum = self.dlg.spinBox_irrig_mf.value() # Find *.wel file and read number of grid cells try: for filename in glob.glob(str(QSWATMOD_path_dict['SMfolder'])+"/*.wel"): with open(filename, "r") as f: data = [] for line in f.readlines(): if not line.startswith("#"): data.append(line.replace('\n', '').split()) wel_row = [] wel_col = [] # Skip two lines in Riv package and get row and col for i in range(2, welnum+2): wel_row.append(int(data[i][1])) wel_col.append(int(data[i][2])) # Find grid cells according to the well package feats = self.layer.getFeatures() wel_matched = [] for f in feats: rowNo = f.attribute("row") colNo = f.attribute("col") # rowNo = f.attribute["row"] # colNo = f.attribute["col"] for i in range(len(wel_row)): if ((rowNo == wel_row[i]) and (colNo == wel_col[i])): wel_matched.append(f.id()) self.layer.selectByIds(wel_matched) name = "irrig_mf" name_ext = "irrig_mf.shp" output_dir = QSWATMOD_path_dict['Scenarios'] # Save just the selected features of the target layer irrig_mf = os.path.join(output_dir, name_ext) # QgsVectorFileWriter.deleteShapeFile(irrig_mf) QgsVectorFileWriter.writeAsVectorFormat( input1, irrig_mf, "utf-8", input1.crs(), "ESRI Shapefile", 1) # Deselect the features self.layer.removeSelection() # Join sub and hru id n3_ext = "irrig_mf_s.shp" irrig_mf_s = os.path.join(output_dir, n3_ext) # QgsVectorFileWriter.deleteShapeFile(irrig_mf_s) sub_shp = QgsProject.instance().mapLayersByName("sub (SWAT)")[0] processing.run( "qgis:joinattributesbylocation", irrig_mf, sub_shp, ['intersects'],0,0,"sum,mean,min,max,median",0, irrig_mf_s) # Join sub id n4_ext = "irrig_mf_f.shp" irrig_mf_f = os.path.join(output_dir, n4_ext) # QgsVectorFileWriter.deleteShapeFile(irrig_mf_f) hru_shp = QgsProject.instance().mapLayersByName("hru (SWAT)")[0] processing.run( "qgis:joinattributesbylocation", irrig_mf_s, hru_shp, ['intersects'],0,0,"sum,mean,min,max,median",0, irrig_mf_f) # delete unnecessary fields layer_mf = QgsVectorLayer(irrig_mf_f, '{0}'.format("irrig_mf"), 'ogr') QgsProject.instance().addMapLayer(layer_mf, False) root = QgsProject.instance().layerTreeRoot() p_mf_tree = root.findGroup("Pumping from MODFLOW") p_mf_tree.insertChildNode(0, QgsLayerTreeLayer(layer_mf)) input2 = QgsProject.instance().mapLayersByName("irrig_mf")[0] fields = input2.dataProvider() fdname = [ fields.indexFromName(field.name()) for field in fields.fields() if not ( field.name() == 'Subbasin' or field.name() == 'row' or field.name() == 'col' or field.name() == 'HRU_ID' ) ] fields.deleteAttributes(fdname) input2.updateFields() msgBox.setWindowTitle("Created!") msgBox.setText( "'irrig_mf.shp' file has been created!\n"+ "If you have multiple HRUs, open its Attribute table and modify it." ) msgBox.exec_() except: msgBox.setWindowTitle("No Well package found!") msgBox.setText("Please, provide a well package to your MODFLOW model first!") self.dlg.spinBox_irrig_mf.setEnabled(False) self.dlg.pushButton_irrig_mf.setEnabled(False) self.dlg.pushButton_irrig_mf_create.setEnabled(False) msgBox.exec_()
def run(self): """Risk plugin for classified polygon hazard on polygon population. Counts population in an area exposed to hazard zones and then computes the proportion of each area that is affected. The population in each area is then calculated as the proportion of the original population to the affected area. :returns: Impact layer :rtype: Vector """ self.validate() self.prepare() self.provenance.append_step( 'Calculating Step', 'Impact function is calculating the impact.') # Identify hazard and exposure layers hazard = self.hazard.layer exposure = self.exposure.layer # prepare objects for re-projection of geometries crs_wgs84 = QgsCoordinateReferenceSystem("EPSG:4326") hazard_to_exposure = QgsCoordinateTransform( hazard.crs(), exposure.crs()) wgs84_to_hazard = QgsCoordinateTransform( crs_wgs84, hazard.crs()) wgs84_to_exposure = QgsCoordinateTransform( crs_wgs84, exposure.crs()) extent = QgsRectangle( self.requested_extent[0], self.requested_extent[1], self.requested_extent[2], self.requested_extent[3]) extent_hazard = wgs84_to_hazard.transformBoundingBox(extent) extent_exposure = wgs84_to_exposure.transformBoundingBox(extent) extent_exposure_geom = QgsGeometry.fromRect(extent_exposure) # make spatial index of hazard hazard_index = QgsSpatialIndex() hazard_features = {} for feature in hazard.getFeatures(QgsFeatureRequest(extent_hazard)): feature.geometry().transform(hazard_to_exposure) hazard_index.insertFeature(feature) hazard_features[feature.id()] = QgsFeature(feature) # create impact layer filename = unique_filename(suffix='.shp') impact_fields = exposure.dataProvider().fields() impact_fields.append(QgsField(self.target_field, QVariant.Int)) unaffected_fields = exposure.dataProvider().fields() unaffected_fields.append(QgsField(self.target_field, QVariant.Int)) writer = QgsVectorFileWriter( filename, "utf-8", impact_fields, QGis.WKBPolygon, exposure.crs()) # Evaluating the impact self.evaluate_impact( exposure, extent_exposure, extent_exposure_geom, hazard_index, hazard_features, writer, unaffected_fields, impact_fields) del writer impact_layer = QgsVectorLayer(filename, "Impacted People", "ogr") # Generate the report of affected populations in the areas # To avoid Null for value in self.all_areas_population.values(): if isinstance(value, QPyNullVariant): value = 0 self.total_population += value self.areas = self.all_areas_ids self.affected_areas = self.all_affected_areas self.areas_population = self.all_areas_population # Calculating number of people affected # This will help area report mixin to know how # to calculate the all row values before other # rows values in the report table self.evaluate_affected_people() impact_summary = self.html_report() # Define style for the impact layer transparent_color = QColor() transparent_color.setAlpha(0) # Retrieve the classification that is used by the hazard layer. vector_hazard_classification = self.hazard.keyword( 'vector_hazard_classification') # Get the dictionary that contains the definition of the classification vector_hazard_classification = definition(vector_hazard_classification) # Get the list classes in the classification vector_hazard_classes = vector_hazard_classification['classes'] classes = self.hazard_class_mapping classes_colours = {} color_mapping = { 'wet': '#F31A1C', 'low': '#1EFC7C', 'medium': '#FFA500', 'high': '#F31A1C' } classes_values = { 'wet': 1, 'low': 1, 'medium': 2, 'high': 3 } # Assigning colors for vector_hazard_class in vector_hazard_classes: key = vector_hazard_class['key'] if key in classes.keys() and key in color_mapping.keys(): classes_colours[key] = color_mapping[key] # Define style info for output polygons showing population counts style_classes = [] index = 0 for class_key, colour in classes_colours.items(): style_class = dict() if class_key in classes.keys(): label = classes[class_key][0] else: continue transparency = 0 style_class['label'] = label style_class['value'] = classes_values[class_key] style_class['colour'] = colour style_class['transparency'] = transparency style_classes.append(style_class) index = index + 1 style_info = dict( target_field=self.target_field, style_classes=style_classes, style_type='categorizedSymbol') extra_keywords = { 'impact_summary': impact_summary, 'target_field': self.target_field, 'map_title': tr('Affected People'), } self.set_if_provenance() impact_layer_keywords = self.generate_impact_keywords(extra_keywords) # Create vector layer and return impact_layer = Vector( data=impact_layer, name=tr('People affected by each hazard zone'), keywords=impact_layer_keywords, style_info=style_info) self._impact = impact_layer return impact_layer
def calculate(self): ''' Prepare environment to run the alg and run it. After run, merge produced data basing on plugin configuration. Before calculation a parametere validation will be executed ''' # perform validation if not self.gui.validate(): return else: # notify successful validation message = self.tr( "QTraffic: Parameters validation passed successfully") iface.messageBar().pushMessage(message, QgsMessageBar.SUCCESS) # set number of classes in the project config (that is the temporary one... but equal to the official one) fleetDistributionRoadTypes = self.gui.getRoadTypes() self.project.setValue('Processing.Parameters/maximum_type', len(fleetDistributionRoadTypes)) self.project.sync() # create the algorithm self.alg = Algorithm() roadLayer = self.gui.getRoadLayer() # prepare layer where to add result addToInputLayer = self.gui.addToOriginaLayer_RButton.isChecked() newOutputLayer = self.gui.outFile_LEdit.text() if addToInputLayer: self.outLayer = roadLayer self.outLayerId = self.outLayer.id() else: # if layer is present... remove it # out layer would not be the same of input road layer... in thi scase don't remove it if self.outLayer and self.outLayer.isValid(): # to be sure, remove only if roadLayer and outLayer are different if self.outLayer.publicSource() != roadLayer.publicSource(): self.outLayerRemoved = False QgsMapLayerRegistry.instance().layerRemoved.connect( self.checkOutLayerRemoved) QgsMapLayerRegistry.instance().removeMapLayer( self.outLayer.id()) # remove file when it has been removed from qgis while not self.outLayerRemoved: sleep(0.1) QgsMapLayerRegistry.instance().layerRemoved.disconnect( self.checkOutLayerRemoved) # reinit outLayer variables # If not, under windws remain a locking of the related file creating # an error during QgsVectorFileWriter.deleteShapeFile self.outLayer = None self.outLayerId = None if os.path.exists(newOutputLayer): if not QgsVectorFileWriter.deleteShapeFile( newOutputLayer): message = self.tr( "Error removing shape: {}".format( newOutputLayer)) iface.messageBar().pushMessage( message, QgsMessageBar.CRITICAL) return # copy input layer to the new one writeError = QgsVectorFileWriter.writeAsVectorFormat( roadLayer, newOutputLayer, 'utf-8', roadLayer.crs()) if writeError != QgsVectorFileWriter.NoError: message = self.tr( 'Error writing vector file {}'.format(newOutputLayer)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return # load the layer newLayerName = os.path.splitext( os.path.basename(newOutputLayer))[0] self.outLayer = QgsVectorLayer(newOutputLayer, newLayerName, 'ogr') if not self.outLayer.isValid(): message = self.tr( 'Error loading vector file {}'.format(newOutputLayer)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return self.outLayerId = self.outLayer.id() # prepare environment try: self.alg.setProject(self.project) self.alg.setLayer(roadLayer) self.alg.initConfig() self.alg.prepareRun() except Exception as ex: traceback.print_exc() message = self.tr( 'Error preparing running contex for the algoritm: %s' % str(ex)) QgsMessageLog.logMessage(message, 'QTraffic', QgsMessageLog.CRITICAL) iface.messageBar().pushCritical('QTraffic', message) return # run the self.alg self.thread = QtCore.QThread(self) self.thread.started.connect(self.alg.run) self.thread.finished.connect(self.threadCleanup) self.thread.terminated.connect(self.threadCleanup) self.alg.moveToThread(self.thread) self.alg.started.connect(self.manageStarted) self.alg.progress.connect(self.manageProgress) self.alg.message.connect(self.manageMessage) self.alg.error.connect(self.manageError) self.alg.finished.connect(self.manageFinished) # set wait cursor and start QgsApplication.instance().setOverrideCursor(QtCore.Qt.WaitCursor) self.thread.start()
def accept(self, *args, **kwargs): """Run the processing""" try: if not self.validate(): return False # disable form via a frame, this will still allow interaction with the message bar self.fraMain.setDisabled(True) # clean gui and Qgis messagebars self.cleanMessageBars(True) # Change cursor to Wait cursor QtGui.qApp.setOverrideCursor(QtGui.QCursor(QtCore.Qt.WaitCursor)) self.iface.mainWindow().statusBar().showMessage( 'Processing {}'.format(self.windowTitle())) LOGGER.info('{st}\nProcessing {}'.format(self.windowTitle(), st='*' * 50)) self.send_to_messagebar( "Please wait.. QGIS will be locked... See log panel for progress.", level=QgsMessageBar.WARNING, duration=0, addToLog=False, core_QGIS=False, showLogPanel=True) selectedIndices = [ x.text() for x in self.chkgrpIndices.buttons() if x.isChecked() ] # Add settings to log settingsStr = 'Parameters:---------------------------------------' settingsStr += '\n {:20}\t{}'.format( 'Image layer:', self.mcboRasterLayer.currentLayer().name()) settingsStr += '\n {:20}\t{}'.format('Image nodata value:', self.spnNoDataVal.value()) if self.chkUsePoly.isChecked(): if self.chkUseSelected.isChecked(): settingsStr += '\n {:20}\t{} with {} selected features'.format( 'Layer:', self.mcboPolygonLayer.currentLayer().name(), len(self.mcboPolygonLayer.currentLayer(). selectedFeatures())) else: settingsStr += '\n {:20}\t{}'.format( 'Boundary layer:', self.mcboPolygonLayer.currentLayer().name()) if self.mFieldComboBox.currentField(): settingsStr += '\n {:20}\t{}'.format( 'Block ID field:', self.mFieldComboBox.currentField()) settingsStr += '\n {:20}\t{}'.format('Resample pixel size: ', self.dsbPixelSize.value()) for k, v in self.band_mapping.iteritems(): if v > 0: settingsStr += '\n {:20}\t{}'.format( '{} Band:'.format(k.title()), v) settingsStr += '\n {:20}\t{}'.format('Calculate Indices: ', ', '.join(selectedIndices)) settingsStr += '\n {:30}\t{}'.format( 'Output Coordinate System:', self.lblOutCRS.text()) settingsStr += '\n {:30}\t{}\n'.format( 'Output Folder:', self.lneOutputFolder.text()) LOGGER.info(settingsStr) lyrRaster = self.mcboRasterLayer.currentLayer() if self.chkUsePoly.isChecked(): lyrBoundary = self.mcboPolygonLayer.currentLayer() if self.chkUseSelected.isChecked(): savePlyName = lyrBoundary.name() + '_poly.shp' filePoly = os.path.join(TEMPDIR, savePlyName) if os.path.exists(filePoly): removeFileFromQGIS(filePoly) QgsVectorFileWriter.writeAsVectorFormat(lyrBoundary, filePoly, "utf-8", lyrBoundary.crs(), "ESRI Shapefile", onlySelected=True) if self.DISP_TEMP_LAYERS: addVectorFileToQGIS(filePoly, layer_name=os.path.splitext( os.path.basename(filePoly))[0], group_layer_name='DEBUG', atTop=True) else: filePoly = lyrBoundary.source() files = calc_indices_for_block( lyrRaster.source(), self.dsbPixelSize.value(), self.band_mapping, self.lneOutputFolder.text(), indices=selectedIndices, image_epsg=int(lyrRaster.crs().authid().replace('EPSG:', '')), image_nodata=self.spnNoDataVal.value(), polygon_shapefile=filePoly if self.chkUsePoly.isChecked() else None, groupby=self.mFieldComboBox.currentField() if self.mFieldComboBox.currentField() else None, out_epsg=int(self.outQgsCRS.authid().replace('EPSG:', ''))) if self.chkAddToDisplay.isChecked(): for ea_file in files: raster_sym = RASTER_SYMBOLOGY[ 'Image Indices (ie PCD, NDVI)'] raster_lyr = addRasterFileToQGIS( ea_file, atTop=False, group_layer_name=os.path.basename( os.path.dirname(ea_file))) raster_apply_classified_renderer( raster_lyr, rend_type=raster_sym['type'], num_classes=raster_sym['num_classes'], color_ramp=raster_sym['colour_ramp']) self.cleanMessageBars(True) self.fraMain.setDisabled(False) self.iface.mainWindow().statusBar().clearMessage() self.iface.messageBar().popWidget() QtGui.qApp.restoreOverrideCursor() return super(CalculateImageIndicesDialog, self).accept(*args, **kwargs) except Exception as err: QtGui.qApp.restoreOverrideCursor() self.iface.mainWindow().statusBar().clearMessage() self.cleanMessageBars(True) self.fraMain.setDisabled(False) self.send_to_messagebar(str(err), level=QgsMessageBar.CRITICAL, duration=0, addToLog=True, core_QGIS=False, showLogPanel=True, exc_info=sys.exc_info()) return False # leave dialog open
def initialize(): icon = QgsApplication.getThemeIcon("/processingAlgorithm.svg") ProcessingConfig.settingIcons['General'] = icon ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.KEEP_DIALOG_OPEN, ProcessingConfig.tr( 'Keep dialog open after running an algorithm'), True)) ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.PREFER_FILENAME_AS_LAYER_NAME, ProcessingConfig.tr('Prefer output filename for layer names'), True)) ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.SHOW_PROVIDERS_TOOLTIP, ProcessingConfig.tr( 'Show tooltip when there are disabled providers'), True)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.OUTPUT_FOLDER, ProcessingConfig.tr('Output folder'), defaultOutputFolder(), valuetype=Setting.FOLDER)) ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.SHOW_CRS_DEF, ProcessingConfig.tr( 'Show layer CRS definition in selection boxes'), True)) ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.WARN_UNMATCHING_CRS, ProcessingConfig.tr( "Warn before executing if parameter CRS's do not match"), True)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.SHOW_ALGORITHMS_KNOWN_ISSUES, ProcessingConfig.tr("Show algorithms with known issues"), False)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.RASTER_STYLE, ProcessingConfig.tr('Style for raster layers'), '', valuetype=Setting.FILE)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.VECTOR_POINT_STYLE, ProcessingConfig.tr('Style for point layers'), '', valuetype=Setting.FILE)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.VECTOR_LINE_STYLE, ProcessingConfig.tr('Style for line layers'), '', valuetype=Setting.FILE)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.VECTOR_POLYGON_STYLE, ProcessingConfig.tr('Style for polygon layers'), '', valuetype=Setting.FILE)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.PRE_EXECUTION_SCRIPT, ProcessingConfig.tr('Pre-execution script'), '', valuetype=Setting.FILE)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.POST_EXECUTION_SCRIPT, ProcessingConfig.tr('Post-execution script'), '', valuetype=Setting.FILE)) invalidFeaturesOptions = [ ProcessingConfig.tr('Do not filter (better performance)'), ProcessingConfig.tr( 'Skip (ignore) features with invalid geometries'), ProcessingConfig.tr( 'Stop algorithm execution when a geometry is invalid') ] ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.FILTER_INVALID_GEOMETRIES, ProcessingConfig.tr('Invalid features filtering'), invalidFeaturesOptions[2], valuetype=Setting.SELECTION, options=invalidFeaturesOptions)) threads = QgsApplication.maxThreads( ) # if user specified limit for rendering, lets keep that as default here, otherwise max threads = cpu_count( ) if threads == -1 else threads # if unset, maxThreads() returns -1 ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.MAX_THREADS, ProcessingConfig.tr('Max Threads'), threads, valuetype=Setting.INT)) extensions = QgsVectorFileWriter.supportedFormatExtensions() ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.DEFAULT_OUTPUT_VECTOR_LAYER_EXT, ProcessingConfig.tr('Default output vector layer extension'), QgsVectorFileWriter.supportedFormatExtensions()[0], valuetype=Setting.SELECTION, options=extensions)) extensions = QgsRasterFileWriter.supportedFormatExtensions() ProcessingConfig.addSetting( Setting( ProcessingConfig.tr('General'), ProcessingConfig.DEFAULT_OUTPUT_RASTER_LAYER_EXT, ProcessingConfig.tr('Default output raster layer extension'), 'tif', valuetype=Setting.SELECTION, options=extensions)) ProcessingConfig.addSetting( Setting(ProcessingConfig.tr('General'), ProcessingConfig.TEMP_PATH, ProcessingConfig.tr('Temporary output folder path'), QgsProcessingUtils.tempFolder(), valuetype=Setting.FOLDER))
def supportedOutputVectorLayerExtensions(self): # We use the same extensions than QGIS because: # - QGIS is using OGR like GRASS # - There are very chances than OGR version used in GRASS is # different from QGIS OGR version. return QgsVectorFileWriter.supportedFormatExtensions()
def recogerRuta(self, event): # Funcion para cargar las capas que necesitaremos, si no existen se crean ruta = QFileDialog.getExistingDirectory(self, 'Selecciona directorio') print(ruta) file_punto = ruta + '/edit_topo_punto.shp' file_linea = ruta + '/edit_topo_linea.shp' file_poligono = ruta + '/edit_topo_poligono.shp' mensaje = '' print(file_linea) crs = QgsCoordinateReferenceSystem('EPSG:25830') if os.path.isfile(file_punto): mensaje = mensaje + 'La capa edit_topo_punto.shp existe' + "\n" layer_punto = iface.addVectorLayer(file_punto, "", "ogr") else: vlpoint = QgsVectorLayer('point', 'edit_topo_punto', 'memory') prpoint = vlpoint.dataProvider() prpoint.addAttributes([QgsField("id", QVariant.Int), QgsField("clave_top", QVariant.String, len=15), QgsField("elemento", QVariant.String), QgsField("texto_norm", QVariant.String, len=100), QgsField("top_mayor", QVariant.String, len=20), QgsField("globalid", QVariant.String, len=38), QgsField("usuario", QVariant.String, len=100), QgsField("fechaalta", QVariant.String, len=20), QgsField("elemento", QVariant.String, len=1)]) vlpoint.updateFields() msg_point = QgsVectorFileWriter.writeAsVectorFormat(vlpoint, file_punto, 'utf-8', crs, driverName="ESRI Shapefile") if msg_point[0] != 0: print(msg_point) else: print("El fichero se ha creado correctamente") layer_punto = iface.addVectorLayer(file_punto, "", "ogr") mensaje = mensaje + 'La capa edit_topo_punto.shp no existe, se ha creado' + "\n" if os.path.isfile(file_linea): mensaje = mensaje + 'La capa edit_topo_linea.shp existe' + "\n" layer_linea = iface.addVectorLayer(file_linea, "", "ogr") else: vllinea = QgsVectorLayer('line', 'edit_topo_linea', 'memory') prlinea = vllinea.dataProvider() prlinea.addAttributes([QgsField("id", QVariant.Int), QgsField("clave_top", QVariant.String, len=15), QgsField("elemento", QVariant.String), QgsField("texto_norm", QVariant.String, len=100), QgsField("top_mayor", QVariant.String, len=20), QgsField("globalid", QVariant.String, len=38), QgsField("usuario", QVariant.String, len=100), QgsField("fechaalta", QVariant.String, len=20), QgsField("elemento", QVariant.String, len=1)]) vllinea.updateFields() msg_linea = QgsVectorFileWriter.writeAsVectorFormat(vllinea, file_linea, 'utf-8', crs, driverName="ESRI Shapefile") if msg_linea[0] != 0: print(msg_linea) else: print("El fichero se ha creado correctamente") layer_linea = iface.addVectorLayer(file_linea, "", "ogr") mensaje = mensaje + 'La capa edit_topo_linea.shp no existe, se ha creado' + "\n" if os.path.isfile(file_poligono): mensaje = mensaje + 'La capa edit_topo_poligono.shp existe' + "\n" layer_polygon = iface.addVectorLayer(file_poligono, "", "ogr") else: vlpoly = QgsVectorLayer('polygon', 'edit_topo_poligono', 'memory') prpoly = vlpoly.dataProvider() prpoly.addAttributes([QgsField("id", QVariant.Int), QgsField("clave_top", QVariant.String, len=15), QgsField("elemento", QVariant.String), QgsField("texto_norm", QVariant.String, len=100), QgsField("top_mayor", QVariant.String, len=20), QgsField("globalid", QVariant.String, len=38), QgsField("usuario", QVariant.String, len=100), QgsField("fechaalta", QVariant.String, len=20), QgsField("elemento", QVariant.String, len=1)]) vlpoly.updateFields() msg_poly = QgsVectorFileWriter.writeAsVectorFormat(vlpoly, file_poligono, 'utf-8', crs, driverName="ESRI Shapefile") if (msg_poly[0] != 0): print(msg_poly) else: print('El fichero se ha creado correctamente') layer_polygon = iface.addVectorLayer(file_poligono, "", "ogr") mensaje = mensaje + 'La capa edit_topo_poligono.shp no existe, se ha creado' + "\n" QMessageBox.information(self.iface.mainWindow(), 'informacion de capas', mensaje) self.txt_ruta.setText('Ruta: ' + ruta) dic_path = os.path.dirname(os.path.realpath(__file__)) + '/datos/dic_toponimia.dbf' if os.path.isfile(dic_path): dic_layer = iface.addVectorLayer(dic_path, "dic_toponimia", "ogr") dic_layer.setProviderEncoding(u'Latin1') if not dic_layer.isValid(): print("Layer failed to load!") else: print("Layer valido") self.cbx_uno.setEnabled(True) features = dic_layer.getFeatures() for feature in features: # Rellenamos el primer combobox con los elementos de primer nivel toponimico if len(str(feature["clave"])) == 1: self.cbx_uno.addItem(feature["elemento"])
def ogrConnectionStringAndFormatFromLayer(layer): provider = layer.dataProvider().name() if provider == 'spatialite': # dbname='/geodata/osm_ch.sqlite' table="places" (Geometry) sql= regex = re.compile("dbname='(.+)'") r = regex.search(str(layer.source())) ogrstr = r.groups()[0] format = 'SQLite' elif provider == 'postgres': # dbname='ktryjh_iuuqef' host=spacialdb.com port=9999 # user='******' password='******' sslmode=disable # key='gid' estimatedmetadata=true srid=4326 type=MULTIPOLYGON # table="t4" (geom) sql= dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri()) conninfo = dsUri.connectionInfo() conn = None ok = False while not conn: try: conn = psycopg2.connect(dsUri.connectionInfo()) except psycopg2.OperationalError: (ok, user, passwd) = QgsCredentials.instance().get( conninfo, dsUri.username(), dsUri.password()) if not ok: break dsUri.setUsername(user) dsUri.setPassword(passwd) if not conn: raise RuntimeError( 'Could not connect to PostgreSQL database - check connection info' ) if ok: QgsCredentials.instance().put(conninfo, user, passwd) ogrstr = "PG:%s" % dsUri.connectionInfo() format = 'PostgreSQL' elif provider == 'mssql': #'dbname=\'db_name\' host=myHost estimatedmetadata=true # srid=27700 type=MultiPolygon table="dbo"."my_table" # #(Shape) sql=' dsUri = layer.dataProvider().uri() ogrstr = 'MSSQL:' ogrstr += 'database={0};'.format(dsUri.database()) ogrstr += 'server={0};'.format(dsUri.host()) if dsUri.username() != "": ogrstr += 'uid={0};'.format(dsUri.username()) else: ogrstr += 'trusted_connection=yes;' if dsUri.password() != '': ogrstr += 'pwd={0};'.format(dsUri.password()) ogrstr += 'tables={0}'.format(dsUri.table()) format = 'MSSQL' elif provider == "oracle": # OCI:user/password@host:port/service:table dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri()) ogrstr = "OCI:" if dsUri.username() != "": ogrstr += dsUri.username() if dsUri.password() != "": ogrstr += "/" + dsUri.password() delim = "@" if dsUri.host() != "": ogrstr += delim + dsUri.host() delim = "" if dsUri.port() != "" and dsUri.port() != '1521': ogrstr += ":" + dsUri.port() ogrstr += "/" if dsUri.database() != "": ogrstr += dsUri.database() elif dsUri.database() != "": ogrstr += delim + dsUri.database() if ogrstr == "OCI:": raise RuntimeError( 'Invalid oracle data source - check connection info') ogrstr += ":" if dsUri.schema() != "": ogrstr += dsUri.schema() + "." ogrstr += dsUri.table() format = 'OCI' else: ogrstr = str(layer.source()).split("|")[0] path, ext = os.path.splitext(ogrstr) format = QgsVectorFileWriter.driverForExtension(ext) return ogrstr, '"' + format + '"'
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') 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 GeoHealthException, e: self.label_progress.setText('') display_message_bar(msg=e.msg, level=e.level, duration=e.duration)
def testDateTimeWriteShapefile(self): """Check writing date and time fields to an ESRI shapefile.""" ml = QgsVectorLayer( ('Point?crs=epsg:4326&field=id:int&' 'field=date_f:date&field=time_f:time&field=dt_f:datetime'), 'test', 'memory') self.assertTrue(ml.isValid()) provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 10))) ft.setAttributes([ 1, QDate(2014, 3, 5), QTime(13, 45, 22), QDateTime(QDate(2014, 3, 5), QTime(13, 45, 22)) ]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) dest_file_name = os.path.join(str(QDir.tempPath()), 'datetime.shp') crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result, error_message = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile') self.assertEqual(write_result, QgsVectorFileWriter.NoError, error_message) # Open result and check created_layer = QgsVectorLayer('{}|layerid=0'.format(dest_file_name), 'test', 'ogr') fields = created_layer.dataProvider().fields() self.assertEqual( fields.at(fields.indexFromName('date_f')).type(), QVariant.Date) # shapefiles do not support time types, result should be string self.assertEqual( fields.at(fields.indexFromName('time_f')).type(), QVariant.String) # shapefiles do not support datetime types, result should be string self.assertEqual( fields.at(fields.indexFromName('dt_f')).type(), QVariant.String) f = next(created_layer.getFeatures(QgsFeatureRequest())) date_idx = created_layer.fields().lookupField('date_f') self.assertIsInstance(f.attributes()[date_idx], QDate) self.assertEqual(f.attributes()[date_idx], QDate(2014, 3, 5)) time_idx = created_layer.fields().lookupField('time_f') # shapefiles do not support time types self.assertIsInstance(f.attributes()[time_idx], str) self.assertEqual(f.attributes()[time_idx], '13:45:22') # shapefiles do not support datetime types datetime_idx = created_layer.fields().lookupField('dt_f') self.assertIsInstance(f.attributes()[datetime_idx], str) self.assertEqual( f.attributes()[datetime_idx], QDateTime(QDate(2014, 3, 5), QTime(13, 45, 22)).toString("yyyy/MM/dd hh:mm:ss.zzz"))
def testWriteShapefileWithZ(self): """Check writing geometries with Z dimension to an ESRI shapefile.""" # start by saving a memory layer and forcing z ml = QgsVectorLayer(('Point?crs=epsg:4326&field=id:int'), 'test', 'memory') self.assertIsNotNone(ml, 'Provider not initialized') self.assertTrue(ml.isValid(), 'Source layer not valid') provider = ml.dataProvider() self.assertIsNotNone(provider) ft = QgsFeature() ft.setGeometry(QgsGeometry.fromWkt('PointZ (1 2 3)')) ft.setAttributes([1]) res, features = provider.addFeatures([ft]) self.assertTrue(res) self.assertTrue(features) # check with both a standard PointZ and 25d style Point25D type for t in [QgsWkbTypes.PointZ, QgsWkbTypes.Point25D]: dest_file_name = os.path.join( str(QDir.tempPath()), 'point_{}.shp'.format(QgsWkbTypes.displayString(t))) crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result = QgsVectorFileWriter.writeAsVectorFormat( ml, dest_file_name, 'utf-8', crs, 'ESRI Shapefile', overrideGeometryType=t) self.assertEqual(write_result, QgsVectorFileWriter.NoError) # Open result and check created_layer = QgsVectorLayer( '{}|layerid=0'.format(dest_file_name), 'test', 'ogr') f = next(created_layer.getFeatures(QgsFeatureRequest())) g = f.geometry() wkt = g.exportToWkt() expWkt = 'PointZ (1 2 3)' self.assertTrue( compareWkt(expWkt, wkt), "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt)) # also try saving out the shapefile version again, as an extra test # this tests that saving a layer with z WITHOUT explicitly telling the writer to keep z values, # will stay retain the z values dest_file_name = os.path.join( str(QDir.tempPath()), 'point_{}_copy.shp'.format(QgsWkbTypes.displayString(t))) crs = QgsCoordinateReferenceSystem() crs.createFromId(4326, QgsCoordinateReferenceSystem.EpsgCrsId) write_result = QgsVectorFileWriter.writeAsVectorFormat( created_layer, dest_file_name, 'utf-8', crs, 'ESRI Shapefile') self.assertEqual(write_result, QgsVectorFileWriter.NoError) # Open result and check created_layer_from_shp = QgsVectorLayer( '{}|layerid=0'.format(dest_file_name), 'test', 'ogr') f = next(created_layer_from_shp.getFeatures(QgsFeatureRequest())) g = f.geometry() wkt = g.exportToWkt() self.assertTrue( compareWkt(expWkt, wkt), "saving geometry with Z failed: mismatch Expected:\n%s\nGot:\n%s\n" % (expWkt, wkt))
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 type(extent) is list: rectangle = QgsRectangle(extent[0], extent[1], extent[2], extent[3]) # noinspection PyCallByClass #noinspection PyTypeChecker polygon = QgsGeometry.fromRect(rectangle) elif (type(extent) is 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