Esempio n. 1
0
    def accept(self):
        """Process the layer and field and generate a new layer.

        .. note:: This is called on OK click.

        """
        # run minimum needs calculator
        try:
            success, self.result_layer = (
                self.minimum_needs(self.layer.currentLayer()))
            if not success:
                return
        except Exception as e:
            error_name, traceback = humanise_exception(e)
            message = (
                'Problem(s) occured. \n%s \nDiagnosis: \n%s' % (
                    error_name, traceback))
            display_critical_message_box(
                title=self.tr('Error while calculating minimum needs'),
                message=message)
            return

        # remove monkey patching keywords
        del self.result_layer.keywords

        # write memory layer to file system
        settings = QSettings()
        default_user_directory = settings.value(
            'inasafe/defaultUserDirectory', defaultValue='')

        if default_user_directory:
            output_directory = os.path.join(
                default_user_directory, 'minimum_needs_calculator')
            if not os.path.exists(output_directory):
                os.makedirs(output_directory)
        else:
            output_directory = temp_dir(sub_dir='minimum_needs_calculator')

        output_layer_name = os.path.split(self.result_layer.name())[1]

        # If normal filename doesn't exist, then use normal filename
        random_string_length = len(output_layer_name.split('_')[-1])
        normal_filename = output_layer_name[:-(random_string_length + 1)]
        if not os.path.exists(os.path.join(output_directory, normal_filename)):
            output_layer_name = normal_filename

        data_store = Folder(output_directory)
        data_store.default_vector_format = 'geojson'
        data_store.add_layer(self.result_layer, output_layer_name)

        self.result_layer = data_store.layer(output_layer_name)

        # noinspection PyArgumentList
        QgsMapLayerRegistry.instance().addMapLayers(
            [data_store.layer(self.result_layer.name())])
        self.done(QtGui.QDialog.Accepted)
Esempio n. 2
0
    def accept(self):
        """Process the layer and field and generate a new layer.

        .. note:: This is called on OK click.

        """
        # run minimum needs calculator
        try:
            success, self.result_layer = (
                self.minimum_needs(self.layer.currentLayer()))
            if not success:
                return
        except Exception as e:
            error_name, traceback = humanise_exception(e)
            message = (
                'Problem(s) occured. \n%s \nDiagnosis: \n%s' % (
                    error_name, traceback))
            display_critical_message_box(
                title=self.tr('Error while calculating minimum needs'),
                message=message)
            return

        # remove monkey patching keywords
        del self.result_layer.keywords

        # write memory layer to file system
        settings = QSettings()
        default_user_directory = settings.value(
            'inasafe/defaultUserDirectory', defaultValue='')

        if default_user_directory:
            output_directory = os.path.join(
                default_user_directory, 'minimum_needs_calculator')
            if not os.path.exists(output_directory):
                os.makedirs(output_directory)
        else:
            output_directory = temp_dir(sub_dir='minimum_needs_calculator')

        output_layer_name = os.path.split(self.result_layer.name())[1]

        # If normal filename doesn't exist, then use normal filename
        random_string_length = len(output_layer_name.split('_')[-1])
        normal_filename = output_layer_name[:-(random_string_length + 1)]
        if not os.path.exists(os.path.join(output_directory, normal_filename)):
            output_layer_name = normal_filename

        data_store = Folder(output_directory)
        data_store.default_vector_format = 'geojson'
        data_store.add_layer(self.result_layer, output_layer_name)

        self.result_layer = data_store.layer(output_layer_name)

        # noinspection PyArgumentList
        QgsProject.instance().addMapLayers(
            [data_store.layer(self.result_layer.name())])
        self.done(QtWidgets.QDialog.Accepted)
    def accept(self):
        """Process the layer and field and generate a new layer.

        .. note:: This is called on OK click.

        """
        # run minimum needs calculator
        try:
            success, self.result_layer = (
                self.minimum_needs(self.layer.currentLayer()))
            if not success:
                return
        except Exception as e:
            error_name, traceback = humanise_exception(e)
            message = (
                'Problem(s) occured. \n%s \nDiagnosis: \n%s' % (
                    error_name, traceback))
            display_critical_message_box(
                title=self.tr('Error while calculating minimum needs'),
                message=message)
            return

        # remove monkey patching keywords
        del self.result_layer.keywords

        # write memory layer to file system
        settings = QSettings()
        default_user_directory = settings.value(
            'inasafe/defaultUserDirectory', defaultValue='')

        if default_user_directory:
            path = os.path.join(
                default_user_directory, self.result_layer.name())
            if not os.path.exists(path):
                os.makedirs(path)
            data_store = Folder(path)
        else:
            data_store = Folder(temp_dir(sub_dir=self.result_layer.name()))

        data_store.default_vector_format = 'geojson'
        data_store.add_layer(self.result_layer, self.result_layer.name())

        self.result_layer = data_store.layer(self.result_layer.name())

        # noinspection PyArgumentList
        QgsMapLayerRegistry.instance().addMapLayers(
            [data_store.layer(self.result_layer.name())])
        self.done(QtGui.QDialog.Accepted)
