예제 #1
0
 def __init__(self, iface):
     QDialog.__init__(self)
     self.iface = iface
     # Set up the user interface from Designer.
     self.setupUi(self)
     self.fields_lbl = QLabel(
         'Fields containing loss-based damage state probabilities')
     self.fields_multiselect = MultiSelectComboBox(self)
     self.vLayout.insertWidget(2, self.fields_lbl)
     self.vLayout.insertWidget(3, self.fields_multiselect)
     self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok)
     approach_explanation = (
         'Aggregate: building-level recovery model as a single process\n'
         'Disaggregate: Building-level recovery modelled using four'
         ' processes: inspection, assessment, mobilization and repair.')
     self.approach_cbx.addItems(['Disaggregate', 'Aggregate'])
     self.approach_cbx.setToolTip(approach_explanation)
     self.approach_lbl.setToolTip(approach_explanation)
     simulations_explanation = (
         'Number of damage realizations used in Monte Carlo Simulation')
     n_simulations = int(
         QSettings().value('irmt/n_simulations_per_building', 1))
     self.n_simulations_sbx.setValue(n_simulations)
     self.n_simulations_lbl.setToolTip(simulations_explanation)
     self.n_simulations_sbx.setToolTip(simulations_explanation)
     self.save_bldg_curves_check.setChecked(False)
     self.populate_layers_in_combos()
     self.restore_state()
     self.set_ok_button()
예제 #2
0
 def __init__(self, downloader):
     QDialog.__init__(self)
     # Set up the user interface from Designer.
     self.setupUi(self)
     self.indicator_lbl = QLabel('Select Indicators')
     self.indicator_multiselect = MultiSelectComboBox(self)
     self.scroll_area_contents.layout().addWidget(self.indicator_lbl)
     self.scroll_area_contents.layout().addWidget(
         self.indicator_multiselect)
     self.country_lbl = QLabel('Select Countries')
     self.country_multiselect = MultiSelectComboBox(self)
     self.scroll_area_contents.layout().addWidget(self.country_lbl)
     self.scroll_area_contents.layout().addWidget(self.country_multiselect)
     self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok)
     self.set_ok_button()
     # login to platform, to be able to retrieve sv indices
     self.sv_downloader = downloader
     self.indicators_info_dict = {}
     with WaitCursorManager('Filling list of indicators...'):
         self.fill_names()
     with WaitCursorManager('Filling list of themes...'):
         self.fill_themes()
     with WaitCursorManager('Filling list of countries...'):
         self.fill_countries()
     self.indicator_multiselect.item_was_clicked.connect(
         self.update_indicator_info)
     self.indicator_multiselect.selection_changed.connect(
         self.set_ok_button)
     self.country_multiselect.selection_changed.connect(self.set_ok_button)
예제 #3
0
    def __init__(self, iface):
        QDialog.__init__(self)
        self.iface = iface
        self.attr_name_user_def = False
        self.use_advanced = False
        # Set up the user interface from Designer.
        self.setupUi(self)
        self.fields_lbl = QLabel('Fields to transform')
        self.fields_multiselect = MultiSelectComboBox(self)
        hlayout = QHBoxLayout()
        hlayout.addWidget(self.fields_lbl)
        hlayout.addWidget(self.fields_multiselect)
        self.vertical_layout.insertLayout(1, hlayout)
        self.adjustSize()
        self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok)
        self.fill_fields_multiselect()

        alg_list = list(TRANSFORMATION_ALGS.keys())
        self.algorithm_cbx.addItems(alg_list)
        if self.algorithm_cbx.currentText() in ['RANK', 'QUADRATIC']:
            self.reload_variant_cbx()
        self.inverse_ckb.setDisabled(
            self.algorithm_cbx.currentText() in ['LOG10'])
        self.warning_lbl.hide()
        self.warning_lbl.setText(
            "<font color='red'>"
            "WARNING: the original attribute will be overwritten by the"
            " results of the transformation (it can not be undone)"
            "</font>")
        self.fields_multiselect.selection_changed.connect(self.set_ok_button)
        self.fields_multiselect.selection_changed.connect(
            self.set_new_field_editable)
        self.fields_multiselect.selection_changed.connect(
            self.update_default_fieldname)
        self.set_ok_button()
        self.set_new_field_editable()
