コード例 #1
0
class UserConfigDialog(QDialog):

    def __init__(self, parent = None):
        super(UserConfigDialog, self).__init__(parent)
        self.user = None
        self.email = None
        self.initGui()

    def initGui(self):
        self.setWindowTitle('GeoGig user configuration')
        verticalLayout = QVBoxLayout()

        horizontalLayout = QHBoxLayout()
        horizontalLayout.setSpacing(30)
        horizontalLayout.setMargin(0)
        usernameLabel = QLabel('Username')
        self.usernameBox = QLineEdit()
        horizontalLayout.addWidget(usernameLabel)
        horizontalLayout.addWidget(self.usernameBox)
        verticalLayout.addLayout(horizontalLayout)

        horizontalLayout = QHBoxLayout()
        horizontalLayout.setSpacing(30)
        horizontalLayout.setMargin(0)
        emailLabel = QLabel('User email')
        self.emailBox = QLineEdit()
        horizontalLayout.addWidget(emailLabel)
        horizontalLayout.addWidget(self.emailBox)
        verticalLayout.addLayout(horizontalLayout)

        self.groupBox = QGroupBox()
        self.groupBox.setTitle("User data")
        self.groupBox.setLayout(verticalLayout)

        layout = QVBoxLayout()
        layout.addWidget(self.groupBox)

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        layout.addWidget(self.buttonBox)

        self.setLayout(layout)

        self.buttonBox.accepted.connect(self.okPressed)
        self.buttonBox.rejected.connect(self.cancelPressed)

        self.resize(400, 200)

    def okPressed(self):
        self.user = self.usernameBox.text()
        self.email = self.emailBox.text()
        self.close()

    def cancelPressed(self):
        self.user = None
        self.email = None
        self.close()
コード例 #2
0
class UserConfigDialog(QDialog):

    def __init__(self, parent = None):
        super(UserConfigDialog, self).__init__(parent)
        self.user = None
        self.email = None
        self.initGui()

    def initGui(self):
        self.setWindowTitle('GeoGig user configuration')
        verticalLayout = QVBoxLayout()

        horizontalLayout = QHBoxLayout()
        horizontalLayout.setSpacing(30)
        horizontalLayout.setMargin(0)
        usernameLabel = QLabel('Username')
        self.usernameBox = QLineEdit()
        horizontalLayout.addWidget(usernameLabel)
        horizontalLayout.addWidget(self.usernameBox)
        verticalLayout.addLayout(horizontalLayout)

        horizontalLayout = QHBoxLayout()
        horizontalLayout.setSpacing(30)
        horizontalLayout.setMargin(0)
        emailLabel = QLabel('User email')
        self.emailBox = QLineEdit()
        horizontalLayout.addWidget(emailLabel)
        horizontalLayout.addWidget(self.emailBox)
        verticalLayout.addLayout(horizontalLayout)

        self.groupBox = QGroupBox()
        self.groupBox.setTitle("User data")
        self.groupBox.setLayout(verticalLayout)

        layout = QVBoxLayout()
        layout.addWidget(self.groupBox)

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        layout.addWidget(self.buttonBox)

        self.setLayout(layout)

        self.buttonBox.accepted.connect(self.okPressed)
        self.buttonBox.rejected.connect(self.cancelPressed)

        self.resize(400, 200)

    def okPressed(self):
        self.user = str(self.usernameBox.text())
        self.email = str(self.emailBox.text())
        self.close()

    def cancelPressed(self):
        self.user = None
        self.email = None
        self.close()
コード例 #3
0
ファイル: options_dialog.py プロジェクト: inasafe/inasafe
    def restore_default_values_page(self):
        """Setup UI for default values setting."""
        # Clear parameters so it doesn't add parameters when
        # restore from changes.
        if self.default_value_parameters:
            self.default_value_parameters = []
        if self.default_value_parameter_containers:
            self.default_value_parameter_containers = []

        for i in reversed(list(range(self.container_layout.count()))):
            widget = self.container_layout.itemAt(i).widget()
            if widget is not None:
                widget.setParent(None)

        default_fields = all_default_fields()

        for field_group in all_field_groups:
            settable_fields = []
            for field in field_group['fields']:
                if field not in default_fields:
                    continue
                else:
                    settable_fields.append(field)
                    default_fields.remove(field)

            if not settable_fields:
                continue
            # Create group box for each field group
            group_box = QGroupBox(self)
            group_box.setTitle(field_group['name'])
            self.container_layout.addWidget(group_box)
            parameters = []
            for settable_field in settable_fields:
                parameter = self.default_field_to_parameter(settable_field)
                if parameter:
                    parameters.append(parameter)
            parameter_container = ParameterContainer(
                parameters,
                description_text=field_group['description'],
                extra_parameters=extra_parameter
            )
            parameter_container.setup_ui(must_scroll=False)
            group_box_inner_layout = QVBoxLayout()
            group_box_inner_layout.addWidget(parameter_container)
            group_box.setLayout(group_box_inner_layout)

            # Add to attribute
            self.default_value_parameter_containers.append(parameter_container)

        # Only show non-groups default fields if there is one
        if len(default_fields) > 0:
            for default_field in default_fields:
                parameter = self.default_field_to_parameter(default_field)
                if parameter:
                    self.default_value_parameters.append(parameter)

            description_text = tr(
                'In this options you can change the global default values for '
                'these variables.')
            parameter_container = ParameterContainer(
                self.default_value_parameters,
                description_text=description_text,
                extra_parameters=extra_parameter
            )
            parameter_container.setup_ui(must_scroll=False)
            self.other_group_box = QGroupBox(tr('Non-group fields'))
            other_group_inner_layout = QVBoxLayout()
            other_group_inner_layout.addWidget(parameter_container)
            self.other_group_box.setLayout(other_group_inner_layout)
            self.container_layout.addWidget(self.other_group_box)

            # Add to attribute
            self.default_value_parameter_containers.append(parameter_container)
コード例 #4
0
    def restore_default_values_page(self):
        """Setup UI for default values setting."""
        # Clear parameters so it doesn't add parameters when
        # restore from changes.
        if self.default_value_parameters:
            self.default_value_parameters = []
        if self.default_value_parameter_containers:
            self.default_value_parameter_containers = []

        for i in reversed(list(range(self.container_layout.count()))):
            widget = self.container_layout.itemAt(i).widget()
            if widget is not None:
                widget.setParent(None)

        default_fields = all_default_fields()

        for field_group in all_field_groups:
            settable_fields = []
            for field in field_group['fields']:
                if field not in default_fields:
                    continue
                else:
                    settable_fields.append(field)
                    default_fields.remove(field)

            if not settable_fields:
                continue
            # Create group box for each field group
            group_box = QGroupBox(self)
            group_box.setTitle(field_group['name'])
            self.container_layout.addWidget(group_box)
            parameters = []
            for settable_field in settable_fields:
                parameter = self.default_field_to_parameter(settable_field)
                if parameter:
                    parameters.append(parameter)
            parameter_container = ParameterContainer(
                parameters,
                description_text=field_group['description'],
                extra_parameters=extra_parameter)
            parameter_container.setup_ui(must_scroll=False)
            group_box_inner_layout = QVBoxLayout()
            group_box_inner_layout.addWidget(parameter_container)
            group_box.setLayout(group_box_inner_layout)

            # Add to attribute
            self.default_value_parameter_containers.append(parameter_container)

        # Only show non-groups default fields if there is one
        if len(default_fields) > 0:
            for default_field in default_fields:
                parameter = self.default_field_to_parameter(default_field)
                if parameter:
                    self.default_value_parameters.append(parameter)

            description_text = tr(
                'In this options you can change the global default values for '
                'these variables.')
            parameter_container = ParameterContainer(
                self.default_value_parameters,
                description_text=description_text,
                extra_parameters=extra_parameter)
            parameter_container.setup_ui(must_scroll=False)
            self.other_group_box = QGroupBox(tr('Non-group fields'))
            other_group_inner_layout = QVBoxLayout()
            other_group_inner_layout.addWidget(parameter_container)
            self.other_group_box.setLayout(other_group_inner_layout)
            self.container_layout.addWidget(self.other_group_box)

            # Add to attribute
            self.default_value_parameter_containers.append(parameter_container)
