コード例 #1
0
 def __init__(self, iface):
     self.iface = iface
     QDialog.__init__(self)
     # Set up the user interface from Designer.
     self.ui = Ui_SelectInputLayersDialog()
     self.ui.setupUi(self)
     # Disable ok_button until loss and zonal layers are selected
     self.ok_button = self.ui.buttonBox.button(QDialogButtonBox.Ok)
     self.ok_button.setDisabled(True)
     self.loss_layer_is_vector = True
     self.populate_cbx()
コード例 #2
0
class SelectInputLayersDialog(QDialog):
    """
    Modal dialog allowing to select a raster or vector layer
    containing loss data points and a vector layer containing polygons
    that define the zones for which data need to be aggregated. When
    both are selected and are valid files, they can be loaded by clicking OK
    """
    def __init__(self, iface):
        self.iface = iface
        QDialog.__init__(self)
        # Set up the user interface from Designer.
        self.ui = Ui_SelectInputLayersDialog()
        self.ui.setupUi(self)
        # Disable ok_button until loss and zonal layers are selected
        self.ok_button = self.ui.buttonBox.button(QDialogButtonBox.Ok)
        self.ok_button.setDisabled(True)
        self.loss_layer_is_vector = True
        self.populate_cbx()

    def open_file_dialog(self, dialog_type):
        """
        Open a file dialog to select the data file to be loaded
        :param string dialog_type:
            Valid types are 'loss_layer' or 'zonal_layer'
        :returns:
        """
        if dialog_type == 'loss_layer':
            text = self.tr('Select loss map to import')
            # FIXME: What should be the format of the raster maps?
            filters = self.tr('Geojson vector loss maps (*.geojson);; '
                              'Shapefile vector loss maps (*.shp);; '
                              'Raster loss maps (*.*)')
        elif dialog_type == 'zonal_layer':
            text = self.tr('Select zonal layer to import')
            filters = self.tr('Vector shapefiles (*.shp);; SQLite (*.sqlite);;'
                              ' All files (*.*)')
        else:
            raise RuntimeError('Invalid dialog_type: {}'.format(dialog_type))
        file_name, file_type = QFileDialog.getOpenFileNameAndFilter(
            self, text, QDir.homePath(), filters)
        if file_name:
            if dialog_type == 'zonal_layer':
                layer = self.load_zonal_layer(file_name)
            elif dialog_type == 'loss_layer':
                if file_type == 'Raster loss maps (*.*)':
                    self.loss_layer_is_vector = False
                layer = self.load_loss_layer(file_name)
            else:
                raise RuntimeError
            return layer
        else:
            return None

    @pyqtSlot()
    def on_loss_layer_tbn_clicked(self):
        layer = self.open_file_dialog('loss_layer')
        if layer and ProcessLayer(layer).is_type_in(["point", "multipoint"]):
            cbx = self.ui.loss_layer_cbx
            cbx.addItem(layer.name())
            last_index = cbx.count() - 1
            cbx.setItemData(last_index, layer.id())
            cbx.setCurrentIndex(last_index)
        self.enable_ok_button_if_both_layers_are_specified()

    @pyqtSlot()
    def on_zonal_layer_tbn_clicked(self):
        layer = self.open_file_dialog('zonal_layer')
        if layer and ProcessLayer(layer).is_type_in(
                ["polygon", "multipolygon"]):
            cbx = self.ui.zonal_layer_cbx
            cbx.addItem(layer.name())
            last_index = cbx.count() - 1
            cbx.setItemData(last_index, layer.id())
            cbx.setCurrentIndex(last_index)
        self.enable_ok_button_if_both_layers_are_specified()

    def populate_cbx(self):
        for key, layer in \
                QgsMapLayerRegistry.instance().mapLayers().iteritems():
            # populate loss cbx only with layers containing points
            if ProcessLayer(layer).is_type_in(["point", "multipoint"]):
                self.ui.loss_layer_cbx.addItem(layer.name())
                self.ui.loss_layer_cbx.setItemData(
                    self.ui.loss_layer_cbx.count()-1, layer.id())
            if ProcessLayer(layer).is_type_in(["polygon", "multipolygon"]):
                self.ui.zonal_layer_cbx.addItem(layer.name())
                self.ui.zonal_layer_cbx.setItemData(
                    self.ui.zonal_layer_cbx.count()-1, layer.id())
        self.enable_ok_button_if_both_layers_are_specified()

    def enable_ok_button_if_both_layers_are_specified(self):
        if self.ui.loss_layer_cbx.currentText() and \
                self.ui.zonal_layer_cbx.currentText():
            self.ok_button.setEnabled(True)
        else:
            self.ok_button.setEnabled(False)

    def load_loss_layer(self, loss_layer_path):
        # Load loss layer
        if self.loss_layer_is_vector:
            loss_layer = QgsVectorLayer(loss_layer_path, tr('Loss map'), 'ogr')
            if not loss_layer.geometryType() == QGis.Point:
                msg = 'Loss map must contain points'
                self.iface.messageBar().pushMessage(
                    tr("Error"),
                    tr(msg),
                    level=QgsMessageBar.CRITICAL)
                return False
        else:
            loss_layer = QgsRasterLayer(loss_layer_path, tr('Loss map'))
        # Add loss layer to registry
        if loss_layer.isValid():
            QgsMapLayerRegistry.instance().addMapLayer(loss_layer)
        else:
            msg = 'Invalid loss map'
            self.iface.messageBar().pushMessage(
                tr("Error"),
                tr(msg),
                level=QgsMessageBar.CRITICAL)
            return None
        # Zoom depending on the zonal layer's extent
        return loss_layer

    def load_zonal_layer(self, zonal_layer_path):
        # Load zonal layer
        zonal_layer = QgsVectorLayer(zonal_layer_path, tr('Zonal data'), 'ogr')
        if not zonal_layer.geometryType() == QGis.Polygon:
            msg = 'Zonal layer must contain zone polygons'
            self.iface.messageBar().pushMessage(
                tr("Error"),
                tr(msg),
                level=QgsMessageBar.CRITICAL)
            return False
        # Add zonal layer to registry
        if zonal_layer.isValid():
            QgsMapLayerRegistry.instance().addMapLayer(zonal_layer)
        else:
            msg = 'Invalid zonal layer'
            self.iface.messageBar().pushMessage(
                tr("Error"),
                tr(msg),
                level=QgsMessageBar.CRITICAL)
            return None
        return zonal_layer