Esempio n. 4
0
    def test_empty_layer(self):
        """Test if we import an empty layer."""
        layer = create_memory_layer(
            'test', QgsWkbTypes.PolygonGeometry,
            QgsCoordinateReferenceSystem(3857), [
                QgsField('my_field_1', QVariant.Int),
                QgsField('my_field_2', QVariant.Double),
                QgsField('my_field_3', QVariant.String)
            ])
        self.assertTrue(layer.isValid())
        self.assertEqual(len(layer.fields()), 3)

        # These following tests doesn't work if we add 'geosjon' in the formats
        # list. https://issues.qgis.org/issues/18370
        formats = ['shp']
        for extension in formats:
            path = QDir(mkdtemp())
            data_store = Folder(path)
            data_store.default_vector_format = extension
            name = 'test'
            result, message = data_store.add_layer(layer, name)
            self.assertTrue(result, message)

            # Fetch the layer
            imported_layer = data_store.layer(name)
            self.assertTrue(imported_layer.isValid())
            self.assertListEqual([f.name() for f in imported_layer.fields()],
                                 ['my_field_1', 'my_field_2', 'my_field_3'])
Esempio n. 5
0
def rasterize_vector_layer(layer, width, height, extent):
    """Rasterize a vector layer to the grid given by extent and width/height.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer

    :param width: The width of the output.
    :type width: int

    :param height: The height of the output.
    :type height: int

    :param extent: The extent to use.
    :type extent: QgsRectangle

    :return: The new raster layer.
    :rtype: QgsRasterLayer
    """
    name = rasterize_steps['gdal_layer_name']
    output_filename = unique_filename(prefix=name, suffix='.tif')

    extent_str = '%f,%f,%f,%f' % (extent.xMinimum(), extent.xMaximum(),
                                  extent.yMinimum(), extent.yMaximum())

    keywords = dict(layer.keywords)

    # The layer is in memory, we need to save it to a file for Processing.
    data_store = Folder(mkdtemp())
    data_store.default_vector_format = 'geojson'
    result = data_store.add_layer(layer, 'vector_layer')
    layer = data_store.layer(result[1])
    assert layer.isValid()

    field = layer.keywords['inasafe_fields'][aggregation_id_field['key']]

    # ET 21/02/17. I got some issues using rasterize algorithm from Processing.
    # I keep it in case of we need it later. Let's use gdal command line.
    use_gdal_command_line = True

    if use_gdal_command_line:
        startupinfo = None
        if sys.platform == 'win32':
            # On windows, we don't want to display the bash shell.
            # https://github.com/inasafe/inasafe/issues/3980
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        commands = [which('gdal_rasterize')[0]]
        commands += ['-a', field]
        commands += ['-ts', str(width), str(height)]
        commands += ['-ot', 'Int16']
        commands += ['-a_nodata', "'-1'"]
        commands += [layer.source(), output_filename]

        LOGGER.info(' '.join(commands))
        result = subprocess.check_call(commands, startupinfo=startupinfo)
        LOGGER.info('Result : %s' % result)
    else:
        parameters = dict()
        parameters['INPUT'] = layer
        parameters['FIELD'] = field
        parameters['DIMENSIONS'] = 0  # output size is given in pixels
        parameters['WIDTH'] = width
        parameters['HEIGHT'] = height
        parameters['RASTER_EXT'] = extent_str
        parameters['TFW'] = False  # force generation of ESRI TFW
        parameters['RTYPE'] = 1  # raster type: Int16
        parameters['NO_DATA'] = '-1'  # nodata value
        parameters['COMPRESS'] = 4  # GeoTIFF compression: DEFLATE
        parameters['JPEGCOMPRESSION'] = 75  # JPEG compression level: 75
        parameters['ZLEVEL'] = 6  # DEFLATE compression level
        parameters['PREDICTOR'] = 1  # predictor for JPEG/DEFLATE
        parameters['TILED'] = False  # Tiled GeoTIFF?
        parameters['BIGTIFF'] = 0  # whether to make big TIFF
        parameters['EXTRA'] = ''  # additional creation parameters
        parameters['OUTPUT'] = output_filename

        result = runalg('gdalogr:rasterize', parameters)
        if result is None:
            # Let's try be removing a new parameter added between 2.14 and 2.16
            del parameters['RASTER_EXT']

        result = runalg('gdalogr:rasterize', parameters)
        assert result is not None

    layer_aligned = QgsRasterLayer(output_filename, name, 'gdal')
    assert layer_aligned.isValid()

    layer_aligned.keywords = keywords
    layer_aligned.keywords['title'] = (rasterize_steps['output_layer_name'] %
                                       'aggregation')
    layer_aligned.keywords['layer_purpose'] = (
        layer_purpose_aggregation_summary['key'])
    del layer_aligned.keywords['inasafe_fields']

    check_layer(layer_aligned)
    return layer_aligned
