예제 #1
0
def setup_translation(file_pattern="{}.qm", folder=None):
    """Find the translation file according to locale.

    :param file_pattern: Custom file pattern to use to find QM files.
    :type file_pattern: basestring

    :param folder: Optional folder to look in if it's not the default.
    :type folder: basestring

    :return: The locale and the file path to the QM file, or None.
    :rtype: (basestring, basestring)
    """
    locale = QgsSettings().value("locale/userLocale", QLocale().name())

    if folder:
        ts_file = QFileInfo(join(folder, file_pattern.format(locale)))
    else:
        ts_file = QFileInfo(resources_path("i18n", file_pattern.format(locale)))
    if ts_file.exists():
        return locale, ts_file.absoluteFilePath()

    if folder:
        ts_file = QFileInfo(join(folder, file_pattern.format(locale[0:2])))
    else:
        ts_file = QFileInfo(resources_path("i18n", file_pattern.format(locale[0:2])))
    if ts_file.exists():
        return locale, ts_file.absoluteFilePath()

    return locale, None
예제 #2
0
def setup_translation(
        file_pattern: str = "{}.qm",
        folder: Optional[str] = None) -> Tuple[str, Optional[str]]:
    """Find the translation file according to locale.

    :param file_pattern: Custom file pattern to use to find QM files.
    :type file_pattern: basestring

    :param folder: Optional folder to look in if it's not the default.
    :type folder: basestring

    :return: The locale and the file path to the QM file, or None.
    :rtype: (basestring, basestring)
    """
    locale = QgsSettings().value("locale/userLocale", QLocale().name())

    for prefix in ['', f'{plugin_name()}_', f'{slug_name()}_']:
        for fldr in [folder, plugin_path('i18n'), resources_path("i18n")]:
            prefixed_locale = prefix + locale
            if fldr:
                ts_file = QFileInfo(
                    join(fldr, file_pattern.format(prefixed_locale)))
                if ts_file.exists():
                    return locale, ts_file.absoluteFilePath()

            prefixed_locale = prefix + locale[0:2]
            if fldr:
                ts_file = QFileInfo(
                    join(fldr, file_pattern.format(prefixed_locale)))
                if ts_file.exists():
                    return locale, ts_file.absoluteFilePath()

    return locale, None
예제 #3
0
파일: folder.py 프로젝트: inasafe/inasafe
    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.
        :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
        """
        if not self.is_writable():
            return False, 'The destination is not writable.'

        output = QFileInfo(self.uri.filePath(layer_name + '.tif'))

        source = QFileInfo(raster_layer.source())
        if source.exists() and source.suffix() in ['tiff', 'tif']:
            # If it's tiff file based.
            QFile.copy(source.absoluteFilePath(), output.absoluteFilePath())

        else:
            # If it's not file based.
            renderer = raster_layer.renderer()
            provider = raster_layer.dataProvider()
            crs = raster_layer.crs()

            pipe = QgsRasterPipe()
            pipe.set(provider.clone())
            pipe.set(renderer.clone())

            file_writer = QgsRasterFileWriter(output.absoluteFilePath())
            file_writer.Mode(1)

            file_writer.writeRaster(
                pipe,
                provider.xSize(),
                provider.ySize(),
                provider.extent(),
                crs)

            del file_writer

        if save_style:
            style_path = QFileInfo(self.uri.filePath(layer_name + '.qml'))
            raster_layer.saveNamedStyle(style_path.absoluteFilePath())

        assert output.exists()
        return True, output.baseName()
예제 #4
0
    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.
        :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
        """
        if not self.is_writable():
            return False, 'The destination is not writable.'

        output = QFileInfo(self.uri.filePath(layer_name + '.tif'))

        source = QFileInfo(raster_layer.source())
        if source.exists() and source.suffix() in ['tiff', 'tif']:
            # If it's tiff file based.
            QFile.copy(source.absoluteFilePath(), output.absoluteFilePath())

        else:
            # If it's not file based.
            renderer = raster_layer.renderer()
            provider = raster_layer.dataProvider()
            crs = raster_layer.crs()

            pipe = QgsRasterPipe()
            pipe.set(provider.clone())
            pipe.set(renderer.clone())

            file_writer = QgsRasterFileWriter(output.absoluteFilePath())
            file_writer.Mode(1)

            file_writer.writeRaster(pipe, provider.xSize(), provider.ySize(),
                                    provider.extent(), crs)

            del file_writer

        if save_style:
            style_path = QFileInfo(self.uri.filePath(layer_name + '.qml'))
            raster_layer.saveNamedStyle(style_path.absoluteFilePath())

        assert output.exists()
        return True, output.baseName()