コード例 #5
0
class GuessIndicatorDialogWidget(QDialog):
    def __init__(self, parent=None, checks=[], command=None):
        """Constructor

        Args:
            parent: Qt parent Widget
            iface: QGiS interface
            command: Command instance with a run_it method which will be called
                     on acceptance of the dialog
        """
        super().__init__(parent)
        self.checks = checks
        self.setupUi(checks)

        self.command = command

        self.databases = get_databases()
        self.database_combo.addItems(list(self.databases.keys()))

        # Connect signals
        self.buttonBox.accepted.connect(self.on_accept)
        self.buttonBox.rejected.connect(self.on_reject)

        self.filename = None

    def on_accept(self):
        """Accept and run the Command.run_it method."""

        db_key = self.database_combo.currentText()

        settings = self.databases[db_key]
        db_set = settings["db_settings"]

        if settings["db_type"] == "spatialite":
            pass
        else:  # postgres

            successful_connection = False

            uname = db_set["username"]
            passwd = db_set["password"]
            msg = "Log in"

            while not successful_connection:

                uri = QgsDataSourceUri()
                uri.setConnection(
                    db_set["host"],
                    db_set["port"],
                    db_set["database"],
                    db_set["username"],
                    db_set["password"],
                )

                # try to connect
                # create a PostgreSQL connection using QSqlDatabase
                db = QSqlDatabase.addDatabase("QPSQL")
                # check to see if it is valid

                db.setHostName(uri.host())
                db.setDatabaseName(uri.database())
                try:
                    # port can be an empty string, e.g. for spatialite db's
                    db.setPort(int(uri.port()))
                except ValueError:
                    # TODO: I've seen this uri.port() handling before in some
                    # other file, this can probably be refactored.
                    pass
                db.setUserName(uri.username())
                db.setPassword(uri.password())

                # open (create) the connection
                if db.open():
                    successful_connection = True
                    break
                else:
                    # todo - provide feedback what is wrong
                    pass

                connInfo = uri.connectionInfo()
                (success, uname, passwd) = QgsCredentialDialog.instance().get(
                    connInfo, uname, passwd, msg)

                if success:
                    db_set["username"] = uname
                    db_set["password"] = passwd
                else:
                    return

        checks = []

        if self.check_manhole_indicator.isChecked():
            checks.append("manhole_indicator")

        if self.check_pipe_friction.isChecked():
            checks.append("pipe_friction")

        if self.check_manhole_area.isChecked():
            checks.append("manhole_area")

        self.command.run_it(
            checks,
            self.check_only_empty_fields.isChecked(),
            db_set,
            settings["db_type"],
        )

        self.accept()

    def on_reject(self):
        """Cancel"""
        self.reject()
        logger.debug("Reject")

    def closeEvent(self, event):
        """
        Close widget, called by Qt on close
        :param event: QEvent, close event
        """

        self.buttonBox.accepted.disconnect(self.on_accept)
        self.buttonBox.rejected.disconnect(self.on_reject)

        event.accept()

    def setupUi(self, checks):
        self.resize(515, 450)
        self.verticalLayout = QVBoxLayout(self)

        self.groupBox_2 = QGroupBox(self)
        self.groupBox_2.setObjectName("groupBox_2")
        self.database_combo = QComboBox(self.groupBox_2)
        self.database_combo.setGeometry(QRect(10, 30, 481, 34))

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.database_combo.sizePolicy().hasHeightForWidth())
        self.database_combo.setSizePolicy(sizePolicy)
        self.database_combo.setObjectName("database_combo")
        self.verticalLayout.addWidget(self.groupBox_2)

        self.groupBox = QGroupBox(self)
        self.verticalLayoutBox = QVBoxLayout(self.groupBox)

        self.check_pipe_friction = QCheckBox(self.groupBox)
        self.check_pipe_friction.setChecked(True)
        self.verticalLayoutBox.addWidget(self.check_pipe_friction)

        self.check_manhole_indicator = QCheckBox(self.groupBox)
        self.check_manhole_indicator.setChecked(True)
        self.verticalLayoutBox.addWidget(self.check_manhole_indicator)

        self.check_manhole_area = QCheckBox(self.groupBox)
        self.check_manhole_area.setChecked(True)
        self.verticalLayoutBox.addWidget(self.check_manhole_area)

        self.verticalLayout.addWidget(self.groupBox)

        self.check_only_empty_fields = QCheckBox(self)
        self.check_only_empty_fields.setChecked(True)
        self.verticalLayout.addWidget(self.check_only_empty_fields)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.verticalLayout.addWidget(self.buttonBox)

        self.retranslateUi()
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        QMetaObject.connectSlotsByName(self)

    def retranslateUi(self):
        self.setWindowTitle("Guess indicators")
        self.groupBox_2.setTitle("Model schematisation database")

        self.groupBox.setTitle("Guess")
        self.check_pipe_friction.setText("Pipe friction")
        self.check_manhole_indicator.setText("Manhole indicator")
        self.check_only_empty_fields.setText("Only fill NULL fields")
        self.check_manhole_area.setText(
            "Manhole area (only fills NULL fields)")
