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)
class LoadInputsDialog(QDialog): """ Dialog to browse zipped input files """ loading_canceled = pyqtSignal(QDialog) loading_completed = pyqtSignal(QDialog) def __init__(self, drive_engine_dlg, zip_filepath, iface, parent=None, mode=None): super().__init__(parent) self.drive_engine_dlg = drive_engine_dlg self.zip_filepath = zip_filepath self.iface = iface self.mode = mode ini_str = self.get_ini_str(self.zip_filepath) self.multi_peril_csv_dict = self.get_multi_peril_csv_dict(ini_str) self.setWindowTitle('Load peril data from csv') self.peril_gbx = QGroupBox('Peril') self.peril_vlayout = QVBoxLayout() self.perils = self.multi_peril_csv_dict.keys() self.peril_gbx.setLayout(self.peril_vlayout) for peril in self.perils: chk = QCheckBox(peril) chk.setChecked(True) self.peril_vlayout.addWidget(chk) self.higher_on_top_chk = QCheckBox('Render higher values on top') self.higher_on_top_chk.setChecked(False) self.button_box = QDialogButtonBox( QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.ok_button = self.button_box.button(QDialogButtonBox.Ok) self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) vlayout = QVBoxLayout() vlayout.addWidget(self.peril_gbx) vlayout.addWidget(self.higher_on_top_chk) vlayout.addWidget(self.button_box) self.setLayout(vlayout) @staticmethod def get_ini_str(filepath): zfile = zipfile.ZipFile(filepath) for fname in zfile.namelist(): if os.path.splitext(fname)[1] == '.ini': ini_str = zfile.open( zfile.NameToInfo[fname]).read().decode('utf8') break return ini_str @staticmethod def get_multi_peril_csv_dict(ini_str): config = configparser.ConfigParser(allow_no_value=True) config.read_string(ini_str) multi_peril_csv_str = None for key in config: if 'multi_peril_csv' in config[key]: multi_peril_csv_str = config[key]['multi_peril_csv'] break if multi_peril_csv_str is None: raise KeyError('multi_peril_csv not found in .ini file') multi_peril_csv_dict = json.loads( multi_peril_csv_str.replace('\'', '"')) return multi_peril_csv_dict def load_from_csv(self, csv_path, peril): # extract the name of the csv file and remove the extension layer_name, ext = os.path.splitext(os.path.basename(csv_path)) wkt_field = None headers = get_headers(csv_path) for header in headers: if header.lower() in GEOM_FIELDNAMES: wkt_field = header break if self.mode == 'testing': add_to_legend = False else: add_to_legend = True try: layer = import_layer_from_csv( self, csv_path, layer_name, self.iface, wkt_field=wkt_field, add_to_legend=add_to_legend, add_on_top=True, zoom_to_layer=True) except RuntimeError as exc: log_msg(str(exc), level='C', message_bar=self.iface.messageBar(), exception=exc) raise exc if self.mode == 'testing': root = QgsProject.instance().layerTreeRoot() root.insertLayer(0, layer) self.iface.setActiveLayer(layer) self.iface.zoomToActiveLayer() if 'intensity' in [field.name() for field in layer.fields()]: LoadOutputAsLayerDialog.style_maps( layer, 'intensity', self.iface, 'input', render_higher_on_top=self.higher_on_top_chk.isChecked()) user_params = {'peril': peril} write_metadata_to_layer( self.drive_engine_dlg, 'input', layer, user_params) log_msg('Layer %s was loaded successfully' % layer_name, level='S', message_bar=self.iface.messageBar()) def accept(self): super().accept() for chk in self.peril_gbx.findChildren(QCheckBox): if chk.isChecked(): peril = chk.text() zfile = zipfile.ZipFile(self.zip_filepath) inner_path = 'input/' + self.multi_peril_csv_dict[peril] extracted_csv_path = zfile.extract( inner_path, path=os.path.dirname(self.zip_filepath)) self.load_from_csv(extracted_csv_path, peril) self.loading_completed.emit(self) def reject(self): super().reject() self.loading_canceled.emit(self)