예제 #1
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})
예제 #2
0
def get_rat(raster_layer, band, colors=('R', 'G', 'B', 'A')):
    """Extracts RAT from raster layer and given band

    :param raster_layer: the raster layer to classify
    :type raster_layer: QgsRasterLayer
    :param band: band number (1-based)
    :type band: int
    :param colors: default name of the RGB(A) columns for sidecar DBF files, defaults to ('R', 'G', 'B', 'A'), these are searched first
    :type red_column_name: tuple, optional
    :return: RAT
    :rtype: RAT
    """

    headers = []
    values = {}
    fields = {}
    # For sidecar files
    path = None

    COLOR_ROLES = (gdal.GFU_Red, gdal.GFU_Green, gdal.GFU_Blue, gdal.GFU_Alpha)

    is_dbf = False

    ds = gdal.OpenEx(raster_layer.source())
    if ds:
        band = ds.GetRasterBand(band)
        if band:
            rat = band.GetDefaultRAT()
            if rat is not None:
                for i in range(0, rat.GetColumnCount()):
                    column = rat.GetNameOfCol(i)
                    headers.append(column)
                    values[column] = []
                    fields[column] = RATField(
                        column, rat.GetUsageOfCol(i), rat.GetTypeOfCol(i))

                for r in range(0, rat.GetRowCount()):
                    for c in range(0, rat.GetColumnCount()):
                        column = headers[c]
                        if fields[column].type == gdal.GFT_Integer:
                            values[headers[c]].append(rat.GetValueAsInt(r, c))
                        elif fields[column].type == gdal.GFT_Real:
                            values[headers[c]].append(
                                rat.GetValueAsDouble(r, c))
                        else:
                            values[headers[c]].append(
                                html.unescape(rat.GetValueAsString(r, c)))

                # Try to identify fields in case of RAT with wrong usages
                usages = [f.usage for f in fields.values()]
                if gdal.GFU_MinMax not in usages and not {gdal.GFU_Min, gdal.GFU_Max}.issubset(usages):
                    try:
                        field_name = [f.name for f in fields.values() if f.name.upper() == 'VALUE'][0]
                        fields[field_name].usage = gdal.GFU_MinMax
                    except IndexError:
                        pass

                    try:
                        field_name = [f.name for f in fields.values() if f.name.upper() in ('VALUE MIN', 'MIN', 'MIN VALUE', 'VALUE_MIN', 'MIN_VALUE')][0]
                        fields[field_name].usage = gdal.GFU_Min
                    except IndexError:
                        pass

                    try:
                        field_name = [f.name for f in fields.values() if f.name.upper() in ('VALUE MAX', 'MAX', 'MAX VALUE', 'VALUE_MAX', 'MAX_VALUE')][0]
                        fields[field_name].usage = gdal.GFU_Max
                    except IndexError:
                        pass

                if gdal.GFU_PixelCount not in usages:
                    try:
                        field_name = [f.name for f in fields.values() if f.name.upper() == 'COUNT'][0]
                        fields[field_name].usage = gdal.GFU_PixelCount
                    except IndexError:
                        pass

                path = raster_layer.source() + '.aux.xml'

    # Search for sidecar DBF files, `band` is ignored!
    if not values:

        info = QFileInfo(raster_layer.publicSource())
        directory = info.dir().path()
        basename = info.baseName()
        filename = info.fileName()
        candidates = (basename + '.dbf', basename + '.vat.dbf',
                      filename + '.dbf', filename + '.vat.dbf')

        for candidate in candidates:

            if os.path.exists(os.path.join(directory, candidate)):
                rat_layer = QgsVectorLayer(os.path.join(
                    directory, candidate), 'rat', 'ogr')

                if rat_layer.isValid():
                    path = os.path.join(directory, candidate)

                    # Get fields
                    # Check if color fields are there, fall-back to RED GREEN BLUE ALPHA if not
                    field_upper_names = [f.name().upper() for f in rat_layer.fields()]
                    upper_colors = [c.upper() for c in colors]

                    def _search_color():
                        color_found = True
                        for color_field_name in upper_colors[:3]:
                            if color_field_name not in field_upper_names:
                                color_found = False
                        return color_found

                    if not _search_color() and colors == ('R', 'G', 'B', 'A'):
                        upper_colors = ('RED', 'GREEN', 'BLUE', 'ALPHA')

                    # Create fields
                    for f in rat_layer.fields():

                        headers.append(f.name())
                        field_name_upper = f.name().upper()
                        if field_name_upper in upper_colors:
                            fields[f.name()] = RATField(
                                f.name(), COLOR_ROLES[upper_colors.index(field_name_upper)], gdal.GFT_Integer if f.type() in (QVariant.Int, QVariant.LongLong) else gdal.GFT_Real)
                        elif field_name_upper == 'COUNT':
                            fields[f.name()] = RATField(
                                f.name(), gdal.GFU_PixelCount, gdal.GFT_Integer)
                        elif field_name_upper == 'VALUE':
                            fields[f.name()] = RATField(
                                f.name(), gdal.GFU_MinMax, gdal.GFT_Integer if f.type() in (QVariant.Int, QVariant.LongLong) else gdal.GFT_Real)
                        elif field_name_upper in ('VALUE MIN', 'VALUE_MIN', 'MIN VALUE', 'MIN_VALUE'):
                            fields[f.name()] = RATField(
                                f.name(), gdal.GFU_Min, gdal.GFT_Integer if f.type() in (QVariant.Int, QVariant.LongLong) else gdal.GFT_Real)
                        elif field_name_upper in ('VALUE MAX', 'VALUE_MAX', 'MAX VALUE', 'MAX_VALUE'):
                            fields[f.name()] = RATField(
                                f.name(), gdal.GFU_Max, gdal.GFT_Integer if f.type() in (QVariant.Int, QVariant.LongLong) else gdal.GFT_Real)
                        else:
                            if f.type() in (QVariant.Int, QVariant.LongLong):
                                type = gdal.GFT_Integer
                            elif f.type() == QVariant.Double:
                                type = gdal.GFT_Real
                            else:
                                type = gdal.GFT_String

                            fields[f.name()] = RATField(
                                f.name(), gdal.GFU_Generic, type)

                    for header in headers:
                        values[header] = []
                    for f in rat_layer.getFeatures():
                        for header in headers:
                            values[header].append(f.attribute(header))
                    is_dbf = True
                    break

    # Colors
    if headers:
        red = None
        green = None
        blue = None
        alpha = None
        is_integer = False

        for name, f in fields.items():
            if f.usage == gdal.GFU_Red:
                red = name
                is_integer = f.type == gdal.GFT_Integer
                continue
            if f.usage == gdal.GFU_Green:
                green = name
                continue
            if f.usage == gdal.GFU_Blue:
                blue = name
                continue
            if f.usage == gdal.GFU_Alpha:
                alpha = name
                continue

        if red and green and blue:
            headers.append(RAT_COLOR_HEADER_NAME)
            values[RAT_COLOR_HEADER_NAME] = []
            for i in range(len(values[red])):
                func = 'fromRgb' if is_integer else 'fromRgbF'
                if alpha:
                    values[RAT_COLOR_HEADER_NAME].append(getattr(QColor, func)(
                        values[red][i], values[green][i], values[blue][i], values[alpha][i]))
                else:
                    values[RAT_COLOR_HEADER_NAME].append(getattr(QColor, func)(
                        values[red][i], values[green][i], values[blue][i]))

    return RAT(values, is_dbf, fields, path)