예제 #5
0
    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()
예제 #6
0
    def run(self) -> str:
        """Run the query.

        :return: The result of the query.
        :rtype: str

        :raise OverpassBadRequestException:
        :raise NetWorkErrorException:
        :raise OverpassTimeoutException:
        """
        self.download()

        for message in self.errors:
            self.is_query_timed_out(message)
            self.too_many_request(message)
            self.is_bad_request(message)
            LOGGER.error(message)

        if len(self.errors):
            raise NetWorkErrorException('Overpass API', ', '.join(self.errors))

        osm_file = QFileInfo(self.result_path)
        if not osm_file.exists() and not osm_file.isFile():
            # Do not raise a QuickOSM exception here
            # It must be a bug from QuickOSM
            raise FileNotFoundError

        self.check_file(self.result_path)

        # Everything went fine
        return self.result_path
예제 #7
0
    def batchFinished(self):
        self.base.stop()

        if len(self.errors) > 0:
            msg = u"Processing of the following files ended with error: <br><br>" + "<br><br>".join(self.errors)
            QErrorMessage(self).showMessage(msg)

        inDir = self.getInputFileName()
        outDir = self.getOutputFileName()
        if outDir is None or inDir == outDir:
            self.outFiles = self.inFiles

        # load layers managing the render flag to avoid waste of time
        canvas = self.iface.mapCanvas()
        previousRenderFlag = canvas.renderFlag()
        canvas.setRenderFlag(False)
        notCreatedList = []
        for item in self.outFiles:
            fileInfo = QFileInfo(item)
            if fileInfo.exists():
                if self.base.loadCheckBox.isChecked():
                    self.addLayerIntoCanvas(fileInfo)
            else:
                notCreatedList.append(item)
        canvas.setRenderFlag(previousRenderFlag)

        if len(notCreatedList) == 0:
            QMessageBox.information(self, self.tr("Finished"), self.tr("Operation completed."))
        else:
            QMessageBox.warning(self, self.tr("Warning"), self.tr("The following files were not created: \n{0}").format(', '.join(notCreatedList)))
예제 #8
0
파일: folder.py 프로젝트: inasafe/inasafe
    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()
예제 #9
0
    def batchFinished(self):
        self.base.stop()

        if len(self.errors) > 0:
            msg = u"Processing of the following files ended with error: <br><br>" + "<br><br>".join(self.errors)
            QErrorMessage(self).showMessage(msg)

        inDir = self.getInputFileName()
        outDir = self.getOutputFileName()
        if outDir is None or inDir == outDir:
            self.outFiles = self.inFiles

        # load layers managing the render flag to avoid waste of time
        canvas = self.iface.mapCanvas()
        previousRenderFlag = canvas.renderFlag()
        canvas.setRenderFlag(False)
        notCreatedList = []
        for item in self.outFiles:
            fileInfo = QFileInfo(item)
            if fileInfo.exists():
                if self.base.loadCheckBox.isChecked():
                    self.addLayerIntoCanvas(fileInfo)
            else:
                notCreatedList.append(item)
        canvas.setRenderFlag(previousRenderFlag)

        if len(notCreatedList) == 0:
            QMessageBox.information(self, self.tr("Finished"), self.tr("Operation completed."))
        else:
            QMessageBox.warning(self, self.tr("Warning"), self.tr("The following files were not created: \n{0}").format(', '.join(notCreatedList)))
예제 #10
0
    def start_logging(self):

        if self._logger is not None:
            return
        self._logger = logging.getLogger('Logger1')
        self._logger.setLevel(logging.DEBUG)
        log_full_path_file_name = '%s/log.log' % os.path.dirname(
            os.path.realpath(__file__))

        log_file_info = QFileInfo(log_full_path_file_name)
        if log_file_info.exists():
            log_created_qdatetime = log_file_info.created()
            current_qdatetime = QDateTime.currentDateTime()
            max_difference_secs = 60 * 60 * 24 * 7  # 7 giorni
            current_difference_secs = log_created_qdatetime.secsTo(
                current_qdatetime)
            if current_difference_secs > max_difference_secs:
                QFile.remove(log_full_path_file_name)

        self._log_handler = LogHandler(log_full_path_file_name)
        formatter = logging.Formatter(
            '%(asctime)s - %(thread)d - %(name)s - %(levelname)s - %(message)s'
        )
        self._log_handler.setFormatter(formatter)
        self._logger.addHandler(self._log_handler)

        # Do not raise logging system exceptions
        logging.raiseExceptions = False

        # Connect log signal
        self._log_handler.logged.connect(self.message_logged)

        self.logging_enabled = True