コード例 #6
0
class LoadOutputAsLayerDialog(QDialog, FORM_CLASS):
    """
    Dialog to load an oq-engine output as layer
    """
    init_done = pyqtSignal(QDialog)
    loading_completed = pyqtSignal(QDialog)
    loading_exception = pyqtSignal(QDialog, Exception)

    def __init__(self,
                 drive_engine_dlg,
                 iface,
                 viewer_dock,
                 session,
                 hostname,
                 calc_id,
                 output_type=None,
                 path=None,
                 mode=None,
                 zonal_layer_path=None,
                 engine_version=None,
                 calculation_mode=None):
        # sanity check
        if output_type not in OQ_TO_LAYER_TYPES:
            raise NotImplementedError(output_type)
        self.drive_engine_dlg = drive_engine_dlg
        self.iface = iface
        self.viewer_dock = viewer_dock
        self.path = path
        self.session = session
        self.hostname = hostname
        self.calc_id = calc_id
        self.output_type = output_type
        self.mode = mode  # if 'testing' it will avoid some user interaction
        self.zonal_layer_path = zonal_layer_path
        self.engine_version = engine_version
        self.calculation_mode = calculation_mode
        QDialog.__init__(self)
        # Set up the user interface from Designer.
        self.setupUi(self)
        # Disable ok_button until all user options are set
        self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok)
        self.ok_button.setDisabled(True)
        self.oqparam = self.drive_engine_dlg.get_oqparam()

    def on_extract_error(self, exception):
        if isinstance(exception, TaskCanceled):
            msg = 'Data extraction canceled'
            log_msg(msg, level='W', message_bar=self.iface.messageBar())
        else:
            log_msg('Unable to complete data extraction',
                    level='C',
                    message_bar=self.iface.messageBar(),
                    exception=exception)
        self.reject()

    def finalize_init(self, extracted_npz):
        self.npz_file = extracted_npz
        self.populate_out_dep_widgets()
        self.adjustSize()
        self.set_ok_button()
        self.show()
        self.init_done.emit(self)

    def create_num_sites_indicator(self):
        self.num_sites_msg = 'Number of sites: %s'
        self.num_sites_lbl = QLabel(self.num_sites_msg % '')
        self.vlayout.addWidget(self.num_sites_lbl)

    def create_file_size_indicator(self):
        self.file_size_msg = 'File size: %s'
        self.file_size_lbl = QLabel(self.file_size_msg % '')
        self.vlayout.addWidget(self.file_size_lbl)

    def create_single_layer_ckb(self):
        self.load_single_layer_ckb = QCheckBox(
            'Load one layer containing all hazard maps')
        self.vlayout.addWidget(self.load_single_layer_ckb)

    def create_load_one_layer_per_stat_ckb(self):
        self.load_one_layer_per_stat_ckb = QCheckBox(
            'Load one layer per realization or statistic')
        self.vlayout.addWidget(self.load_one_layer_per_stat_ckb)

    def create_min_mag_dsb(self, min_mag=4.0):
        self.min_mag_lbl = QLabel()
        self.min_mag_dsb = QDoubleSpinBox(self)
        self.min_mag_dsb.setRange(0, 10)
        self.min_mag_dsb.setDecimals(1)
        self.min_mag_dsb.setSingleStep(0.1)
        self.min_mag_dsb.setValue(min_mag)
        self.vlayout.addWidget(self.min_mag_lbl)
        self.vlayout.addWidget(self.min_mag_dsb)
        # NOTE: if we don't modify the text of the label after adding the
        # widget to the layout, the adjustSize does not work properly, for some
        # unknown reason
        self.min_mag_lbl.setText('Minimum magnitude')

    def create_rlz_or_stat_selector(self, all_ckb=False, label='Realization'):
        self.rlz_or_stat_lbl = QLabel(label)
        self.rlz_or_stat_cbx = QComboBox()
        self.rlz_or_stat_cbx.setEnabled(False)
        self.rlz_or_stat_cbx.currentIndexChanged['QString'].connect(
            self.on_rlz_or_stat_changed)
        if all_ckb:
            self.load_all_rlzs_or_stats_chk = QCheckBox(
                'Load all realizations')
            self.load_all_rlzs_or_stats_chk.stateChanged[int].connect(
                self.on_load_all_rlzs_or_stats_chk_stateChanged)
            self.vlayout.addWidget(self.load_all_rlzs_or_stats_chk)
        self.vlayout.addWidget(self.rlz_or_stat_lbl)
        self.vlayout.addWidget(self.rlz_or_stat_cbx)

    def on_load_all_rlzs_or_stats_chk_stateChanged(self, state):
        self.rlz_or_stat_cbx.setEnabled(state == Qt.Unchecked)

    def create_selector(self,
                        name,
                        label_text,
                        filter_ckb=False,
                        add_to_layout=None,
                        on_text_changed=None):
        if add_to_layout is not None:
            layout = add_to_layout
        else:
            layout = self.vlayout
        setattr(self, "%s_lbl" % name, QLabel(label_text))
        setattr(self, "%s_cbx" % name, QComboBox())
        lbl = getattr(self, "%s_lbl" % name)
        cbx = getattr(self, "%s_cbx" % name)
        cbx.setDisabled(filter_ckb)
        if on_text_changed is not None:
            cbx.currentTextChanged['QString'].connect(on_text_changed)
        if filter_ckb:
            setattr(self, "filter_by_%s_ckb" % name,
                    QCheckBox('Filter by %s' % name))
            filter_ckb = getattr(self, "filter_by_%s_ckb" % name)

            def on_load_all_ckb_changed():
                cbx.setEnabled(filter_ckb.isChecked())

            filter_ckb.stateChanged[int].connect(on_load_all_ckb_changed)
            filter_ckb.setChecked(False)
            layout.addWidget(filter_ckb)
        layout.addWidget(lbl)
        layout.addWidget(cbx)

    def create_imt_selector(self, all_ckb=False):
        self.imt_lbl = QLabel('Intensity Measure Type')
        self.imt_cbx = QComboBox()
        self.imt_cbx.setEnabled(False)
        self.imt_cbx.currentIndexChanged['QString'].connect(
            self.on_imt_changed)
        if all_ckb:
            self.load_all_imts_chk = QCheckBox('Load all IMTs')
            self.load_all_imts_chk.stateChanged[int].connect(
                self.on_load_all_imts_chk_stateChanged)
            self.vlayout.addWidget(self.load_all_imts_chk)
        self.vlayout.addWidget(self.imt_lbl)
        self.vlayout.addWidget(self.imt_cbx)

    def on_load_all_imts_chk_stateChanged(self, state):
        self.imt_cbx.setEnabled(state == Qt.Unchecked)

    def create_poe_selector(self, all_ckb=False):
        self.poe_lbl = QLabel('Probability of Exceedance')
        self.poe_cbx = QComboBox()
        self.poe_cbx.setEnabled(False)
        self.poe_cbx.currentIndexChanged['QString'].connect(
            self.on_poe_changed)
        if all_ckb:
            self.load_all_poes_chk = QCheckBox('Load all PoEs')
            self.load_all_poes_chk.stateChanged[int].connect(
                self.on_load_all_poes_chk_stateChanged)
            self.vlayout.addWidget(self.load_all_poes_chk)
        self.vlayout.addWidget(self.poe_lbl)
        self.vlayout.addWidget(self.poe_cbx)

    def on_load_all_poes_chk_stateChanged(self, state):
        self.poe_cbx.setEnabled(state == Qt.Unchecked)

    def create_loss_type_selector(self):
        self.loss_type_lbl = QLabel('Loss Type')
        self.loss_type_cbx = QComboBox()
        self.loss_type_cbx.setEnabled(False)
        self.loss_type_cbx.currentIndexChanged['QString'].connect(
            self.on_loss_type_changed)
        self.vlayout.addWidget(self.loss_type_lbl)
        self.vlayout.addWidget(self.loss_type_cbx)

    def create_eid_selector(self):
        self.eid_lbl = QLabel('Event ID')
        self.eid_sbx = QSpinBox()
        self.eid_sbx.setEnabled(False)
        self.vlayout.addWidget(self.eid_lbl)
        self.vlayout.addWidget(self.eid_sbx)

    def create_dmg_state_selector(self):
        self.dmg_state_lbl = QLabel('Damage state')
        self.dmg_state_cbx = QComboBox()
        self.dmg_state_cbx.setEnabled(False)
        self.dmg_state_cbx.currentIndexChanged['QString'].connect(
            self.on_dmg_state_changed)
        self.vlayout.addWidget(self.dmg_state_lbl)
        self.vlayout.addWidget(self.dmg_state_cbx)

    def create_taxonomy_selector(self):
        self.taxonomy_lbl = QLabel('Taxonomy')
        self.taxonomy_cbx = QComboBox()
        self.taxonomy_cbx.setEnabled(False)
        self.vlayout.addWidget(self.taxonomy_lbl)
        self.vlayout.addWidget(self.taxonomy_cbx)

    def create_style_by_selector(self):
        self.style_by_lbl = QLabel('Style by')
        self.style_by_cbx = QComboBox()
        self.vlayout.addWidget(self.style_by_lbl)
        self.vlayout.addWidget(self.style_by_cbx)

    def create_load_selected_only_ckb(self):
        self.load_selected_only_ckb = QCheckBox("Load only the selected items")
        self.load_selected_only_ckb.setChecked(True)
        self.vlayout.addWidget(self.load_selected_only_ckb)

    def create_show_return_period_ckb(self):
        self.show_return_period_chk = QCheckBox(
            "Show the return period in layer names")
        self.show_return_period_chk.setChecked(False)
        self.vlayout.addWidget(self.show_return_period_chk)

    def create_aggregate_by_site_ckb(self):
        self.aggregate_by_site_ckb = QCheckBox("Aggregate by site")
        self.aggregate_by_site_ckb.setChecked(True)
        self.vlayout.addWidget(self.aggregate_by_site_ckb)

    def create_zonal_layer_selector(self, discard_nonmatching=True):
        self.added_zonal_layer = None
        self.zonal_layer_gbx = QGroupBox()
        self.zonal_layer_gbx.setTitle('Aggregate by zone')
        self.zonal_layer_gbx.setCheckable(True)
        self.zonal_layer_gbx.setChecked(False)
        self.zonal_layer_gbx_v_layout = QVBoxLayout()
        self.zonal_layer_gbx.setLayout(self.zonal_layer_gbx_v_layout)
        self.zonal_layer_cbx = QComboBox()
        self.zonal_layer_cbx.addItem('')
        self.zonal_layer_lbl = QLabel('Zonal layer')
        self.zonal_layer_tbn = QToolButton()
        self.zonal_layer_tbn.setText('...')
        self.discard_nonmatching_chk = QCheckBox(
            'Discard zones with no points')
        self.discard_nonmatching_chk.setChecked(discard_nonmatching)
        self.zonal_layer_h_layout = QHBoxLayout()
        self.zonal_layer_h_layout.addWidget(self.zonal_layer_cbx)
        self.zonal_layer_h_layout.addWidget(self.zonal_layer_tbn)
        self.zonal_layer_gbx_v_layout.addWidget(self.zonal_layer_lbl)
        self.zonal_layer_gbx_v_layout.addLayout(self.zonal_layer_h_layout)
        self.zonal_layer_gbx_v_layout.addWidget(self.discard_nonmatching_chk)
        self.vlayout.addWidget(self.zonal_layer_gbx)
        self.zonal_layer_tbn.clicked.connect(self.open_load_zonal_layer_dialog)
        self.zonal_layer_cbx.currentIndexChanged[int].connect(
            self.on_zonal_layer_cbx_currentIndexChanged)
        self.zonal_layer_gbx.toggled[bool].connect(
            self.on_zonal_layer_gbx_toggled)
        self.iface.layerTreeView().currentLayerChanged.connect(
            self.on_currentLayerChanged)

    def on_currentLayerChanged(self):
        self.pre_populate_zonal_layer_cbx()

    def pre_populate_zonal_layer_cbx(self):
        # populate cbx only with vector layers containing polygons
        self.zonal_layer_cbx.clear()
        for key, layer in QgsProject.instance().mapLayers().items():
            if layer.type() != QgsMapLayer.VectorLayer:
                continue
            if layer.geometryType() == QgsWkbTypes.PolygonGeometry:
                self.zonal_layer_cbx.addItem(layer.name())
                self.zonal_layer_cbx.setItemData(
                    self.zonal_layer_cbx.count() - 1, layer.id())
        if self.added_zonal_layer is not None:
            self.zonal_layer_cbx.setCurrentIndex(
                self.zonal_layer_cbx.findData(self.added_zonal_layer.id()))
        self.zonal_layer_gbx.setChecked(
            self.zonal_layer_cbx.currentIndex() != -1)

    def on_zonal_layer_cbx_currentIndexChanged(self, new_index):
        self.zonal_layer = None
        if not self.zonal_layer_cbx.currentText():
            if self.zonal_layer_gbx.isChecked():
                self.ok_button.setEnabled(False)
            return
        zonal_layer_id = self.zonal_layer_cbx.itemData(new_index)
        self.zonal_layer = QgsProject.instance().mapLayer(zonal_layer_id)
        self.set_ok_button()

    def on_zonal_layer_gbx_toggled(self, is_checked):
        if is_checked and not self.zonal_layer_cbx.currentText():
            self.ok_button.setEnabled(False)
        else:
            self.set_ok_button()

    def on_output_type_changed(self):
        if self.output_type in OQ_TO_LAYER_TYPES:
            self.create_load_selected_only_ckb()
        self.set_ok_button()

    def on_rlz_or_stat_changed(self):
        self.dataset = self.npz_file[self.rlz_or_stat_cbx.currentText()]
        self.set_ok_button()

    def on_loss_type_changed(self):
        self.set_ok_button()

    def on_imt_changed(self):
        self.set_ok_button()

    def on_poe_changed(self):
        self.set_ok_button()

    def on_eid_changed(self):
        self.set_ok_button()

    def on_dmg_state_changed(self):
        self.set_ok_button()

    def populate_out_dep_widgets(self):
        self.populate_rlz_or_stat_cbx()
        self.show_num_sites()

    def get_taxonomies(self):
        raise NotImplementedError()

    def populate_rlz_or_stat_cbx(self):
        self.rlzs_or_stats = [
            key for key in sorted(self.npz_file)
            if key not in ('imtls', 'array')
        ]
        self.rlz_or_stat_cbx.clear()
        self.rlz_or_stat_cbx.setEnabled(True)
        self.rlz_or_stat_cbx.addItems(self.rlzs_or_stats)

    def populate_loss_type_cbx(self, loss_types):
        self.loss_type_cbx.clear()
        self.loss_type_cbx.setEnabled(True)
        self.loss_type_cbx.addItems(loss_types)

    def show_num_sites(self):
        # NOTE: we are assuming all realizations have the same number of sites,
        #       which currently is always true.
        #       If different realizations have a different number of sites, we
        #       need to move this block of code inside on_rlz_or_stat_changed()
        rlz_or_stat_data = self.npz_file[self.rlz_or_stat_cbx.currentText()]
        self.num_sites_lbl.setText(self.num_sites_msg % rlz_or_stat_data.shape)

    def set_ok_button(self):
        raise NotImplementedError()

    def build_layer_name(self, *args, **kwargs):
        raise NotImplementedError()

    def get_field_types(self, **kwargs):
        raise NotImplementedError()

    def read_npz_into_layer(self, field_types, **kwargs):
        raise NotImplementedError()

    def load_from_npz(self):
        raise NotImplementedError()

    def add_field_to_layer(self, field_name, field_type):
        # NOTE: add_attribute use the native qgis editing manager
        added_field_name = add_attribute(field_name, field_type, self.layer)
        return added_field_name

    def get_investigation_time(self):
        if self.output_type in ('hcurves', 'uhs', 'hmaps', 'ruptures'):
            try:
                investigation_time = self.npz_file['investigation_time']
            except KeyError as exc:
                msg = ('investigation_time not found. It is mandatory for %s.'
                       ' Please check if the ouptut was produced by an'
                       ' obsolete version of the OpenQuake Engine'
                       ' Server.') % self.output_type
                log_msg(msg,
                        level='C',
                        message_bar=self.iface.messageBar(),
                        exception=exc)
            else:
                # We must cast to 'str' to keep numerical padding
                # after saving the project
                return str(investigation_time)
        else:
            # some outputs do not need the investigation time
            return None

    def build_layer(self,
                    rlz_or_stat=None,
                    taxonomy=None,
                    poe=None,
                    loss_type=None,
                    dmg_state=None,
                    gsim=None,
                    imt=None,
                    boundaries=None,
                    geometry_type='point',
                    wkt_geom_type=None,
                    row_wkt_geom_types=None,
                    add_to_group=None,
                    add_to_map=True):
        layer_name = self.build_layer_name(rlz_or_stat=rlz_or_stat,
                                           taxonomy=taxonomy,
                                           poe=poe,
                                           loss_type=loss_type,
                                           dmg_state=dmg_state,
                                           gsim=gsim,
                                           imt=imt,
                                           geometry_type=geometry_type)
        field_types = self.get_field_types(rlz_or_stat=rlz_or_stat,
                                           taxonomy=taxonomy,
                                           poe=poe,
                                           loss_type=loss_type,
                                           dmg_state=dmg_state,
                                           imt=imt)

        # create layer
        self.layer = QgsVectorLayer("%s?crs=epsg:4326" % geometry_type,
                                    layer_name, "memory")
        modified_field_types = copy.copy(field_types)
        for field_name, field_type in field_types.items():
            if field_name in ['lon', 'lat', 'boundary']:
                continue
            added_field_name = self.add_field_to_layer(field_name, field_type)
            if field_name != added_field_name:
                if field_name == self.default_field_name:
                    self.default_field_name = added_field_name
                # replace field_name with the actual added_field_name
                del modified_field_types[field_name]
                modified_field_types[added_field_name] = field_type
        field_types = copy.copy(modified_field_types)

        self.layer = self.read_npz_into_layer(
            field_types,
            rlz_or_stat=rlz_or_stat,
            taxonomy=taxonomy,
            poe=poe,
            loss_type=loss_type,
            dmg_state=dmg_state,
            imt=imt,
            boundaries=boundaries,
            geometry_type=geometry_type,
            wkt_geom_type=wkt_geom_type,
            row_wkt_geom_types=row_wkt_geom_types)
        if (self.output_type == 'damages-rlzs'
                and not self.aggregate_by_site_ckb.isChecked()):
            self.layer.setCustomProperty('output_type', 'recovery_curves')
        else:
            self.layer.setCustomProperty('output_type', self.output_type)
        investigation_time = self.get_investigation_time()
        if investigation_time is not None:
            self.layer.setCustomProperty('investigation_time',
                                         investigation_time)
        if self.engine_version is not None:
            self.layer.setCustomProperty('engine_version', self.engine_version)
        irmt_version = get_irmt_version()
        self.layer.setCustomProperty('irmt_version', irmt_version)
        self.layer.setCustomProperty('calc_id', self.calc_id)
        if poe is not None:
            self.layer.setCustomProperty('poe', poe)
        user_params = {
            'rlz_or_stat': rlz_or_stat,
            'taxonomy': taxonomy,
            'poe': poe,
            'loss_type': loss_type,
            'dmg_state': dmg_state,
            'gsim': gsim,
            'imt': imt
        }
        write_metadata_to_layer(self.drive_engine_dlg, self.output_type,
                                self.layer, user_params)
        try:
            if (self.zonal_layer_cbx.currentText()
                    and self.zonal_layer_gbx.isChecked()):
                return
        except AttributeError:
            # the aggregation stuff might not exist for some loaders
            pass
        if add_to_map:
            if add_to_group:
                tree_node = add_to_group
            else:
                tree_node = QgsProject.instance().layerTreeRoot()
            if self.mode != 'testing':
                # NOTE: the following commented line would cause (unexpectedly)
                #       "QGIS died on signal 11" and double creation of some
                #       layers during integration tests
                QgsProject.instance().addMapLayer(self.layer, False)
            tree_node.insertLayer(0, self.layer)
            self.iface.setActiveLayer(self.layer)
            if add_to_group:
                # NOTE: zooming to group from caller function, to avoid
                #       repeating it once per layer
                pass
            else:
                self.iface.zoomToActiveLayer()
            log_msg('Layer %s was created successfully' % layer_name,
                    level='S',
                    message_bar=self.iface.messageBar())
        return self.layer

    @staticmethod
    def style_maps(layer,
                   style_by,
                   iface,
                   output_type='damages-rlzs',
                   perils=None,
                   add_null_class=False,
                   render_higher_on_top=False,
                   repaint=True,
                   use_sgc_style=False):
        symbol = QgsSymbol.defaultSymbol(layer.geometryType())
        # see properties at:
        # https://qgis.org/api/qgsmarkersymbollayerv2_8cpp_source.html#l01073
        symbol.setOpacity(1)
        if isinstance(symbol, QgsMarkerSymbol):
            # do it only for the layer with points
            symbol.symbolLayer(0).setStrokeStyle(Qt.PenStyle(Qt.NoPen))

        style = get_style(layer, iface.messageBar())

        # this is the default, as specified in the user settings
        ramp = QgsGradientColorRamp(style['color_from'], style['color_to'])
        style_mode = style['style_mode']

        # in most cases, we override the user-specified setting, and use
        # instead a setting that was required by scientists
        if output_type in OQ_TO_LAYER_TYPES:
            default_qgs_style = QgsStyle().defaultStyle()
            default_color_ramp_names = default_qgs_style.colorRampNames()
            if output_type in (
                    'damages-rlzs',
                    'avg_losses-rlzs',
                    'avg_losses-stats',
            ):
                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                if Qgis.QGIS_VERSION_INT < 31000:
                    style_mode = QgsGraduatedSymbolRenderer.Jenks
                else:
                    style_mode = 'Jenks'
                ramp_type_idx = default_color_ramp_names.index('Reds')
                symbol.setColor(QColor(RAMP_EXTREME_COLORS['Reds']['top']))
                inverted = False
            elif (output_type in ('gmf_data', 'ruptures')
                  or (output_type == 'hmaps' and not use_sgc_style)):
                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                if output_type == 'ruptures':
                    if Qgis.QGIS_VERSION_INT < 31000:
                        style_mode = QgsGraduatedSymbolRenderer.Pretty
                    else:
                        style_mode = 'PrettyBreaks'
                else:
                    if Qgis.QGIS_VERSION_INT < 31000:
                        style_mode = QgsGraduatedSymbolRenderer.EqualInterval
                    else:
                        style_mode = 'EqualInterval'
                ramp_type_idx = default_color_ramp_names.index('Spectral')
                inverted = True
                symbol.setColor(QColor(RAMP_EXTREME_COLORS['Reds']['top']))
            elif output_type == 'hmaps' and use_sgc_style:
                # FIXME: for SGC they were using size 10000 map units

                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                if Qgis.QGIS_VERSION_INT < 31000:
                    style_mode = QgsGraduatedSymbolRenderer.Pretty
                else:
                    style_mode = 'PrettyBreaks'
                try:
                    ramp_type_idx = default_color_ramp_names.index(
                        'SGC_Green2Red_Hmap_Color_Ramp')
                except ValueError:
                    raise ValueError(
                        'Color ramp SGC_Green2Red_Hmap_Color_Ramp was '
                        'not found. Please import it from '
                        'Settings -> Style Manager, loading '
                        'svir/resources/sgc_green2red_hmap_color_ramp.xml')
                inverted = False
                registry = QgsApplication.symbolLayerRegistry()
                symbol_props = {
                    'name': 'square',
                    'color': '0,0,0',
                    'color_border': '0,0,0',
                    'offset': '0,0',
                    'size': '1.5',  # FIXME
                    'angle': '0',
                }
                square = registry.symbolLayerMetadata(
                    "SimpleMarker").createSymbolLayer(symbol_props)
                symbol = QgsSymbol.defaultSymbol(layer.geometryType()).clone()
                symbol.deleteSymbolLayer(0)
                symbol.appendSymbolLayer(square)
                symbol.symbolLayer(0).setStrokeStyle(Qt.PenStyle(Qt.NoPen))
            elif output_type in ['asset_risk', 'input']:
                # options are EqualInterval, Quantile, Jenks, StdDev, Pretty
                # jenks = natural breaks
                if Qgis.QGIS_VERSION_INT < 31000:
                    style_mode = QgsGraduatedSymbolRenderer.EqualInterval
                else:
                    style_mode = 'EqualInterval'
                # exposure_strings = ['number', 'occupants', 'value']
                # setting exposure colors by default
                colors = {
                    'single': RAMP_EXTREME_COLORS['Blues']['top'],
                    'ramp_name': 'Blues'
                }
                inverted = False
                if output_type == 'asset_risk':
                    damage_strings = perils
                    for damage_string in damage_strings:
                        if damage_string in style_by:
                            colors = {
                                'single':
                                RAMP_EXTREME_COLORS['Spectral']['top'],
                                'ramp_name': 'Spectral'
                            }
                            inverted = True
                            break
                else:  # 'input'
                    colors = {
                        'single': RAMP_EXTREME_COLORS['Greens']['top'],
                        'ramp_name': 'Greens'
                    }
                    symbol.symbolLayer(0).setShape(
                        QgsSimpleMarkerSymbolLayerBase.Square)
                single_color = colors['single']
                ramp_name = colors['ramp_name']
                ramp_type_idx = default_color_ramp_names.index(ramp_name)
                symbol.setColor(QColor(single_color))
            else:
                raise NotImplementedError(
                    'Undefined color ramp for output type %s' % output_type)
            ramp = default_qgs_style.colorRamp(
                default_color_ramp_names[ramp_type_idx])
            if inverted:
                ramp.invert()
        # get unique values
        fni = layer.fields().indexOf(style_by)
        unique_values = layer.dataProvider().uniqueValues(fni)
        num_unique_values = len(unique_values - {NULL})
        if num_unique_values > 2:
            if Qgis.QGIS_VERSION_INT < 31000:
                renderer = QgsGraduatedSymbolRenderer.createRenderer(
                    layer, style_by, min(num_unique_values, style['classes']),
                    style_mode, symbol.clone(), ramp)
            else:
                renderer = QgsGraduatedSymbolRenderer(style_by, [])
                # NOTE: the following returns an instance of one of the
                #       subclasses of QgsClassificationMethod
                classification_method = \
                    QgsApplication.classificationMethodRegistry().method(
                        style_mode)
                renderer.setClassificationMethod(classification_method)
                renderer.updateColorRamp(ramp)
                renderer.updateSymbols(symbol.clone())
                renderer.updateClasses(
                    layer, min(num_unique_values, style['classes']))
            if not use_sgc_style:
                if Qgis.QGIS_VERSION_INT < 31000:
                    label_format = renderer.labelFormat()
                    # NOTE: the following line might be useful
                    # label_format.setTrimTrailingZeroes(True)
                    label_format.setPrecision(2)
                    renderer.setLabelFormat(label_format, updateRanges=True)
                else:
                    renderer.classificationMethod().setLabelPrecision(2)
                    renderer.calculateLabelPrecision()
        elif num_unique_values == 2:
            categories = []
            for unique_value in unique_values:
                symbol = symbol.clone()
                try:
                    symbol.setColor(
                        QColor(RAMP_EXTREME_COLORS[ramp_name]
                               ['bottom' if unique_value ==
                                min(unique_values) else 'top']))
                except Exception:
                    symbol.setColor(
                        QColor(style['color_from'] if unique_value ==
                               min(unique_values) else style['color_to']))
                category = QgsRendererCategory(unique_value, symbol,
                                               str(unique_value))
                # entry for the list of category items
                categories.append(category)
            renderer = QgsCategorizedSymbolRenderer(style_by, categories)
        else:
            renderer = QgsSingleSymbolRenderer(symbol.clone())
        if add_null_class and NULL in unique_values:
            # add a class for NULL values
            rule_renderer = QgsRuleBasedRenderer(symbol.clone())
            root_rule = rule_renderer.rootRule()
            not_null_rule = root_rule.children()[0].clone()
            # strip parentheses from stringified color HSL
            not_null_rule.setFilterExpression(
                '%s IS NOT NULL' % QgsExpression.quotedColumnRef(style_by))
            not_null_rule.setLabel('%s:' % style_by)
            root_rule.appendChild(not_null_rule)
            null_rule = root_rule.children()[0].clone()
            null_rule.setSymbol(
                QgsFillSymbol.createSimple({
                    'color': '160,160,160',
                    'style': 'diagonal_x'
                }))
            null_rule.setFilterExpression(
                '%s IS NULL' % QgsExpression.quotedColumnRef(style_by))
            null_rule.setLabel(tr('No points'))
            root_rule.appendChild(null_rule)
            if isinstance(renderer, QgsGraduatedSymbolRenderer):
                # create value ranges
                rule_renderer.refineRuleRanges(not_null_rule, renderer)
                # remove default rule
            elif isinstance(renderer, QgsCategorizedSymbolRenderer):
                rule_renderer.refineRuleCategoris(not_null_rule, renderer)
            for rule in rule_renderer.rootRule().children()[1].children():
                label = rule.label()
                # by default, labels are like:
                # ('"collapse-structural-ASH_DRY_sum" >= 0.0000 AND
                # "collapse-structural-ASH_DRY_sum" <= 2.3949')
                first, second = label.split(" AND ")
                bottom = first.rsplit(" ", 1)[1]
                top = second.rsplit(" ", 1)[1]
                simplified = "%s - %s" % (bottom, top)
                rule.setLabel(simplified)
            root_rule.removeChildAt(0)
            renderer = rule_renderer
        if render_higher_on_top:
            renderer.setUsingSymbolLevels(True)
            symbol_items = [item for item in renderer.legendSymbolItems()]
            for i in range(len(symbol_items)):
                sym = symbol_items[i].symbol().clone()
                key = symbol_items[i].ruleKey()
                for lay in range(sym.symbolLayerCount()):
                    sym.symbolLayer(lay).setRenderingPass(i)
                renderer.setLegendSymbolItem(key, sym)
        layer.setRenderer(renderer)
        if not use_sgc_style:
            layer.setOpacity(0.7)
        if repaint:
            layer.triggerRepaint()
            iface.setActiveLayer(layer)
            iface.zoomToActiveLayer()
            # NOTE QGIS3: probably not needed
            # iface.layerTreeView().refreshLayerSymbology(layer.id())
            iface.mapCanvas().refresh()

    def style_categorized(self, layer=None, style_by=None):
        if layer is None:
            layer = self.layer
        if style_by is None:
            style_by = self.default_field_name
        # get unique values
        fni = layer.fields().indexOf(style_by)
        unique_values = layer.dataProvider().uniqueValues(fni)
        # define categories
        categories = []
        for unique_value in unique_values:
            # initialize the default symbol for this geometry type
            symbol = QgsSymbol.defaultSymbol(layer.geometryType())
            # configure a symbol layer
            layer_style = {}
            layer_style['color'] = '%d, %d, %d' % (randrange(
                0, 256), randrange(0, 256), randrange(0, 256))
            layer_style['outline'] = '#000000'
            symbol_layer = QgsSimpleFillSymbolLayer.create(layer_style)
            # replace default symbol layer with the configured one
            if symbol_layer is not None:
                symbol.changeSymbolLayer(0, symbol_layer)
            # create renderer object
            category = QgsRendererCategory(unique_value, symbol,
                                           str(unique_value))
            # entry for the list of category items
            categories.append(category)
        # create renderer object
        renderer = QgsCategorizedSymbolRenderer(style_by, categories)
        # assign the created renderer to the layer
        if renderer is not None:
            layer.setRenderer(renderer)
        layer.triggerRepaint()

        # NOTE QGIS3: probably not needed
        # self.iface.layerTreeView().refreshLayerSymbology(layer.id())

        self.iface.mapCanvas().refresh()

    def style_curves(self):
        registry = QgsApplication.symbolLayerRegistry()
        symbol_props = {
            'name': 'cross2',
            'color': '0,0,0',
            'color_border': '0,0,0',
            'offset': '0,0',
            'size': '1.5',
            'angle': '0',
        }
        opacity = 0.7
        cross = registry.symbolLayerMetadata("SimpleMarker").createSymbolLayer(
            symbol_props)
        # NOTE: Cross symbols rendered for OQ-Engine disaggregation outputs are
        # opaque, wider and thicker than those used for other outputs (e.g.
        # hcurves)
        if self.output_type == 'disagg':
            cross.setSize(3)
            cross.setStrokeWidth(0.5)
            opacity = 1
        symbol = QgsSymbol.defaultSymbol(self.layer.geometryType()).clone()
        symbol.deleteSymbolLayer(0)
        symbol.appendSymbolLayer(cross)
        renderer = QgsSingleSymbolRenderer(symbol)
        effect = QgsOuterGlowEffect()
        effect.setSpread(0.5)
        effect.setOpacity(opacity)
        effect.setColor(QColor(255, 255, 255))
        effect.setBlurLevel(1)

        renderer.paintEffect().appendEffect(effect)
        renderer.paintEffect().setEnabled(True)

        self.layer.setRenderer(renderer)
        self.layer.setOpacity(opacity)
        self.layer.triggerRepaint()

        # NOTE QGIS3: probably not needed
        # self.iface.layerTreeView().refreshLayerSymbology(self.layer.id())

        self.iface.mapCanvas().refresh()

    def open_load_zonal_layer_dialog(self):
        """
        Open a file dialog to select the zonal layer to be loaded
        :returns: the zonal layer
        """
        text = self.tr('Select zonal layer to import')
        filters = self.tr('All files (*.*);;'
                          'GeoPackages (*.gpkg);;'
                          'Vector shapefiles (*.shp);;'
                          'SQLite (*.sqlite);;')
        default_dir = QSettings().value('irmt/select_layer_dir',
                                        QDir.homePath())
        file_name, _ = QFileDialog.getOpenFileName(self, text, default_dir,
                                                   filters)
        if not file_name:
            return None
        selected_dir = QFileInfo(file_name).dir().path()
        QSettings().setValue('irmt/select_layer_dir', selected_dir)
        zonal_layer = self.load_zonal_layer(file_name)
        return zonal_layer

    def load_zonal_layer(self, zonal_layer_path):
        self.added_zonal_layer = zonal_layer = None
        zonal_layer_basename, zonal_layer_ext = os.path.splitext(
            os.path.basename(zonal_layer_path))
        if zonal_layer_ext == '.gpkg':
            dlg = QgsSublayersDialog(QgsSublayersDialog.Ogr,
                                     'Select zonal layer')
            conn = ogr.Open(zonal_layer_path)
            layer_defs = []
            for idx, c in enumerate(conn):
                ld = QgsSublayersDialog.LayerDefinition()
                ld.layerId = idx
                ld.layerName = c.GetDescription()
                ld.count = c.GetFeatureCount()
                ld.type = ogr.GeometryTypeToName(c.GetGeomType())
                layer_defs.append(ld)
            dlg.populateLayerTable(layer_defs)
            dlg.exec_()
            if not dlg.selection():
                return None
            for sel in dlg.selection():
                # NOTE: the last one will be chosen as zonal layer
                zonal_layer = QgsVectorLayer(
                    zonal_layer_path + "|layername=" + sel.layerName,
                    sel.layerName, 'ogr')
                if zonal_layer.isValid():
                    root = QgsProject.instance().layerTreeRoot()
                    QgsProject.instance().addMapLayer(zonal_layer, False)
                    root.insertLayer(0, zonal_layer)
                else:
                    msg = 'Invalid layer'
                    log_msg(msg,
                            level='C',
                            message_bar=self.iface.messageBar())
                    return None
        else:
            zonal_layer = QgsVectorLayer(zonal_layer_path,
                                         zonal_layer_basename, 'ogr')
        if not zonal_layer.geometryType() == QgsWkbTypes.PolygonGeometry:
            msg = 'Zonal layer must contain zone polygons'
            log_msg(msg, level='C', message_bar=self.iface.messageBar())
            return None
        if zonal_layer_ext != '.gpkg':
            # Add zonal layer to registry
            if zonal_layer.isValid():
                root = QgsProject.instance().layerTreeRoot()
                QgsProject.instance().addMapLayer(zonal_layer, False)
                root.insertLayer(0, zonal_layer)
            else:
                msg = 'Invalid zonal layer'
                log_msg(msg, level='C', message_bar=self.iface.messageBar())
                return None
        self.added_zonal_layer = zonal_layer
        self.pre_populate_zonal_layer_cbx()
        return zonal_layer

    def populate_zonal_layer_cbx(self, zonal_layer):
        cbx = self.zonal_layer_cbx
        cbx.addItem(zonal_layer.name())
        last_index = cbx.count() - 1
        cbx.setItemData(last_index, zonal_layer.id())
        cbx.setCurrentIndex(last_index)

    def show_file_size(self):
        file_size = get_file_size(self.path)
        self.file_size_lbl.setText(self.file_size_msg % file_size)

    def accept(self):
        log_msg('Loading output started. Watch progress in QGIS task bar',
                level='I',
                message_bar=self.iface.messageBar())
        try:
            self.iface.layerTreeView().currentLayerChanged.disconnect(
                self.on_currentLayerChanged)
        except Exception:
            # it's connected only for some loaders
            pass
        self.hide()
        if self.output_type in OQ_EXTRACT_TO_LAYER_TYPES:
            self.load_from_npz()
            if self.output_type in ('avg_losses-rlzs', 'damages-rlzs',
                                    'avg_losses-stats'):
                # check if also aggregating by zone or not
                if (not self.zonal_layer_cbx.currentText()
                        or not self.zonal_layer_gbx.isChecked()):
                    super().accept()
                    return
                self.aggregate_by_zone()
            else:
                super().accept()
        elif self.output_type in OQ_CSV_TO_LAYER_TYPES:
            self.load_from_csv()
            super().accept()

    def aggregate_by_zone(self):
        loss_layer = self.layer
        zonal_layer_id = self.zonal_layer_cbx.itemData(
            self.zonal_layer_cbx.currentIndex())
        zonal_layer = QgsProject.instance().mapLayer(zonal_layer_id)
        QgsProject.instance().layerTreeRoot().findLayer(
            zonal_layer.id()).setItemVisibilityChecked(False)
        # if the two layers have different projections, display a
        # warning, but try proceeding anyway
        have_same_projection, check_projection_msg = ProcessLayer(
            loss_layer).has_same_projection_as(zonal_layer)
        if not have_same_projection:
            log_msg(check_projection_msg,
                    level='W',
                    message_bar=self.iface.messageBar())
        try:
            [self.loss_attr_name
             ] = [field.name() for field in loss_layer.fields()]
        except ValueError:
            self.loss_attr_name = self.default_field_name
        zonal_layer_plus_sum_name = "%s: %s_sum" % (zonal_layer.name(),
                                                    self.loss_attr_name)
        discard_nonmatching = self.discard_nonmatching_chk.isChecked()
        try:
            calculate_zonal_stats(self.on_calculate_zonal_stats_completed,
                                  zonal_layer,
                                  loss_layer, [self.loss_attr_name],
                                  zonal_layer_plus_sum_name,
                                  discard_nonmatching=discard_nonmatching,
                                  predicates=('intersects', ),
                                  summaries=('sum', ))
        except Exception as exc:
            log_msg(str(exc),
                    level='C',
                    message_bar=self.iface.messageBar(),
                    exception=exc)

    def on_calculate_zonal_stats_completed(self, zonal_layer_plus_sum):
        if zonal_layer_plus_sum is None:
            msg = 'The calculation of zonal statistics was not completed'
            log_msg(msg, level='C', message_bar=self.iface.messageBar())
            return None
        # Add zonal layer to registry
        if zonal_layer_plus_sum.isValid():
            root = QgsProject.instance().layerTreeRoot()
            QgsProject.instance().addMapLayer(zonal_layer_plus_sum, False)
            root.insertLayer(0, zonal_layer_plus_sum)
        else:
            msg = 'The layer aggregating data by zone is invalid.'
            log_msg(msg, level='C', message_bar=self.iface.messageBar())
            return None
        # NOTE: in scenario damage, keys are like
        #       u'structural_no_damage_mean', and not just
        #       u'structural', therefore we can't just use the selected
        #       loss type, but we must use the actual only key in the
        #       dict
        added_loss_attr = "%s_sum" % self.loss_attr_name
        style_by = added_loss_attr
        try:
            perils = self.perils
        except AttributeError:
            perils = None
        self.style_maps(zonal_layer_plus_sum,
                        style_by,
                        self.iface,
                        self.output_type,
                        perils=perils,
                        add_null_class=True)
        super().accept()

    def reject(self):
        try:
            self.iface.layerTreeView().currentLayerChanged.disconnect(
                self.on_currentLayerChanged)
        except Exception:
            # it's connected only for some loaders
            pass
        super().reject()