예제 #3
0
def get_rat(raster_layer, band, colors=('R', 'G', 'B', 'A')):
    """Extracts RAT from raster layer and given band

    :param raster_layer: the raster layer to classify
    :type raster_layer: QgsRasterLayer
    :param band: band number (1-based)
    :type band: int
    :param colors: name of the RGB(A) columns for sidecar DBF files, defaults to ('R', 'G', 'B', 'A')
    :type red_column_name: tuple, optional
    :return: RAT
    :rtype: RAT
    """

    headers = []
    values = {}
    fields = {}
    # For sidecar files
    path = None

    COLOR_ROLES = (gdal.GFU_Red, gdal.GFU_Green, gdal.GFU_Blue, gdal.GFU_Alpha)

    is_sidecar = False

    ds = gdal.OpenEx(raster_layer.source())
    if ds:
        band = ds.GetRasterBand(band)
        if band:
            rat = band.GetDefaultRAT()
            if rat is not None:
                for i in range(0, rat.GetColumnCount()):
                    column = rat.GetNameOfCol(i)
                    headers.append(column)
                    values[column] = []
                    fields[column] = RATField(column, rat.GetUsageOfCol(i),
                                              rat.GetTypeOfCol(i))

                for r in range(0, rat.GetRowCount()):
                    for c in range(0, rat.GetColumnCount()):
                        column = headers[c]
                        if fields[column].type == gdal.GFT_Integer:
                            values[headers[c]].append(rat.GetValueAsInt(r, c))
                        elif fields[column].type == gdal.GFT_Real:
                            values[headers[c]].append(
                                rat.GetValueAsDouble(r, c))
                        else:
                            values[headers[c]].append(
                                html.unescape(rat.GetValueAsString(r, c)))

            path = raster_layer.source() + '.aux.xml'

    # Search for sidecar DBF files, `band` is ignored!
    if not values:

        info = QFileInfo(raster_layer.publicSource())
        directory = info.dir().path()
        basename = info.baseName()
        filename = info.fileName()
        candidates = (basename + '.dbf', basename + '.vat.dbf',
                      filename + '.dbf', filename + '.vat.dbf')

        for candidate in candidates:
            if os.path.exists(os.path.join(directory, candidate)):
                rat_layer = QgsVectorLayer(os.path.join(directory, candidate),
                                           'rat', 'ogr')
                if rat_layer.isValid():
                    path = os.path.join(directory, candidate)
                    for f in rat_layer.fields():
                        headers.append(f.name())
                        if f.name().upper() in colors:
                            fields[f.name()] = RATField(
                                f.name(),
                                COLOR_ROLES[colors.index(f.name().upper())],
                                gdal.GFT_Integer if f.type()
                                in (QVariant.Int,
                                    QVariant.LongLong) else gdal.GFT_Real)
                        elif f.name().upper() == 'COUNT':
                            fields[f.name()] = RATField(
                                f.name(), gdal.GFU_PixelCount,
                                gdal.GFT_Integer)
                        elif f.name().upper() == 'VALUE':
                            fields[f.name()] = RATField(
                                f.name(), gdal.GFU_MinMax,
                                gdal.GFT_Integer if f.type()
                                in (QVariant.Int,
                                    QVariant.LongLong) else gdal.GFT_Real)
                        else:
                            if f.type() in (QVariant.Int, QVariant.LongLong):
                                type = gdal.GFT_Integer
                            elif f.type() == QVariant.Double:
                                type = gdal.GFT_Real
                            else:
                                type = gdal.GFT_String

                            fields[f.name()] = RATField(
                                f.name(), gdal.GFU_Generic, type)

                    for header in headers:
                        values[header] = []
                    for f in rat_layer.getFeatures():
                        for header in headers:
                            values[header].append(f.attribute(header))
                    is_sidecar = True
                    break

    # Colors
    if headers:
        red = None
        green = None
        blue = None
        alpha = None
        is_integer = False

        for name, f in fields.items():
            if f.usage == gdal.GFU_Red:
                red = name
                is_integer = f.type == gdal.GFT_Integer
                continue
            if f.usage == gdal.GFU_Green:
                green = name
                continue
            if f.usage == gdal.GFU_Blue:
                blue = name
                continue
            if f.usage == gdal.GFU_Alpha:
                alpha = name
                continue

        if red and green and blue:
            headers.append(RAT_COLOR_HEADER_NAME)
            values[RAT_COLOR_HEADER_NAME] = []
            for i in range(len(values[red])):
                func = 'fromRgb' if is_integer else 'fromRgbF'
                if alpha:
                    values[RAT_COLOR_HEADER_NAME].append(
                        getattr(QColor,
                                func)(values[red][i], values[green][i],
                                      values[blue][i], values[alpha][i]))
                else:
                    values[RAT_COLOR_HEADER_NAME].append(
                        getattr(QColor, func)(values[red][i], values[green][i],
                                              values[blue][i]))

    return RAT(values, is_sidecar, fields, path)