Esempio n. 6
0
class MultiBufferDialog(QtWidgets.QDialog, FORM_CLASS):
    """Dialog implementation class for the InaSAFE multi buffer tool."""
    def __init__(self, parent=None, iface=None, dock_widget=None):
        """Constructor for the multi buffer dialog.

        :param parent: Parent widget of this dialog.
        :type parent: QWidget
        """
        QtWidgets.QDialog.__init__(self, parent)
        self.setupUi(self)
        self.setWindowTitle(self.tr('InaSAFE Multi Buffer Tool'))
        icon = resources_path('img', 'icons', 'show-multi-buffer.svg')
        self.setWindowIcon(QtGui.QIcon(icon))
        self.parent = parent
        self.iface = iface
        self.dock_widget = dock_widget
        self.keyword_wizard = None

        # output file properties initialisation
        self.data_store = None
        self.output_directory = None
        self.output_filename = None
        self.output_extension = None
        self.output_layer = None
        self.classification = []

        # set icon
        self.add_class_button.setIcon(
            QIcon(resources_path('img', 'icons', 'add.svg')))
        self.remove_class_button.setIcon(
            QIcon(resources_path('img', 'icons', 'remove.svg')))

        # prepare dialog initialisation
        self.layer.setFilters(QgsMapLayerProxyModel.VectorLayer)
        self.directory_button_status()
        self.add_class_button_status()
        self.ok_button_status()
        self.output_form.setPlaceholderText(
            self.tr('[Create a temporary layer]'))
        self.keyword_wizard_checkbox.setChecked(True)

        # set signal
        self.layer.layerChanged.connect(self.directory_button_status)
        self.layer.layerChanged.connect(self.ok_button_status)
        self.output_form.textChanged.connect(self.ok_button_status)
        self.directory_button.clicked.connect(
            self.on_directory_button_tool_clicked)
        self.radius_form.valueChanged.connect(self.add_class_button_status)
        self.class_form.textChanged.connect(self.add_class_button_status)
        self.add_class_button.clicked.connect(
            self.populate_hazard_classification)
        self.add_class_button.clicked.connect(self.ok_button_status)
        self.remove_class_button.clicked.connect(
            self.remove_selected_classification)
        self.remove_class_button.clicked.connect(self.ok_button_status)

        # Set up things for context help
        self.help_button = self.button_box.button(
            QtWidgets.QDialogButtonBox.Help)
        # Allow toggling the help button
        self.help_button.setCheckable(True)
        self.help_button.toggled.connect(self.help_toggled)
        self.main_stacked_widget.setCurrentIndex(1)

        # Fix for issue 1699 - cancel button does nothing
        cancel_button = self.button_box.button(
            QtWidgets.QDialogButtonBox.Cancel)
        cancel_button.clicked.connect(self.reject)
        # Fix ends
        ok_button = self.button_box.button(QtWidgets.QDialogButtonBox.Ok)
        ok_button.clicked.connect(self.accept)

    def accept(self):
        """Process the layer for multi buffering and generate a new layer.

        .. note:: This is called on OK click.
        """
        # set parameter from dialog
        input_layer = self.layer.currentLayer()
        output_path = self.output_form.text()
        radius = self.get_classification()
        # monkey patch keywords so layer works on multi buffering function
        input_layer.keywords = {'inasafe_fields': {}}

        # run multi buffering
        self.output_layer = multi_buffering(input_layer, radius)

        # save output layer to data store and check whether user
        # provide the output path.
        if output_path:
            self.output_directory, self.output_filename = (
                os.path.split(output_path))
            self.output_filename, self.output_extension = (os.path.splitext(
                self.output_filename))

        # if user do not provide the output path, create a temporary file.
        else:
            self.output_directory = temp_dir(sub_dir='work')
            self.output_filename = (unique_filename(prefix='hazard_layer',
                                                    suffix='.geojson',
                                                    dir=self.output_directory))
            self.output_filename = os.path.split(self.output_filename)[1]
            self.output_filename, self.output_extension = (os.path.splitext(
                self.output_filename))

        self.data_store = Folder(self.output_directory)
        if self.output_extension == '.shp':
            self.data_store.default_vector_format = 'shp'
        elif self.output_extension == '.geojson':
            self.data_store.default_vector_format = 'geojson'
        self.data_store.add_layer(self.output_layer, self.output_filename)

        # add output layer to map canvas
        self.output_layer = self.data_store.layer(self.output_filename)

        QgsProject.instance().addMapLayers([self.output_layer])
        self.iface.setActiveLayer(self.output_layer)
        self.iface.zoomToActiveLayer()
        self.done(QtWidgets.QDialog.Accepted)

        if self.keyword_wizard_checkbox.isChecked():
            self.launch_keyword_wizard()

    @pyqtSlot()  # prevents actions being handled twice
    def on_directory_button_tool_clicked(self):
        """Autoconnect slot activated when directory button is clicked."""
        # noinspection PyCallByClass,PyTypeChecker
        # set up parameter from dialog
        input_path = self.layer.currentLayer().source()
        input_directory, self.output_filename = os.path.split(input_path)
        file_extension = os.path.splitext(self.output_filename)[1]
        self.output_filename = os.path.splitext(self.output_filename)[0]
        # show Qt file directory dialog
        output_path, __ = QtWidgets.QFileDialog.getSaveFileName(
            self, self.tr('Output file'), '%s_multi_buffer%s' % (os.path.join(
                input_directory, self.output_filename), file_extension),
            'GeoJSON (*.geojson);;Shapefile (*.shp)')
        # set selected path to the dialog
        self.output_form.setText(output_path)

    def get_output_from_input(self):
        """Populate output form with default output path based on input layer.
        """
        input_path = self.layer.currentLayer().source()
        output_path = (os.path.splitext(input_path)[0] + '_multi_buffer' +
                       os.path.splitext(input_path)[1])
        self.output_form.setText(output_path)

    def populate_hazard_classification(self):
        """Populate hazard classification on hazard class form."""
        new_class = {
            'value': self.radius_form.value(),
            'name': self.class_form.text()
        }
        self.classification.append(new_class)
        self.classification = sorted(self.classification,
                                     key=itemgetter('value'))

        self.hazard_class_form.clear()
        for item in self.classification:
            new_item = '{value} - {name}'.format(value=item['value'],
                                                 name=item['name'])
            self.hazard_class_form.addItem(new_item)

        self.radius_form.setValue(0)
        self.class_form.clear()
        self.ok_button_status()

    def remove_selected_classification(self):
        """Remove selected item on hazard class form."""
        removed_classes = self.hazard_class_form.selectedItems()
        current_item = self.hazard_class_form.currentItem()
        removed_index = self.hazard_class_form.indexFromItem(current_item)
        del self.classification[removed_index.row()]
        for item in removed_classes:
            self.hazard_class_form.takeItem(self.hazard_class_form.row(item))

    def get_classification(self):
        """Get all hazard class created by user.

        :return: Hazard class definition created by user.
        :rtype: OrderedDict
        """
        classification_dictionary = {}
        for item in self.classification:
            classification_dictionary[item['value']] = item['name']

        classification_dictionary = OrderedDict(
            sorted(classification_dictionary.items()))

        return classification_dictionary

    def directory_button_status(self):
        """Function to enable or disable directory button."""
        if self.layer.currentLayer():
            self.directory_button.setEnabled(True)
        else:
            self.directory_button.setEnabled(False)

    def add_class_button_status(self):
        """Function to enable or disable add class button."""
        if self.class_form.text() and self.radius_form.value() >= 0:
            self.add_class_button.setEnabled(True)
        else:
            self.add_class_button.setEnabled(False)

    def ok_button_status(self):
        """Function to enable or disable OK button."""
        if not self.layer.currentLayer():
            self.button_box.button(
                QtWidgets.QDialogButtonBox.Ok).setEnabled(False)
        elif (self.hazard_class_form.count() > 0
              and self.layer.currentLayer().name()
              and len(self.output_form.text()) >= 0):
            self.button_box.button(
                QtWidgets.QDialogButtonBox.Ok).setEnabled(True)
        else:
            self.button_box.button(
                QtWidgets.QDialogButtonBox.Ok).setEnabled(False)

    @pyqtSlot(bool)  # prevents actions being handled twice
    def help_toggled(self, flag):
        """Show or hide the help tab in the stacked widget.

        :param flag: Flag indicating whether help should be shown or hidden.
        :type flag: bool
        """
        if flag:
            self.help_button.setText(self.tr('Hide Help'))
            self.show_help()
        else:
            self.help_button.setText(self.tr('Show Help'))
            self.hide_help()

    def hide_help(self):
        """Hide the usage info from the user."""
        self.main_stacked_widget.setCurrentIndex(1)

    def show_help(self):
        """Show usage info to the user."""
        # Read the header and footer html snippets
        self.main_stacked_widget.setCurrentIndex(0)
        header = html_header()
        footer = html_footer()

        string = header

        message = multi_buffer_help()

        string += message.to_html()
        string += footer

        self.help_web_view.setHtml(string)

    def launch_keyword_wizard(self):
        """Launch keyword creation wizard."""
        # make sure selected layer is the output layer
        if self.iface.activeLayer() != self.output_layer:
            return

        # launch wizard dialog
        self.keyword_wizard = WizardDialog(self.iface.mainWindow(), self.iface,
                                           self.dock_widget)
        self.keyword_wizard.set_keywords_creation_mode(self.output_layer)
        self.keyword_wizard.exec_()  # modal