예제 #11
0
    def finished(self):
        outFn = self.getOutputFileName()
        if self.needOverwrite:
            oldFile = QFile(outFn)
            newFile = QFile(self.tempFile)
            if oldFile.remove():
                newFile.rename(outFn)

        fileInfo = QFileInfo(outFn)
        if fileInfo.exists():
            if self.base.loadCheckBox.isChecked():
                self.addLayerIntoCanvas(fileInfo)
            QMessageBox.information(self, self.tr("Finished"), self.tr("Processing completed."))
        else:
            QMessageBox.warning(self, self.tr("Warning"), self.tr("{0} not created.").format(outFn))
예제 #12
0
    def finished(self):
        outFn = self.getOutputFileName()
        if self.needOverwrite:
            oldFile = QFile(outFn)
            newFile = QFile(self.tempFile)
            if oldFile.remove():
                newFile.rename(outFn)

        fileInfo = QFileInfo(outFn)
        if fileInfo.exists():
            if self.base.loadCheckBox.isChecked():
                self.addLayerIntoCanvas(fileInfo)
            QMessageBox.information(self, self.tr("Finished"), self.tr("Processing completed."))
        else:
            QMessageBox.warning(self, self.tr("Warning"), self.tr("{0} not created.").format(outFn))
예제 #13
0
    def finished(self, load):
        outFn = self.getOutputFileName()
        if outFn is None:
            return

        if outFn == '':
            QMessageBox.warning(self, self.tr("Warning"), self.tr("No output file created."))
            return

        fileInfo = QFileInfo(outFn)
        if fileInfo.exists():
            if load:
                self.addLayerIntoCanvas(fileInfo)
            QMessageBox.information(self, self.tr("Finished"), self.tr("Processing completed."))
        else:
            #QMessageBox.warning(self, self.tr( "Warning" ), self.tr( "%1 not created." ).arg( outFn ) )
            QMessageBox.warning(self, self.tr("Warning"), self.tr("%s not created.") % outFn)
예제 #14
0
    def _add_vector_layer(self, vector_layer, layer_name, save_style=False):
        """Add a vector layer to the folder.

        :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.
        :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
        """

        if not self.is_writable():
            return False, 'The destination is not writable.'

        output = QFileInfo(
            self.uri.filePath(layer_name + '.' + self._default_vector_format))

        driver_mapping = {
            'shp': 'ESRI Shapefile',
            'kml': 'KML',
            'geojson': 'GeoJSON',
        }

        QgsVectorFileWriter.writeAsVectorFormat(
            vector_layer,
            output.absoluteFilePath(),
            'utf-8',
            QgsCoordinateTransform(),  # No tranformation
            driver_mapping[self._default_vector_format])

        if save_style:
            style_path = QFileInfo(self.uri.filePath(layer_name + '.qml'))
            vector_layer.saveNamedStyle(style_path.absoluteFilePath())

        assert output.exists()
        return True, output.baseName()
예제 #15
0
파일: folder.py 프로젝트: inasafe/inasafe
    def _add_vector_layer(self, vector_layer, layer_name, save_style=False):
        """Add a vector layer to the folder.

        :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.
        :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
        """

        if not self.is_writable():
            return False, 'The destination is not writable.'

        output = QFileInfo(
            self.uri.filePath(layer_name + '.' + self._default_vector_format))

        driver_mapping = {
            'shp': 'ESRI Shapefile',
            'kml': 'KML',
            'geojson': 'GeoJSON',
        }

        QgsVectorFileWriter.writeAsVectorFormat(
            vector_layer,
            output.absoluteFilePath(),
            'utf-8',
            QgsCoordinateTransform(),  # No tranformation
            driver_mapping[self._default_vector_format])

        if save_style:
            style_path = QFileInfo(self.uri.filePath(layer_name + '.qml'))
            vector_layer.saveNamedStyle(style_path.absoluteFilePath())

        assert output.exists()
        return True, output.baseName()
예제 #16
0
    def layer_uri(self, layer_name):
        """Get layer URI.

        :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
        """
        layers = self.layers()
        for layer, extension in product(layers, EXTENSIONS):
            one_file = QFileInfo(self.uri.filePath(layer + '.' + extension))
            if one_file.exists():
                if one_file.baseName() == layer_name:
                    return one_file.absoluteFilePath()
        else:
            return None