コード例 #7
0
class RemoteRefDialog(QDialog):
    def __init__(self, repo, parent=None):
        super(RemoteRefDialog, self).__init__(parent)
        self.remote = None
        self.branch = None
        self.repo = repo
        self.initGui()

    def initGui(self):
        self.setWindowTitle('Remote reference')
        verticalLayout = QVBoxLayout()

        horizontalLayout = QHBoxLayout()
        horizontalLayout.setSpacing(30)
        horizontalLayout.setMargin(0)
        remoteLabel = QLabel('Remote')
        self.remoteCombo = QComboBox()
        self.remotes = self.repo.remotes()
        self.remoteCombo.addItems(list(self.remotes.keys()))
        self.remoteCombo.currentIndexChanged.connect(self.currentRemoteChanged)
        horizontalLayout.addWidget(remoteLabel)
        horizontalLayout.addWidget(self.remoteCombo)
        verticalLayout.addLayout(horizontalLayout)

        horizontalLayout = QHBoxLayout()
        horizontalLayout.setSpacing(30)
        horizontalLayout.setMargin(0)
        branchLabel = QLabel('Branch')
        self.branchCombo = QComboBox()
        self.branchCombo.addItems(self.repo.branches())
        horizontalLayout.addWidget(branchLabel)
        horizontalLayout.addWidget(self.branchCombo)
        verticalLayout.addLayout(horizontalLayout)

        self.groupBox = QGroupBox()
        self.groupBox.setTitle("Remote info")
        self.groupBox.setLayout(verticalLayout)

        layout = QVBoxLayout()
        layout.addWidget(self.groupBox)

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok
                                          | QDialogButtonBox.Cancel)
        layout.addWidget(self.buttonBox)

        self.setLayout(layout)

        self.buttonBox.accepted.connect(self.okPressed)
        self.buttonBox.rejected.connect(self.cancelPressed)

        self.resize(400, 200)

    def currentRemoteChanged(self):
        remote = self.remoteCombo.currentText()
        repo = Repository(self.remotes[remote])
        #TODO handle case of remote not being available
        branches = repo.branches()
        self.branchesCombo.clear()
        self.branchesCombo.addItems(branches)

    def okPressed(self):
        remote = self.remoteCombo.currentText().strip()
        if remote:
            self.remote = remote
        else:
            QMessageBox.warning(self, "Missing value",
                                "Please select a remote")
            return
        branch = self.branchCombo.currentText().strip()
        if branch:
            self.branch = branch
        else:
            QMessageBox.warning(self, "Missing value",
                                "Please select a branch")
            return
        self.close()

    def cancelPressed(self):
        self.remote = None
        self.branch = None
        self.close()