예제 #4
0
    def onGenerate(self):
        """
        Slot raised to initiate the certificate generation process.
        """
        self._notif_bar.clear()
        success_status = True
        config = self.current_config()
        self.last_data_source = config.data_source()
        if config is None:
            self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \
                                                                           "The entity configuration could not be extracted."))
            return

        # Get selected records and validate
        records = self.tabWidget.currentWidget().entities()

        if self.chk_template_datasource.isChecked():
            records = self._dummy_template_records()

        if len(records) == 0:
            self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \
                                                                           "Please load at least one entity record"))
            return

        if not self._docTemplatePath:
            self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \
                                                                           "Please select a document template to use"))
            return

        documentNamingAttrs = self.lstDocNaming.selectedMappings()

        if self.chkUseOutputFolder.checkState() == Qt.Checked and len(
                documentNamingAttrs) == 0:
            self._notif_bar.insertErrorNotification(QApplication.translate("DocumentGeneratorDialog", \
                                                                           "Please select at least one field for naming the output document"))

            return

        # Set output file properties
        if self.rbExpImage.isChecked():
            outputMode = DocumentGenerator.Image
            fileExtension = self.cboImageType.currentText()
            saveAsText = "Image File"

        else:
            outputMode = DocumentGenerator.PDF
            fileExtension = "pdf"
            saveAsText = "PDF File"

        # Show save file dialog if not using output folder
        if self.chkUseOutputFolder.checkState() == Qt.Unchecked:
            docDir = source_document_location()

            if self._outputFilePath:
                fileInfo = QFileInfo(self._outputFilePath)
                docDir = fileInfo.dir().path()

            self._outputFilePath, _ = QFileDialog.getSaveFileName(
                self,
                QApplication.translate("DocumentGeneratorDialog",
                                       "Save Document"), docDir,
                "{0} (*.{1})".format(
                    QApplication.translate("DocumentGeneratorDialog",
                                           saveAsText), fileExtension))

            if not self._outputFilePath:
                self._notif_bar.insertErrorNotification(
                    QApplication.translate(
                        "DocumentGeneratorDialog",
                        "Process aborted. No output file was specified."))

                return

            # Include extension in file name
            self._outputFilePath = self._outputFilePath  # + "." + fileExtension

        # else:
        # Multiple files to be generated.
        # pass

        self._doc_generator.set_link_field(config.link_field())

        self._doc_generator.clear_attr_value_formatters()

        if not self.chk_template_datasource.isChecked():
            # Apply cell formatters for naming output files
            self._doc_generator.set_attr_value_formatters(config.formatters())

        entity_field_name = "id"

        # Iterate through the selected records
        progressDlg = QProgressDialog(self)
        progressDlg.setMaximum(len(records))

        try:
            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

            for i, record in enumerate(records):
                progressDlg.setValue(i)

                if progressDlg.wasCanceled():
                    success_status = False
                    break

                # User-defined location
                if self.chkUseOutputFolder.checkState() == Qt.Unchecked:
                    status, msg = self._doc_generator.run(
                        self._docTemplatePath,
                        entity_field_name,
                        record.id,
                        outputMode,
                        data_source=self.ds_entity.name,
                        filePath=self._outputFilePath)
                    self._doc_generator.clear_temporary_layers()
                # Output folder location using custom naming
                else:

                    status, msg = self._doc_generator.run(
                        self._docTemplatePath,
                        entity_field_name,
                        record.id,
                        outputMode,
                        dataFields=documentNamingAttrs,
                        fileExtension=fileExtension,
                        data_source=self.ds_entity.name)
                    self._doc_generator.clear_temporary_layers()

                if not status:
                    result = QMessageBox.warning(
                        self,
                        QApplication.translate("DocumentGeneratorDialog",
                                               "Document Generate Error"), msg,
                        QMessageBox.Ignore | QMessageBox.Abort)

                    if result == QMessageBox.Abort:
                        progressDlg.close()
                        success_status = False

                        # Restore cursor
                        QApplication.restoreOverrideCursor()

                        return

                    # If its the last record and user has selected to ignore
                    if i + 1 == len(records):
                        progressDlg.close()
                        success_status = False

                        # Restore cursor
                        QApplication.restoreOverrideCursor()

                        return

                else:
                    progressDlg.setValue(len(records))

            QApplication.restoreOverrideCursor()

            QMessageBox.information(
                self,
                QApplication.translate("DocumentGeneratorDialog",
                                       "Document Generation Complete"),
                QApplication.translate(
                    "DocumentGeneratorDialog",
                    "Document generation has successfully completed."))

        except DummyException as ex:
            LOGGER.debug(str(ex))
            err_msg = sys.exc_info()[1]
            QApplication.restoreOverrideCursor()

            QMessageBox.critical(
                self, "STDM",
                QApplication.translate(
                    "DocumentGeneratorDialog",
                    "Error Generating documents - %s" % (err_msg)))
            success_status = False

        # Reset UI
        self.reset(success_status)