class postTelemacComboboxDialog(QDialog): def __init__(self, parent=None): super(postTelemacComboboxDialog, self).__init__(parent) # Set up the user interface from Designer. # After setupUI you can access any designer object by doing # self.<objectname>, and you can use autoconnect slots - see # http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html # #widgets-and-dialogs-with-auto-connect #self.setupUi(self) self.layout = QVBoxLayout() self.label = QLabel() self.combobox = QComboBox() self.dlgbuttonbox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.layout.addWidget(self.label) self.layout.addWidget(self.combobox) self.layout.addWidget(self.dlgbuttonbox) self.setLayout(self.layout) self.dlgbuttonbox.accepted.connect(self.accept) self.dlgbuttonbox.rejected.connect(self.reject) #self.loadvalues(ldp) def loadValues(self, ldp): self.combobox.clear() self.combobox.addItems(ldp)
def create_zonal_layer_selector(self): self.zonal_layer_gbx = QGroupBox() self.zonal_layer_gbx.setTitle('Aggregate by zone (optional)') 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.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.zone_id_field_lbl = QLabel('Field containing zone ids') self.zone_id_field_cbx = QComboBox() self.zonal_layer_gbx_v_layout.addWidget(self.zone_id_field_lbl) self.zonal_layer_gbx_v_layout.addWidget(self.zone_id_field_cbx) self.vlayout.addWidget(self.zonal_layer_gbx) self.zonal_layer_tbn.clicked.connect(self.on_zonal_layer_tbn_clicked) 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)
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_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_poe_selector(self): 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) self.vlayout.addWidget(self.poe_lbl) self.vlayout.addWidget(self.poe_cbx)
def create_imt_selector(self): 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) self.vlayout.addWidget(self.imt_lbl) self.vlayout.addWidget(self.imt_cbx)
def create_rlz_or_stat_selector(self, 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) self.vlayout.addWidget(self.rlz_or_stat_lbl) self.vlayout.addWidget(self.rlz_or_stat_cbx)
class LoadOutputAsLayerDialog(QDialog, FORM_CLASS): """ Modal dialog to load an oq-engine output as layer """ def __init__(self, iface, viewer_dock, session, hostname, calc_id, output_type=None, path=None, mode=None, zonal_layer_path=None, engine_version=None): # sanity check if output_type not in OQ_TO_LAYER_TYPES: raise NotImplementedError(output_type) 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 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) def create_file_hlayout(self): self.file_hlayout = QHBoxLayout() self.file_lbl = QLabel('File to load') self.file_browser_tbn = QToolButton() self.file_browser_tbn.setText('...') self.file_browser_tbn.clicked.connect(self.on_file_browser_tbn_clicked) self.path_le = QLineEdit() self.path_le.setEnabled(False) self.file_hlayout.addWidget(self.file_lbl) self.file_hlayout.addWidget(self.file_browser_tbn) self.file_hlayout.addWidget(self.path_le) self.vlayout.addLayout(self.file_hlayout) 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_rlz_or_stat_selector(self, 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) self.vlayout.addWidget(self.rlz_or_stat_lbl) self.vlayout.addWidget(self.rlz_or_stat_cbx) def create_imt_selector(self): 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) self.vlayout.addWidget(self.imt_lbl) self.vlayout.addWidget(self.imt_cbx) def create_poe_selector(self): 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) self.vlayout.addWidget(self.poe_lbl) self.vlayout.addWidget(self.poe_cbx) 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_save_as_shp_ckb(self): self.save_as_shp_ckb = QCheckBox("Save the loaded layer as shapefile") self.save_as_shp_ckb.setChecked(False) self.vlayout.addWidget(self.save_as_shp_ckb) def create_zonal_layer_selector(self): self.zonal_layer_gbx = QGroupBox() self.zonal_layer_gbx.setTitle('Aggregate by zone (optional)') 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.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.zone_id_field_lbl = QLabel('Field containing zone ids') self.zone_id_field_cbx = QComboBox() self.zonal_layer_gbx_v_layout.addWidget(self.zone_id_field_lbl) self.zonal_layer_gbx_v_layout.addWidget(self.zone_id_field_cbx) self.vlayout.addWidget(self.zonal_layer_gbx) self.zonal_layer_tbn.clicked.connect(self.on_zonal_layer_tbn_clicked) 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) def pre_populate_zonal_layer_cbx(self): for key, layer in \ QgsMapLayerRegistry.instance().mapLayers().iteritems(): # populate loss cbx only with layers containing points if layer.type() != QgsMapLayer.VectorLayer: continue if layer.geometryType() == QGis.Polygon: self.zonal_layer_cbx.addItem(layer.name()) self.zonal_layer_cbx.setItemData( self.zonal_layer_cbx.count() - 1, layer.id()) def on_zonal_layer_cbx_currentIndexChanged(self, new_index): self.zone_id_field_cbx.clear() 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) zonal_layer = QgsMapLayerRegistry.instance().mapLayer(zonal_layer_id) # if the zonal_layer doesn't have a field containing a unique zone id, # the user can choose to add such unique id self.zone_id_field_cbx.addItem("Add field with unique zone id") for field in zonal_layer.fields(): # for the zone id accept both numeric or textual fields self.zone_id_field_cbx.addItem(field.name()) # by default, set the selection to the first textual field self.set_ok_button() def on_zonal_layer_gbx_toggled(self, on): if on 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() elif self.output_type in OQ_COMPLEX_CSV_TO_LAYER_TYPES: self.create_save_as_shp_ckb() self.set_ok_button() @pyqtSlot() def on_file_browser_tbn_clicked(self): path = self.open_file_dialog() if path: self.populate_out_dep_widgets() 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 open_file_dialog(self): """ Open a file dialog to select the data file to be loaded """ text = self.tr('Select the OQ-Engine output file to import') if self.output_type in OQ_CSV_TO_LAYER_TYPES: filters = self.tr('CSV files (*.csv)') else: raise NotImplementedError(self.output_type) default_dir = QSettings().value('irmt/load_as_layer_dir', QDir.homePath()) path = QFileDialog.getOpenFileName(self, text, default_dir, filters) if not path: return selected_dir = QFileInfo(path).dir().path() QSettings().setValue('irmt/load_as_layer_dir', selected_dir) self.path = path self.path_le.setText(self.path) return path 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_names(self, **kwargs): raise NotImplementedError() def add_field_to_layer(self, field_name): raise NotImplementedError() def read_npz_into_layer(self, field_names, **kwargs): raise NotImplementedError() def load_from_npz(self): raise NotImplementedError() def get_investigation_time(self): if self.output_type in ('hcurves', 'uhs', 'hmaps'): try: investigation_time = self.npz_file['investigation_time'] except KeyError: 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()) else: return 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): 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) field_names = self.get_field_names(rlz_or_stat=rlz_or_stat, taxonomy=taxonomy, poe=poe, loss_type=loss_type, dmg_state=dmg_state) # create layer self.layer = QgsVectorLayer("Point?crs=epsg:4326", layer_name, "memory") for field_name in field_names: if field_name in ['lon', 'lat']: continue added_field_name = self.add_field_to_layer(field_name) 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 field_name_idx = field_names.index(field_name) field_names.remove(field_name) field_names.insert(field_name_idx, added_field_name) self.read_npz_into_layer(field_names, rlz_or_stat=rlz_or_stat, taxonomy=taxonomy, poe=poe, loss_type=loss_type, dmg_state=dmg_state) 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) QgsMapLayerRegistry.instance().addMapLayer(self.layer) self.iface.setActiveLayer(self.layer) self.iface.zoomToActiveLayer() def _set_symbol_size(self, symbol): if self.iface.mapCanvas().mapUnits() == QGis.Degrees: point_size = 0.05 elif self.iface.mapCanvas().mapUnits() == QGis.Meters: point_size = 4000 else: # it is not obvious how to choose the point size in the other # cases, so we conservatively keep the default sizing return symbol.symbolLayer(0).setSizeUnit(symbol.MapUnit) symbol.symbolLayer(0).setSize(point_size) map_unit_scale = QgsMapUnitScale() map_unit_scale.maxSizeMMEnabled = True map_unit_scale.minSizeMMEnabled = True map_unit_scale.minSizeMM = 0.5 map_unit_scale.maxSizeMM = 10 symbol.symbolLayer(0).setSizeMapUnitScale(map_unit_scale) def style_maps(self, layer=None, style_by=None): if layer is None: layer = self.layer if style_by is None: style_by = self.default_field_name symbol = QgsSymbolV2.defaultSymbol(layer.geometryType()) # see properties at: # https://qgis.org/api/qgsmarkersymbollayerv2_8cpp_source.html#l01073 symbol.setAlpha(1) # opacity if isinstance(symbol, QgsMarkerSymbolV2): # do it only for the layer with points self._set_symbol_size(symbol) symbol.symbolLayer(0).setOutlineStyle(Qt.PenStyle(Qt.NoPen)) style = get_style(layer, self.iface.messageBar()) # this is the default, as specified in the user settings ramp = QgsVectorGradientColorRampV2(style['color_from'], style['color_to']) mode = style['mode'] # in most cases, we override the user-specified setting, and use # instead a setting that was required by scientists if self.output_type in OQ_TO_LAYER_TYPES: default_qgs_style = QgsStyleV2().defaultStyle() default_color_ramp_names = default_qgs_style.colorRampNames() if self.output_type in ('dmg_by_asset', 'losses_by_asset', 'avg_losses-stats'): # options are EqualInterval, Quantile, Jenks, StdDev, Pretty # jenks = natural breaks mode = QgsGraduatedSymbolRendererV2.Jenks ramp_type_idx = default_color_ramp_names.index('Reds') inverted = False elif self.output_type in ('hmaps', 'gmf_data', 'ruptures'): # options are EqualInterval, Quantile, Jenks, StdDev, Pretty if self.output_type == 'ruptures': mode = QgsGraduatedSymbolRendererV2.Pretty else: mode = QgsGraduatedSymbolRendererV2.EqualInterval ramp_type_idx = default_color_ramp_names.index('Spectral') inverted = True ramp = default_qgs_style.colorRamp( default_color_ramp_names[ramp_type_idx]) graduated_renderer = QgsGraduatedSymbolRendererV2.createRenderer( layer, style_by, style['classes'], mode, symbol, ramp, inverted=inverted) label_format = graduated_renderer.labelFormat() # label_format.setTrimTrailingZeroes(True) # it might be useful label_format.setPrecision(2) graduated_renderer.setLabelFormat(label_format, updateRanges=True) # add a class for 0 values, unless while styling ruptures if self.output_type != 'ruptures': VERY_SMALL_VALUE = 1e-20 graduated_renderer.updateRangeLowerValue(0, VERY_SMALL_VALUE) symbol_zeros = QgsSymbolV2.defaultSymbol(layer.geometryType()) symbol_zeros.setColor(QColor(240, 240, 240)) # very light grey if isinstance(symbol, QgsMarkerSymbolV2): # do it only for the layer with points self._set_symbol_size(symbol_zeros) symbol_zeros.symbolLayer(0).setOutlineStyle( Qt.PenStyle(Qt.NoPen)) zeros_min = 0.0 zeros_max = VERY_SMALL_VALUE range_zeros = QgsRendererRangeV2( zeros_min, zeros_max, symbol_zeros, " %.2f - %.2f" % (zeros_min, zeros_max), True) graduated_renderer.addClassRange(range_zeros) graduated_renderer.moveClass( len(graduated_renderer.ranges()) - 1, 0) layer.setRendererV2(graduated_renderer) layer.setLayerTransparency(30) # percent layer.triggerRepaint() self.iface.legendInterface().refreshLayerSymbology(layer) self.iface.mapCanvas().refresh() def style_categorized(self, layer, style_by): # get unique values fni = layer.fieldNameIndex(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 = QgsSymbolV2.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 = QgsSimpleFillSymbolLayerV2.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 = QgsRendererCategoryV2(unique_value, symbol, str(unique_value)) # entry for the list of category items categories.append(category) # create renderer object renderer = QgsCategorizedSymbolRendererV2(style_by, categories) # assign the created renderer to the layer if renderer is not None: layer.setRendererV2(renderer) layer.triggerRepaint() self.iface.legendInterface().refreshLayerSymbology(layer) self.iface.mapCanvas().refresh() def style_curves(self): registry = QgsSymbolLayerV2Registry.instance() cross = registry.symbolLayerMetadata("SimpleMarker").createSymbolLayer( { 'name': 'cross2', 'color': '0,0,0', 'color_border': '0,0,0', 'offset': '0,0', 'size': '1.5', 'angle': '0' }) symbol = QgsSymbolV2.defaultSymbol(self.layer.geometryType()) symbol.deleteSymbolLayer(0) symbol.appendSymbolLayer(cross) self._set_symbol_size(symbol) renderer = QgsSingleSymbolRendererV2(symbol) effect = QgsOuterGlowEffect() effect.setSpread(0.5) effect.setTransparency(0) effect.setColor(QColor(255, 255, 255)) effect.setBlurLevel(1) renderer.paintEffect().appendEffect(effect) renderer.paintEffect().setEnabled(True) self.layer.setRendererV2(renderer) self.layer.setLayerTransparency(30) # percent self.layer.triggerRepaint() self.iface.legendInterface().refreshLayerSymbology(self.layer) self.iface.mapCanvas().refresh() def open_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('Vector shapefiles (*.shp);;SQLite (*.sqlite);;' 'All files (*.*)') default_dir = QSettings().value('irmt/select_layer_dir', QDir.homePath()) file_name, file_type = QFileDialog.getOpenFileNameAndFilter( 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_plus_stats = self.load_zonal_layer(file_name) return zonal_layer_plus_stats def load_zonal_layer(self, zonal_layer_path, make_a_copy=False): # Load zonal layer zonal_layer = QgsVectorLayer(zonal_layer_path, tr('Zonal data'), 'ogr') if not zonal_layer.geometryType() == QGis.Polygon: msg = 'Zonal layer must contain zone polygons' log_msg(msg, level='C', message_bar=self.iface.messageBar()) return False if make_a_copy: # Make a copy, where stats will be added zonal_layer_plus_stats = ProcessLayer( zonal_layer).duplicate_in_memory() else: zonal_layer_plus_stats = zonal_layer # Add zonal layer to registry if zonal_layer_plus_stats.isValid(): QgsMapLayerRegistry.instance().addMapLayer(zonal_layer_plus_stats) else: msg = 'Invalid zonal layer' log_msg(msg, level='C', message_bar=self.iface.messageBar()) return None return zonal_layer_plus_stats def on_zonal_layer_tbn_clicked(self): zonal_layer_plus_stats = self.open_zonal_layer_dialog() if (zonal_layer_plus_stats and zonal_layer_plus_stats.geometryType() == QGis.Polygon): self.populate_zonal_layer_cbx(zonal_layer_plus_stats) def populate_zonal_layer_cbx(self, zonal_layer_plus_stats): cbx = self.zonal_layer_cbx cbx.addItem(zonal_layer_plus_stats.name()) last_index = cbx.count() - 1 cbx.setItemData(last_index, zonal_layer_plus_stats.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): if self.output_type in OQ_EXTRACT_TO_LAYER_TYPES: self.load_from_npz() if self.output_type in ('losses_by_asset', 'dmg_by_asset', '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(LoadOutputAsLayerDialog, self).accept() return loss_layer = self.layer self.iface.legendInterface().setLayerVisible(loss_layer, False) zonal_layer_id = self.zonal_layer_cbx.itemData( self.zonal_layer_cbx.currentIndex()) zonal_layer = QgsMapLayerRegistry.instance().mapLayer( zonal_layer_id) # if the two layers have different projections, display an # error message and return 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='C', message_bar=self.iface.messageBar()) # TODO: load only loss layer super(LoadOutputAsLayerDialog, self).accept() return loss_attr_names = [ field.name() for field in loss_layer.fields() ] zone_id_in_losses_attr_name = None # index 0 is for "Add field with unique zone id" if self.zone_id_field_cbx.currentIndex() == 0: zone_id_in_zones_attr_name = None else: zone_id_in_zones_attr_name = \ self.zone_id_field_cbx.currentText() # aggregate losses by zone (calculate count of points in the # zone, sum and average loss values for the same zone) loss_layer_is_vector = True try: res = calculate_zonal_stats(loss_layer, zonal_layer, loss_attr_names, loss_layer_is_vector, zone_id_in_losses_attr_name, zone_id_in_zones_attr_name, self.iface, extra=False) except TypeError as exc: log_msg(str(exc), level='C', message_bar=self.iface.messageBar()) return (loss_layer, zonal_layer, loss_attrs_dict) = res # sanity check assert len(loss_attrs_dict) == 1, ( "Only one attribute should be added to the zonal layer." " %s were added insted" % len(loss_attrs_dict)) # 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] = loss_attrs_dict style_by = loss_attrs_dict[added_loss_attr]['sum'] self.style_maps(layer=zonal_layer, style_by=style_by) elif self.output_type in OQ_CSV_TO_LAYER_TYPES: self.load_from_csv() super(LoadOutputAsLayerDialog, self).accept() def reject(self): if (hasattr(self, 'npz_file') and self.npz_file is not None and self.output_type in OQ_TO_LAYER_TYPES): self.npz_file.close() super(LoadOutputAsLayerDialog, self).reject()
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_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 show_results(self, api_results, tbl_result=None, pg_connections=dict(), progress_bar=QProgressBar): """Display the results in a table .""" logger.info("Results manager called. Displaying the results") # check parameters if not tbl_result: tbl_result = self.isogeo_widget.tbl_result else: pass # Get the name (and other informations) of all databases whose # connection is set up in QGIS if pg_connections == {}: pg_connections = self.pg_connections else: pass # Set table rows if api_results.get("total") >= 10: tbl_result.setRowCount(10) else: tbl_result.setRowCount(api_results.get("total")) # Looping inside the table lines. For each of them, showing the title, # abstract, geometry type, and a button that allow to add the data # to the canvas. count = 0 for i in api_results.get("results"): # get useful metadata md_id = i.get("_id") md_keywords = [ i.get("tags").get(k) for k in i.get("tags", [ "NR", ]) if k.startswith("keyword:isogeo") ] md_title = i.get("title", "NR") ds_geometry = i.get("geometry") # COLUMN 1 - Title and abstract # Displaying the metadata title inside a button btn_md_title = QPushButton( custom_tools.format_button_title(md_title)) # Connecting the button to the full metadata popup btn_md_title.pressed.connect( partial(self.send_details_request, md_id=md_id)) # Putting the abstract as a tooltip on this button btn_md_title.setToolTip(i.get("abstract", "")[:300]) # Insert it in column 1 tbl_result.setCellWidget(count, 0, btn_md_title) # COLUMN 2 - Data last update tbl_result.setItem( count, 1, QTableWidgetItem(custom_tools.handle_date(i.get("_modified")))) # COLUMN 3 - Geometry type lbl_geom = QLabel(tbl_result) if ds_geometry: if ds_geometry in point_list: lbl_geom.setPixmap(pix_point) lbl_geom.setToolTip(self.tr("Point", "ResultsManager")) elif ds_geometry in polygon_list: lbl_geom.setPixmap(pix_polyg) lbl_geom.setToolTip(self.tr("Polygon", "ResultsManager")) elif ds_geometry in line_list: lbl_geom.setPixmap(pix_line) lbl_geom.setToolTip(self.tr("Line", "ResultsManager")) elif ds_geometry in multi_list: lbl_geom.setPixmap(pix_multi) lbl_geom.setToolTip( self.tr("MultiPolygon", "ResultsManager")) elif ds_geometry == "TIN": tbl_result.setItem(count, 2, QTableWidgetItem(u"TIN")) else: tbl_result.setItem( count, 2, QTableWidgetItem( self.tr("Unknown geometry", "ResultsManager"))) else: if "rasterDataset" in i.get("type"): lbl_geom.setPixmap(pix_rastr) lbl_geom.setToolTip(self.tr("Raster", "ResultsManager")) elif "service" in i.get("type"): lbl_geom.setPixmap(pix_serv) lbl_geom.setToolTip(self.tr("Service", "ResultsManager")) else: lbl_geom.setPixmap(pix_nogeo) lbl_geom.setToolTip( self.tr("Unknown geometry", "ResultsManager")) tbl_result.setCellWidget(count, 2, lbl_geom) # COLUMN 4 - Add options dico_add_options = {} # Files and PostGIS direct access if "format" in i.keys(): # If the data is a vector and the path is available, store # useful information in the dict if i.get("format", "NR") in li_formats_vect and "path" in i: filepath = custom_tools.format_path(i.get("path")) dir_file = os.path.dirname(filepath) if dir_file not in self.cached_unreach_paths: try: open(filepath) params = [ "vector", filepath, i.get("title", "NR"), i.get("abstract", "NR"), md_keywords ] dico_add_options[self.tr( "Data file", "ResultsManager")] = params except IOError: self.cached_unreach_paths.append(dir_file) self.cached_unreach_paths = list( set(self.cached_unreach_paths)) else: logger.debug( "Path has been ignored because it's cached.") pass # Same if the data is a raster elif i.get("format", "NR") in li_formats_rastr and "path" in i: filepath = custom_tools.format_path(i.get("path")) dir_file = os.path.dirname(filepath) if dir_file not in self.cached_unreach_paths: try: open(filepath) params = [ "raster", filepath, i.get("title", "NR"), i.get("abstract", "NR"), md_keywords ] dico_add_options[self.tr( "Data file", "ResultsManager")] = params except IOError: self.cached_unreach_paths.append(dir_file) pass else: logger.debug( "Path has been ignored because it's cached.") pass # If the data is a postGIS table and the connexion has # been saved in QGIS. elif i.get("format") == "postgis": # Récupère le nom de la base de données base_name = i.get("path") if base_name in pg_connections.keys(): params = {} params["base_name"] = base_name schema_table = i.get("name") if schema_table is not None and "." in schema_table: params["schema"] = schema_table.split(".")[0] params["table"] = schema_table.split(".")[1] params["abstract"] = i.get("abstract", None) params["title"] = i.get("title", None) params["keywords"] = md_keywords dico_add_options[self.tr( "PostGIS table", "ResultsManager")] = params else: pass else: pass else: pass # Associated service layers d_type = i.get("type") if d_type == "vectorDataset" or d_type == "rasterDataset": for layer in i.get("serviceLayers"): service = layer.get("service") if service is not None: srv_details = { "path": service.get("path", "NR"), "formatVersion": service.get("formatVersion") } # EFS if service.get("format") == "efs": name_url = srv_url_bld.build_efs_url( layer, srv_details, rsc_type="ds_dyn_lyr_srv", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: pass # EMS if service.get("format") == "ems": name_url = srv_url_bld.build_ems_url( layer, srv_details, rsc_type="ds_dyn_lyr_srv", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: pass # WFS if service.get("format") == "wfs": name_url = srv_url_bld.build_wfs_url( layer, srv_details, rsc_type="ds_dyn_lyr_srv", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: pass # WMS elif service.get("format") == "wms": name_url = srv_url_bld.build_wms_url( layer, srv_details, rsc_type="ds_dyn_lyr_srv", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: pass # WMTS elif service.get("format") == "wmts": name_url = srv_url_bld.build_wmts_url( layer, srv_details, rsc_type="ds_dyn_lyr_srv") if name_url[0] != 0: dico_add_options[u"WMTS : " + name_url[1]] = name_url else: pass else: pass else: pass # New association mode. For services metadata sheet, the layers # are stored in the purposely named include: "layers". elif i.get("type") == "service": if i.get("layers") is not None: srv_details = { "path": i.get("path", "NR"), "formatVersion": i.get("formatVersion") } # WFS if i.get("format") == "wfs": for layer in i.get("layers"): name_url = srv_url_bld.build_wfs_url( layer, srv_details, rsc_type="service", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: continue pass # WMS elif i.get("format") == "wms": for layer in i.get("layers"): name_url = srv_url_bld.build_wms_url( layer, srv_details, rsc_type="service", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: continue pass # WMTS elif i.get("format") == "wmts": for layer in i.get("layers"): name_url = srv_url_bld.build_wmts_url( layer, srv_details, rsc_type="service") if name_url[0] != 0: btn_label = "WMTS : {}".format(name_url[1]) dico_add_options[btn_label] = name_url else: continue pass else: pass else: pass # Now the plugin has tested every possibility for the layer to be # added. The "Add" column has to be filled accordingly. # If the data can't be added, just insert "can't" text. if dico_add_options == {}: text = self.tr("Can't be added", "ResultsManager") fake_button = QPushButton(text) fake_button.setStyleSheet("text-align: left") fake_button.setEnabled(False) tbl_result.setCellWidget(count, 3, fake_button) # If there is only one way for the data to be added, insert a # button. elif len(dico_add_options) == 1: text = dico_add_options.keys()[0] params = dico_add_options.get(text) if text.startswith("WFS"): icon = ico_wfs elif text.startswith("WMS"): icon = ico_wms elif text.startswith("WMTS"): icon = ico_wmts elif text.startswith("EFS"): icon = ico_efs elif text.startswith("EMS"): icon = ico_ems elif text.startswith(self.tr("PostGIS table", "ResultsManager")): icon = ico_pgis elif text.startswith(self.tr("Data file", "ResultsManager")): icon = ico_file add_button = QPushButton(icon, text) add_button.setStyleSheet("text-align: left") add_button.pressed.connect( partial(self.add_layer, layer_info=["info", params])) tbl_result.setCellWidget(count, 3, add_button) # Else, add a combobox, storing all possibilities. else: combo = QComboBox() for i in dico_add_options: if i.startswith("WFS"): icon = ico_wfs elif i.startswith("WMS"): icon = ico_wms elif i.startswith("WMTS"): icon = ico_wmts elif i.startswith("EFS"): icon = ico_efs elif i.startswith("EMS"): icon = ico_ems elif i.startswith( self.tr("PostGIS table", "ResultsManager")): icon = ico_pgis elif i.startswith(self.tr("Data file", "ResultsManager")): icon = ico_file combo.addItem(icon, i, dico_add_options.get(i)) combo.activated.connect( partial(self.add_layer, layer_info=["index", count])) tbl_result.setCellWidget(count, 3, combo) count += 1 # dimensions header = tbl_result.horizontalHeader() header.setResizeMode(0, QHeaderView.Stretch) header.setResizeMode(1, QHeaderView.ResizeToContents) header.setResizeMode(2, QHeaderView.ResizeToContents) # Remove the "loading" bar iface.mainWindow().statusBar().removeWidget(progress_bar) # method ending return None
def show_results(self, api_results, tbl_result=None, pg_connections=dict(), progress_bar=QProgressBar): """Display the results in a table .""" logger.info("Results manager called. Displaying the results") # check parameters if not tbl_result: tbl_result = self.isogeo_widget.tbl_result else: pass # Get the name (and other informations) of all databases whose # connection is set up in QGIS if pg_connections == {}: pg_connections = self.pg_connections else: pass # Set table rows if api_results.get("total") >= 10: tbl_result.setRowCount(10) else: tbl_result.setRowCount(api_results.get("total")) # Looping inside the table lines. For each of them, showing the title, # abstract, geometry type, and a button that allow to add the data # to the canvas. count = 0 for i in api_results.get("results"): # get useful metadata md_id = i.get("_id") md_keywords = [i.get("tags").get(k) for k in i.get("tags", ["NR", ]) if k.startswith("keyword:isogeo")] md_title = i.get("title", "NR") ds_geometry = i.get("geometry") # COLUMN 1 - Title and abstract # Displaying the metadata title inside a button btn_md_title = QPushButton(plg_tools.format_button_title(md_title)) # Connecting the button to the full metadata popup btn_md_title.pressed.connect(partial( self.send_details_request, md_id=md_id)) # Putting the abstract as a tooltip on this button btn_md_title.setToolTip(i.get("abstract", "")[:300]) # Insert it in column 1 tbl_result.setCellWidget(count, 0, btn_md_title) # COLUMN 2 - Data last update tbl_result.setItem( count, 1, QTableWidgetItem( plg_tools.handle_date(i.get("_modified")))) # COLUMN 3 - Geometry type lbl_geom = QLabel(tbl_result) if ds_geometry: if ds_geometry in point_list: lbl_geom.setPixmap(pix_point) lbl_geom.setToolTip(self.tr("Point", "ResultsManager")) elif ds_geometry in polygon_list: lbl_geom.setPixmap(pix_polyg) lbl_geom.setToolTip(self.tr("Polygon", "ResultsManager")) elif ds_geometry in line_list: lbl_geom.setPixmap(pix_line) lbl_geom.setToolTip(self.tr("Line", "ResultsManager")) elif ds_geometry in multi_list: lbl_geom.setPixmap(pix_multi) lbl_geom.setToolTip(self.tr("MultiPolygon", "ResultsManager")) elif ds_geometry == "TIN": tbl_result.setItem( count, 2, QTableWidgetItem(u"TIN")) else: tbl_result.setItem( count, 2, QTableWidgetItem( self.tr("Unknown geometry", "ResultsManager"))) else: if "rasterDataset" in i.get("type"): lbl_geom.setPixmap(pix_rastr) lbl_geom.setToolTip(self.tr("Raster", "ResultsManager")) elif "service" in i.get("type"): lbl_geom.setPixmap(pix_serv) lbl_geom.setToolTip(self.tr("Service", "ResultsManager")) else: lbl_geom.setPixmap(pix_nogeo) lbl_geom.setToolTip(self.tr("Unknown geometry", "ResultsManager")) tbl_result.setCellWidget(count, 2, lbl_geom) # COLUMN 4 - Add options dico_add_options = {} # Files and PostGIS direct access if "format" in i.keys(): # If the data is a vector and the path is available, store # useful information in the dict if i.get("format", "NR") in li_formats_vect and "path" in i: add_path = self._filepath_builder(i.get("path")) if add_path: params = ["vector", add_path, i.get("title", "NR"), i.get("abstract", "NR"), md_keywords] dico_add_options[self.tr("Data file", "ResultsManager")] = params else: pass # Same if the data is a raster elif i.get("format", "NR") in li_formats_rastr and "path" in i: add_path = self._filepath_builder(i.get("path")) if add_path: params = ["raster", add_path, i.get("title", "NR"), i.get("abstract", "NR"), md_keywords] dico_add_options[self.tr("Data file", "ResultsManager")] = params else: pass # If the data is a postGIS table and the connexion has # been saved in QGIS. elif i.get("format") == "postgis": base_name = i.get("path", "No path") if base_name in pg_connections.keys(): params = {} params["base_name"] = base_name schema_table = i.get("name") if schema_table is not None and "." in schema_table: params["schema"] = schema_table.split(".")[0] params["table"] = schema_table.split(".")[1] params["abstract"] = i.get("abstract", None) params["title"] = i.get("title", None) params["keywords"] = md_keywords dico_add_options[self.tr("PostGIS table", "ResultsManager")] = params else: pass else: pass else: logger.debug("Metadata {} has a format but it's not recognized or path is missing".format(md_id)) pass # Associated service layers d_type = i.get("type") if d_type == "vectorDataset" or d_type == "rasterDataset": for layer in i.get("serviceLayers"): service = layer.get("service") if service is not None: srv_details = {"path": service.get("path", "NR"), "formatVersion": service.get("formatVersion")} # EFS if service.get("format") == "efs": name_url = plg_url_bldr.build_efs_url(layer, srv_details, rsc_type="ds_dyn_lyr_srv", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: pass # EMS if service.get("format") == "ems": name_url = plg_url_bldr.build_ems_url(layer, srv_details, rsc_type="ds_dyn_lyr_srv", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: pass # WFS if service.get("format") == "wfs": name_url = plg_url_bldr.build_wfs_url(layer, srv_details, rsc_type="ds_dyn_lyr_srv", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: pass # WMS elif service.get("format") == "wms": name_url = plg_url_bldr.build_wms_url(layer, srv_details, rsc_type="ds_dyn_lyr_srv", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: pass # WMTS elif service.get("format") == "wmts": name_url = plg_url_bldr.build_wmts_url(layer, srv_details, rsc_type="ds_dyn_lyr_srv") if name_url[0] != 0: dico_add_options[u"WMTS : " + name_url[1]] = name_url else: pass else: pass else: pass # New association mode. For services metadata sheet, the layers # are stored in the purposely named include: "layers". elif i.get("type") == "service": if i.get("layers") is not None: srv_details = {"path": i.get("path", "NR"), "formatVersion": i.get("formatVersion")} # EFS if i.get("format") == "efs": for layer in i.get("layers"): name_url = plg_url_bldr.build_efs_url(layer, srv_details, rsc_type="service", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: continue # EMS if i.get("format") == "ems": for layer in i.get("layers"): name_url = plg_url_bldr.build_ems_url(layer, srv_details, rsc_type="service", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: continue # WFS if i.get("format") == "wfs": for layer in i.get("layers"): name_url = plg_url_bldr.build_wfs_url(layer, srv_details, rsc_type="service", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: continue # WMS elif i.get("format") == "wms": for layer in i.get("layers"): name_url = plg_url_bldr.build_wms_url(layer, srv_details, rsc_type="service", mode="quicky") if name_url[0] != 0: dico_add_options[name_url[5]] = name_url else: continue # WMTS elif i.get("format") == "wmts": for layer in i.get("layers"): name_url = plg_url_bldr.build_wmts_url(layer, srv_details, rsc_type="service") if name_url[0] != 0: btn_label = "WMTS : {}".format(name_url[1]) dico_add_options[btn_label] = name_url else: continue else: pass else: pass # Now the plugin has tested every possibility for the layer to be # added. The "Add" column has to be filled accordingly. # If the data can't be added, just insert "can't" text. if dico_add_options == {}: text = self.tr("Can't be added", "ResultsManager") fake_button = QPushButton(text) fake_button.setStyleSheet("text-align: left") fake_button.setEnabled(False) tbl_result.setCellWidget(count, 3, fake_button) # If there is only one way for the data to be added, insert a # button. elif len(dico_add_options) == 1: text = dico_add_options.keys()[0] params = dico_add_options.get(text) if text.startswith("WFS"): icon = ico_wfs elif text.startswith("WMS"): icon = ico_wms elif text.startswith("WMTS"): icon = ico_wmts elif text.startswith("EFS"): icon = ico_efs elif text.startswith("EMS"): icon = ico_ems elif text.startswith(self.tr("PostGIS table", "ResultsManager")): icon = ico_pgis elif text.startswith(self.tr("Data file", "ResultsManager")): icon = ico_file add_button = QPushButton(icon, text) add_button.setStyleSheet("text-align: left") add_button.pressed.connect(partial(self.add_layer, layer_info=["info", params]) ) tbl_result.setCellWidget(count, 3, add_button) # Else, add a combobox, storing all possibilities. else: combo = QComboBox() for i in dico_add_options: if i.startswith("WFS"): icon = ico_wfs elif i.startswith("WMS"): icon = ico_wms elif i.startswith("WMTS"): icon = ico_wmts elif i.startswith("EFS"): icon = ico_efs elif i.startswith("EMS"): icon = ico_ems elif i.startswith(self.tr("PostGIS table", "ResultsManager")): icon = ico_pgis elif i.startswith(self.tr("Data file", "ResultsManager")): icon = ico_file combo.addItem(icon, i, dico_add_options.get(i)) combo.activated.connect(partial(self.add_layer, layer_info=["index", count])) combo.model().sort(0) # sort alphabetically on option prefix. see: #113 tbl_result.setCellWidget(count, 3, combo) count += 1 # dimensions header = tbl_result.horizontalHeader() header.setResizeMode(0, QHeaderView.Stretch) header.setResizeMode(1, QHeaderView.ResizeToContents) header.setResizeMode(2, QHeaderView.ResizeToContents) # Remove the "loading" bar iface.mainWindow().statusBar().removeWidget(progress_bar) # method ending return None