コード例 #8
0
class RemoteRefDialog(QDialog):

    def __init__(self, repo, parent = None):
        super(RemoteRefDialog, self).__init__(parent)
        self.remote = None
        self.branch = None
        self.repo = repo
        self.initGui()

    def initGui(self):
        self.setWindowTitle('Remote connection reference')
        verticalLayout = QVBoxLayout()

        horizontalLayout = QHBoxLayout()
        horizontalLayout.setSpacing(30)
        horizontalLayout.setMargin(0)
        remoteLabel = QLabel('Remote connection')
        self.remoteCombo = QComboBox()
        self.remotes = self.repo.remotes()
        self.remoteCombo.addItems(list(self.remotes.keys()))
        self.remoteCombo.currentIndexChanged.connect(self.currentRemoteChanged)
        horizontalLayout.addWidget(remoteLabel)
        horizontalLayout.addWidget(self.remoteCombo)
        verticalLayout.addLayout(horizontalLayout)

        horizontalLayout = QHBoxLayout()
        horizontalLayout.setSpacing(30)
        horizontalLayout.setMargin(0)
        branchLabel = QLabel('Branch')
        self.branchCombo = QComboBox()
        self.branchCombo.addItems(self.repo.branches())
        horizontalLayout.addWidget(branchLabel)
        horizontalLayout.addWidget(self.branchCombo)
        verticalLayout.addLayout(horizontalLayout)

        self.groupBox = QGroupBox()
        self.groupBox.setTitle("Remote connection info")
        self.groupBox.setLayout(verticalLayout)

        layout = QVBoxLayout()
        layout.addWidget(self.groupBox)

        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        layout.addWidget(self.buttonBox)

        self.setLayout(layout)

        self.buttonBox.accepted.connect(self.okPressed)
        self.buttonBox.rejected.connect(self.cancelPressed)

        self.resize(400, 200)

    def currentRemoteChanged(self):
        self.branchCombo.clear()
        remote = self.remoteCombo.currentText()
        try:
            repo = Repository(self.remotes[remote])
            branches = repo.branches()
            self.branchCombo.addItems(branches)
        except:
            QMessageBox.warning(self, "Wrong connection", "The selected remote connection is not available or not supported.\n"
                                    "Only http-based connections are supported")
            return

    def okPressed(self):
        remote = self.remoteCombo.currentText().strip()
        if remote:
            self.remote = remote
        else:
            QMessageBox.warning(self, "Missing value", "Please select a remote connection")
            return
        branch = self.branchCombo.currentText().strip()
        if branch:
            self.branch = branch
        else:
            QMessageBox.warning(self, "Missing value", "Please select a branch")
            return
        self.close()

    def cancelPressed(self):
        self.remote = None
        self.branch = None
        self.close()