예제 #17
0
        def _getRasterLayer(feature):
            pathfile = feature.attribute('pathfile')
            info = QFileInfo(pathfile)
            if not info.exists():
                return {
                    'isOk': False,
                    'message': "Raster file '{}' not found".format(pathfile)
                }

            sources = dict([(layer.source(), layer)
                            for layer in project.mapLayers().values()])
            if pathfile in sources.keys():
                layer = sources[pathfile]
                needAdd = False
            else:
                name = QFileInfo(pathfile).completeBaseName()
                layer = QgsRasterLayer(pathfile, name)
                needAdd = True
            return {'isOk': True, 'layer': layer, 'needAdd': needAdd}
예제 #18
0
파일: folder.py 프로젝트: inasafe/inasafe
    def layer_uri(self, layer_name):
        """Get layer URI.

        :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
        """
        layers = self.layers()
        for layer, extension in product(layers, EXTENSIONS):
            one_file = QFileInfo(
                self.uri.filePath(layer + '.' + extension))
            if one_file.exists():
                if one_file.baseName() == layer_name:
                    return one_file.absoluteFilePath()
        else:
            return None
예제 #19
0
    def run(self):
        """Run the query.

        @raise OverpassBadRequestException,NetWorkErrorException,
        OverpassTimeoutException

        @return: The result of the query.
        @rtype: str
        """
        loop = QEventLoop()
        downloader = QgsFileDownloader(self._url,
                                       self.result_path,
                                       delayStart=True)
        downloader.downloadExited.connect(loop.quit)
        downloader.downloadError.connect(self.error)
        downloader.downloadCanceled.connect(self.canceled)
        downloader.downloadCompleted.connect(self.completed)
        downloader.startDownload()
        loop.exec_()

        osm_file = QFileInfo(self.result_path)
        if not osm_file.exists() and not osm_file.isFile():
            raise OverpassTimeoutException

        # The download is done, checking for not complete OSM file.
        # Overpass might aborted the request with HTTP 200.
        file_obj = codecs.open(self.result_path, 'r', 'utf-8')
        file_obj.seek(0, 2)
        fsize = file_obj.tell()
        file_obj.seek(max(fsize - 1024, 0), 0)
        lines = file_obj.readlines()
        file_obj.close()
        lines = lines[-10:]  # Get last 10 lines
        timeout = (
            '<remark> runtime error: Query timed out in "[a-z]+" at line '
            '[\d]+ after ([\d]+) seconds. </remark>')
        if re.search(timeout, ''.join(lines)):
            raise OverpassTimeoutException

        # Everything went fine
        return self.result_path
예제 #20
0
def set_source_document_location(doc_path):
    """
    Set the latest source directory of uploaded source documents.
    :param doc_path: Directory path or file path. The system will
     attempt to extract the directory path from the file name.
    """
    doc_dir_path = ""
    # Check if it is a file or directory
    doc_dir = QDir(doc_path)

    if not doc_dir.exists():
        doc_file_info = QFileInfo(doc_path)

        if doc_file_info.exists():
            doc_dir_path = doc_file_info.dir().path()

    else:
        doc_dir_path = doc_path

    if len(doc_dir_path) > 0:
        reg_config = RegistryConfig()
        reg_config.write({LOCAL_SOURCE_DOC: doc_dir_path})
예제 #21
0
    def run(self):
        """Run the query.

        @raise OverpassBadRequestException,NetWorkErrorException,
        OverpassTimeoutException

        @return: The result of the query.
        @rtype: str
        """
        loop = QEventLoop()
        downloader = QgsFileDownloader(self._url,
                                       self.result_path,
                                       delayStart=True)
        downloader.downloadExited.connect(loop.quit)
        downloader.downloadError.connect(self.error)
        downloader.downloadCanceled.connect(self.canceled)
        downloader.downloadCompleted.connect(self.completed)
        downloader.startDownload()
        loop.exec_()

        for message in self.errors:
            self.is_query_timed_out(message)
            self.is_bad_request(message)
            LOGGER.error(message)

        if len(self.errors):
            raise NetWorkErrorException('Overpass API', ', '.join(self.errors))

        osm_file = QFileInfo(self.result_path)
        if not osm_file.exists() and not osm_file.isFile():
            # Do not raise a QuickOSM exception here
            # It must be a bug from QuickOSM
            raise FileNotFoundError

        self.check_file(self.result_path)

        # Everything went fine
        return self.result_path
