Exemple #1
0
    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)
Exemple #3
0
 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()
Exemple #5
0
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)
Exemple #9
0
    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)
Exemple #10
0
 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
Exemple #13
0
 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)
Exemple #16
0
 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()
Exemple #23
0
    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)
Exemple #27
0
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())
Exemple #28
0
 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)