class MultiBufferDialog(QtGui.QDialog, FORM_CLASS):
    """Dialog implementation class for the InaSAFE multi buffer tool."""

    def __init__(self, parent=None, iface=None, dock_widget=None):
        """Constructor for the multi buffer dialog.

        :param parent: Parent widget of this dialog.
        :type parent: QWidget
        """
        QtGui.QDialog.__init__(self, parent)
        self.setupUi(self)
        self.setWindowTitle(self.tr('InaSAFE Multi Buffer Tool'))
        self.parent = parent
        self.iface = iface
        self.dock_widget = dock_widget
        self.keyword_wizard = None

        # output file properties initialisation
        self.data_store = None
        self.output_directory = None
        self.output_filename = None
        self.output_extension = None
        self.output_layer = None
        self.classification = []

        # set icon
        self.add_class_button.setIcon(
            QIcon(resources_path('img', 'icons', 'add.svg')))
        self.remove_class_button.setIcon(
            QIcon(resources_path('img', 'icons', 'remove.svg')))

        # prepare dialog initialisation
        self.layer.setFilters(QgsMapLayerProxyModel.VectorLayer)
        self.directory_button_status()
        self.add_class_button_status()
        self.ok_button_status()
        self.output_form.setPlaceholderText(
            self.tr('[Create a temporary layer]'))
        self.keyword_wizard_checkbox.setChecked(True)

        # set signal
        self.layer.layerChanged.connect(self.directory_button_status)
        self.layer.layerChanged.connect(self.ok_button_status)
        self.output_form.textChanged.connect(self.ok_button_status)
        self.directory_button.clicked.connect(
            self.on_directory_button_tool_clicked)
        self.radius_form.valueChanged.connect(self.add_class_button_status)
        self.class_form.textChanged.connect(self.add_class_button_status)
        self.add_class_button.clicked.connect(
            self.populate_hazard_classification)
        self.add_class_button.clicked.connect(self.ok_button_status)
        self.remove_class_button.clicked.connect(
            self.remove_selected_classification)
        self.remove_class_button.clicked.connect(self.ok_button_status)

        # Set up things for context help
        self.help_button = self.button_box.button(QtGui.QDialogButtonBox.Help)
        # Allow toggling the help button
        self.help_button.setCheckable(True)
        self.help_button.toggled.connect(self.help_toggled)
        self.main_stacked_widget.setCurrentIndex(1)

        # Fix for issue 1699 - cancel button does nothing
        cancel_button = self.button_box.button(QtGui.QDialogButtonBox.Cancel)
        cancel_button.clicked.connect(self.reject)
        # Fix ends
        ok_button = self.button_box.button(QtGui.QDialogButtonBox.Ok)
        ok_button.clicked.connect(self.accept)

    def accept(self):
        """Process the layer for multi buffering and generate a new layer.

        .. note:: This is called on OK click.
        """
        # set parameter from dialog
        input_layer = self.layer.currentLayer()
        output_path = self.output_form.text()
        radius = self.get_classification()
        # monkey patch keywords so layer works on multi buffering function
        input_layer.keywords = {'inasafe_fields': {}}

        # run multi buffering
        self.output_layer = multi_buffering(input_layer, radius)

        # save output layer to data store and check whether user
        # provide the output path.
        if output_path:
            self.output_directory, self.output_filename = (
                os.path.split(output_path))
            self.output_filename, self.output_extension = (
                os.path.splitext(self.output_filename))

        # if user do not provide the output path, create a temporary file.
        else:
            self.output_directory = temp_dir(sub_dir='work')
            self.output_filename = (
                unique_filename(
                    prefix='hazard_layer',
                    suffix='.geojson',
                    dir=self.output_directory))
            self.output_filename = os.path.split(self.output_filename)[1]
            self.output_filename, self.output_extension = (
                os.path.splitext(self.output_filename))

        self.data_store = Folder(self.output_directory)
        if self.output_extension == '.shp':
            self.data_store.default_vector_format = 'shp'
        elif self.output_extension == '.geojson':
            self.data_store.default_vector_format = 'geojson'
        self.data_store.add_layer(self.output_layer, self.output_filename)

        # add output layer to map canvas
        self.output_layer = self.data_store.layer(self.output_filename)

        QgsMapLayerRegistry.instance().addMapLayers(
            [self.output_layer])
        self.iface.setActiveLayer(self.output_layer)
        self.iface.zoomToActiveLayer()
        self.done(QtGui.QDialog.Accepted)

        if self.keyword_wizard_checkbox.isChecked():
            self.launch_keyword_wizard()

    @pyqtSignature('')  # prevents actions being handled twice
    def on_directory_button_tool_clicked(self):
        """Autoconnect slot activated when directory button is clicked."""
        # noinspection PyCallByClass,PyTypeChecker
        # set up parameter from dialog
        input_path = self.layer.currentLayer().source()
        input_directory, self.output_filename = os.path.split(input_path)
        file_extension = os.path.splitext(self.output_filename)[1]
        self.output_filename = os.path.splitext(self.output_filename)[0]
        # show Qt file directory dialog
        output_path = QFileDialog.getSaveFileName(
            self,
            self.tr('Output file'),
            '%s_multi_buffer%s' % (
                os.path.join(input_directory, self.output_filename),
                file_extension),
            'GeoJSON (*.geojson);;Shapefile (*.shp)')
        # set selected path to the dialog
        self.output_form.setText(output_path)

    def get_output_from_input(self):
        """Populate output form with default output path based on input layer.
        """
        input_path = self.layer.currentLayer().source()
        output_path = (
            os.path.splitext(input_path)[0] + '_multi_buffer' +
            os.path.splitext(input_path)[1])
        self.output_form.setText(output_path)

    def populate_hazard_classification(self):
        """Populate hazard classification on hazard class form."""
        new_class = {
            'value': self.radius_form.value(),
            'name': self.class_form.text()}
        self.classification.append(new_class)
        self.classification = sorted(
            self.classification, key=itemgetter('value'))

        self.hazard_class_form.clear()
        for item in self.classification:
            new_item = '{value} - {name}'.format(
                value=item['value'], name=item['name'])
            self.hazard_class_form.addItem(new_item)

        self.radius_form.setValue(0)
        self.class_form.clear()
        self.ok_button_status()

    def remove_selected_classification(self):
        """Remove selected item on hazard class form."""
        removed_classes = self.hazard_class_form.selectedItems()
        current_item = self.hazard_class_form.currentItem()
        removed_index = self.hazard_class_form.indexFromItem(current_item)
        del self.classification[removed_index.row()]
        for item in removed_classes:
            self.hazard_class_form.takeItem(
                self.hazard_class_form.row(item))

    def get_classification(self):
        """Get all hazard class created by user.

        :return: Hazard class definition created by user.
        :rtype: OrderedDict
        """
        classification_dictionary = {}
        for item in self.classification:
            classification_dictionary[item['value']] = item['name']

        classification_dictionary = OrderedDict(
            sorted(classification_dictionary.items()))

        return classification_dictionary

    def directory_button_status(self):
        """Function to enable or disable directory button."""
        if self.layer.currentLayer():
            self.directory_button.setEnabled(True)
        else:
            self.directory_button.setEnabled(False)

    def add_class_button_status(self):
        """Function to enable or disable add class button."""
        if self.class_form.text() and self.radius_form >= 0:
            self.add_class_button.setEnabled(True)
        else:
            self.add_class_button.setEnabled(False)

    def ok_button_status(self):
        """Function to enable or disable OK button."""
        if not self.layer.currentLayer():
            self.button_box.button(QtGui.QDialogButtonBox.Ok).setEnabled(False)
        elif (self.hazard_class_form.count() > 0 and
                self.layer.currentLayer().name() and
                    len(self.output_form.text()) >= 0):
            self.button_box.button(QtGui.QDialogButtonBox.Ok).setEnabled(True)
        else:
            self.button_box.button(QtGui.QDialogButtonBox.Ok).setEnabled(False)

    @pyqtSlot()
    @pyqtSignature('bool')  # prevents actions being handled twice
    def help_toggled(self, flag):
        """Show or hide the help tab in the stacked widget.

        :param flag: Flag indicating whether help should be shown or hidden.
        :type flag: bool
        """
        if flag:
            self.help_button.setText(self.tr('Hide Help'))
            self.show_help()
        else:
            self.help_button.setText(self.tr('Show Help'))
            self.hide_help()

    def hide_help(self):
        """Hide the usage info from the user."""
        self.main_stacked_widget.setCurrentIndex(1)

    def show_help(self):
        """Show usage info to the user."""
        # Read the header and footer html snippets
        self.main_stacked_widget.setCurrentIndex(0)
        header = html_header()
        footer = html_footer()

        string = header

        message = multi_buffer_help()

        string += message.to_html()
        string += footer

        self.help_web_view.setHtml(string)

    def launch_keyword_wizard(self):
        """Launch keyword creation wizard."""
        # make sure selected layer is the output layer
        if self.iface.activeLayer() != self.output_layer:
            return

        # launch wizard dialog
        self.keyword_wizard = WizardDialog(
            self.iface.mainWindow(),
            self.iface,
            self.dock_widget)
        self.keyword_wizard.set_keywords_creation_mode(self.output_layer)
        self.keyword_wizard.exec_()  # modal