예제 #4
0
class SelectSvVariablesDialog(QDialog, FORM_CLASS):
    """
    Modal dialog giving to the user the possibility to select
    social vulnerability variables to import from the oq-platform
    """
    def __init__(self, downloader):
        QDialog.__init__(self)
        # Set up the user interface from Designer.
        self.setupUi(self)
        self.indicator_lbl = QLabel('Select Indicators')
        self.indicator_multiselect = MultiSelectComboBox(self)
        self.scroll_area_contents.layout().addWidget(self.indicator_lbl)
        self.scroll_area_contents.layout().addWidget(
            self.indicator_multiselect)
        self.country_lbl = QLabel('Select Countries')
        self.country_multiselect = MultiSelectComboBox(self)
        self.scroll_area_contents.layout().addWidget(self.country_lbl)
        self.scroll_area_contents.layout().addWidget(self.country_multiselect)
        self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok)
        self.set_ok_button()
        # login to platform, to be able to retrieve sv indices
        self.sv_downloader = downloader
        self.indicators_info_dict = {}
        with WaitCursorManager('Filling list of indicators...'):
            self.fill_names()
        with WaitCursorManager('Filling list of themes...'):
            self.fill_themes()
        with WaitCursorManager('Filling list of countries...'):
            self.fill_countries()
        self.indicator_multiselect.item_was_clicked.connect(
            self.update_indicator_info)
        self.indicator_multiselect.selection_changed.connect(
            self.set_ok_button)
        self.country_multiselect.selection_changed.connect(self.set_ok_button)

    @pyqtSlot(str)
    def on_theme_cbx_currentIndexChanged(self):
        theme = self.theme_cbx.currentText()
        with WaitCursorManager():
            self.fill_subthemes(theme)

    @pyqtSlot()
    def on_filter_btn_clicked(self):
        with WaitCursorManager():
            self.fill_names()

    def set_ok_button(self):
        self.ok_button.setEnabled(
            self.indicator_multiselect.selected_count() > 0
            and self.country_multiselect.selected_count() > 0)

    def fill_themes(self):
        self.theme_cbx.clear()
        # load list of themes from the platform
        self.theme_cbx.addItems([None])
        try:
            themes = self.sv_downloader.get_themes()
            self.theme_cbx.addItems(themes)
        except SvNetworkError as e:
            raise SvNetworkError(
                "Unable to download social vulnerability themes: %s" % e)
        # populate the subsequent combo boxes accordingly with the currently
        # selected item
        current_theme = self.theme_cbx.currentText()
        self.fill_subthemes(current_theme)

    def fill_subthemes(self, theme):
        self.subtheme_cbx.clear()
        # load list of subthemes from the platform
        self.subtheme_cbx.addItems([None])
        if theme:
            try:
                subthemes = self.sv_downloader.get_subthemes_by_theme(theme)
                self.subtheme_cbx.addItems(subthemes)
            except SvNetworkError as e:
                raise SvNetworkError("Unable to download social vulnerability"
                                     " subthemes: %s" % e)

    def fill_names(self):
        self.indicator_multiselect.clear()
        # load list of social vulnerability variable names from the platform
        name_filter = self.name_filter_le.text()
        keywords = self.keywords_le.text()
        theme = self.theme_cbx.currentText()
        subtheme = self.subtheme_cbx.currentText()
        try:
            filter_result_dict = self.sv_downloader.get_indicators_info(
                name_filter, keywords, theme, subtheme)
            self.indicators_info_dict.update(filter_result_dict)
            names = sorted([
                code + ': ' + filter_result_dict[code]['name']
                for code in filter_result_dict
            ])
            self.indicator_multiselect.add_unselected_items(names)
        except SvNetworkError as e:
            raise SvNetworkError(
                "Unable to download social vulnerability names: %s" % e)

    def update_indicator_info(self, text, status):
        if status:
            hint_text = text
            indicator_code = text.split(':')[0]
            indicator_info_dict = self.indicators_info_dict[indicator_code]
            hint_text += '\n\n' + 'Description:\n' + indicator_info_dict[
                'description']
            hint_text += '\n\n' + 'Source:\n' + indicator_info_dict['source']
            hint_text += ('\n\n' + 'Aggregation method:\n' +
                          indicator_info_dict['aggregation_method'])
        else:
            hint_text = ''
        self.indicator_details.setText(hint_text)

    def fill_countries(self):
        # load from platform a list of countries for which socioeconomic data
        # are available
        try:
            countries_dict = self.sv_downloader.get_countries_info()
            names = sorted([
                countries_dict[iso] + ' (' + iso + ')'
                for iso in countries_dict
            ])
            self.country_multiselect.add_unselected_items(names)
        except SvNetworkError as e:
            raise SvNetworkError(
                "Unable to download the list of countries: %s" % e)