コード例 #9
0
class LoadAssetRiskAsLayerDialog(LoadOutputAsLayerDialog):
    """
    Dialog to load asset_risk from an oq-engine output, as layer
    """
    def __init__(self,
                 drive_engine_dlg,
                 iface,
                 viewer_dock,
                 session,
                 hostname,
                 calc_id,
                 output_type='asset_risk',
                 path=None,
                 mode=None,
                 engine_version=None,
                 calculation_mode=None):
        assert output_type == 'asset_risk'
        super().__init__(drive_engine_dlg,
                         iface,
                         viewer_dock,
                         session,
                         hostname,
                         calc_id,
                         output_type=output_type,
                         path=path,
                         mode=mode,
                         engine_version=engine_version,
                         calculation_mode=calculation_mode)

        self.setWindowTitle('Load Exposure/Risk as layer')
        log_msg(
            'Extracting exposure metadata.'
            ' Watch progress in QGIS task bar',
            level='I',
            message_bar=self.iface.messageBar())
        self.extract_npz_task = ExtractNpzTask('Extract exposure metadata',
                                               QgsTask.CanCancel, self.session,
                                               self.hostname, self.calc_id,
                                               'exposure_metadata',
                                               self.finalize_init,
                                               self.on_extract_error)
        QgsApplication.taskManager().addTask(self.extract_npz_task)

    def finalize_init(self, extracted_npz):
        self.exposure_metadata = extracted_npz
        self.tag_names = sorted(self.exposure_metadata['tagnames'])
        self.exposure_categories = sorted(self.exposure_metadata['names'])
        self.risk_categories = sorted(self.exposure_metadata['multi_risk'])
        self.perils = set(
            [cat.rsplit('-', 1)[-1] for cat in self.risk_categories])

        self.populate_out_dep_widgets()

        self.adjustSize()
        self.taxonomies_gbx.toggled.emit(False)
        self.tag_gbx.toggled.emit(False)
        self.set_ok_button()
        self.show()
        self.init_done.emit(self)

    def populate_out_dep_widgets(self):
        self.visualize_gbx = QGroupBox('Visualize')
        self.visualize_gbx_h_layout = QHBoxLayout()
        self.exposure_rbn = QRadioButton('Exposure')
        self.risk_rbn = QRadioButton('Risk')
        self.exposure_rbn.toggled.connect(self.on_visualize_changed)
        self.risk_rbn.toggled.connect(self.on_visualize_changed)
        self.visualize_gbx_h_layout.addWidget(self.exposure_rbn)
        self.visualize_gbx_h_layout.addWidget(self.risk_rbn)
        self.visualize_gbx.setLayout(self.visualize_gbx_h_layout)
        self.vlayout.addWidget(self.visualize_gbx)
        self.create_selector("peril",
                             "Peril",
                             filter_ckb=False,
                             on_text_changed=self.on_peril_changed)
        self.peril_cbx.setDisabled(True)
        self.peril_lbl.setVisible(False)
        self.peril_cbx.setVisible(False)
        self.create_selector("category", "Category", filter_ckb=False)
        self.peril_cbx.addItems(sorted(self.perils))
        self.taxonomies_gbx = QGroupBox()
        self.taxonomies_gbx.setTitle('Filter by taxonomy')
        self.taxonomies_gbx.setCheckable(True)
        self.taxonomies_gbx.setChecked(False)
        self.taxonomies_gbx_v_layout = QVBoxLayout()
        self.taxonomies_gbx.setLayout(self.taxonomies_gbx_v_layout)
        self.taxonomies_lbl = QLabel("Taxonomies")
        self.taxonomies_multisel = MultiSelectComboBox(self)
        self.taxonomies_multisel.add_unselected_items(
            sorted([
                taxonomy for taxonomy in self.exposure_metadata['taxonomy']
                if taxonomy != '?'
            ]))
        self.taxonomies_gbx_v_layout.addWidget(self.taxonomies_lbl)
        self.taxonomies_gbx_v_layout.addWidget(self.taxonomies_multisel)
        self.taxonomies_gbx.toggled[bool].connect(
            self.on_taxonomies_gbx_toggled)
        self.vlayout.addWidget(self.taxonomies_gbx)
        self.tag_gbx = QGroupBox()
        self.tag_gbx.setTitle('Filter by tag')
        self.tag_gbx.setCheckable(True)
        self.tag_gbx.setChecked(False)
        self.tag_gbx_v_layout = QVBoxLayout()
        self.tag_gbx.setLayout(self.tag_gbx_v_layout)
        self.tag_values_lbl = QLabel("Tag values")
        self.tag_values_multisel = MultiSelectComboBox(self)
        self.create_selector("tag",
                             "Tag",
                             add_to_layout=self.tag_gbx_v_layout,
                             on_text_changed=self.on_tag_changed)
        self.tag_cbx.addItems([
            tag_name for tag_name in self.tag_names if tag_name != 'taxonomy'
        ])
        self.tag_gbx_v_layout.addWidget(self.tag_values_lbl)
        self.tag_gbx_v_layout.addWidget(self.tag_values_multisel)
        self.tag_gbx.toggled[bool].connect(self.on_tag_gbx_toggled)
        self.vlayout.addWidget(self.tag_gbx)
        self.higher_on_top_chk = QCheckBox('Render higher values on top')
        self.higher_on_top_chk.setChecked(True)
        self.vlayout.addWidget(self.higher_on_top_chk)
        self.create_zonal_layer_selector()
        if self.zonal_layer_path:
            zonal_layer = self.load_zonal_layer(self.zonal_layer_path)
            self.populate_zonal_layer_cbx(zonal_layer)
        else:
            self.pre_populate_zonal_layer_cbx()
        self.exposure_rbn.setChecked(True)

    def on_taxonomies_gbx_toggled(self, is_checked):
        for widget in self.taxonomies_gbx.findChildren(QWidget):
            widget.setVisible(is_checked)

    def on_tag_gbx_toggled(self, is_checked):
        for widget in self.tag_gbx.findChildren(QWidget):
            widget.setVisible(is_checked)

    def on_visualize_changed(self):
        self.peril_cbx.setEnabled(self.risk_rbn.isChecked())
        self.peril_lbl.setVisible(self.risk_rbn.isChecked())
        self.peril_cbx.setVisible(self.risk_rbn.isChecked())
        if self.exposure_rbn.isChecked():
            self.category_cbx.clear()
            self.category_cbx.addItems(self.exposure_categories)
        else:  # 'Risk'
            self.peril_cbx.setCurrentIndex(0)
            self.peril_cbx.currentTextChanged.emit(
                self.peril_cbx.currentText())

    def on_peril_changed(self, peril):
        categories = [
            category.rsplit('-', 1)[0] for category in self.risk_categories
            if peril in category
        ]
        self.category_cbx.clear()
        self.category_cbx.addItems(sorted(categories))

    def on_tag_changed(self, tag_name):
        tag_values = sorted([
            value for value in self.exposure_metadata[tag_name] if value != '?'
        ])
        self.tag_values_multisel.clear()
        self.tag_values_multisel.add_unselected_items(tag_values)

    def set_ok_button(self):
        self.ok_button.setEnabled(self.category_cbx.currentIndex() != -1)

    def build_layer_name(self, rlz_or_stat=None, **kwargs):
        if self.exposure_rbn.isChecked():
            self.default_field_name = self.category_cbx.currentText()
        else:  # 'Risk'
            self.default_field_name = "%s-%s" % (
                self.category_cbx.currentText(), self.peril_cbx.currentText())
        if self.exposure_rbn.isChecked():
            layer_name = 'Exposure: %s' % self.category_cbx.currentText()
        else:  # Risk
            layer_name = 'Risk: %s %s' % (self.peril_cbx.currentText(),
                                          self.category_cbx.currentText())
        return layer_name

    def get_field_types(self, **kwargs):
        field_types = {
            name: self.dataset[name].dtype.char
            for name in self.dataset.dtype.names
            if name not in ['lon', 'lat'] and name not in self.tag_names
        }
        return field_types

    def read_npz_into_layer(self, field_types, **kwargs):
        with edit(self.layer):
            lons = self.dataset['lon']
            lats = self.dataset['lat']
            feats = []
            for row_idx, row in enumerate(self.dataset):
                # add a feature
                feat = QgsFeature(self.layer.fields())
                for field_name in field_types:
                    value = row[field_name].item()
                    if isinstance(value, bytes):
                        value = value.decode('utf8')
                    feat.setAttribute(field_name, value)
                feat.setGeometry(
                    QgsGeometry.fromPointXY(
                        QgsPointXY(lons[row_idx], lats[row_idx])))
                feats.append(feat)
            added_ok = self.layer.addFeatures(feats)
            if not added_ok:
                msg = 'There was a problem adding features to the layer.'
                log_msg(msg, level='C', message_bar=self.iface.messageBar())
        return self.layer

    def accept(self):
        log_msg('Loading output started. Watch progress in QGIS task bar',
                level='I',
                message_bar=self.iface.messageBar())
        self.iface.layerTreeView().currentLayerChanged.disconnect(
            self.on_currentLayerChanged)
        self.hide()
        extract_params = self.get_extract_params()
        self.download_asset_risk(extract_params)

    def get_extract_params(self):
        params = {}
        if self.tag_gbx.isChecked():
            tag_name = self.tag_cbx.currentText()
            params[tag_name] = self.tag_values_multisel.get_selected_items()
        if self.taxonomies_gbx.isChecked():
            params['taxonomy'] = self.taxonomies_multisel.get_selected_items()
        return params

    def download_asset_risk(self, extract_params):
        self.extract_npz_task = ExtractNpzTask('Extract asset_risk',
                                               QgsTask.CanCancel,
                                               self.session,
                                               self.hostname,
                                               self.calc_id,
                                               'asset_risk',
                                               self.on_asset_risk_downloaded,
                                               self.on_extract_error,
                                               params=extract_params)
        QgsApplication.taskManager().addTask(self.extract_npz_task)

    def on_asset_risk_downloaded(self, extracted_npz):
        self.npz_file = extracted_npz
        self.dataset = self.npz_file['array']
        with WaitCursorManager('Creating layer...', self.iface.messageBar()):
            self.layer = self.build_layer()
            self.style_maps(
                self.layer,
                self.default_field_name,
                self.iface,
                self.output_type,
                perils=self.perils,
                render_higher_on_top=self.higher_on_top_chk.isChecked())
        if (self.zonal_layer_cbx.currentText()
                and self.zonal_layer_gbx.isChecked()):
            self.aggregate_by_zone()
        else:
            self.loading_completed.emit(self)
        QDialog.accept(self)