Esempio n. 8
0
def rasterize_vector_layer(layer, width, height, extent):
    """Rasterize a vector layer to the grid given by extent and width/height.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer

    :param width: The width of the output.
    :type width: int

    :param height: The height of the output.
    :type height: int

    :param extent: The extent to use.
    :type extent: QgsRectangle

    :return: The new raster layer.
    :rtype: QgsRasterLayer
    """
    name = rasterize_steps['gdal_layer_name']
    output_filename = unique_filename(prefix=name, suffix='.tif')

    extent_str = '%f,%f,%f,%f' % (
        extent.xMinimum(),
        extent.xMaximum(),
        extent.yMinimum(),
        extent.yMaximum())

    keywords = dict(layer.keywords)

    # The layer is in memory, we need to save it to a file for Processing.
    data_store = Folder(mkdtemp())
    data_store.default_vector_format = 'geojson'
    result = data_store.add_layer(layer, 'vector_layer')
    layer = data_store.layer(result[1])
    assert layer.isValid()

    field = layer.keywords['inasafe_fields'][aggregation_id_field['key']]

    # ET 21/02/17. I got some issues using rasterize algorithm from Processing.
    # I keep it in case of we need it later. Let's use gdal command line.
    use_gdal_command_line = True

    if use_gdal_command_line:
        startupinfo = None
        if sys.platform == 'win32':
            # On windows, we don't want to display the bash shell.
            # https://github.com/inasafe/inasafe/issues/3980
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        commands = [which('gdal_rasterize')[0]]
        commands += ['-a', field]
        commands += ['-ts', str(width), str(height)]
        commands += ['-ot', 'Int16']
        commands += ['-a_nodata', "'-1'"]
        commands += [layer.source(), output_filename]

        LOGGER.info(' '.join(commands))
        result = subprocess.check_call(commands, startupinfo=startupinfo)
        LOGGER.info('Result : %s' % result)
    else:
        parameters = dict()
        parameters['INPUT'] = layer
        parameters['FIELD'] = field
        parameters['DIMENSIONS'] = 0  # output size is given in pixels
        parameters['WIDTH'] = width
        parameters['HEIGHT'] = height
        parameters['RASTER_EXT'] = extent_str
        parameters['TFW'] = False  # force generation of ESRI TFW
        parameters['RTYPE'] = 1  # raster type: Int16
        parameters['NO_DATA'] = '-1'   # nodata value
        parameters['COMPRESS'] = 4  # GeoTIFF compression: DEFLATE
        parameters['JPEGCOMPRESSION'] = 75  # JPEG compression level: 75
        parameters['ZLEVEL'] = 6  # DEFLATE compression level
        parameters['PREDICTOR'] = 1  # predictor for JPEG/DEFLATE
        parameters['TILED'] = False  # Tiled GeoTIFF?
        parameters['BIGTIFF'] = 0  # whether to make big TIFF
        parameters['EXTRA'] = ''  # additional creation parameters
        parameters['OUTPUT'] = output_filename

        result = runalg('gdalogr:rasterize', parameters)
        if result is None:
            # Let's try be removing a new parameter added between 2.14 and 2.16
            del parameters['RASTER_EXT']

        result = runalg('gdalogr:rasterize', parameters)
        assert result is not None

    layer_aligned = QgsRasterLayer(output_filename, name, 'gdal')
    assert layer_aligned.isValid()

    layer_aligned.keywords = keywords
    layer_aligned.keywords['title'] = (
        rasterize_steps['output_layer_name'] % 'aggregation')
    layer_aligned.keywords['layer_purpose'] = (
        layer_purpose_aggregation_summary['key'])
    del layer_aligned.keywords['inasafe_fields']

    check_layer(layer_aligned)
    return layer_aligned