예제 #5
0
class RecoveryModelingDialog(QDialog, FORM_CLASS):
    """
    Modal dialog to perform recovery modeling analysis.
    """
    def __init__(self, iface):
        QDialog.__init__(self)
        self.iface = iface
        # Set up the user interface from Designer.
        self.setupUi(self)
        self.fields_lbl = QLabel(
            'Fields containing loss-based damage state probabilities')
        self.fields_multiselect = MultiSelectComboBox(self)
        self.vLayout.insertWidget(2, self.fields_lbl)
        self.vLayout.insertWidget(3, self.fields_multiselect)
        self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok)
        approach_explanation = (
            'Aggregate: building-level recovery model as a single process\n'
            'Disaggregate: Building-level recovery modelled using four'
            ' processes: inspection, assessment, mobilization and repair.')
        self.approach_cbx.addItems(['Disaggregate', 'Aggregate'])
        self.approach_cbx.setToolTip(approach_explanation)
        self.approach_lbl.setToolTip(approach_explanation)
        simulations_explanation = (
            'Number of damage realizations used in Monte Carlo Simulation')
        n_simulations = int(
            QSettings().value('irmt/n_simulations_per_building', 1))
        self.n_simulations_sbx.setValue(n_simulations)
        self.n_simulations_lbl.setToolTip(simulations_explanation)
        self.n_simulations_sbx.setToolTip(simulations_explanation)
        self.save_bldg_curves_check.setChecked(False)
        self.populate_layers_in_combos()
        self.restore_state()
        self.set_ok_button()

    def populate_layers_in_combos(self):
        for key, layer in \
                QgsProject.instance().mapLayers().items():
            if layer.type() != QgsMapLayer.VectorLayer:
                continue
            if layer.geometryType() == QgsWkbTypes.PointGeometry:
                self.damages_rlzs_layer_cbx.addItem(layer.name(), layer)
            if layer.geometryType() == QgsWkbTypes.PolygonGeometry:
                self.svi_layer_cbx.addItem(layer.name(), layer)
        # if the active layer contains points, preselect it
        active_layer = self.iface.activeLayer()
        if active_layer is not None:
            idx = self.damages_rlzs_layer_cbx.findData(active_layer)
            if idx != -1:
                self.damages_rlzs_layer_cbx.setCurrentIndex(idx)

    def restore_state(self):
        """
        Reinstate the options based on the user's stored session info.
        """
        mySettings = QSettings()
        self.output_data_dir = mySettings.value(
            'irmt/recovery_output_data_dir', '')
        # hack for strange mac behaviour
        if not self.output_data_dir:
            self.output_data_dir = ''
        self.output_data_dir_le.setText(self.output_data_dir)

    def save_state(self):
        """
        Store the options into the user's stored session info.
        """
        mySettings = QSettings()
        mySettings.setValue('irmt/recovery_output_data_dir',
                            self.output_data_dir_le.text())

    def set_ok_button(self):
        self.ok_button.setEnabled(
            os.path.isdir(self.output_data_dir_le.text())
            and self.approach_cbx.currentIndex != -1
            and self.damages_rlzs_layer_cbx.currentIndex != -1)
        # and self.svi_layer_cbx.currentIndex != -1
        # and self.svi_field_name_cbx.currentIndex != -1
        # and self.zone_field_name_cbx.currentIndex != -1)

    @pyqtSlot(str)
    def on_output_data_dir_le_textChanged(self, text):
        self.output_data_dir = self.output_data_dir_le.text()
        self.set_ok_button()

    @pyqtSlot(str)
    def on_approach_cbx_currentIndexChanged(self, selected_text):
        # TODO: we might need to ask the user to provide the necessary files
        self.set_ok_button()

    @pyqtSlot(int)
    def on_damages_rlzs_layer_cbx_currentIndexChanged(
            self, selected_index):
        self.damages_rlzs_layer = self.damages_rlzs_layer_cbx.itemData(
            selected_index)
        self.fields_multiselect.clear()
        fill_fields_multiselect(
            self.fields_multiselect, self.damages_rlzs_layer)

    @pyqtSlot(int)
    def on_svi_layer_cbx_currentIndexChanged(self, selected_index):
        self.svi_layer = self.svi_layer_cbx.itemData(selected_index)
        # FIXME self.svi_field_name is temporarily ignored
        # reload_attrib_cbx(self.svi_field_name_cbx, self.svi_layer)
        reload_attrib_cbx(self.zone_field_name_cbx, self.svi_layer)

    @pyqtSlot()
    def on_output_data_dir_btn_clicked(self):
        default_dir = QSettings().value('irmt/output_data_dir',
                                        QDir.homePath())
        path = QFileDialog.getExistingDirectory(
            self, self.tr('Choose output directory'), default_dir)
        if path:
            QSettings().setValue('irmt/output_data_dir', path)
            self.output_data_dir_le.setText(path)

    def calculate_community_level_recovery_curve(
            self, point_attrs_dict, integrate_svi=True):
        # Developed By: Henry Burton
        # Edited by: Hua Kang
        # Reimplemented for this plugin by: Paolo Tormene and Marco Bernasocchi
        # Objective: GenerateCommunityLevelRecoveryCurve
        # Initial date: August 26, 2016

        zone_field_name = None
        if integrate_svi:
            self.svi_layer = self.svi_layer_cbx.itemData(
                    self.svi_layer_cbx.currentIndex())
            # FIXME self.svi_field_name is temporarily ignored
            # self.svi_field_name = self.svi_field_name_cbx.currentText()
            zone_field_name = self.zone_field_name_cbx.currentText()

        approach = self.approach_cbx.currentText()
        request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry)
        damages_rlzs_features = list(
            self.damages_rlzs_layer.getFeatures(request))
        recovery = RecoveryModeling(
            damages_rlzs_features, approach, self.iface, self.svi_layer,
            self.output_data_dir, self.save_bldg_curves_check.isChecked())

        probs_field_names = self.fields_multiselect.get_selected_items()
        for i, fieldname in enumerate(probs_field_names):
            probs_field_names[i] = point_attrs_dict[fieldname]
        zonal_damages_rlzs_probs, zonal_asset_refs = \
            recovery.collect_zonal_data(
                probs_field_names, integrate_svi, zone_field_name)

        # Incorporate Napa Data to community recovery model
        summary_filename = os.path.join(
            self.output_data_dir, 'summary.csv')
        summary = open(summary_filename, 'w', newline='')
        writer = csv.writer(summary)
        header = ['zone_id', 'days_to_recover_95_perc', 'event_time',
                  'after_6_months', 'after_12_months', 'after_18_months']
        writer.writerow(header)
        n_simulations = self.n_simulations_sbx.value()
        n_zones = len(zonal_damages_rlzs_probs)
        # for each zone, calculate a zone-level recovery function
        for zone_index, zone_id in enumerate(
                list(zonal_damages_rlzs_probs.keys()), start=1):
            seed = None
            if DEBUG:
                seed = 42
            recovery.generate_community_level_recovery_curve(
                zone_id, zonal_damages_rlzs_probs,
                zonal_asset_refs, writer, integrate_svi, seed,
                n_simulations=n_simulations, n_zones=n_zones,
                zone_index=zone_index)
        summary.close()

    def accept(self):
        if self.integrate_svi_check.isChecked():
            self.zone_field_name = self.zone_field_name_cbx.currentText()
            (point_attrs_dict, self.damages_rlzs_layer,
             self.zone_field_name) = add_zone_id_to_points(
                self.damages_rlzs_layer,
                self.svi_layer, self.zone_field_name)
        else:
            # the layer containing points was not modified by the zonal
            # aggregation, so the field names remained as the original ones
            point_attrs_dict = {
                field.name(): field.name()
                for field in self.damages_rlzs_layer.fields()}
        with WaitCursorManager('Generating recovery curves...',
                               self.iface.messageBar()):
            self.calculate_community_level_recovery_curve(
                point_attrs_dict,
                self.integrate_svi_check.isChecked())
        msg = 'Recovery curves have been saved to [%s]' % self.output_data_dir
        log_msg(msg, level='S', message_bar=self.iface.messageBar())
        self.save_state()
        super(RecoveryModelingDialog, self).accept()
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)
 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)