コード例 #10
0
class RasterCheckerDialogWidget(QDialog):
    def __init__(self, parent=None, checks=[], command=None):
        """Constructor
        Args:
            parent: Qt parent Widget
            iface: QGiS interface
            command: Command instance with a run_it method which will be
                     called on acceptance of the dialog
        """
        super().__init__(parent)
        self.checks = checks
        self.setupUi(checks)
        self.command = command

        # rasterchecker only works on spatialte db (and not also postgres db)
        self.databases = {}
        self.all_databases = get_databases()
        for k, v in self.all_databases.items():
            if "spatialite" in k:
                if v["db_name"]:
                    self.databases[k] = v

        self.database_combo.addItems(self.databases.keys())

        # Connect signals
        self.buttonBox.accepted.connect(self.on_accept)
        self.buttonBox.rejected.connect(self.on_reject)

    def on_accept(self):
        """Accept and run the Command.run_it method."""
        db_key = self.database_combo.currentText()
        settings = self.databases[db_key]
        db_set = settings["db_settings"]

        if not os.path.isfile(db_set["db_path"]):
            msg = "sqlite %s not found" % str(db_set["db_path"])
            raise Exception(msg)

        # TODO: check_all_rasters always runs. Enable check per model entry
        checks = []
        if self.check_all_rasters.isChecked():
            checks.append("check all rasters")
            # TODO: write improve first
            # improve_when_necessary may only be checked when
            # 'check_all_rasters' is checked
            # if self.improve_when_necessary.isChecked():
            #     checks.append('improve when necessary')

        self.command.run_it(checks, db_set, settings["db_type"])
        self.accept()

    def on_reject(self):
        """Cancel"""
        self.reject()
        logger.debug("Reject")

    def closeEvent(self, event):
        """
        Close widget, called by Qt on close
        :param event: QEvent, close event
        """
        self.buttonBox.accepted.disconnect(self.on_accept)
        self.buttonBox.rejected.disconnect(self.on_reject)

        event.accept()

    def setupUi(self, checks):

        self.resize(815, 266)
        self.verticalLayout = QVBoxLayout(self)

        self.groupBox_2 = QGroupBox(self)
        self.groupBox_2.setObjectName("groupBox_2")
        self.database_combo = QComboBox(self.groupBox_2)
        self.database_combo.setGeometry(QRect(10, 30, 481, 34))
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.database_combo.sizePolicy().hasHeightForWidth())
        self.database_combo.setSizePolicy(sizePolicy)
        self.database_combo.setObjectName("database_combo")
        self.verticalLayout.addWidget(self.groupBox_2)

        self.groupBox = QGroupBox(self)
        self.verticalLayoutBox = QVBoxLayout(self.groupBox)

        self.check_all_rasters = QCheckBox(self.groupBox)
        self.check_all_rasters.setChecked(True)
        self.check_all_rasters.setDisabled(True)
        self.verticalLayoutBox.addWidget(self.check_all_rasters)

        # TODO: write improve function first
        # self.improve_when_necessary = QCheckBox(self.groupBox)
        # self.improve_when_necessary.setChecked(False)
        # self.improve_when_necessary.setDisabled(True)
        # self.verticalLayoutBox.addWidget(self.improve_when_necessary)

        self.verticalLayout.addWidget(self.groupBox)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.verticalLayout.addWidget(self.buttonBox)

        self.retranslateUi()
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        QMetaObject.connectSlotsByName(self)

    def retranslateUi(self):
        self.setWindowTitle("Raster Checker")
        self.groupBox_2.setTitle("Model schematisation database")

        self.groupBox.setTitle("Options")

        self.check_all_rasters.setText(
            "1. Check all rasters of all v2_global_settings rows")