예제 #22
0
    def reloadData(self):
        self.beginResetModel()
        self._document_list = []

        if self._relation.isValid() is False or self._feature.isValid(
        ) is False:
            self.endResetModel()
            return

        feature_list = []
        layer = self._relation.referencingLayer()
        request = self._relation.getRelatedFeaturesRequest(self._feature)
        for feature in layer.getFeatures(request):
            feature_list.append(feature)

        if self._nmRelation.isValid():
            filters = []
            for joinTableFeature in feature_list:
                referencedFeatureRequest = self._nmRelation.getReferencedFeatureRequest(
                    joinTableFeature)
                filterExpression = referencedFeatureRequest.filterExpression()
                filters.append("(" + filterExpression.expression() + ")")

            nmRequest = QgsFeatureRequest()
            nmRequest.setFilterExpression(" OR ".join(filters))

            feature_list = []
            layer = self._nmRelation.referencedLayer()
            for documentFeature in layer.getFeatures(nmRequest):
                feature_list.append(documentFeature)

        for documentFeature in feature_list:
            documents_path = str()
            if self._documents_path:
                exp = QgsExpression(self._documents_path)
                context = QgsExpressionContext()
                context.appendScopes(
                    QgsExpressionContextUtils.globalProjectLayerScopes(layer))
                context.setFeature(documentFeature)
                documents_path = exp.evaluate(context)

            document_filename = str()
            if self._document_filename:
                exp = QgsExpression(self._document_filename)
                context = QgsExpressionContext()
                context.appendScopes(
                    QgsExpressionContextUtils.globalProjectLayerScopes(layer))
                context.setFeature(documentFeature)
                document_filename = exp.evaluate(context)
            file_info = QFileInfo(QDir(str(documents_path)),
                                  str(document_filename))

            # ToolTip
            toolTipList = []
            toolTipList.append("<ul>")
            for field in documentFeature.fields():
                index = documentFeature.fields().indexFromName(field.name())
                toolTipList.append("<li><strong>{0}</strong>: {1}</li>".format(
                    field.displayName(), documentFeature[index]))
            toolTipList.append("</ul>")

            self._document_list.append({
                self.DocumentIdRole:
                documentFeature.id(),
                self.DocumentPathRole:
                file_info.filePath(),
                self.DocumentNameRole:
                file_info.fileName(),
                self.DocumentExistsRole:
                file_info.exists(),
                self.DocumentToolTipRole:
                "".join(toolTipList),
                self.DocumentIsImageRole:
                PreviewImageProvider.isMimeTypeSupported(file_info.filePath())
            })

        self.endResetModel()
예제 #23
0
    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
예제 #24
0
    def test_create_geopackage(self):
        """Test if we can store geopackage."""

        # Create a geopackage from an empty file.
        path = QFileInfo(mktemp() + '.gpkg')
        self.assertFalse(path.exists())
        data_store = GeoPackage(path)
        path.refresh()
        self.assertTrue(path.exists())

        # Let's add a vector layer.
        layer_name = 'flood_test'
        layer = standard_data_path('hazard', 'flood_multipart_polygons.shp')
        vector_layer = QgsVectorLayer(layer, 'Flood', 'ogr')
        result = data_store.add_layer(vector_layer, layer_name)
        self.assertTrue(result[0])

        # We should have one layer.
        layers = data_store.layers()
        self.assertEqual(len(layers), 1)
        self.assertIn(layer_name, layers)

        # Add the same layer with another name.
        layer_name = 'another_vector_flood'
        result = data_store.add_layer(vector_layer, layer_name)
        self.assertTrue(result[0])

        # We should have two layers.
        layers = data_store.layers()
        self.assertEqual(len(layers), 2)
        self.assertIn(layer_name, layers)

        # Test the URI of the new layer.
        expected = path.absoluteFilePath() + '|layername=' + layer_name
        self.assertEqual(data_store.layer_uri(layer_name), expected)

        # Test a fake layer.
        self.assertIsNone(data_store.layer_uri('fake_layer'))

        # Test to add a raster
        layer_name = 'raster_flood'
        layer = standard_data_path('hazard', 'classified_hazard.tif')
        raster_layer = QgsRasterLayer(layer, layer_name)

        result = data_store.add_layer(raster_layer, layer_name)
        self.assertTrue(result[0])

        # We should have 3 layers inside.
        layers = data_store.layers()
        self.assertEqual(len(layers), 3)

        # Check the URI for the raster layer.
        expected = 'GPKG:' + path.absoluteFilePath() + ':' + layer_name
        self.assertEqual(data_store.layer_uri(layer_name), expected)

        # Add a second raster.
        layer_name = 'big raster flood'
        self.assertTrue(data_store.add_layer(raster_layer, layer_name))
        self.assertEqual(len(data_store.layers()), 4)

        # Test layer without geometry
        layer = load_test_vector_layer(
            'gisv4', 'impacts', 'exposure_summary_table.csv')
        tabular_layer_name = 'breakdown'
        result = data_store.add_layer(layer, tabular_layer_name)
        self.assertTrue(result[0])