def delete_attributes(self, attribute_list): """ Delete attributes from the layer :param attribute_list: list of ids of attributes to be removed from the layer (if a list of field names is given instead of a list of ids, then the corresponding indices are found and used) :type attribute_list: list of int (or list of str) :return: true in case of success and false in case of failure """ caps = self.layer.dataProvider().capabilities() if not (caps & QgsVectorDataProvider.DeleteAttributes): raise TypeError('Unable to delete attributes to this kind of' ' layer (%s). Please consider saving the layer' ' with an editable format before attempting to' ' delete attributes from it.' % self.layer.providerType()) attr_idx_list = [] with edit(self.layer): # TODO QGIS3: check if usage of dataProvider is needed layer_pr = self.layer.dataProvider() for attribute in attribute_list: if isinstance(attribute, str): attr_idx = layer_pr.fields().indexOf(attribute) else: attr_idx = attribute attr_idx_list.append(attr_idx) # remove attributes if DEBUG: log_msg("REMOVING %s, (indices %s)" % (attribute_list, attr_idx_list)) return layer_pr.deleteAttributes(attr_idx_list)
def run_calc(self, calc_id=None, file_names=None, directory=None): """ Run a calculation. If `calc_id` is given, it means we want to run a calculation re-using the output of the given calculation """ text = self.tr('Select the files needed to run the calculation,' ' or the zip archive containing those files.') if directory is None: default_dir = QSettings().value('irmt/run_oqengine_calc_dir', QDir.homePath()) else: default_dir = directory if not file_names: file_names = QFileDialog.getOpenFileNames(self, text, default_dir) if not file_names: return if directory is None: selected_dir = QFileInfo(file_names[0]).dir().path() QSettings().setValue('irmt/run_oqengine_calc_dir', selected_dir) else: file_names = [os.path.join(directory, os.path.basename(file_name)) for file_name in file_names] if len(file_names) == 1: file_full_path = file_names[0] _, file_ext = os.path.splitext(file_full_path) if file_ext == '.zip': zipped_file_name = file_full_path else: # NOTE: an alternative solution could be to check if the single # file is .ini, to look for all the files specified in the .ini # and to build a zip archive with all them msg = "Please select all the files needed, or a zip archive" log_msg(msg, level='C', message_bar=self.message_bar) return else: _, zipped_file_name = tempfile.mkstemp() with zipfile.ZipFile(zipped_file_name, 'w') as zipped_file: for file_name in file_names: zipped_file.write(file_name) run_calc_url = "%s/v1/calc/run" % self.hostname with WaitCursorManager('Starting calculation...', self.message_bar): if calc_id is not None: # FIXME: currently the web api is expecting a hazard_job_id # although it could be any kind of job_id. This will have to be # changed as soon as the web api is updated. data = {'hazard_job_id': calc_id} else: data = {} files = {'archive': open(zipped_file_name, 'rb')} try: resp = self.session.post( run_calc_url, files=files, data=data, timeout=20) except HANDLED_EXCEPTIONS as exc: self._handle_exception(exc) return if resp.ok: self.refresh_calc_list() return resp.json() else: log_msg(resp.text, level='C', message_bar=self.message_bar)
def read_npz_into_layer(self, field_types, **kwargs): rlz_or_stat = kwargs['rlz_or_stat'] loss_type = kwargs['loss_type'] taxonomy = kwargs['taxonomy'] with edit(self.layer): feats = [] grouped_by_site = self.group_by_site(self.npz_file, rlz_or_stat, loss_type, taxonomy) for row in grouped_by_site: # add a feature feat = QgsFeature(self.layer.fields()) field_idx = 0 for field_name, field_type in field_types.items(): if field_name in ['lon', 'lat']: field_idx += 1 continue value = row[field_idx].item() if isinstance(value, bytes): value = value.decode('utf8') feat.setAttribute(field_name, value) field_idx += 1 feat.setGeometry( QgsGeometry.fromPointXY(QgsPointXY(row['lon'], row['lat']))) 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 on_calculate_zonal_stats_completed(self, zonal_layer_plus_sum): if zonal_layer_plus_sum is None: msg = 'The calculation of zonal statistics was not completed' log_msg(msg, level='C', message_bar=self.iface.messageBar()) return None # Add zonal layer to registry if zonal_layer_plus_sum.isValid(): root = QgsProject.instance().layerTreeRoot() QgsProject.instance().addMapLayer(zonal_layer_plus_sum, False) root.insertLayer(0, zonal_layer_plus_sum) else: msg = 'The layer aggregating data by zone is invalid.' log_msg(msg, level='C', message_bar=self.iface.messageBar()) return None # NOTE: in scenario damage, keys are like # u'structural_no_damage_mean', and not just # u'structural', therefore we can't just use the selected # loss type, but we must use the actual only key in the # dict added_loss_attr = "%s_sum" % self.loss_attr_name style_by = added_loss_attr try: perils = self.perils except AttributeError: perils = None self.style_maps(zonal_layer_plus_sum, style_by, self.iface, self.output_type, perils=perils, add_null_class=True) super().accept()
def get_node_attr_id_and_name(node, layer): """ Get the field (id and name) to be re-used to store the results of the calculation, if possible. Otherwise, add a new field to the layer and return its id and name. Also return True if a new field was added, or False if an old field was re-used. """ field_was_added = False if 'field' in node: node_attr_name = node['field'] # check that the field is still in the layer (the user might have # deleted it). If it is not there anymore, add a new field if layer.fieldNameIndex(node_attr_name) == -1: # not found proposed_node_attr_name = node_attr_name node_attr_name = add_numeric_attribute(proposed_node_attr_name, layer) field_was_added = True elif DEBUG: log_msg('Reusing field %s' % node_attr_name) elif 'name' in node: proposed_node_attr_name = node['name'] node_attr_name = add_numeric_attribute(proposed_node_attr_name, layer) field_was_added = True else: # this corner case should never happen (hopefully) raise InvalidNode('This node has no name and it does' ' not correspond to any field') # get the id of the new attribute node_attr_id = ProcessLayer(layer).find_attribute_id(node_attr_name) return node_attr_id, node_attr_name, field_was_added
def update_default_fieldname(self): if self.fields_multiselect.selected_widget.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.selected_widget.item(0).text()) 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()) return self.new_field_name_txt.setText(new_attr_name) self.attr_name_user_def = False
def download_output(self, output_id, outtype, dest_folder=None): if not dest_folder: dest_folder = ask_for_download_destination_folder(self) if not dest_folder: return output_download_url = ( "%s/v1/calc/result/%s?export_type=%s&dload=true" % (self.hostname, output_id, outtype)) with WaitCursorManager('Downloading output...', self.message_bar): try: # FIXME: enable the user to set verify=True resp = self.session.get(output_download_url, verify=False) except HANDLED_EXCEPTIONS as exc: self._handle_exception(exc) return if not resp.ok: err_msg = ( 'Unable to download the output.\n%s: %s.\n%s' % (resp.status_code, resp.reason, resp.text)) log_msg(err_msg, level='C', message_bar=self.message_bar) return filename = resp.headers['content-disposition'].split( 'filename=')[1] filepath = os.path.join(dest_folder, filename) open(filepath, "wb").write(resp.content) return filepath
def __init__( self, description, flags, output_id, outtype, output_type, dest_folder, session, hostname, on_success, on_error, del_task, task_id, current_calc_id=None): super().__init__(description, flags) self.output_id = output_id self.outtype = outtype self.output_type = output_type self.dest_folder = dest_folder self.session = session self.hostname = hostname self.on_success = on_success self.on_error = on_error self.del_task = del_task self.task_id = task_id self.current_calc_id = current_calc_id self.exception = None if self.current_calc_id: self.download_url = "%s/v1/calc/%s/datastore" % ( self.hostname, self.current_calc_id) else: self.download_url = ( "%s/v1/calc/result/%s?export_type=%s&dload=true" % ( self.hostname, self.output_id, self.outtype)) log_msg('GET: %s' % self.download_url, level='I', print_to_stderr=True)
def _update_layer_style(self): # The file stem contains the full path. We get just the basename layer_name = os.path.basename(self.file_stem) # Since the style name is set by default substituting '-' with '_', # tp get the right style we need to do the same substitution style_name = layer_name.replace('-', '_') try: sld = getGsCompatibleSld(self.iface.activeLayer(), style_name) except Exception as e: error_msg = ( 'Unable to export the styled layer descriptor: ' + e.message) self.message_bar.pushMessage( 'Style error', error_msg, duration=0, level=QgsMessageBar.CRITICAL) return if DEBUG: import tempfile fd, fname = tempfile.mkstemp(suffix=".sld") os.close(fd) with open(fname, 'w') as f: f.write(sld) os.system('tidy -xml -i %s' % fname) headers = {'content-type': 'application/vnd.ogc.sld+xml'} resp = self.session.put( self.hostname + '/gs/rest/styles/%s' % style_name, data=sld, headers=headers) if DEBUG: log_msg('Style upload response: %s' % resp) if not resp.ok: error_msg = ( 'Error while styling the uploaded layer: ' + resp.reason) self.message_bar.pushMessage( 'Style error', error_msg, duration=0, level=QgsMessageBar.CRITICAL)
def __init__(self, description, flags, session, hostname, calc_id, output_type, on_success, on_error, params=None): super().__init__(description, flags) self.session = session self.hostname = hostname self.calc_id = calc_id self.output_type = output_type self.on_success = on_success self.on_error = on_error self.dest_folder = tempfile.gettempdir() self.extract_url = '%s/v1/calc/%s/extract/%s' % ( self.hostname, self.calc_id, self.output_type) self.extract_params = params self.exception = None log_msg('GET: %s, with parameters: %s' % (self.extract_url, self.extract_params), level='I', print_to_stderr=True)
def accept(self): log_msg('Loading output started. Watch progress in QGIS task bar', level='I', message_bar=self.iface.messageBar()) try: self.iface.layerTreeView().currentLayerChanged.disconnect( self.on_currentLayerChanged) except Exception: # it's connected only for some loaders pass self.hide() if self.output_type in OQ_EXTRACT_TO_LAYER_TYPES: self.load_from_npz() if self.output_type in ('avg_losses-rlzs', 'damages-rlzs', 'avg_losses-stats'): # check if also aggregating by zone or not if (not self.zonal_layer_cbx.currentText() or not self.zonal_layer_gbx.isChecked()): super().accept() return self.aggregate_by_zone() else: super().accept() elif self.output_type in OQ_CSV_TO_LAYER_TYPES: self.load_from_csv() super().accept()
def read_npz_into_layer(self, field_types, rlz_or_stat, **kwargs): with edit(self.layer): feats = [] fields = self.layer.fields() layer_field_names = [field.name() for field in fields] dataset_field_names = list(self.get_field_types()) d2l_field_names = dict( list(zip(dataset_field_names[2:], layer_field_names))) rlz_name = 'rlz-%03d' % rlz_or_stat for row in self.npz_file[rlz_name]: # add a feature feat = QgsFeature(fields) for field_name in dataset_field_names: if field_name in ['lon', 'lat']: continue layer_field_name = d2l_field_names[field_name] value = row[field_name].item() if isinstance(value, bytes): value = value.decode('utf8') feat.setAttribute(layer_field_name, value) feat.setGeometry( QgsGeometry.fromPointXY(QgsPointXY(row[0], row[1]))) 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 build_custom_site_ids_layer(self, lons, lats, custom_site_ids): layer_name = 'custom_site_ids_%s' % self.calc_id custom_site_id_layer = QgsVectorLayer( "%s?crs=epsg:4326" % 'point', layer_name, "memory") add_attribute('custom_site_id', 'I', custom_site_id_layer) custom_site_id_layer = self.read_custom_site_ids_into_layer( custom_site_id_layer, lons, lats, custom_site_ids) custom_site_id_layer.setCustomProperty( 'output_type', '%s-%s' % (self.output_type, 'custom_site_ids')) if self.engine_version is not None: custom_site_id_layer.setCustomProperty( 'engine_version', self.engine_version) irmt_version = get_irmt_version() custom_site_id_layer.setCustomProperty('irmt_version', irmt_version) custom_site_id_layer.setCustomProperty('calc_id', self.calc_id) if self.mode != 'testing': # NOTE: the following commented line would cause (unexpectedly) # "QGIS died on signal 11" and double creation of some # layers during integration tests QgsProject.instance().addMapLayer(custom_site_id_layer, False) tree_node = QgsProject.instance().layerTreeRoot() tree_node.insertLayer(0, custom_site_id_layer) # self.iface.setActiveLayer(custom_site_id_layer) log_msg('Layer %s was created successfully' % layer_name, level='S', message_bar=self.iface.messageBar(), print_to_stdout=True)
def read_npz_into_layer( self, field_types, rlz_or_stat, boundaries, wkt_geom_type, row_wkt_geom_types, **kwargs): with edit(self.layer): feats = [] fields = self.layer.fields() field_names = [field.name() for field in fields] for row_idx, row in enumerate(self.npz_file['array']): if row_wkt_geom_types[row_idx] != wkt_geom_type: continue # add a feature feat = QgsFeature(fields) for field_name in field_names: value = row[field_name].item() if isinstance(value, bytes): value = value.decode('utf8') feat.setAttribute(field_name, value) feat.setGeometry(QgsGeometry.fromWkt( boundaries[row_idx].decode('utf8'))) 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 load_from_csv_file(self, csv_path, save_format, save_dest, do_show_table=True): # extract the name of the csv file and remove the extension layer_name = os.path.splitext(os.path.basename(csv_path))[0] try: layer = import_layer_from_csv(self, csv_path, layer_name, self.iface, save_format=save_format, save_dest=save_dest, zoom_to_layer=False, has_geom=False) except RuntimeError as exc: log_msg(str(exc), level='C', message_bar=self.iface.messageBar(), exception=exc) return write_metadata_to_layer(self.drive_engine_dlg, self.output_type, layer) log_msg('Layer %s was loaded successfully' % layer_name, level='S', message_bar=self.iface.messageBar()) if do_show_table: self.iface.showAttributeTable(layer)
def add_field_to_layer(self, field_name): try: # NOTE: add_numeric_attribute uses the native qgis editing manager added_field_name = add_numeric_attribute(field_name, self.layer) except TypeError as exc: log_msg(str(exc), level='C', message_bar=self.iface.messageBar()) return return added_field_name
def load_from_npz(self): boundaries = gzip.decompress(self.npz_file['boundaries']).split(b'\n') row_wkt_geom_types = { row_idx: QgsGeometry.fromWkt(boundary.decode('utf8')).wkbType() for row_idx, boundary in enumerate(boundaries)} wkt_geom_types = set(row_wkt_geom_types.values()) if len(wkt_geom_types) > 1: root = QgsProject.instance().layerTreeRoot() rup_group = root.insertGroup(0, "Earthquake Ruptures") else: rup_group = None for wkt_geom_type in wkt_geom_types: if wkt_geom_type == QgsWkbTypes.Point: layer_geom_type = "point" elif wkt_geom_type == QgsWkbTypes.LineString: layer_geom_type = "linestring" elif wkt_geom_type == QgsWkbTypes.Polygon: layer_geom_type = "polygon" elif wkt_geom_type == QgsWkbTypes.MultiPoint: layer_geom_type = "multipoint" elif wkt_geom_type == QgsWkbTypes.MultiLineString: layer_geom_type = "multilinestring" elif wkt_geom_type == QgsWkbTypes.MultiPolygon: layer_geom_type = "multipolygon" else: raise ValueError( 'Unexpected geometry type: %s' % wkt_geom_type) with WaitCursorManager( 'Creating layer for "%s" ruptures...' % layer_geom_type, self.iface.messageBar()): # NOTE: adding to map in this method self.layer = self.build_layer( boundaries=boundaries, geometry_type=layer_geom_type, wkt_geom_type=wkt_geom_type, row_wkt_geom_types=row_wkt_geom_types, add_to_group=rup_group, add_to_map=False) style_by = self.style_by_cbx.itemData( self.style_by_cbx.currentIndex()) if style_by == 'mag': self.style_maps(self.layer, style_by, self.iface, self.output_type) else: # 'trt' self.style_categorized(layer=self.layer, style_by=style_by) if rup_group: tree_node = rup_group else: tree_node = QgsProject.instance().layerTreeRoot() QgsProject.instance().addMapLayer(self.layer, False) tree_node.insertLayer(0, self.layer) self.iface.setActiveLayer(self.layer) log_msg('Layer %s was loaded successfully' % self.layer.name(), level='S', message_bar=self.iface.messageBar()) if rup_group: zoom_to_group(rup_group) else: self.iface.zoomToActiveLayer()
def get_eid(self, events_npz): self.events_npz = events_npz events = events_npz['array'] self.eid = -1 # assuming events start from 0 if 'GEM_QGIS_TEST' in os.environ: self.eid = self.get_closest_element(self.eid, events['id']) ok = True elif 'scenario' in self.calculation_mode: range_width = self.oqparam['number_of_ground_motion_fields'] ranges = {} for gsim_idx, gsim in enumerate(self.gsims): ranges[gsim] = (gsim_idx * range_width, gsim_idx * range_width + range_width - 1) ranges_str = '' for gsim in ranges: ranges_str += '\n%s: %s' % (gsim, ranges[gsim]) input_msg = "Ranges:%s" % ranges_str else: input_msg = "Range (%s - %s)" % (events[0]['id'], events[-1]['id']) if 'GEM_QGIS_TEST' not in os.environ: while self.eid not in events['id']: if self.eid == -1: is_first_iteration = True self.eid = self.get_closest_element(self.eid, events['id']) if is_first_iteration: msg = 'The first relevant event id is %s' % self.eid level = 'I' else: msg = 'The closest relevant event id is %s' % self.eid level = 'W' log_msg(msg, level=level, message_bar=self.iface.messageBar()) self.eid, ok = QInputDialog.getInt(self.drive_engine_dlg, 'Select an event ID', input_msg, self.eid, events[0]['id'], events[-1]['id']) if not ok: self.reject() return if not ok: self.reject() return log_msg( 'Extracting ground motion fields.' ' Watch progress in QGIS task bar', level='I', message_bar=self.iface.messageBar()) self.extract_npz_task = ExtractNpzTask('Extract ground motion fields', QgsTask.CanCancel, self.session, self.hostname, self.calc_id, self.output_type, self.finalize_init, self.on_extract_error, params={'event_id': self.eid}) QgsApplication.taskManager().addTask(self.extract_npz_task)
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 on_ruptures_extracted(self, extracted_npz): self.npz_file = extracted_npz if 'array' not in self.npz_file: log_msg("No ruptures were found above magnitude %s" % self.min_mag_dsb.text(), level='C', message_bar=self.iface.messageBar()) return self.load_from_npz() QDialog.accept(self) self.loading_completed.emit(self)
def on_extract_error(self, exception): if isinstance(exception, TaskCanceled): msg = 'Data extraction canceled' log_msg(msg, level='W', message_bar=self.iface.messageBar()) else: log_msg('Unable to complete data extraction', level='C', message_bar=self.iface.messageBar(), exception=exception) self.reject()
def accept(self): try: self.save_state() except ValueError as exc: log_msg(exc.message, level='C', message_bar=self.iface.messageBar(), duration=5) else: super(RecoverySettingsDialog, self).accept()
def __init__(self, drive_engine_dlg, iface, viewer_dock, session, hostname, calc_id, output_type=None, path=None, mode=None, zonal_layer_path=None, engine_version=None, calculation_mode=None): assert output_type in ('avg_losses-rlzs', 'avg_losses-stats') super().__init__(drive_engine_dlg, iface, viewer_dock, session, hostname, calc_id, output_type=output_type, path=path, mode=mode, zonal_layer_path=zonal_layer_path, engine_version=engine_version, calculation_mode=calculation_mode) if self.output_type == 'avg_losses-rlzs': self.setWindowTitle( 'Load losses by asset, aggregated by location, as layer') elif self.output_type == 'avg_losses-stats': self.setWindowTitle('Load average asset losses (statistics),' ' aggregated by location, as layer') else: raise NotImplementedError(output_type) self.create_load_selected_only_ckb() self.create_num_sites_indicator() self.create_rlz_or_stat_selector() self.create_taxonomy_selector() self.create_loss_type_selector() self.create_zonal_layer_selector() # NOTE: it's correct to use 'avg_losses-rlzs' instead of output_type, # both in case of avg_losses-rlzs and in case of avg_losses-stats log_msg('Extracting output data.' ' Watch progress in QGIS task bar', level='I', message_bar=self.iface.messageBar()) self.extract_npz_task = ExtractNpzTask('Extract losses by asset', QgsTask.CanCancel, self.session, self.hostname, self.calc_id, 'losses_by_asset', self.finalize_init, self.on_extract_error) QgsApplication.taskManager().addTask(self.extract_npz_task)
def setup_js(self): # pass a reference (called qt_page) of self to the JS world # to expose a member of self to js you need to declare it as property # see for example self.json_str() if DEBUG: log_msg("######################### for weight_data_debug.html") self.print_self_for_debug() log_msg("######################### end for weight_data_debug.html") self.frame.addToJavaScriptWindowObject('qt_page', self)
def accept(self): loss_layer_id = self.loss_layer_cbx.itemData( self.loss_layer_cbx.currentIndex()) loss_layer = QgsMapLayerRegistry.instance().mapLayer( loss_layer_id) 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()) return # check if loss layer is raster or vector (aggregating by zone # is different in the two cases) loss_layer_is_vector = self.loss_layer_is_vector # Open dialog to ask the user to specify attributes # * loss from loss_layer # * zone_id from loss_layer # * svi from zonal_layer # * zone_id from zonal_layer ret_val = self.attribute_selection( loss_layer, zonal_layer) if not ret_val: return (loss_attr_names, zone_id_in_losses_attr_name, zone_id_in_zones_attr_name) = ret_val # aggregate losses by zone (calculate count of points in the # zone, sum and average loss values for the same zone) 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) except TypeError as exc: log_msg(str(exc), level='C', message_bar=self.iface.messageBar()) return (loss_layer, zonal_layer, loss_attrs_dict) = res if self.purge_chk.isChecked(): purge_zones_without_loss_points( zonal_layer, loss_attrs_dict, self.iface) super(SelectInputLayersDialog, self).accept()
def accept(self): log_msg('Loading output started. Watch progress in QGIS task bar', level='I', message_bar=self.iface.messageBar()) self.hide() min_mag = self.min_mag_dsb.value() self.extract_npz_task = ExtractNpzTask( 'Extract ruptures', QgsTask.CanCancel, self.session, self.hostname, self.calc_id, 'rupture_info', self.on_ruptures_extracted, self.on_extract_error, params={'min_mag': min_mag}) QgsApplication.taskManager().addTask(self.extract_npz_task)
def notify_loss_aggregation_by_zone_complete(loss_attrs_dict, loss_attr_names, iface, extra=True): added_attrs = [] if extra: added_attrs.append(loss_attrs_dict['count']) for loss_attr_name in loss_attr_names: added_attrs.extend(loss_attrs_dict[loss_attr_name].values()) msg = "New attributes [%s] have been added to the zonal layer" % ( ', '.join(added_attrs)) log_msg(msg, level='I', message_bar=iface.messageBar())
def accept(self): with WaitCursorManager( 'Extracting custom site ids...', message_bar=self.iface.messageBar()): log_msg('Extracting custom site ids', level='I', print_to_stdout=True) sitecol = extract_npz( self.session, self.hostname, self.calc_id, 'sitecol', message_bar=self.iface.messageBar()) try: custom_site_ids = sitecol['array']['custom_site_id'] except ValueError: custom_site_ids = sitecol['array']['sids'] msg = ('Missing field "custom_site_id", needed by some ' 'OQ-GeoViewer projects. Using "sids" instead.') log_msg(msg, level='W', print_to_stdout=True, message_bar=self.iface.messageBar()) with WaitCursorManager( 'Creating disaggregation layer', self.iface.messageBar()): log_msg('Creating disagg_layer', level='I', print_to_stdout=True) log_msg('Getting disagg array', level='I', print_to_stdout=True) disagg_array = self.disagg['array'] lons = disagg_array['lon'] lats = disagg_array['lat'] self.layer = self.build_layer( self.disagg, disagg_array, lons, lats, custom_site_ids) if custom_site_ids is not None: self.build_custom_site_ids_layer(lons, lats, custom_site_ids) self.style_curves()
def on_output_action_btn_clicked(self, output, action, outtype): output_id = output['id'] output_type = output['type'] if action in ['Show', 'Aggregate']: dest_folder = tempfile.gettempdir() if output_type in OQ_EXTRACT_TO_VIEW_TYPES: self.viewer_dock.load_no_map_output( self.current_calc_id, self.session, self.hostname, output_type, self.engine_version) elif outtype == 'rst': filepath = self.download_output( output_id, outtype, dest_folder) if not filepath: return # NOTE: it might be created here directly instead, but this way # we can use the qt-designer self.full_report_dlg = ShowFullReportDialog(filepath) self.full_report_dlg.setWindowTitle( 'Full report of calculation %s' % self.current_calc_id) self.full_report_dlg.show() else: raise NotImplementedError("%s %s" % (action, outtype)) elif action == 'Load as layer': filepath = None if output_type not in OUTPUT_TYPE_LOADERS: raise NotImplementedError(output_type) if outtype == 'csv': dest_folder = tempfile.gettempdir() filepath = self.download_output( output_id, outtype, dest_folder) if not filepath: return if outtype in ('npz', 'csv'): dlg = OUTPUT_TYPE_LOADERS[output_type]( self.iface, self.viewer_dock, self.session, self.hostname, self.current_calc_id, output_type, path=filepath, engine_version=self.engine_version) dlg.exec_() else: raise NotImplementedError("%s %s" % (action, outtype)) elif action == 'Download': filepath = self.download_output(output_id, outtype) if not filepath: return msg = 'Calculation %s was saved as %s' % (output_id, filepath) log_msg(msg, level='I', message_bar=self.message_bar) else: raise NotImplementedError(action)
def __init__(self, drive_engine_dlg, iface, viewer_dock, session, hostname, calc_id, output_type='hmaps', path=None, mode=None, engine_version=None, calculation_mode=None): assert output_type == 'hmaps' 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 hazard maps as layer') self.create_num_sites_indicator() self.create_single_layer_ckb() self.create_load_one_layer_per_stat_ckb() self.create_rlz_or_stat_selector(all_ckb=True) self.create_imt_selector(all_ckb=True) self.create_poe_selector(all_ckb=True) self.create_show_return_period_ckb() self.load_single_layer_ckb.stateChanged[int].connect( self.on_load_single_layer_ckb_stateChanged) self.load_one_layer_per_stat_ckb.stateChanged[int].connect( self.on_load_one_layer_per_stat_ckb_stateChanged) log_msg('Extracting hazard maps.' ' Watch progress in QGIS task bar', level='I', message_bar=self.iface.messageBar()) self.extract_npz_task = ExtractNpzTask('Extract hazard maps', QgsTask.CanCancel, self.session, self.hostname, self.calc_id, self.output_type, self.finalize_init, self.on_extract_error) QgsApplication.taskManager().addTask(self.extract_npz_task)