예제 #8
0
class TransformationDialog(QDialog, FORM_CLASS):
    """
    Modal dialog giving to the user the possibility to transform
    one or multiple attributes in the active layer, using one of the available
    algorithms and variants.
    """
    def __init__(self, iface):
        QDialog.__init__(self)
        self.iface = iface
        self.attr_name_user_def = False
        self.use_advanced = False
        # Set up the user interface from Designer.
        self.setupUi(self)
        self.fields_lbl = QLabel('Fields to transform')
        self.fields_multiselect = MultiSelectComboBox(self)
        hlayout = QHBoxLayout()
        hlayout.addWidget(self.fields_lbl)
        hlayout.addWidget(self.fields_multiselect)
        self.vertical_layout.insertLayout(1, hlayout)
        self.adjustSize()
        self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok)
        self.fill_fields_multiselect()

        alg_list = list(TRANSFORMATION_ALGS.keys())
        self.algorithm_cbx.addItems(alg_list)
        if self.algorithm_cbx.currentText() in ['RANK', 'QUADRATIC']:
            self.reload_variant_cbx()
        self.inverse_ckb.setDisabled(
            self.algorithm_cbx.currentText() in ['LOG10'])
        self.warning_lbl.hide()
        self.warning_lbl.setText(
            "<font color='red'>"
            "WARNING: the original attribute will be overwritten by the"
            " results of the transformation (it can not be undone)"
            "</font>")
        self.fields_multiselect.selection_changed.connect(self.set_ok_button)
        self.fields_multiselect.selection_changed.connect(
            self.set_new_field_editable)
        self.fields_multiselect.selection_changed.connect(
            self.update_default_fieldname)
        self.set_ok_button()
        self.set_new_field_editable()

    def set_ok_button(self):
        self.ok_button.setEnabled(self.fields_multiselect.selected_count() > 0)

    def set_new_field_editable(self):
        n_fields_selected = self.fields_multiselect.selected_count()
        self.new_field_name_lbl.setEnabled(n_fields_selected == 1)
        self.new_field_name_txt.setEnabled(n_fields_selected == 1)

    @pyqtSlot(int)
    def on_overwrite_ckb_stateChanged(self):
        overwrite_checked = self.overwrite_ckb.isChecked()
        self.new_field_name_lbl.setDisabled(overwrite_checked)
        self.new_field_name_txt.setDisabled(overwrite_checked)
        self.track_new_field_ckb.setDisabled(overwrite_checked)
        if overwrite_checked:
            self.attr_name_user_def = False
            self.warning_lbl.show()
        else:
            self.warning_lbl.hide()
        self.update_default_fieldname()

    @pyqtSlot()
    def on_calc_btn_clicked(self):
        self.close()
        # layer is put in editing mode. If the user clicks on ok, the field
        # calculator will update the layers attributes.
        # if the user clicks cancel, the field calculator does nothing.
        # the layer stays in editing mode with the use_advanced flag set.
        # the calling code should take care of doing layer.commitChanges()
        # if the flag is set to true.
        self.use_advanced = True
        self.iface.activeLayer().startEditing()
        self.iface.actionOpenFieldCalculator().trigger()

    @pyqtSlot(str)
    def on_algorithm_cbx_currentIndexChanged(self):
        self.reload_variant_cbx()
        self.update_default_fieldname()

    @pyqtSlot(str)
    def on_variant_cbx_currentIndexChanged(self):
        self.update_default_fieldname()

    @pyqtSlot()
    def on_new_field_name_txt_editingFinished(self):
        self.attr_name_user_def = True
        new_field_name = self.new_field_name_txt.text()
        # if the name of the new field is empty, automatically assign a name
        if not new_field_name:
            self.update_default_fieldname()

    @pyqtSlot(str)
    def on_new_field_name_txt_textEdited(self):
        # we assume exactly one item is in the selected list
        input_field_name = self._extract_field_name(
            self.fields_multiselect.get_selected_items()[0])
        new_field_name = self.new_field_name_txt.text()
        # if the name of the new field is equal to the name of the input field,
        # automatically check the 'overwrite' checkbox (and consequently
        # display the warning)
        if new_field_name == input_field_name:
            self.overwrite_ckb.setChecked(True)

    def reload_variant_cbx(self):
        self.variant_cbx.clear()
        self.variant_cbx.setEnabled(True)
        if self.algorithm_cbx.currentText() == 'RANK':
            self.variant_cbx.addItems(RANK_VARIANTS)
        elif self.algorithm_cbx.currentText() == 'QUADRATIC':
            self.variant_cbx.addItems(QUADRATIC_VARIANTS)
        elif self.algorithm_cbx.currentText() == 'LOG10':
            self.variant_cbx.addItems(LOG10_VARIANTS)
        else:
            self.variant_cbx.setDisabled(True)
        self.inverse_ckb.setDisabled(
            self.algorithm_cbx.currentText() in ['LOG10'])

    def _extract_field_name(self, field_name_plus_alias):
        # attribute_name is something like 'ABCDEFGHIL (Readable name)'
        # and we want to use only the heading code
        return field_name_plus_alias.split('(')[0].strip()

    def update_default_fieldname(self):
        if self.fields_multiselect.selected_count() != 1:
            self.new_field_name_txt.setText('')
            self.attr_name_user_def = False
            return
        if (not self.attr_name_user_def or not self.new_field_name_txt.text()):
            attribute_name = self._extract_field_name(
                self.fields_multiselect.get_selected_items()[0])
            algorithm_name = self.algorithm_cbx.currentText()
            variant = self.variant_cbx.currentText()
            inverse = self.inverse_ckb.isChecked()
            if self.overwrite_ckb.isChecked():
                new_attr_name = attribute_name
            else:
                try:
                    new_attr_name = ProcessLayer(
                        self.iface.activeLayer()).transform_attribute(
                            attribute_name,
                            algorithm_name,
                            variant,
                            inverse,
                            simulate=True)
                except TypeError as exc:
                    log_msg(str(exc),
                            level='C',
                            message_bar=self.iface.messageBar(),
                            exception=exc)
                    return
            self.new_field_name_txt.setText(new_attr_name)
            self.attr_name_user_def = False

    def fill_fields_multiselect(self):
        names_plus_aliases = []
        for field_idx, field in enumerate(self.iface.activeLayer().fields()):
            if field.typeName() in NUMERIC_FIELD_TYPES:
                alias = self.iface.activeLayer().attributeAlias(field_idx)
                if '(' in field.name():
                    msg = ('Please remove parentheses from the name of field'
                           ' %s before attempting to transform it, otherwise'
                           ' the tool will not be able to distinguish between'
                           ' the alias and the part of the name included'
                           ' between parentheses. For instance, you may'
                           ' replace "(" with "[" to avoid ambiguity.' %
                           field.name())
                    log_msg(msg,
                            level='W',
                            message_bar=self.iface.messageBar())
                else:
                    name_plus_alias = field.name()
                    if alias:
                        name_plus_alias += ' (%s)' % alias
                    names_plus_aliases.append(name_plus_alias)
        self.fields_multiselect.add_unselected_items(names_plus_aliases)
예제 #9
0
 def setUpClass(cls):
     cls.wdg = QWidget()
     cls.mscb = MultiSelectComboBox(cls.wdg)