def _export_composition_as_image(self, composition, file_path): """ Export the composition as a raster image. """ num_pages = composition.numPages() for p in range(num_pages): img = composition.printPageAsRaster(p) if img.isNull(): msg = QApplication.translate("DocumentGenerator", "Memory allocation error. Please try " "a lower resolution or a smaller paper size.") raise Exception(msg) if p == 0: state = img.save(file_path) else: fi = QFileInfo(file_path) file_path = "{0}/{1}_{2}.{3}".format(fi.absolutePath(), fi.baseName(), (p+1), fi.suffix()) state = img.save(file_path) if not state: msg = QApplication.translate("DocumentGenerator", "Error creating {0}.".format(file_path)) raise Exception(msg)
def on_upload_document(self): ''' Slot raised when the user clicks to upload a supporting document. ''' document_str = QApplication.translate( "SupportingDocuments", "Specify the Document File Location") documents = self.select_file_dialog(document_str) cbo_index = self.doc_type_cbo.currentIndex() doc_id = self.doc_type_cbo.itemData(cbo_index) for doc in documents: self.supporting_doc_manager.insertDocumentFromFile( doc, doc_id, self.social_tenure, self.current_party_count) # Set last path if len(documents) > 0: doc = documents[0] fi = QFileInfo(doc) dir_path = fi.absolutePath() set_last_document_path(dir_path) model_objs = self.supporting_doc_manager.model_objects() self.onUploadDocument.emit(model_objs)
def select_output_file(self): prjfi = QFileInfo(QgsProject.instance().fileName()) filename, __ = QFileDialog.getSaveFileName(self.dlg, "Select output file ", prjfi.absolutePath(), '*.shp') self.dlg.outputPath.setText(filename)
def loadList(self): self.fileName, _ = QFileDialog.getOpenFileName( None, "Load data separated by ';'", self.fPath, "" ) if not os.path.exists(self.fileName): return 0 # update selected file's folder fInfo = QFileInfo(self.fileName) self.fPath = fInfo.absolutePath() self.saveConf() self.render_temp_band() # get saved data try: f = open(self.fileName) lines = f.readlines() f.close() self.clearList() for line in lines: # remove trailing 'new lines', etc and break into parts parts = ((line.strip()).lower()).split("=") if len(parts) > 1: # self.say("line="+line+'\nparts[0]='+parts[0]+'\nparts[1]='+parts[1]) if parts[0].lower() == "angle": self.setAngle(parts[1].lower()) elif parts[0].lower() == "heading": self.setHeading(parts[1].lower()) elif parts[0].lower() == "declination": self.setDeclination(parts[1].lower()) elif parts[0].lower() == "dist_units": self.setDistanceUnits(parts[1].lower()) elif parts[0].lower() == "angle_unit": self.setAngleUnit(parts[1].lower()) elif parts[0].lower() == "startat": self.setStartAt(parts[1].lower()) elif parts[0].lower() == "survey": self.setSurvey(parts[1].lower()) else: coords = tuple((line.strip()).split(";")) if coords[0].lower() == "[data]": pass else: self.addrow(*coords) except: self.say("Invalid input")
def _on_add_supporting_document(self): # Slot raised when the user select to add a supporting document if self.count == 0: return select = self.tr('Select') supporting_docs_str = 'Supporting Documents' title = '{0} {1} {2}'.format(select, self.current_document_type(), supporting_docs_str) filter_str = '{0} (*.jpg *.jpeg *.png *.bmp *.tiff *.svg *.pdf)'.format( supporting_docs_str) # Get last path for supporting documents last_path = last_document_path() if last_path is None: last_path = '/home' else: dir = QDir(last_path) if not dir.exists(): last_path = '/home' source_docs, _ = QFileDialog.getOpenFileNames(self, title, last_path, filter_str) doc_type_id = self._cbo_doc_type.itemData( self._cbo_doc_type.currentIndex()) parent_entity = self._entity_supporting_doc.parent_entity for doc in source_docs: self.source_document_manager.insertDocumentFromFile( doc, doc_type_id, parent_entity) # Set last path if len(source_docs) > 0: doc = source_docs[0] fi = QFileInfo(doc) dir_path = fi.absolutePath() set_last_document_path(dir_path)
class GeoPackage(DataStore): """ GeoPackage DataStore .. versionadded:: 4.0 """ def __init__(self, uri): """ Constructor for the GeoPackage DataStore. :param uri: A filepath which doesn't exist :type uri: QFileInfo, str .. versionadded:: 4.0 """ super(GeoPackage, self).__init__(uri) self.vector_driver = ogr.GetDriverByName('GPKG') self.raster_driver = gdal.GetDriverByName('GPKG') if isinstance(uri, QFileInfo): self._uri = uri elif isinstance(uri, str): self._uri = QFileInfo(uri) else: raise ErrorDataStore('Unknown type') if self.uri.exists(): raster_datasource = gdal.Open(self.uri.absoluteFilePath()) if raster_datasource is None: # Let's try if it's a vector one. vector_datasource = self.vector_driver.Open( self.uri.absoluteFilePath()) if vector_datasource is None: msg = 'The file is not a geopackage or it doesn\'t ' \ 'contain any layers.' raise ErrorDataStore(msg) else: path = self.uri.absoluteFilePath() # We need this variable to be created. The delete will create it. datasource = self.vector_driver.CreateDataSource(path) # NOQA del datasource @property def uri_path(self): """Return the URI of the datastore as a path. It's not a layer URI. :return: The URI. :rtype: str .. versionadded:: 4.0 """ return self.uri.absolutePath() def is_writable(self): """Check if the folder is writable. :return: If it's writable or not. :rtype: bool .. versionadded:: 4.0 """ # Fixme, need to check DB permissions ? return self._uri.absolutePath().isWritable() def supports_rasters(self): """Check if we can support raster in the geopackage. :return: If it's writable or not. :rtype: bool .. versionadded:: 4.0 """ if int(gdal.VersionInfo('VERSION_NUM')) < 2000000: return False else: return True def _vector_layers(self): """Return a list of vector layers available. :return: List of vector layers available in the geopackage. :rtype: list .. versionadded:: 4.0 """ layers = [] vector_datasource = self.vector_driver.Open( self.uri.absoluteFilePath()) if vector_datasource: for i in range(vector_datasource.GetLayerCount()): layers.append(vector_datasource.GetLayer(i).GetName()) return layers def _raster_layers(self): """Return a list of raster layers available. :return: List of raster layers available in the geopackage. :rtype: list .. versionadded:: 4.0 """ layers = [] raster_datasource = gdal.Open(self.uri.absoluteFilePath()) if raster_datasource: subdatasets = raster_datasource.GetSubDatasets() if len(subdatasets) == 0: metadata = raster_datasource.GetMetadata() layers.append(metadata['IDENTIFIER']) else: for subdataset in subdatasets: layers.append(subdataset[0].split(':')[2]) return layers def layers(self): """Return a list of layers available. :return: List of layers available in the datastore. :rtype: list .. versionadded:: 4.0 """ return self._vector_layers() + self._raster_layers() def layer_uri(self, layer_name): """Get layer URI. For a vector layer : /path/to/the/geopackage.gpkg|layername=my_vector_layer For a raster : GPKG:/path/to/the/geopackage.gpkg:my_raster_layer :param layer_name: The name of the layer to fetch. :type layer_name: str :return: The URI to the layer. :rtype: str .. versionadded:: 4.0 """ for layer in self._vector_layers(): if layer == layer_name: uri = '{}|layername={}'.format(self.uri.absoluteFilePath(), layer_name) return uri else: for layer in self._raster_layers(): if layer == layer_name: uri = 'GPKG:{}:{}'.format(self.uri.absoluteFilePath(), layer_name) return uri else: return None def _add_vector_layer(self, vector_layer, layer_name, save_style=False): """Add a vector layer to the geopackage. :param vector_layer: The layer to add. :type vector_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. Not implemented in geopackage ! :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 """ # Fixme # if not self.is_writable(): # return False, 'The destination is not writable.' geometry = QGIS_OGR_GEOMETRY_MAP[vector_layer.wkbType()] spatial_reference = osr.SpatialReference() qgis_spatial_reference = vector_layer.crs().authid() # Use 4326 as default if the spatial reference is not found epsg = 4326 epsg_string = qgis_spatial_reference if epsg_string: epsg = int(epsg_string.split(':')[1]) spatial_reference.ImportFromEPSG(epsg) vector_datasource = self.vector_driver.Open( self.uri.absoluteFilePath(), True) vector_datasource.CreateLayer(layer_name, spatial_reference, geometry) uri = '{}|layerid=0'.format(self.uri.absoluteFilePath()) vector_layer = QgsVectorLayer(uri, layer_name, 'ogr') data_provider = vector_layer.dataProvider() for feature in vector_layer.getFeatures(): data_provider.addFeatures([feature]) return True, layer_name def _add_raster_layer(self, raster_layer, layer_name, save_style=False): """Add a raster layer to the folder. :param raster_layer: The layer to add. :type raster_layer: QgsRasterLayer :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. Not implemented in geopackage ! :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 """ source = gdal.Open(raster_layer.source()) array = source.GetRasterBand(1).ReadAsArray() x_size = source.RasterXSize y_size = source.RasterYSize output = self.raster_driver.Create( self.uri.absoluteFilePath(), x_size, y_size, 1, gdal.GDT_Byte, ['APPEND_SUBDATASET=YES', 'RASTER_TABLE=%s' % layer_name]) output.SetGeoTransform(source.GetGeoTransform()) output.SetProjection(source.GetProjection()) output.GetRasterBand(1).WriteArray(array) # Once we're done, close properly the dataset output = None source = None return True, layer_name def _add_tabular_layer(self, tabular_layer, layer_name, save_style=False): """Add a tabular layer to the geopackage. :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. Not implemented in geopackage ! :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 """ return self._add_vector_layer(tabular_layer, layer_name, save_style)
def workerFinished(self, ok, ret): """Handles the output from the worker and cleans up after the worker has finished.""" # clean up the worker and thread self.showInfo("Handling the result") self.worker.deleteLater() self.thread.quit() self.thread.wait() self.thread.deleteLater() # remove widget from message bar (pop) self.iface.messageBar().popWidget(self.messageBar) if ok and ret is not None: #self.showInfo("Ret: "+str(ret[10,])) # Transformation: self.minx = self.thinninglayer.extent().xMinimum() self.maxx = self.thinninglayer.extent().xMaximum() self.miny = self.thinninglayer.extent().yMinimum() self.maxy = self.thinninglayer.extent().yMaximum() self.rows = self.thinninglayer.height() self.cols = self.thinninglayer.width() self.xres = (self.maxx - self.minx) / float(self.cols) self.yres = (self.maxy - self.miny) / float(self.rows) geotransform = (self.minx, self.xres, 0, self.maxy, 0, -self.yres) try: format = self.DEFAULTPROVIDER driver = gdal.GetDriverByName(format) NOVALUE = 0 metadata = driver.GetMetadata() fileName = self.outputRaster.text() if self.outputRaster.text() == "": self.showInfo("No output file specified, " + "creating a temporary file") # Get a temporary file fileName = mktemp(prefix='greyskel', suffix=self.DEFAULTEXTENSION) fileInfo = QFileInfo(fileName) filepath = fileInfo.absolutePath() baseName = fileInfo.baseName() suffix = fileInfo.suffix() thisfilename = filepath + baseName + '.' + suffix thisfilename = fileName self.showInfo("File name: " + thisfilename) gdaldatatype = gdal.GDT_Byte skelmatrix = None if self.levelValuesCheckBox.isChecked(): # Transform the pixel values back to the original # level values my_dict = {} # Add zero to handle the "empty" pixels my_dict[0] = 0 for i in range(len(self.levels)): my_dict[i + 1] = self.levels[i] skelmatrix = np.vectorize(my_dict.__getitem__, otypes=[np.float])(ret) gdaldatatype = gdal.GDT_Int32 if not self.intband: gdaldatatype = gdal.GDT_Float32 else: skelmatrix = ret outDataset = driver.Create(thisfilename, self.cols, self.rows, 1, gdaldatatype) if self.thinninglayer.dataProvider().crs() is not None: srs = self.thinninglayer.dataProvider().crs() outDataset.SetProjection(srs.toWkt().encode('ascii', 'ignore')) skeletonband = outDataset.GetRasterBand(1) skeletonband.WriteArray(skelmatrix) skeletonband.SetNoDataValue(NOVALUE) #stats = skeletonband.GetStatistics(False, True) #skeletonband.SetStatistics(stats[0], stats[1], # stats[2], stats[3]) outDataset.SetGeoTransform(geotransform) outDataset = None # To close the file # report the result rlayer = QgsRasterLayer(thisfilename, baseName) self.layerlistchanging = True #QgsMapLayerRegistry.instance().addMapLayer(rlayer) QgsProject.instance().addMapLayer(rlayer) self.layerlistchanging = False except: import traceback self.showError("Can't write the skeleton file: %s" % self.outputRaster.text() + ' - ' + traceback.format_exc()) okb = self.button_box.button(QDialogButtonBox.Ok) okb.setEnabled(True) closb = self.button_box.button(QDialogButtonBox.Close) closb.setEnabled(True) cancb = self.button_box.button(QDialogButtonBox.Cancel) cancb.setEnabled(False) return QgsMessageLog.logMessage(self.tr('ThinGreyscale finished'), self.THINGREYSCALE, Qgis.Info) else: # notify the user that something went wrong if not ok: self.showError(self.tr('Aborted') + '!') else: self.showError(self.tr('No skeleton created') + '!') self.progressBar.setValue(0.0) #self.aprogressBar.setValue(0.0) self.iterProgressBar.setValue(0.0) self.button_box.button(QDialogButtonBox.Ok).setEnabled(True) self.button_box.button(QDialogButtonBox.Close).setEnabled(True) self.button_box.button(QDialogButtonBox.Cancel).setEnabled(False)
def workerFinished(self, ok, ret): """Handles the output from the worker and cleans up after the worker has finished.""" # clean up the worker and thread self.showInfo("Handling the result") self.worker.deleteLater() self.thread.quit() self.thread.wait() self.thread.deleteLater() # remove widget from message bar (pop) self.iface.messageBar().popWidget(self.messageBar) if ok and ret is not None: #self.showInfo("Ret: "+str(ret[10,])) # Transformation: self.minx = self.thinninglayer.extent().xMinimum() self.maxx = self.thinninglayer.extent().xMaximum() self.miny = self.thinninglayer.extent().yMinimum() self.maxy = self.thinninglayer.extent().yMaximum() self.rows = self.thinninglayer.height() self.cols = self.thinninglayer.width() self.xres = (self.maxx - self.minx) / float(self.cols) self.yres = (self.maxy - self.miny) / float(self.rows) geotransform = (self.minx, self.xres, 0, self.maxy, 0, -self.yres) try: format = self.DEFAULTPROVIDER driver = gdal.GetDriverByName(format) NOVALUE = 0 metadata = driver.GetMetadata() fileName = self.outputRaster.text() if self.outputRaster.text() == "": self.showInfo("No output file specified, " + "creating a temporary file") # Get a temporary file fileName = mktemp(prefix='greyskel', suffix=self.DEFAULTEXTENSION) fileInfo = QFileInfo(fileName) filepath = fileInfo.absolutePath() baseName = fileInfo.baseName() suffix = fileInfo.suffix() thisfilename = filepath + baseName + '.' + suffix thisfilename = fileName self.showInfo("File name: " + thisfilename) gdaldatatype = gdal.GDT_Byte skelmatrix = None if self.levelValuesCheckBox.isChecked(): # Transform the pixel values back to the original # level values my_dict = {} # Add zero to handle the "empty" pixels my_dict[0] = 0 for i in range(len(self.levels)): my_dict[i + 1] = self.levels[i] skelmatrix = np.vectorize(my_dict.__getitem__, otypes=[np.float])(ret) gdaldatatype = gdal.GDT_Int32 if not self.intband: gdaldatatype = gdal.GDT_Float32 else: skelmatrix = ret outDataset = driver.Create(thisfilename, self.cols, self.rows, 1, gdaldatatype) if self.thinninglayer.dataProvider().crs() is not None: srs = self.thinninglayer.dataProvider().crs() outDataset.SetProjection(srs.toWkt().encode( 'ascii', 'ignore')) skeletonband = outDataset.GetRasterBand(1) skeletonband.WriteArray(skelmatrix) skeletonband.SetNoDataValue(NOVALUE) #stats = skeletonband.GetStatistics(False, True) #skeletonband.SetStatistics(stats[0], stats[1], # stats[2], stats[3]) outDataset.SetGeoTransform(geotransform) outDataset = None # To close the file # report the result rlayer = QgsRasterLayer(thisfilename, baseName) self.layerlistchanging = True #QgsMapLayerRegistry.instance().addMapLayer(rlayer) QgsProject.instance().addMapLayer(rlayer) self.layerlistchanging = False except: import traceback self.showError("Can't write the skeleton file: %s" % self.outputRaster.text() + ' - ' + traceback.format_exc()) okb = self.button_box.button(QDialogButtonBox.Ok) okb.setEnabled(True) closb = self.button_box.button(QDialogButtonBox.Close) closb.setEnabled(True) cancb = self.button_box.button(QDialogButtonBox.Cancel) cancb.setEnabled(False) return QgsMessageLog.logMessage(self.tr('ThinGreyscale finished'), self.THINGREYSCALE, Qgis.Info) else: # notify the user that something went wrong if not ok: self.showError(self.tr('Aborted') + '!') else: self.showError(self.tr('No skeleton created') + '!') self.progressBar.setValue(0.0) #self.aprogressBar.setValue(0.0) self.iterProgressBar.setValue(0.0) self.button_box.button(QDialogButtonBox.Ok).setEnabled(True) self.button_box.button(QDialogButtonBox.Close).setEnabled(True) self.button_box.button(QDialogButtonBox.Cancel).setEnabled(False)
class GeoPackage(DataStore): """ GeoPackage DataStore .. versionadded:: 4.0 """ def __init__(self, uri): """ Constructor for the GeoPackage DataStore. :param uri: A filepath which doesn't exist :type uri: QFileInfo, str .. versionadded:: 4.0 """ super(GeoPackage, self).__init__(uri) self.vector_driver = ogr.GetDriverByName('GPKG') self.raster_driver = gdal.GetDriverByName('GPKG') if isinstance(uri, QFileInfo): self._uri = uri elif isinstance(uri, str): self._uri = QFileInfo(uri) else: raise ErrorDataStore('Unknown type') if self.uri.exists(): raster_datasource = gdal.Open(self.uri.absoluteFilePath()) if raster_datasource is None: # Let's try if it's a vector one. vector_datasource = self.vector_driver.Open( self.uri.absoluteFilePath()) if vector_datasource is None: msg = 'The file is not a geopackage or it doesn\'t ' \ 'contain any layers.' raise ErrorDataStore(msg) else: path = self.uri.absoluteFilePath() # We need this variable to be created. The delete will create it. datasource = self.vector_driver.CreateDataSource(path) # NOQA del datasource @property def uri_path(self): """Return the URI of the datastore as a path. It's not a layer URI. :return: The URI. :rtype: str .. versionadded:: 4.0 """ return self.uri.absolutePath() def is_writable(self): """Check if the folder is writable. :return: If it's writable or not. :rtype: bool .. versionadded:: 4.0 """ # Fixme, need to check DB permissions ? return self._uri.absolutePath().isWritable() def supports_rasters(self): """Check if we can support raster in the geopackage. :return: If it's writable or not. :rtype: bool .. versionadded:: 4.0 """ if int(gdal.VersionInfo('VERSION_NUM')) < 2000000: return False else: return True def _vector_layers(self): """Return a list of vector layers available. :return: List of vector layers available in the geopackage. :rtype: list .. versionadded:: 4.0 """ layers = [] vector_datasource = self.vector_driver.Open( self.uri.absoluteFilePath()) if vector_datasource: for i in range(vector_datasource.GetLayerCount()): layers.append(vector_datasource.GetLayer(i).GetName()) return layers def _raster_layers(self): """Return a list of raster layers available. :return: List of raster layers available in the geopackage. :rtype: list .. versionadded:: 4.0 """ layers = [] raster_datasource = gdal.Open(self.uri.absoluteFilePath()) if raster_datasource: subdatasets = raster_datasource.GetSubDatasets() if len(subdatasets) == 0: metadata = raster_datasource.GetMetadata() layers.append(metadata['IDENTIFIER']) else: for subdataset in subdatasets: layers.append(subdataset[0].split(':')[2]) return layers def layers(self): """Return a list of layers available. :return: List of layers available in the datastore. :rtype: list .. versionadded:: 4.0 """ return self._vector_layers() + self._raster_layers() def layer_uri(self, layer_name): """Get layer URI. For a vector layer : /path/to/the/geopackage.gpkg|layername=my_vector_layer For a raster : GPKG:/path/to/the/geopackage.gpkg:my_raster_layer :param layer_name: The name of the layer to fetch. :type layer_name: str :return: The URI to the layer. :rtype: str .. versionadded:: 4.0 """ for layer in self._vector_layers(): if layer == layer_name: uri = '{}|layername={}'.format( self.uri.absoluteFilePath(), layer_name) return uri else: for layer in self._raster_layers(): if layer == layer_name: uri = 'GPKG:{}:{}'.format( self.uri.absoluteFilePath(), layer_name) return uri else: return None def _add_vector_layer(self, vector_layer, layer_name, save_style=False): """Add a vector layer to the geopackage. :param vector_layer: The layer to add. :type vector_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. Not implemented in geopackage ! :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 """ # Fixme # if not self.is_writable(): # return False, 'The destination is not writable.' geometry = QGIS_OGR_GEOMETRY_MAP[vector_layer.wkbType()] spatial_reference = osr.SpatialReference() qgis_spatial_reference = vector_layer.crs().authid() # Use 4326 as default if the spatial reference is not found epsg = 4326 epsg_string = qgis_spatial_reference if epsg_string: epsg = int(epsg_string.split(':')[1]) spatial_reference.ImportFromEPSG(epsg) vector_datasource = self.vector_driver.Open( self.uri.absoluteFilePath(), True) vector_datasource.CreateLayer(layer_name, spatial_reference, geometry) uri = '{}|layerid=0'.format(self.uri.absoluteFilePath()) vector_layer = QgsVectorLayer(uri, layer_name, 'ogr') data_provider = vector_layer.dataProvider() for feature in vector_layer.getFeatures(): data_provider.addFeatures([feature]) return True, layer_name def _add_raster_layer(self, raster_layer, layer_name, save_style=False): """Add a raster layer to the folder. :param raster_layer: The layer to add. :type raster_layer: QgsRasterLayer :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. Not implemented in geopackage ! :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 """ source = gdal.Open(raster_layer.source()) array = source.GetRasterBand(1).ReadAsArray() x_size = source.RasterXSize y_size = source.RasterYSize output = self.raster_driver.Create( self.uri.absoluteFilePath(), x_size, y_size, 1, gdal.GDT_Byte, ['APPEND_SUBDATASET=YES', 'RASTER_TABLE=%s' % layer_name] ) output.SetGeoTransform(source.GetGeoTransform()) output.SetProjection(source.GetProjection()) output.GetRasterBand(1).WriteArray(array) # Once we're done, close properly the dataset output = None source = None return True, layer_name def _add_tabular_layer(self, tabular_layer, layer_name, save_style=False): """Add a tabular layer to the geopackage. :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. Not implemented in geopackage ! :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 """ return self._add_vector_layer(tabular_layer, layer_name, save_style)
def demProcessed(self): """ Return true if we can proceed with HRU creation. Return false if any required project setting is not found in the project file Return true if: Using existing watershed and watershed grid exists and is newer than dem or Not using existing watershed and filled dem exists and is no older than dem, and watershed shapefile exists and is no older than filled dem """ proj = QgsProject.instance() if not proj: QSWATUtils.loginfo('demProcessed failed: no project') return False title = proj.title() root = proj.layerTreeRoot() demFile, found = proj.readEntry(title, 'delin/DEM', '') if not found or demFile == '': QSWATUtils.loginfo('demProcessed failed: no DEM') return False demFile = proj.readPath(demFile) demLayer, _ = QSWATUtils.getLayerByFilename(root.findLayers(), demFile, FileTypes._DEM, self._gv, None, QSWATUtils._WATERSHED_GROUP_NAME) if not demLayer: QSWATUtils.loginfo('demProcessed failed: no DEM layer') return False self._gv.demFile = demFile self._gv.elevationNoData = demLayer.dataProvider().sourceNoDataValue(1) units = demLayer.crs().mapUnits() factor = 1 if units == QgsUnitTypes.DistanceMeters else Parameters._FEETTOMETRES if units == QgsUnitTypes.DistanceFeet else 0 if factor == 0: QSWATUtils.loginfo('demProcessed failed: units are {0!s}'.format(units)) return False self._gv.cellArea = demLayer.rasterUnitsPerPixelX() * demLayer.rasterUnitsPerPixelY() * factor * factor # hillshade Delineation.addHillshade(demFile, root, demLayer, self._gv) outletFile, found = proj.readEntry(title, 'delin/outlets', '') if found and outletFile != '': outletFile = proj.readPath(outletFile) outletLayer, _ = \ QSWATUtils.getLayerByFilename(root.findLayers(), outletFile, FileTypes._OUTLETS, self._gv, None, QSWATUtils._WATERSHED_GROUP_NAME) if not outletLayer: QSWATUtils.loginfo('demProcessed failed: no outlet layer') return False else: outletLayer = None self._gv.outletFile = outletFile self._gv.existingWshed = proj.readBoolEntry(title, 'delin/existingWshed', False)[0] self._gv.useGridModel = proj.readBoolEntry(title, 'delin/useGridModel', False)[0] self._gv.useLandscapes = proj.readBoolEntry(title, 'lsu/useLandscapes', False)[0] streamFile, found = proj.readEntry(title, 'delin/net', '') if self._gv.useGridModel or not self._gv.existingWshed: if not found or streamFile == '': QSWATUtils.loginfo('demProcessed failed: no streams shapefile') return False streamFile = proj.readPath(streamFile) ft = FileTypes._GRIDSTREAMS if self._gv.useGridModel else FileTypes._STREAMS streamLayer, _ = \ QSWATUtils.getLayerByFilename(root.findLayers(), streamFile, ft, self._gv, None, QSWATUtils._WATERSHED_GROUP_NAME) if not streamLayer: QSWATUtils.loginfo('demProcessed failed: no streams layer') return False self._gv.streamFile = streamFile if self._gv.useGridModel: self._gv.gridSize, found = proj.readNumEntry(title, 'delin/gridSize', 0) if not found or self._gv.gridSize <= 0: QSWATUtils.loginfo('demProcessed failed: grid size not set') return False else: channelFile, found = proj.readEntry(title, 'delin/channels', '') if not found or channelFile == '': QSWATUtils.loginfo('demProcessed failed: no channels shapefile') return False channelFile = proj.readPath(channelFile) channelLayer, _ = \ QSWATUtils.getLayerByFilename(root.findLayers(), channelFile, FileTypes._CHANNELS, self._gv, None, QSWATUtils._WATERSHED_GROUP_NAME) if not channelLayer: QSWATUtils.loginfo('demProcessed failed: no channels layer') return False self._gv.channelFile = channelFile subbasinsFile, found = proj.readEntry(title, 'delin/subbasins', '') if not found or subbasinsFile == '': QSWATUtils.loginfo('demProcessed failed: no subbasins shapefile') return False subbasinsFile = proj.readPath(subbasinsFile) subbasinsInfo = QFileInfo(subbasinsFile) subbasinsTime = subbasinsInfo.lastModified() subbasinsLayer, _ = \ QSWATUtils.getLayerByFilename(root.findLayers(), subbasinsFile, FileTypes._SUBBASINS, self._gv, None, QSWATUtils._WATERSHED_GROUP_NAME) if not subbasinsLayer: QSWATUtils.loginfo('demProcessed failed: no subbasins layer') return False self._gv.subbasinsFile = subbasinsFile self._gv.subsNoLakesFile, _ = proj.readEntry(title, 'delin/subsNoLakes', '') if self._gv.subsNoLakesFile != '': self._gv.subsNoLakesFile = proj.readPath(self._gv.subsNoLakesFile) if not self._gv.useGridModel: wshedFile, found = proj.readEntry(title, 'delin/wshed', '') if not found or wshedFile == '': QSWATUtils.loginfo('demProcessed failed: no wshed shapefile') return False wshedFile = proj.readPath(wshedFile) if self._gv.existingWshed: wshedLayer, _ = \ QSWATUtils.getLayerByFilename(root.findLayers(), wshedFile, FileTypes._EXISTINGWATERSHED, self._gv, None, QSWATUtils._WATERSHED_GROUP_NAME) if not wshedLayer: QSWATUtils.loginfo('demProcessed failed: no wshed layer') return False self._gv.wshedFile = wshedFile demInfo = QFileInfo(demFile) if not demInfo.exists(): QSWATUtils.loginfo('demProcessed failed: no DEM info') return False base = QSWATUtils.join(demInfo.absolutePath(), demInfo.baseName()) if not self._gv.existingWshed: burnFile, found = proj.readEntry(title, 'delin/burn', '') if found and burnFile != '': burnFile = proj.readPath(burnFile) if not os.path.exists(burnFile): QSWATUtils.loginfo('demProcessed failed: no burn file') return False self._gv.slopeFile = base + 'slope.tif' else: self._gv.slopeFile = base + 'slp.tif' else: self._gv.slopeFile = base + 'slp.tif' if not os.path.exists(self._gv.slopeFile): QSWATUtils.loginfo('demProcessed failed: no slope raster') return False self._gv.basinFile = base + 'wStream.tif' if not self._gv.useGridModel: self._gv.channelBasinFile = base + 'wChannel.tif' self._gv.srcChannelFile = base + 'srcChannel.tif' streamDrainage = proj.readBoolEntry(title, 'delin/streamDrainage', False)[0] if self._gv.existingWshed: if not self._gv.useGridModel: if not os.path.exists(self._gv.basinFile): QSWATUtils.loginfo('demProcessed failed: no subbasins raster') return False else: self._gv.pFile = base + 'p.tif' if not os.path.exists(self._gv.pFile): QSWATUtils.loginfo('demProcessed failed: no p raster') return False self._gv.felFile = base + 'fel.tif' felInfo = QFileInfo(self._gv.felFile) if not (felInfo.exists() and subbasinsInfo.exists()): QSWATUtils.loginfo('demProcessed failed: no filled raster') return False self._gv.ad8File = base + 'ad8.tif' if not os.path.exists(self._gv.ad8File): QSWATUtils.loginfo('demProcessed failed: no D8 accumulation raster') return False demTime = demInfo.lastModified() felTime = felInfo.lastModified() if not (demTime <= felTime <= subbasinsTime): QSWATUtils.loginfo('demProcessed failed: not up to date') return False self._gv.distStFile = base + 'distst.tif' if not os.path.exists(self._gv.distStFile): QSWATUtils.loginfo('demProcessed failed: no distance to outlet raster') return False self._gv.distChFile = base + 'distch.tif' if not self._gv.useGridModel: if not os.path.exists(self._gv.distChFile): QSWATUtils.loginfo('demProcessed failed: no distance to channel raster') return False valleyDepthsFile = base + 'depths.tif' if os.path.exists(valleyDepthsFile): self._gv.valleyDepthsFile = valleyDepthsFile # no longer compulsory # if not os.path.exists(self._gv.valleyDepthsFile): # QSWATUtils.loginfo('demProcessed failed: no valley depths raster') # return False if not self._gv.useGridModel: if not os.path.exists(self._gv.channelBasinFile): QSWATUtils.loginfo('demProcessed failed: no channel basins raster') return False snapFile, found = proj.readEntry(title, 'delin/snapOutlets', '') if found and snapFile != '': snapFile = proj.readPath(snapFile) if os.path.exists(snapFile): self._gv.snapFile = snapFile else: snapFile = '' else: snapFile = '' lakeLayer = None lakeFile, found = proj.readEntry(title, 'delin/lakes', '') if found and lakeFile != '': lakeFile = proj.readPath(lakeFile) if os.path.exists(lakeFile): self._gv.lakeFile = lakeFile lakeLayer = QgsVectorLayer(lakeFile, 'Lakes', 'ogr') if self._gv.useGridModel: gridLakesAdded = proj.readBoolEntry(title, 'delin/gridLakesAdded', False)[0] if not gridLakesAdded: QSWATUtils.loginfo('demProcessed failed: grid lakes not added') return False else: chBasinNoLakeFile = base + 'wChannelNoLake.tif' if os.path.exists(chBasinNoLakeFile): self._gv.chBasinNoLakeFile = chBasinNoLakeFile if not self._gv.existingWshed: lakePointsAdded = proj.readBoolEntry(title, 'delin/lakePointsAdded', False)[0] if not lakePointsAdded: QSWATUtils.loginfo('demProcessed failed: lake points not added') return False else: QSWATUtils.loginfo('demProcessed failed: no channel basins without lakes raster') return False playaFile = os.path.splitext(self._gv.demFile)[0] + 'playa.tif' if QSWATUtils.isUpToDate(lakeFile, playaFile): self._gv.playaFile = playaFile snapLayer = outletLayer if snapFile == '' else QgsVectorLayer(self._gv.snapFile, 'Snapped outlets', 'ogr') chanLayer = streamLayer if self._gv.useGridModel else channelLayer if self._gv.existingWshed: ad8Layer = None else: ad8Layer = QgsRasterLayer(self._gv.ad8File, 'Accumulation') if not self._gv.topo.setUp0(demLayer, chanLayer, snapLayer, ad8Layer, self._gv): return False basinIndex = self._gv.topo.getIndex(subbasinsLayer, QSWATTopology._POLYGONID) if basinIndex < 0: return False for feature in subbasinsLayer.getFeatures(): basin = feature.attributes()[basinIndex] centroid = feature.geometry().centroid().asPoint() self._gv.topo.basinCentroids[basin] = (centroid.x(), centroid.y()) if lakeLayer is not None: if not self._gv.topo.readLakesData(self._gv.db): QSWATUtils.loginfo('demProcessed failed: lakes data not read') return False # this can go wrong if eg the streams and watershed files exist but are inconsistent try: if not self._gv.topo.setUp(demLayer, chanLayer, subbasinsLayer, snapLayer, lakeLayer, self._gv, self._gv.existingWshed, False, self._gv.useGridModel, streamDrainage, False): QSWATUtils.loginfo('demProcessed failed: topo setup failed') return False if len(self._gv.topo.inlets) == 0: # no inlets, so no need to expand subbasins layer legend treeSubbasinsLayer = root.findLayer(subbasinsLayer.id()) treeSubbasinsLayer.setExpanded(False) except Exception: QSWATUtils.loginfo('demProcessed failed: topo setup raised exception: {0}'.format(traceback.format_exc())) return False return True
def saveList(self): file, _ = QFileDialog.getSaveFileName( None, "Save segment list to file.", self.fileName, "" ) if file == "": return f = open(file, "w") # update selected file's folder fInfo = QFileInfo(file) self.fPath = fInfo.absolutePath() self.saveConf() if self.pluginGui.radioButton_azimuthAngle.isChecked(): s = "Azimuth" elif self.pluginGui.radioButton_bearingAngle.isChecked(): s = "Bearing" f.write("angle=" + s + "\n") if self.pluginGui.radioButton_defaultNorth.isChecked(): s = "Coordinate_System" elif self.pluginGui.radioButton_magNorth.isChecked(): s = "Magnetic" f.write("heading=" + s + "\n") if hasattr(self, "magDev") and self.magDev != 0.0: f.write("declination=" + str(self.magDev) + "\n") if self.pluginGui.radioButton_defaultUnits.isChecked(): s = "Default" elif self.pluginGui.radioButton_englishUnits.isChecked(): s = "Feet" f.write("dist_units=" + s + "\n") if self.pluginGui.radioButton_degreeUnit.isChecked(): s = "degree" elif self.pluginGui.radioButton_gradianUnit.isChecked(): s = "gradian" f.write("angle_unit=" + s + "\n") f.write( "startAt=" + str(self.pluginGui.lineEdit_vertexX0.text()) + ";" + str(self.pluginGui.lineEdit_vertexY0.text()) + ";" + str(self.pluginGui.lineEdit_vertexZ0.text()) + "\n" ) if self.pluginGui.radioButton_boundarySurvey.isChecked(): s = "Polygonal" elif self.pluginGui.radioButton_radialSurvey.isChecked(): s = "Radial" f.write("survey=" + s + "\n") f.write("[data]\n") for row in range(self.pluginGui.table_segmentList.rowCount()): line = ( str(self.pluginGui.table_segmentList.item(row, 0).text()) + ";" + str(self.pluginGui.table_segmentList.item(row, 1).text()) + ";" + str(self.pluginGui.table_segmentList.item(row, 2).text()) + ";" + str(self.pluginGui.table_segmentList.item(row, 3).text()) + ";" + str(self.pluginGui.table_segmentList.item(row, 4).text()) ) f.write(line + "\n") f.close()