class PredictCalcPointsDialogWidget(QDialog):
    def __init__(self, parent=None, command=None):
        """Constructor

        Args:
            parent: Qt parent Widget
            iface: QGiS interface
            command: Command instance with a run_it method which will be called
                     on acceptance of the dialog
        """
        super().__init__(parent)
        self.setupUi()

        self.command = command

        self.databases = get_databases()
        self.database_combo.addItems(list(self.databases.keys()))

        # Connect signals
        self.buttonBox.accepted.connect(self.on_accept)
        self.buttonBox.rejected.connect(self.on_reject)

        self.filename = None

    def on_accept(self):
        """Accept and run the Command.run_it method."""

        db_key = self.database_combo.currentText()
        db_entry = self.databases[db_key]

        _db_settings = db_entry["db_settings"]

        if db_entry["db_type"] == "spatialite":
            host = _db_settings["db_path"]
            db_settings = {
                "host": host,
                "port": "",
                "name": "",
                "username": "",
                "password": "",
                "schema": "",
                "database": "",
                "db_path": host,
            }
        else:
            db_settings = _db_settings
            db_settings["schema"] = "public"
        self.command.run_it(db_settings, db_entry["db_type"])

        self.accept()

    def on_reject(self):
        """Cancel"""
        self.reject()
        logger.debug("Reject")

    def closeEvent(self, event):
        """
        Close widget, called by Qt on close
        :param event: QEvent, close event
        """

        self.buttonBox.accepted.disconnect(self.on_accept)
        self.buttonBox.rejected.disconnect(self.on_reject)

        event.accept()

    def setupUi(self):
        self.resize(815, 250)
        self.verticalLayout = QVBoxLayout(self)

        self.groupBox_2 = QGroupBox(self)
        self.groupBox_2.setObjectName("groupBox_2")
        self.database_combo = QComboBox(self.groupBox_2)
        self.database_combo.setGeometry(QRect(10, 30, 481, 34))

        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.database_combo.sizePolicy().hasHeightForWidth())
        self.database_combo.setSizePolicy(sizePolicy)
        self.database_combo.setObjectName("database_combo")
        self.verticalLayout.addWidget(self.groupBox_2)

        self.groupBox = QGroupBox(self)
        self.verticalLayoutBox = QVBoxLayout(self.groupBox)

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel
                                          | QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.verticalLayout.addWidget(self.buttonBox)

        self.retranslateUi()
        self.buttonBox.accepted.connect(self.accept)
        self.buttonBox.rejected.connect(self.reject)
        QMetaObject.connectSlotsByName(self)

    def retranslateUi(self):
        self.setWindowTitle("Predict calc points")
        self.groupBox_2.setTitle("Model schematisation database")