Пример #1
0
    def test_provenance_without_aggregation(self):
        """Test provenance of impact function without aggregation."""
        hazard_layer = load_test_vector_layer(
            'gisv4', 'hazard', 'classified_vector.geojson')
        exposure_layer = load_test_vector_layer(
            'gisv4', 'exposure', 'building-points.geojson')

        hazard = definition(hazard_layer.keywords['hazard'])
        exposure = definition(exposure_layer.keywords['exposure'])
        hazard_category = definition(hazard_layer.keywords['hazard_category'])

        expected_provenance = {
            'gdal_version': gdal.__version__,
            'host_name': gethostname(),
            'map_title': get_map_title(hazard, exposure, hazard_category),
            'map_legend_title': exposure['layer_legend_title'],
            'inasafe_version': get_version(),
            'pyqt_version': PYQT_VERSION_STR,
            'qgis_version': QGis.QGIS_VERSION,
            'qt_version': QT_VERSION_STR,
            'user': getpass.getuser(),
            'os': readable_os_version(),
            'aggregation_layer': None,
            'aggregation_layer_id': None,
            'exposure_layer': exposure_layer.source(),
            'exposure_layer_id': exposure_layer.id(),
            'hazard_layer': hazard_layer.source(),
            'hazard_layer_id': hazard_layer.id(),
            'analysis_question': get_analysis_question(hazard, exposure),
            'aggregation_keywords': None,
            'exposure_keywords': deepcopy(exposure_layer.keywords),
            'hazard_keywords': deepcopy(hazard_layer.keywords),
        }

        # Set up impact function
        impact_function = ImpactFunction()
        impact_function.exposure = exposure_layer
        impact_function.hazard = hazard_layer
        status, message = impact_function.prepare()
        self.assertEqual(PREPARE_SUCCESS, status, message)
        status, message = impact_function.run()
        self.assertEqual(ANALYSIS_SUCCESS, status, message)

        self.maxDiff = None

        expected_provenance.update({
            'action_checklist': impact_function.action_checklist(),
            'analysis_extent': impact_function.analysis_extent.exportToWkt(),
            'impact_function_name': impact_function.name,
            'impact_function_title': impact_function.title,
            'notes': impact_function.notes(),
            'requested_extent': impact_function.requested_extent,
            'data_store_uri': impact_function.datastore.uri_path,
            'start_datetime': impact_function.start_datetime,
            'end_datetime': impact_function.end_datetime,
            'duration': impact_function.duration
        })

        self.assertDictEqual(expected_provenance, impact_function.provenance)
Пример #2
0
    def _dict_to_row(keyword_value):
        """Helper to make a message row from a keyword where value is a dict.

        .. versionadded:: 3.2

        Use this when constructing a table from keywords to display as
        part of a message object. This variant will unpack the dict and
        present it nicely in the keyword value area as a nested table in the
        cell.

        We are expecting keyword value would be something like this:

            "{'high': ['Kawasan Rawan Bencana III'], "
            "'medium': ['Kawasan Rawan Bencana II'], "
            "'low': ['Kawasan Rawan Bencana I']}"

        Or by passing a python dict object with similar layout to above.

        i.e. A string representation of a dict where the values are lists.

        :param keyword_value: Value of the keyword to be rendered. This must
            be a string representation of a dict, or a dict.
        :type keyword_value: basestring, dict

        :returns: A table to be added into a cell in the keywords table.
        :rtype: safe.messaging.items.table
        """
        if isinstance(keyword_value, basestring):
            keyword_value = literal_eval(keyword_value)
        table = m.Table(style_class='table table-condensed')
        for key, value in keyword_value.items():
            row = m.Row()
            # First the heading
            if definition(key):
                name = definition(key)['name']
            else:
                name = tr(key.capitalize())
            row.add(m.Cell(m.ImportantText(name)))
            # Then the value. If it contains more than one element we
            # present it as a bullet list, otherwise just as simple text
            if isinstance(value, (tuple, list, dict, set)):
                if len(value) > 1:
                    bullets = m.BulletedList()
                    for item in value:
                        bullets.add(item)
                    row.add(m.Cell(bullets))
                elif len(value) == 0:
                    row.add(m.Cell(""))
                else:
                    row.add(m.Cell(value[0]))
            else:
                row.add(m.Cell(value))

            table.add(row)
        return table
Пример #3
0
def layer_definition_type(layer):
    """Returned relevant layer definition based on layer purpose.

    Returned the the correct definition of layer based on its purpose.
    For example, if a layer have layer_purpose: exposure, and exposure: roads
    then it will return definition for exposure_roads.

    That's why it only supports hazard layer or exposure layer.

    :param layer: hazard layer or exposure layer
    :type layer: qgis.core.QgsVectorLayer

    :return: Layer definitions.
    :rtype: dict

    .. versionadded:: 4.0
    """
    layer_purposes = ['exposure', 'hazard']

    layer_purpose = [p for p in layer_purposes if p in layer.keywords]

    if not layer_purpose:
        return None

    layer_purpose = layer_purpose[0]

    return definition(layer.keywords[layer_purpose])
Пример #4
0
    def __init__(self, coordinate_reference_system, geometry_type,
                 exposure_key):
        """Constructor for the size calculator.

        :param coordinate_reference_system: The Coordinate Reference System of
            the layer.
        :type coordinate_reference_system: QgsCoordinateReferenceSystem

        :param exposure_key: The geometry type of the layer.
        :type exposure_key: qgis.core.QgsWkbTypes.GeometryType
        """
        self.calculator = QgsDistanceArea()
        self.calculator.setSourceCrs(coordinate_reference_system,
                                     QgsProject.instance().transformContext())
        self.calculator.setEllipsoid('WGS84')

        if geometry_type == QgsWkbTypes.LineGeometry:
            self.default_unit = unit_metres
            LOGGER.info('The size calculator is set to use {unit}'.format(
                unit=distance_unit[self.calculator.lengthUnits()]))
        else:
            self.default_unit = unit_square_metres
            LOGGER.info('The size calculator is set to use {unit}'.format(
                unit=distance_unit[self.calculator.areaUnits()]))
        self.geometry_type = geometry_type
        self.output_unit = None
        if exposure_key:
            exposure_definition = definition(exposure_key)
            self.output_unit = exposure_definition['size_unit']
    def set_widgets(self):
        """Set widgets on the Classification tab."""
        self.clear_further_steps()
        purpose = self.parent.step_kw_purpose.selected_purpose()['name']
        subcategory = self.parent.step_kw_subcategory.\
            selected_subcategory()['name']
        self.lstClassifications.clear()
        self.lblDescribeClassification.setText('')
        self.lblSelectClassification.setText(classification_question %
                                             (subcategory, purpose))
        classifications = self.classifications_for_layer()
        for classification in classifications:
            if not isinstance(classification, dict):
                classification = definition(classification)
            item = QListWidgetItem(classification['name'],
                                   self.lstClassifications)
            item.setData(QtCore.Qt.UserRole, classification['key'])
            self.lstClassifications.addItem(item)

        # Set values based on existing keywords (if already assigned)
        classification_keyword = self.parent.get_existing_keyword(
            'classification')
        if classification_keyword:
            classifications = []
            for index in xrange(self.lstClassifications.count()):
                item = self.lstClassifications.item(index)
                classifications.append(item.data(QtCore.Qt.UserRole))
            if classification_keyword in classifications:
                self.lstClassifications.setCurrentRow(
                    classifications.index(classification_keyword))

        self.auto_select_one_item(self.lstClassifications)
Пример #6
0
def inasafe_field_header(field, feature, parent):
    """Retrieve a header name of the field name from definitions.

    For instance:
    inasafe_field_header('minimum_needs__clean_water') -> 'Clean water'
    """
    _ = feature, parent  # NOQA
    age_fields = [under_5_displaced_count_field, over_60_displaced_count_field]
    symbol_mapping = {'over': '>', 'under': '<'}

    field_definition = definition(field, 'field_name')
    if field_definition:
        if field_definition in age_fields:
            header_format = tr('{symbol} {age} y.o')
            field_name = field_definition.get('field_name')
            if field_name:
                symbol, age = field_name.split('_')[:2]
                if symbol.lower() in symbol_mapping.keys():
                    header_name = header_format.format(
                        symbol=symbol_mapping[symbol.lower()], age=age)
                    return header_name

        header_name = field_definition.get('header_name')
        name = field_definition.get('name')
        if header_name:
            return header_name.capitalize()
        else:
            return name.capitalize()
    return None
Пример #7
0
def hazard_extra_keyword(keyword, feature, parent):
    """Given a keyword, it will return the value of the keyword
    from the hazard layer's extra keywords.

    For instance:
    *   hazard_extra_keyword( 'depth' ) -> will return the value of 'depth'
        in current hazard layer's extra keywords.
    """
    _ = feature, parent  # NOQA
    hazard_layer_path = QgsExpressionContextUtils. \
        projectScope(QgsProject.instance()).variable(
          'hazard_layer')
    hazard_layer = load_layer(hazard_layer_path)[0]
    keywords = KeywordIO.read_keywords(hazard_layer)
    extra_keywords = keywords.get('extra_keywords')
    if extra_keywords:
        value = extra_keywords.get(keyword)
        if value:
            value_definition = definition(value)
            if value_definition:
                return value_definition['name']
            return value
        else:
            return tr('Keyword %s is not found' % keyword)
    return tr('No extra keywords found')
Пример #8
0
def inasafe_field_header(field, feature, parent):
    """Retrieve a header name of the field name from definitions.

    For instance:
    inasafe_field_header('minimum_needs__clean_water') -> 'Clean water'
    """
    _ = feature, parent  # NOQA
    age_fields = [under_5_displaced_count_field, over_60_displaced_count_field]
    symbol_mapping = {
        'over': '>',
        'under': '<'
    }

    field_definition = definition(field, 'field_name')
    if field_definition:
        if field_definition in age_fields:
            header_format = tr('{symbol} {age} y.o')
            field_name = field_definition.get('field_name')
            if field_name:
                symbol, age = field_name.split('_')[:2]
                if symbol.lower() in symbol_mapping.keys():
                    header_name = header_format.format(
                        symbol=symbol_mapping[symbol.lower()],
                        age=age
                    )
                    return header_name

        header_name = field_definition.get('header_name')
        name = field_definition.get('name')
        if header_name:
            return header_name.capitalize()
        else:
            return name.capitalize()
    return None
Пример #9
0
    def __init__(
            self, coordinate_reference_system, geometry_type, exposure_key):
        """Constructor for the size calculator.

        :param coordinate_reference_system: The Coordinate Reference System of
            the layer.
        :type coordinate_reference_system: QgsCoordinateReferenceSystem

        :param exposure_key: The geometry type of the layer.
        :type exposure_key: qgis.core.QgsWkbTypes.GeometryType
        """
        self.calculator = QgsDistanceArea()
        self.calculator.setSourceCrs(
            coordinate_reference_system,
            QgsProject.instance().transformContext()
        )
        self.calculator.setEllipsoid('WGS84')

        if geometry_type == QgsWkbTypes.LineGeometry:
            self.default_unit = unit_metres
            LOGGER.info('The size calculator is set to use {unit}'.format(
                unit=distance_unit[self.calculator.lengthUnits()]))
        else:
            self.default_unit = unit_square_metres
            LOGGER.info('The size calculator is set to use {unit}'.format(
                unit=distance_unit[self.calculator.areaUnits()]))
        self.geometry_type = geometry_type
        self.output_unit = None
        if exposure_key:
            exposure_definition = definition(exposure_key)
            self.output_unit = exposure_definition['size_unit']
Пример #10
0
def layer_definition_type(layer):
    """Returned relevant layer definition based on layer purpose.

    Returned the the correct definition of layer based on its purpose.
    For example, if a layer have layer_purpose: exposure, and exposure: roads
    then it will return definition for exposure_roads.

    That's why it only supports hazard layer or exposure layer.

    :param layer: hazard layer or exposure layer
    :type layer: qgis.core.QgsVectorLayer

    :return: Layer definitions.
    :rtype: dict

    .. versionadded:: 4.0
    """
    layer_purposes = ['exposure', 'hazard']

    layer_purpose = [p for p in layer_purposes if p in layer.keywords]

    if not layer_purpose:
        return None

    layer_purpose = layer_purpose[0]

    return definition(layer.keywords[layer_purpose])
Пример #11
0
    def set_widgets(self):
        """Set widgets on the Hazard Category tab."""
        self.clear_further_steps()
        # Set widgets
        self.lstHazardCategories.clear()
        self.lblDescribeHazardCategory.setText('')
        self.lblSelectHazardCategory.setText(hazard_category_question)
        hazard_categories = self.hazard_categories_for_layer()
        for hazard_category in hazard_categories:
            if not isinstance(hazard_category, dict):
                # noinspection PyTypeChecker
                hazard_category = definition(hazard_category)
            # noinspection PyTypeChecker
            item = QListWidgetItem(hazard_category['name'],
                                   self.lstHazardCategories)
            # noinspection PyTypeChecker
            item.setData(QtCore.Qt.UserRole, hazard_category['key'])
            self.lstHazardCategories.addItem(item)

        # Set values based on existing keywords (if already assigned)
        category_keyword = self.parent.get_existing_keyword('hazard_category')
        if category_keyword:
            categories = []
            for index in range(self.lstHazardCategories.count()):
                item = self.lstHazardCategories.item(index)
                categories.append(item.data(QtCore.Qt.UserRole))
            if category_keyword in categories:
                self.lstHazardCategories.setCurrentRow(
                    categories.index(category_keyword))

        self.auto_select_one_item(self.lstHazardCategories)
Пример #12
0
    def set_widgets(self):
        """Set widgets on the Hazard Category tab."""
        self.clear_further_steps()
        # Set widgets
        self.lstHazardCategories.clear()
        self.lblDescribeHazardCategory.setText('')
        self.lblSelectHazardCategory.setText(
            hazard_category_question)
        hazard_categories = self.hazard_categories_for_layer()
        for hazard_category in hazard_categories:
            if not isinstance(hazard_category, dict):
                # noinspection PyTypeChecker
                hazard_category = definition(hazard_category)
            # noinspection PyTypeChecker
            item = QListWidgetItem(
                hazard_category['name'],
                self.lstHazardCategories)
            # noinspection PyTypeChecker
            item.setData(QtCore.Qt.UserRole, hazard_category['key'])
            self.lstHazardCategories.addItem(item)

        # Set values based on existing keywords (if already assigned)
        category_keyword = self.parent.get_existing_keyword('hazard_category')
        if category_keyword:
            categories = []
            for index in range(self.lstHazardCategories.count()):
                item = self.lstHazardCategories.item(index)
                categories.append(item.data(QtCore.Qt.UserRole))
            if category_keyword in categories:
                self.lstHazardCategories.setCurrentRow(
                    categories.index(category_keyword))

        self.auto_select_one_item(self.lstHazardCategories)
Пример #13
0
def get_inasafe_default_value_qsetting(qsetting, category, inasafe_field_key):
    """Helper method to get the inasafe default value from qsetting.

    :param qsetting: QSetting.
    :type qsetting: QSetting

    :param category: Category of the default value. It can be global or
        recent. Global means the global setting for default value. Recent
        means the last set custom for default value from the user.
    :type category: str

    :param inasafe_field_key: Key for the field.
    :type inasafe_field_key: str

    :returns: Value of the inasafe_default_value.
    :rtype: float
    """
    key = 'inasafe/default_value/%s/%s' % (category, inasafe_field_key)
    default_value = qsetting.value(key)
    if default_value is None:
        if category == GLOBAL:
            # If empty for global setting, use default one.
            inasafe_field = definition(inasafe_field_key)
            default_value = inasafe_field.get('default_value', {})
            return default_value.get('default_value', zero_default_value)

        return zero_default_value
    try:
        return float(default_value)
    except ValueError:
        return zero_default_value
Пример #14
0
    def test_analysis_earthquake_summary(self):
        """Test we can compute summary after an EQ on population."""
        hazard = load_test_raster_layer('gisv4', 'hazard', 'earthquake.asc')
        exposure = load_test_raster_layer(
            'gisv4', 'exposure', 'raster', 'population.asc')
        aggregation = load_test_vector_layer(
            'gisv4', 'aggregation', 'small_grid.geojson')

        impact_function = ImpactFunction()
        impact_function.hazard = hazard
        impact_function.exposure = exposure
        impact_function.aggregation = aggregation
        status, message = impact_function.prepare()
        self.assertEqual(PREPARE_SUCCESS, status, message)
        status, message = impact_function.run()
        self.assertEqual(ANALYSIS_SUCCESS, status, message)

        layer = impact_function.analysis_impacted
        classification = hazard.keywords['classification']
        classes = definition(classification)['classes']
        for hazard_class in classes:
            field_name = hazard_count_field['field_name'] % hazard_class['key']
            message = '%s is not found in the EQ summary layer.' % field_name
            self.assertNotEqual(-1, layer.fieldNameIndex(field_name), message)

        check_inasafe_fields(impact_function.analysis_impacted)
        check_inasafe_fields(impact_function.aggregation_summary)
Пример #15
0
    def test_analysis_earthquake_summary(self):
        """Test we can compute summary after an EQ on population."""
        hazard = load_test_raster_layer('gisv4', 'hazard', 'earthquake.asc')
        exposure = load_test_raster_layer('gisv4', 'exposure', 'raster',
                                          'population.asc')
        aggregation = load_test_vector_layer('gisv4', 'aggregation',
                                             'small_grid.geojson')

        impact_function = ImpactFunction()
        impact_function.hazard = hazard
        impact_function.exposure = exposure
        impact_function.aggregation = aggregation
        status, message = impact_function.prepare()
        self.assertEqual(PREPARE_SUCCESS, status, message)
        status, message = impact_function.run()
        self.assertEqual(ANALYSIS_SUCCESS, status, message)

        layer = impact_function.analysis_impacted
        classification = hazard.keywords['classification']
        classes = definition(classification)['classes']
        for hazard_class in classes:
            field_name = hazard_count_field['field_name'] % hazard_class['key']
            message = '%s is not found in the EQ summary layer.' % field_name
            self.assertNotEqual(-1, layer.fieldNameIndex(field_name), message)

        check_inasafe_fields(impact_function.analysis_impacted)
        check_inasafe_fields(impact_function.aggregation_summary)
Пример #16
0
def get_inasafe_default_value_qsetting(
        qsetting, category, inasafe_field_key):
    """Helper method to get the inasafe default value from qsetting.

    :param qsetting: QSetting.
    :type qsetting: QSetting

    :param category: Category of the default value. It can be global or
        recent. Global means the global setting for default value. Recent
        means the last set custom for default value from the user.
    :type category: str

    :param inasafe_field_key: Key for the field.
    :type inasafe_field_key: str

    :returns: Value of the inasafe_default_value.
    :rtype: float
    """
    key = 'inasafe/default_value/%s/%s' % (category, inasafe_field_key)
    default_value = qsetting.value(key)
    if default_value is None:
        if category == GLOBAL:
            # If empty for global setting, use default one.
            inasafe_field = definition(inasafe_field_key)
            default_value = inasafe_field.get('default_value', {})
            return default_value.get('default_value', zero_default_value)

        return zero_default_value
    try:
        return float(default_value)
    except ValueError:
        return zero_default_value
    def set_widgets(self):
        """Set widgets on the Classification tab."""
        self.clear_further_steps()
        purpose = self.parent.step_kw_purpose.selected_purpose()['name']
        subcategory = self.parent.step_kw_subcategory.\
            selected_subcategory()['name']
        self.lstClassifications.clear()
        self.lblDescribeClassification.setText('')
        self.lblSelectClassification.setText(
            classification_question % (subcategory, purpose))
        classifications = self.classifications_for_layer()
        for classification in classifications:
            if not isinstance(classification, dict):
                classification = definition(classification)
            item = QListWidgetItem(
                classification['name'],
                self.lstClassifications)
            item.setData(QtCore.Qt.UserRole, classification['key'])
            self.lstClassifications.addItem(item)

        # Set values based on existing keywords (if already assigned)
        classification_keyword = self.parent.get_existing_keyword(
            'classification')
        if classification_keyword:
            classifications = []
            for index in xrange(self.lstClassifications.count()):
                item = self.lstClassifications.item(index)
                classifications.append(item.data(QtCore.Qt.UserRole))
            if classification_keyword in classifications:
                self.lstClassifications.setCurrentRow(
                    classifications.index(classification_keyword))

        self.auto_select_one_item(self.lstClassifications)
Пример #18
0
def hazard_extra_keyword(keyword, feature, parent):
    """Given a keyword, it will return the value of the keyword
    from the hazard layer's extra keywords.

    For instance:
    *   hazard_extra_keyword( 'depth' ) -> will return the value of 'depth'
        in current hazard layer's extra keywords.
    """
    _ = feature, parent  # NOQA
    hazard_layer_path = QgsExpressionContextUtils. \
        projectScope(QgsProject.instance()).variable(
          'hazard_layer')
    hazard_layer = load_layer(hazard_layer_path)[0]
    keywords = KeywordIO.read_keywords(hazard_layer)
    extra_keywords = keywords.get('extra_keywords')
    if extra_keywords:
        value = extra_keywords.get(keyword)
        if value:
            value_definition = definition(value)
            if value_definition:
                return value_definition['name']
            return value
        else:
            return tr('Keyword %s is not found' % keyword)
    return tr('No extra keywords found')
Пример #19
0
    def _populate_reporting_tab(self):
        """Populate trees about layers."""
        self.tree.clear()
        self.add_layer.setEnabled(False)
        self.remove_layer.setEnabled(False)
        self.move_up.setEnabled(False)
        self.move_down.setEnabled(False)
        self.tree.setColumnCount(1)
        self.tree.setRootIsDecorated(False)
        self.tree.setHeaderHidden(True)

        analysis_branch = QTreeWidgetItem(self.tree.invisibleRootItem(),
                                          [FROM_ANALYSIS['name']])
        analysis_branch.setFont(0, bold_font)
        analysis_branch.setExpanded(True)
        analysis_branch.setFlags(Qt.ItemIsEnabled)

        if self._multi_exposure_if:
            expected = self._multi_exposure_if.output_layers_expected()
            for group, layers in list(expected.items()):
                group_branch = QTreeWidgetItem(analysis_branch, [group])
                group_branch.setFont(0, bold_font)
                group_branch.setExpanded(True)
                group_branch.setFlags(Qt.ItemIsEnabled)

                for layer in layers:
                    layer = definition(layer)
                    if layer.get('allowed_geometries', None):
                        item = QTreeWidgetItem(group_branch,
                                               [layer.get('name')])
                        item.setData(0, LAYER_ORIGIN_ROLE,
                                     FROM_ANALYSIS['key'])
                        item.setData(0, LAYER_PARENT_ANALYSIS_ROLE, group)
                        item.setData(0, LAYER_PURPOSE_KEY_OR_ID_ROLE,
                                     layer['key'])
                        item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)

        canvas_branch = QTreeWidgetItem(self.tree.invisibleRootItem(),
                                        [FROM_CANVAS['name']])
        canvas_branch.setFont(0, bold_font)
        canvas_branch.setExpanded(True)
        canvas_branch.setFlags(Qt.ItemIsEnabled)

        # List layers from the canvas
        loaded_layers = list(QgsProject.instance().mapLayers().values())
        canvas_layers = self.iface.mapCanvas().layers()
        flag = setting('visibleLayersOnlyFlag', expected_type=bool)
        for loaded_layer in loaded_layers:
            if flag and loaded_layer not in canvas_layers:
                continue

            title = loaded_layer.name()
            item = QTreeWidgetItem(canvas_branch, [title])
            item.setData(0, LAYER_ORIGIN_ROLE, FROM_CANVAS['key'])
            item.setData(0, LAYER_PURPOSE_KEY_OR_ID_ROLE, loaded_layer.id())
            item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)

        self.tree.resizeColumnToContents(0)
Пример #20
0
    def test_definition(self):
        """Test we can get definitions for keywords.

        .. versionadded:: 3.2

        """
        keyword = 'hazards'
        keyword_definition = definition(keyword)
        self.assertTrue('description' in keyword_definition)
Пример #21
0
    def test_definition(self):
        """Test we can get definitions for keywords.

        .. versionadded:: 3.2

        """
        keyword = 'hazards'
        keyword_definition = definition(keyword)
        self.assertTrue('description' in keyword_definition)
Пример #22
0
 def selected_layermode(self):
     """Obtain the layer mode selected by user.
     :returns: selected layer mode.
     :rtype: string, None
     """
     item = self.lstLayerModes.currentItem()
     try:
         return definition(item.data(QtCore.Qt.UserRole))
     except (AttributeError, NameError):
         return None
Пример #23
0
 def selected_layermode(self):
     """Obtain the layer mode selected by user.
     :returns: selected layer mode.
     :rtype: string, None
     """
     item = self.lstLayerModes.currentItem()
     try:
         return definition(item.data(QtCore.Qt.UserRole))
     except (AttributeError, NameError):
         return None
Пример #24
0
def sum_fields(layer, output_field_key, input_fields):
    """Sum the value of input_fields and put it as output_field.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer

    :param output_field_key: The output field definition key.
    :type output_field_key: basestring

    :param input_fields: List of input fields' name.
    :type input_fields: list
    """
    field_definition = definition(output_field_key)
    output_field_name = field_definition['field_name']
    # If the fields only has one element
    if len(input_fields) == 1:
        # Name is different, copy it
        if input_fields[0] != output_field_name:
            to_rename = {input_fields[0]: output_field_name}
            # We copy only, it will be deleted later.
            # We can't rename the field, we need to copy it as the same
            # field might be used many times in the FMT tool.
            copy_fields(layer, to_rename)
        else:
            # Name is same, do nothing
            return
    else:
        # Creating expression
        # Put field name in a double quote. See #4248
        input_fields = ['"%s"' % f for f in input_fields]
        string_expression = ' + '.join(input_fields)
        sum_expression = QgsExpression(string_expression)
        context = QgsExpressionContext()
        context.setFields(layer.pendingFields())
        sum_expression.prepare(context)

        # Get the output field index
        output_idx = layer.fieldNameIndex(output_field_name)
        # Output index is not found
        if output_idx == -1:
            output_field = create_field_from_definition(field_definition)
            layer.startEditing()
            layer.addAttribute(output_field)
            layer.commitChanges()
            output_idx = layer.fieldNameIndex(output_field_name)

        layer.startEditing()
        # Iterate to all features
        for feature in layer.getFeatures():
            context.setFeature(feature)
            result = sum_expression.evaluate(context)
            feature[output_idx] = result
            layer.updateFeature(feature)

        layer.commitChanges()
    def selected_classification(self):
        """Obtain the classification selected by user.

        :returns: Metadata of the selected classification.
        :rtype: dict, None
        """
        item = self.lstClassifications.currentItem()
        try:
            return definition(item.data(QtCore.Qt.UserRole))
        except (AttributeError, NameError):
            return None
Пример #26
0
    def selected_unit(self):
        """Obtain the unit selected by user.

        :returns: Metadata of the selected unit.
        :rtype: dict, None
        """
        item = self.lstUnits.currentItem()
        try:
            return definition(item.data(QtCore.Qt.UserRole))
        except (AttributeError, NameError):
            return None
Пример #27
0
    def selected_subcategory(self):
        """Obtain the subcategory selected by user.

        :returns: Metadata of the selected subcategory.
        :rtype: dict, None
        """
        item = self.lstSubcategories.currentItem()
        try:
            return definition(item.data(QtCore.Qt.UserRole))
        except (AttributeError, NameError):
            return None
Пример #28
0
    def selected_unit(self):
        """Obtain the unit selected by user.

        :returns: Metadata of the selected unit.
        :rtype: dict, None
        """
        item = self.lstUnits.currentItem()
        try:
            return definition(item.data(QtCore.Qt.UserRole))
        except (AttributeError, NameError):
            return None
    def selected_classification(self):
        """Obtain the classification selected by user.

        :returns: Metadata of the selected classification.
        :rtype: dict, None
        """
        item = self.lstClassifications.currentItem()
        try:
            return definition(item.data(QtCore.Qt.UserRole))
        except (AttributeError, NameError):
            return None
Пример #30
0
    def selected_purpose(self):
        """Obtain the layer purpose selected by user.

        :returns: Metadata of the selected layer purpose.
        :rtype: dict, None
        """
        item = self.lstCategories.currentItem()
        try:
            return definition(item.data(QtCore.Qt.UserRole))
        except (AttributeError, NameError):
            return None
Пример #31
0
    def selected_hazard_category(self):
        """Obtain the hazard category selected by user.

        :returns: Metadata of the selected hazard category.
        :rtype: dict, None
        """
        item = self.lstHazardCategories.currentItem()
        try:
            return definition(item.data(QtCore.Qt.UserRole))
        except (AttributeError, NameError):
            return None
Пример #32
0
def layer_title(layer):
    """Set the layer title according to the standards.

    :param layer: The layer to style.
    :type layer: QgsVectorLayer
    """
    exposure_type = layer.keywords['exposure_keywords']['exposure']
    exposure_definitions = definition(exposure_type)
    title = exposure_definitions['layer_legend_title']
    layer.setTitle(title)
    layer.keywords['title'] = title
Пример #33
0
def layer_title(layer):
    """Set the layer title according to the standards.

    :param layer: The layer to style.
    :type layer: QgsVectorLayer
    """
    exposure_type = layer.keywords['exposure_keywords']['exposure']
    exposure_definitions = definition(exposure_type)
    title = exposure_definitions['layer_legend_title']
    layer.setTitle(title)
    layer.keywords['title'] = title
Пример #34
0
def sum_fields(layer, output_field_key, input_fields):
    """Sum the value of input_fields and put it as output_field.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer

    :param output_field_key: The output field definition key.
    :type output_field_key: basestring

    :param input_fields: List of input fields' name.
    :type input_fields: list
    """
    field_definition = definition(output_field_key)
    output_field_name = field_definition['field_name']
    # If the fields only has one element
    if len(input_fields) == 1:
        # Name is different, copy it
        if input_fields[0] != output_field_name:
            to_rename = {input_fields[0]: output_field_name}
            # We copy only, it will be deleted later.
            # We can't rename the field, we need to copy it as the same
            # field might be used many times in the FMT tool.
            copy_fields(layer, to_rename)
        else:
            # Name is same, do nothing
            return
    else:
        # Creating expression
        # Put field name in a double quote. See #4248
        input_fields = ['"%s"' % f for f in input_fields]
        string_expression = ' + '.join(input_fields)
        sum_expression = QgsExpression(string_expression)
        context = QgsExpressionContext()
        context.setFields(layer.fields())
        sum_expression.prepare(context)

        # Get the output field index
        output_idx = layer.fields().lookupField(output_field_name)
        # Output index is not found
        layer.startEditing()
        if output_idx == -1:
            output_field = create_field_from_definition(field_definition)
            layer.addAttribute(output_field)
            output_idx = layer.fields().lookupField(output_field_name)

        # Iterate to all features
        for feature in layer.getFeatures():
            context.setFeature(feature)
            result = sum_expression.evaluate(context)
            feature[output_idx] = result
            layer.updateFeature(feature)

        layer.commitChanges()
Пример #35
0
def add_fields(
        layer, absolute_values, static_fields, dynamic_structure):
    """Function to add fields needed in the output layer.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer

    :param absolute_values: The absolute value structure.
    :type absolute_values: dict

    :param static_fields: The list of static fields to add.
    :type static_fields: list

    :param dynamic_structure: The list of dynamic fields to add to the layer.
    The list must be structured like this:
    dynamic_structure = [
        [exposure_count_field, unique_exposure]
    ]
    where "exposure_count_field" is the dynamic to field to add and
    "unique_exposure" is the list of unique values to associate with this
    dynamic field. Because dynamic_structure is a ordered list, you can add
    many dynamic fields.
    :type dynamic_structure: list
    """
    for new_dynamic_field in dynamic_structure:
        field_definition = new_dynamic_field[0]
        unique_values = new_dynamic_field[1]
        for column in unique_values:
            if (column == ''
                    or (hasattr(column, 'isNull')
                        and column.isNull())):
                column = 'NULL'
            field = create_field_from_definition(field_definition, column)
            layer.addAttribute(field)
            key = field_definition['key'] % column
            value = field_definition['field_name'] % column
            layer.keywords['inasafe_fields'][key] = value

    for static_field in static_fields:
        field = create_field_from_definition(static_field)
        layer.addAttribute(field)
        # noinspection PyTypeChecker
        layer.keywords['inasafe_fields'][static_field['key']] = (
            static_field['field_name'])

    # For each absolute values
    for absolute_field in list(absolute_values.keys()):
        field_definition = definition(absolute_values[absolute_field][1])
        field = create_field_from_definition(field_definition)
        layer.addAttribute(field)
        key = field_definition['key']
        value = field_definition['field_name']
        layer.keywords['inasafe_fields'][key] = value
Пример #36
0
def add_fields(
        layer, absolute_values, static_fields, dynamic_structure):
    """Function to add fields needed in the output layer.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer

    :param absolute_values: The absolute value structure.
    :type absolute_values: dict

    :param static_fields: The list of static fields to add.
    :type static_fields: list

    :param dynamic_structure: The list of dynamic fields to add to the layer.
    The list must be structured like this:
    dynamic_structure = [
        [exposure_count_field, unique_exposure]
    ]
    where "exposure_count_field" is the dynamic to field to add and
    "unique_exposure" is the list of unique values to associate with this
    dynamic field. Because dynamic_structure is a ordered list, you can add
    many dynamic fields.
    :type dynamic_structure: list
    """
    for new_dynamic_field in dynamic_structure:
        field_definition = new_dynamic_field[0]
        unique_values = new_dynamic_field[1]
        for column in unique_values:
            if (column == ''
                    or (hasattr(column, 'isNull')
                        and column.isNull())):
                column = 'NULL'
            field = create_field_from_definition(field_definition, column)
            layer.addAttribute(field)
            key = field_definition['key'] % column
            value = field_definition['field_name'] % column
            layer.keywords['inasafe_fields'][key] = value

    for static_field in static_fields:
        field = create_field_from_definition(static_field)
        layer.addAttribute(field)
        # noinspection PyTypeChecker
        layer.keywords['inasafe_fields'][static_field['key']] = (
            static_field['field_name'])

    # For each absolute values
    for absolute_field in list(absolute_values.keys()):
        field_definition = definition(absolute_values[absolute_field][1])
        field = create_field_from_definition(field_definition)
        layer.addAttribute(field)
        key = field_definition['key']
        value = field_definition['field_name']
        layer.keywords['inasafe_fields'][key] = value
Пример #37
0
def sum_fields(layer, output_field_key, input_fields):
    """Sum the value of input_fields and put it as output_field.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer

    :param output_field_key: The output field definition key.
    :type output_field_key: basestring

    :param input_fields: List of input fields' name.
    :type input_fields: list
    """
    field_definition = definition(output_field_key)
    output_field_name = field_definition['field_name']
    # If the fields only has one element
    if len(input_fields) == 1:
        # Name is different, copy it
        if input_fields[0] != output_field_name:
            copy_fields(layer, {
                input_fields[0]: output_field_name})
        # Name is same, do nothing
        else:
            return
    else:
        # Creating expression
        # Put field name in a double quote. See #4248
        input_fields = ['"%s"' % f for f in input_fields]
        string_expression = ' + '.join(input_fields)
        sum_expression = QgsExpression(string_expression)
        context = QgsExpressionContext()
        context.setFields(layer.pendingFields())
        sum_expression.prepare(context)

        # Get the output field index
        output_idx = layer.fieldNameIndex(output_field_name)
        # Output index is not found
        if output_idx == -1:
            output_field = create_field_from_definition(field_definition)
            layer.startEditing()
            layer.addAttribute(output_field)
            layer.commitChanges()
            output_idx = layer.fieldNameIndex(output_field_name)

        layer.startEditing()
        # Iterate to all features
        for feature in layer.getFeatures():
            context.setFeature(feature)
            result = sum_expression.evaluate(context)
            feature[output_idx] = result
            layer.updateFeature(feature)

        layer.commitChanges()
Пример #38
0
def _check_value_mapping(layer, exposure_key=None):
    """Loop over the exposure type field and check if the value map is correct.

    :param layer: The layer
    :type layer: QgsVectorLayer

    :param exposure_key: The exposure key.
    :type exposure_key: str
    """
    index = layer.fieldNameIndex(exposure_type_field['field_name'])
    unique_exposure = layer.uniqueValues(index)
    if layer.keywords['layer_purpose'] == layer_purpose_hazard['key']:
        if not exposure_key:
            message = tr('Hazard value mapping missing exposure key.')
            raise InvalidKeywordsForProcessingAlgorithm(message)
        value_map = active_thresholds_value_maps(layer.keywords, exposure_key)
    else:
        value_map = layer.keywords.get('value_map')

    if not value_map:
        # The exposure do not have a value_map, we can skip the layer.
        return layer

    if layer.keywords['layer_purpose'] == layer_purpose_hazard['key']:
        if not exposure_key:
            message = tr('Hazard classification is missing exposure key.')
            raise InvalidKeywordsForProcessingAlgorithm(message)
        classification = active_classification(layer.keywords, exposure_key)
    else:
        classification = layer.keywords['classification']

    exposure_classification = definition(classification)

    other = None
    if exposure_classification['key'] != 'data_driven_classes':
        other = exposure_classification['classes'][-1]['key']

    exposure_mapped = []
    for group in value_map.itervalues():
        exposure_mapped.extend(group)

    diff = list(set(unique_exposure) - set(exposure_mapped))

    if other in value_map.keys():
        value_map[other].extend(diff)
    else:
        value_map[other] = diff

    layer.keywords['value_map'] = value_map
    layer.keywords['classification'] = classification
    return layer
Пример #39
0
def _check_value_mapping(layer, exposure_key=None):
    """Loop over the exposure type field and check if the value map is correct.

    :param layer: The layer
    :type layer: QgsVectorLayer

    :param exposure_key: The exposure key.
    :type exposure_key: str
    """
    index = layer.fields().lookupField(exposure_type_field['field_name'])
    unique_exposure = layer.uniqueValues(index)
    if layer.keywords['layer_purpose'] == layer_purpose_hazard['key']:
        if not exposure_key:
            message = tr('Hazard value mapping missing exposure key.')
            raise InvalidKeywordsForProcessingAlgorithm(message)
        value_map = active_thresholds_value_maps(layer.keywords, exposure_key)
    else:
        value_map = layer.keywords.get('value_map')

    if not value_map:
        # The exposure do not have a value_map, we can skip the layer.
        return layer

    if layer.keywords['layer_purpose'] == layer_purpose_hazard['key']:
        if not exposure_key:
            message = tr('Hazard classification is missing exposure key.')
            raise InvalidKeywordsForProcessingAlgorithm(message)
        classification = active_classification(layer.keywords, exposure_key)
    else:
        classification = layer.keywords['classification']

    exposure_classification = definition(classification)

    other = None
    if exposure_classification['key'] != data_driven_classes['key']:
        other = exposure_classification['classes'][-1]['key']

    exposure_mapped = []
    for group in list(value_map.values()):
        exposure_mapped.extend(group)

    diff = list(unique_exposure - set(exposure_mapped))

    if other in list(value_map.keys()):
        value_map[other].extend(diff)
    else:
        value_map[other] = diff

    layer.keywords['value_map'] = value_map
    layer.keywords['classification'] = classification
    return layer
Пример #40
0
def add_debug_layers_to_canvas(impact_function):
    """Helper method to add debug layers to QGIS from impact function.

    :param impact_function: The impact function used.
    :type impact_function: ImpactFunction
    """
    name = 'DEBUG %s' % impact_function.name
    root = QgsProject.instance().layerTreeRoot()
    group_debug = root.insertGroup(0, name)
    group_debug.setItemVisibilityChecked(False)
    group_debug.setExpanded(False)
    hazard_keywords = impact_function.provenance['hazard_keywords']
    exposure_keywords = impact_function.provenance['exposure_keywords']

    # Let's style the hazard class in each layers.
    # noinspection PyBroadException
    try:
        classification = active_classification(
            hazard_keywords, exposure_keywords['exposure'])
        classification = definition(classification)

        classes = OrderedDict()
        for f in reversed(classification['classes']):
            classes[f['key']] = (f['color'], f['name'])
        hazard_class = hazard_class_field['key']
    except BaseException:
        # We might not have a classification. But this is the debug group so
        # let's not raise a new exception.
        classification = None

    datastore = impact_function.datastore
    for layer in datastore.layers():
        qgis_layer = datastore.layer(layer)
        if not isinstance(qgis_layer, QgsMapLayer):
            continue
        QgsProject.instance().addMapLayer(
            qgis_layer, False)
        layer_node = group_debug.insertLayer(0, qgis_layer)
        layer_node.setItemVisibilityChecked(False)
        layer_node.setExpanded(False)

        # Let's style layers which have a geometry and have
        # hazard_class
        if qgis_layer.type() == QgsMapLayer.VectorLayer:
            if qgis_layer.geometryType() not in [
                        QgsWkbTypes.NullGeometry,
                        QgsWkbTypes.UnknownGeometry
                    ] and classification: # noqa
                if qgis_layer.keywords['inasafe_fields'].get(hazard_class):
                    hazard_class_style(qgis_layer, classes, True)
Пример #41
0
def add_debug_layers_to_canvas(impact_function):
    """Helper method to add debug layers to QGIS from impact function.

    :param impact_function: The impact function used.
    :type impact_function: ImpactFunction
    """
    name = 'DEBUG %s' % impact_function.name
    root = QgsProject.instance().layerTreeRoot()
    group_debug = root.insertGroup(0, name)
    group_debug.setItemVisibilityChecked(False)
    group_debug.setExpanded(False)
    hazard_keywords = impact_function.provenance['hazard_keywords']
    exposure_keywords = impact_function.provenance['exposure_keywords']

    # Let's style the hazard class in each layers.
    # noinspection PyBroadException
    try:
        classification = active_classification(hazard_keywords,
                                               exposure_keywords['exposure'])
        classification = definition(classification)

        classes = OrderedDict()
        for f in reversed(classification['classes']):
            classes[f['key']] = (f['color'], f['name'])
        hazard_class = hazard_class_field['key']
    except BaseException:
        # We might not have a classification. But this is the debug group so
        # let's not raise a new exception.
        classification = None

    datastore = impact_function.datastore
    for layer in datastore.layers():
        qgis_layer = datastore.layer(layer)
        if not isinstance(qgis_layer, QgsMapLayer):
            continue
        QgsProject.instance().addMapLayer(qgis_layer, False)
        layer_node = group_debug.insertLayer(0, qgis_layer)
        layer_node.setItemVisibilityChecked(False)
        layer_node.setExpanded(False)

        # Let's style layers which have a geometry and have
        # hazard_class
        not_allowed_geom = [
            QgsWkbTypes.NullGeometry, QgsWkbTypes.UnknownGeometry
        ]
        if qgis_layer.type() == QgsMapLayer.VectorLayer:
            if qgis_layer.geometryType() not in not_allowed_geom \
                    and classification: # noqa
                if qgis_layer.keywords['inasafe_fields'].get(hazard_class):
                    hazard_class_style(qgis_layer, classes, True)
Пример #42
0
    def test_title(self):
        """Test we can set the layer title correctly."""
        layer = load_test_vector_layer('impact',
                                       'buildings_without_style.geojson')

        layer_title(layer)

        # The code tested is running the same logic as the test itself.
        # But at least we have a test.
        exposure_type = layer.keywords['exposure_keywords']['exposure']
        exposure_definitions = definition(exposure_type)
        title = exposure_definitions['layer_legend_title']
        layer.setTitle(title)
        self.assertEqual(title, layer.title())
Пример #43
0
    def test_title(self):
        """Test we can set the layer title correctly."""
        layer = load_test_vector_layer(
            'impact', 'buildings_without_style.geojson')

        layer_title(layer)

        # The code tested is running the same logic as the test itself.
        # But at least we have a test.
        exposure_type = layer.keywords['exposure_keywords']['exposure']
        exposure_definitions = definition(exposure_type)
        title = exposure_definitions['layer_legend_title']
        layer.setTitle(title)
        self.assertEqual(title, layer.title())
Пример #44
0
def add_fields(
        layer, absolute_values, static_fields, dynamic_values, dynamic_field):
    """Function to add fields needed in the output layer.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer

    :param absolute_values: The absolute value structure.
    :type absolute_values: dict

    :param static_fields: The list of static fields to add.
    :type static_fields: list

    :param dynamic_values: The list of unique field to create.
    :type dynamic_values: list

    :param dynamic_field: The dynamic field to add.
    :type dynamic_field: safe.definitions.fields

    :param static_fields
    """
    for column in dynamic_values:
        if not column or isinstance(column, QPyNullVariant):
            column = 'NULL'
        field = create_field_from_definition(dynamic_field, column)
        layer.addAttribute(field)
        key = dynamic_field['key'] % column
        value = dynamic_field['field_name'] % column
        layer.keywords['inasafe_fields'][key] = value

    for static_field in static_fields:
        field = create_field_from_definition(static_field)
        layer.addAttribute(field)
        # noinspection PyTypeChecker
        layer.keywords['inasafe_fields'][static_field['key']] = (
            static_field['field_name'])

    # For each absolute values
    for absolute_field in absolute_values.iterkeys():
        field_definition = definition(absolute_values[absolute_field][1])
        field = create_field_from_definition(field_definition)
        layer.addAttribute(field)
        key = field_definition['key']
        value = field_definition['field_name']
        layer.keywords['inasafe_fields'][key] = value
Пример #45
0
def add_debug_layers_to_canvas(impact_function):
    """Helper method to add debug layers to QGIS from impact function.

    :param impact_function: The impact function used.
    :type impact_function: ImpactFunction
    """
    name = 'DEBUG %s' % impact_function.name
    root = QgsProject.instance().layerTreeRoot()
    group_debug = root.insertGroup(0, name)
    group_debug.setVisible(Qt.Unchecked)
    group_debug.setExpanded(False)

    # Let's style the hazard class in each layers.
    # noinspection PyBroadException
    try:
        classification = (
            impact_function.hazard.keywords['classification'])
        classification = definition(classification)

        classes = OrderedDict()
        for f in reversed(classification['classes']):
            classes[f['key']] = (f['color'], f['name'])
        hazard_class = hazard_class_field['key']
    except:
        # We might not have a classification. But this is the debug group so
        # let's not raise a new exception.
        classification = None

    datastore = impact_function.datastore
    for layer in datastore.layers():
        qgis_layer = datastore.layer(layer)
        if not isinstance(qgis_layer, QgsMapLayer):
            continue
        QgsMapLayerRegistry.instance().addMapLayer(
            qgis_layer, False)
        layer_node = group_debug.insertLayer(0, qgis_layer)
        layer_node.setVisible(Qt.Unchecked)
        layer_node.setExpanded(False)

        # Let's style layers which have a geometry and have
        # hazard_class
        if qgis_layer.type() == QgsMapLayer.VectorLayer:
            if qgis_layer.geometryType() != QGis.NoGeometry and classification:
                if qgis_layer.keywords['inasafe_fields'].get(hazard_class):
                    hazard_class_style(qgis_layer, classes, True)
Пример #46
0
def add_fields(
        layer, absolute_values, static_fields, dynamic_values, dynamic_field):
    """Function to add fields needed in the output layer.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer

    :param absolute_values: The absolute value structure.
    :type absolute_values: dict

    :param static_fields: The list of static fields to add.
    :type static_fields: list

    :param dynamic_values: The list of unique field to create.
    :type dynamic_values: list

    :param dynamic_field: The dynamic field to add.
    :type dynamic_field: safe.definitions.fields

    :param static_fields
    """
    for column in dynamic_values:
        if not column or isinstance(column, QPyNullVariant):
            column = 'NULL'
        field = create_field_from_definition(dynamic_field, column)
        layer.addAttribute(field)
        key = dynamic_field['key'] % column
        value = dynamic_field['field_name'] % column
        layer.keywords['inasafe_fields'][key] = value

    for static_field in static_fields:
        field = create_field_from_definition(static_field)
        layer.addAttribute(field)
        # noinspection PyTypeChecker
        layer.keywords['inasafe_fields'][static_field['key']] = (
            static_field['field_name'])

    # For each absolute values
    for absolute_field in absolute_values.iterkeys():
        field_definition = definition(absolute_values[absolute_field][1])
        field = create_field_from_definition(field_definition)
        layer.addAttribute(field)
        key = field_definition['key']
        value = field_definition['field_name']
        layer.keywords['inasafe_fields'][key] = value
Пример #47
0
def retrieve_exposure_classes_lists(exposure_keywords):
    """Retrieve exposures classes.

    Only if the exposure has some classifications.

    :param exposure_keywords: exposure keywords
    :type exposure_keywords: dict

    :return: lists of classes used in the classifications.
    :rtype: list(dict)
    """
    # return None in case exposure doesn't have classifications
    classification = exposure_keywords.get('classification')
    if not classification:
        return None
    # retrieve classes definitions
    exposure_classifications = definition(classification)
    return exposure_classifications['classes']
Пример #48
0
def retrieve_exposure_classes_lists(exposure_keywords):
    """Retrieve exposures classes.

    Only if the exposure has some classifications.

    :param exposure_keywords: exposure keywords
    :type exposure_keywords: dict

    :return: lists of classes used in the classifications.
    :rtype: list(dict)
    """
    # return None in case exposure doesn't have classifications
    classification = exposure_keywords.get('classification')
    if not classification:
        return None
    # retrieve classes definitions
    exposure_classifications = definition(classification)
    return exposure_classifications['classes']
Пример #49
0
def retrieve_exposure_classes_lists(exposure_layer):
    """Retrieve exposures classes.

    Only if the exposure has some classifications.

    :param exposure_layer: exposure layer
    :type exposure_layer: qgis.core.QgsMapLayer

    :return: lists of classes used in the classifications.
    :rtype: list(dict)
    """
    # return None in case exposure doesn't have classifications
    keywords = exposure_layer.keywords
    classification = keywords.get('classification')
    if not classification:
        return None
    # retrieve classes definitions
    exposure_classifications = definition(classification)
    return exposure_classifications['classes']
Пример #50
0
def retrieve_exposure_classes_lists(exposure_layer):
    """Retrieve exposures classes.

    Only if the exposure has some classifications.

    :param exposure_layer: exposure layer
    :type exposure_layer: qgis.core.QgsMapLayer

    :return: lists of classes used in the classifications.
    :rtype: list(dict)
    """
    # return None in case exposure doesn't have classifications
    keywords = exposure_layer.keywords
    classification = keywords.get('classification')
    if not classification:
        return None
    # retrieve classes definitions
    exposure_classifications = definition(classification)
    return exposure_classifications['classes']
    def get_current_state(self):
        """Obtain current classification and value map / threshold."""
        def clean_state(dictionary):
            """Clean dictionary from bad value.

            :param dictionary: Dictionary of value maps or thresholds.
            :type dictionary: dict

            :returns: Clean state.
            :rtype: dict
            """
            clean_dictionary = {
                k: v for k, v in list(dictionary.items())
                if isinstance(v, dict)}

            return clean_dictionary

        if self.layer_mode == layer_mode_continuous:
            output = {'thresholds': clean_state(self.thresholds)}
            key = 'thresholds'
        else:
            output = {'value_maps': clean_state(self.value_maps)}
            key = 'value_maps'

        # Clean non existing hazard class key
        empty_exposure_classifications = []
        for the_exposure, the_hazard_classifications in list(
                output[key].items()):
            for the_hazard_classification in list(the_hazard_classifications.
                                                  keys()):
                invalid_classifications = []
                if not definition(the_hazard_classification):
                    invalid_classifications.append(
                        the_hazard_classification)
                for invalid_classification in invalid_classifications:
                    the_hazard_classifications.pop(invalid_classification)
            if not the_hazard_classifications:
                empty_exposure_classifications.append(the_exposure)

        for empty_exposure_classification in empty_exposure_classifications:
            output[key].pop(empty_exposure_classification)

        return output
    def get_current_state(self):
        """Obtain current classification and value map / threshold."""
        def clean_state(dictionary):
            """Clean dictionary from bad value.

            :param dictionary: Dictionary of value maps or thresholds.
            :type dictionary: dict

            :returns: Clean state.
            :rtype: dict
            """
            clean_dictionary = {
                k: v for k, v in list(dictionary.items())
                if isinstance(v, dict)}

            return clean_dictionary

        if self.layer_mode == layer_mode_continuous:
            output = {'thresholds': clean_state(self.thresholds)}
            key = 'thresholds'
        else:
            output = {'value_maps': clean_state(self.value_maps)}
            key = 'value_maps'

        # Clean non existing hazard class key
        empty_exposure_classifications = []
        for the_exposure, the_hazard_classifications in list(
                output[key].items()):
            for the_hazard_classification in list(the_hazard_classifications.
                                                  keys()):
                invalid_classifications = []
                if not definition(the_hazard_classification):
                    invalid_classifications.append(
                        the_hazard_classification)
                for invalid_classification in invalid_classifications:
                    the_hazard_classifications.pop(invalid_classification)
            if not the_hazard_classifications:
                empty_exposure_classifications.append(the_exposure)

        for empty_exposure_classification in empty_exposure_classifications:
            output[key].pop(empty_exposure_classification)

        return output
Пример #53
0
def from_mmi_to_hazard_class(mmi_level, classification_key):
    """From a MMI level, it returns the hazard class given a classification.

    :param mmi_level: The MMI level.
    :type mmi_level: int

    :param classification_key: The earthquake classification key.
    :type classification_key: safe.definitions.hazard_classifications

    :return: The hazard class key
    :rtype: basestring
    """
    classes = definition(classification_key)['classes']
    for hazard_class in classes:
        minimum = hazard_class['numeric_default_min']
        maximum = hazard_class['numeric_default_max']
        if minimum < mmi_level <= maximum:
            return hazard_class['key']
    return None
Пример #54
0
def fatality_rate(mmi_level, classification_key):
    """From a MMI level, it gives the fatality rate given a classification.

    :param mmi_level: The MMI level.
    :type mmi_level: int

    :param classification_key: The earthquake classification key.
    :type classification_key: safe.definitions.hazard_classifications

    :return: The fatality rate.
    :rtype: float
    """
    classes = definition(classification_key)['classes']
    for hazard_class in classes:
        minimum = hazard_class['numeric_default_min']
        maximum = hazard_class['numeric_default_max']
        if minimum < mmi_level <= maximum:
            return hazard_class['fatality_rate']
    return 0.0
Пример #55
0
def report_on_field(layer):
    """Helper function to set on which field we are going to report.

    The return might be empty if we don't report on a field.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer

    :return: The field index on which we should report.
    :rtype: int
    """
    source_fields = layer.keywords['inasafe_fields']
    if source_fields.get(size_field['key']):
        field_size = source_fields[size_field['key']]
        field_index = layer.fields().lookupField(field_size)
    else:
        field_index = None

    # Special case for a point layer and indivisible polygon,
    # we do not want to report on the size.
    geometry = layer.geometryType()
    exposure = layer.keywords.get('exposure')
    if geometry == QgsWkbTypes.PointGeometry:
        field_index = None
    if geometry == QgsWkbTypes.PolygonGeometry and exposure == \
            exposure_structure['key']:
        field_index = None

    # Special case if it's an exposure without classification. It means it's
    # a continuous exposure. We count the compulsory field.
    classification = layer.keywords.get('classification')
    if not classification:
        exposure_definitions = definition(exposure)
        # I take the only first field for reporting, I don't know how to manage
        # with many fields. AFAIK we don't have this case yet.
        field = exposure_definitions['compulsory_fields'][0]
        field_name = source_fields[field['key']]
        field_index = layer.fields().lookupField(field_name)

    return field_index
Пример #56
0
 def _remove_layer_clicked(self):
     """Remove layer clicked."""
     layer = self.list_layers_in_map_report.selectedItems()[0]
     origin = layer.data(LAYER_ORIGIN_ROLE)
     if origin == FROM_ANALYSIS['key']:
         key = layer.data(LAYER_PURPOSE_KEY_OR_ID_ROLE)
         parent = layer.data(LAYER_PARENT_ANALYSIS_ROLE)
         parent_item = self.tree.findItems(
             parent, Qt.MatchContains | Qt.MatchRecursive, 0)[0]
         item = QTreeWidgetItem(parent_item, [definition(key)['name']])
         item.setData(0, LAYER_PARENT_ANALYSIS_ROLE, parent)
     else:
         parent_item = self.tree.findItems(
             FROM_CANVAS['name'], Qt.MatchContains | Qt.MatchRecursive,
             0)[0]
         item = QTreeWidgetItem(parent_item, [layer.text()])
         layer_id = layer.data(LAYER_PURPOSE_KEY_OR_ID_ROLE)
         item.setData(0, LAYER_PURPOSE_KEY_OR_ID_ROLE, layer_id)
     item.setData(0, LAYER_ORIGIN_ROLE, origin)
     index = self.list_layers_in_map_report.indexFromItem(layer)
     self.list_layers_in_map_report.takeItem(index.row())
     self.list_layers_in_map_report.clearSelection()
def report_on_field(layer):
    """Helper function to set on which field we are going to report.

    The return might be empty if we don't report on a field.

    :param layer: The vector layer.
    :type layer: QgsVectorLayer

    :return: The field index on which we should report.
    :rtype: int
    """
    source_fields = layer.keywords['inasafe_fields']
    if source_fields.get(size_field['key']):
        field_size = source_fields[size_field['key']]
        field_index = layer.fieldNameIndex(field_size)
    else:
        field_index = None

    # Special case for a point layer and indivisible polygon,
    # we do not want to report on the size.
    geometry = layer.geometryType()
    exposure = layer.keywords.get('exposure')
    if geometry == QGis.Point:
        field_index = None
    if geometry == QGis.Polygon and exposure == 'structure':
        field_index = None

    # Special case if it's an exposure without classification. It means it's
    # a continuous exposure. We count the compulsory field.
    classification = layer.keywords.get('classification')
    if not classification:
        exposure_definitions = definition(exposure)
        # I take the only first field for reporting, I don't know how to manage
        # with many fields. AFAIK we don't have this case yet.
        field = exposure_definitions['compulsory_fields'][0]
        field_name = source_fields[field['key']]
        field_index = layer.fieldNameIndex(field_name)

    return field_index
Пример #58
0
def minimum_needs_unit(field, feature, parent):
    """Retrieve units of the given minimum needs field name.

    For instance:
    * minimum_needs_unit('minimum_needs__clean_water') -> 'l/weekly'
    """
    _ = feature, parent  # NOQA
    field_definition = definition(field, 'field_name')
    if field_definition:
        unit_abbreviation = None
        frequency = None
        if field_definition.get('need_parameter'):
            need = field_definition['need_parameter']
            if isinstance(need, ResourceParameter):
                unit_abbreviation = need.unit.abbreviation
                frequency = need.frequency
        elif field_definition.get('unit'):
            need_unit = field_definition.get('unit')
            unit_abbreviation = need_unit.get('abbreviation')

        if field_definition.get('frequency') and not frequency:
            frequency = field_definition.get('frequency')

        if not unit_abbreviation:
            unit_abbreviation = exposure_unit['plural_name']

        once_frequency_field_keys = [
            'minimum_needs__toilets_count_field'
        ]
        if not frequency or (
                    field_definition['key'] in once_frequency_field_keys):
            return unit_abbreviation.lower()

        unit_format = u'{unit_abbreviation}/{frequency}'
        return unit_format.format(
            unit_abbreviation=unit_abbreviation, frequency=frequency).lower()

    return None
Пример #59
0
    def set_widgets(self):
        """Set widgets on the layer purpose tab."""
        self.clear_further_steps()
        # Set widgets
        self.lstCategories.clear()
        self.lblDescribeCategory.setText('')
        self.lblIconCategory.setPixmap(QPixmap())
        self.lblSelectCategory.setText(
            category_question % self.parent.layer.name())
        purposes = self.purposes_for_layer()
        for purpose in purposes:
            if not isinstance(purpose, dict):
                purpose = definition(purpose)
            item = QListWidgetItem(purpose['name'], self.lstCategories)
            item.setData(QtCore.Qt.UserRole, purpose['key'])
            self.lstCategories.addItem(item)

        # Check if layer keywords are already assigned
        purpose_keyword = self.parent.get_existing_keyword('layer_purpose')

        # Overwrite the purpose_keyword if it's KW mode embedded in IFCW mode
        if self.parent.parent_step:
            purpose_keyword = self.parent.\
                get_parent_mode_constraints()[0]['key']

        # Set values based on existing keywords or parent mode
        if purpose_keyword:
            purposes = []
            for index in xrange(self.lstCategories.count()):
                item = self.lstCategories.item(index)
                purposes.append(item.data(QtCore.Qt.UserRole))
            if purpose_keyword in purposes:
                self.lstCategories.setCurrentRow(
                    purposes.index(purpose_keyword))

        self.auto_select_one_item(self.lstCategories)
Пример #60
0
def generate_classified_legend(
        analysis,
        exposure,
        hazard,
        debug_mode):
    """Generate an ordered python structure with the classified symbology.

    :param analysis: The analysis layer.
    :type analysis: QgsVectorLayer

    :param exposure: The exposure layer.
    :type exposure: QgsVectorLayer

    :param hazard: The hazard layer.
    :type hazard: QgsVectorLayer

    :param debug_mode: Boolean if run in debug mode.
    :type debug_mode: bool

    :return: The ordered dictionary to use to build the classified style.
    :rtype: OrderedDict
    """
    # We need to read the analysis layer to get the number of features.
    analysis_row = analysis.getFeatures().next()

    # Let's style the hazard class in each layers.
    hazard_classification = hazard.keywords['classification']
    hazard_classification = definition(hazard_classification)

    # Let's check if there is some thresholds:
    thresholds = hazard.keywords.get('thresholds')
    if thresholds:
        hazard_unit = hazard.keywords.get('continuous_hazard_unit')
        hazard_unit = definition(hazard_unit)['abbreviation']
    else:
        hazard_unit = None

    exposure = exposure.keywords['exposure']
    exposure_definitions = definition(exposure)
    exposure_units = exposure_definitions['units']
    exposure_unit = exposure_units[0]
    coefficient = 1
    # We check if can use a greater unit, such as kilometre for instance.
    if len(exposure_units) > 1:
        # We use only two units for now.
        delta = coefficient_between_units(
            exposure_units[1], exposure_units[0])

        all_values_are_greater = True

        # We check if all values are greater than the coefficient
        for i, hazard_class in enumerate(hazard_classification['classes']):
            field_name = hazard_count_field['field_name'] % hazard_class['key']
            try:
                value = analysis_row[field_name]
            except KeyError:
                value = 0

            if 0 < value < delta:
                # 0 is fine, we can still keep the second unit.
                all_values_are_greater = False

        if all_values_are_greater:
            # If yes, we can use this unit.
            exposure_unit = exposure_units[1]
            coefficient = delta

    classes = OrderedDict()

    # In debug mode we don't round number.
    enable_rounding = not debug_mode

    for i, hazard_class in enumerate(hazard_classification['classes']):
        # Get the hazard class name.
        field_name = hazard_count_field['field_name'] % hazard_class['key']

        # Get the number of affected feature by this hazard class.
        try:
            value = analysis_row[field_name]
        except KeyError:
            # The field might not exist if no feature impacted in this hazard
            # zone.
            value = 0
        value = format_number(
            value,
            enable_rounding,
            exposure_definitions['use_population_rounding'],
            coefficient)

        minimum = None
        maximum = None

        # Check if we need to add thresholds.
        if thresholds:
            if i == 0:
                minimum = thresholds[hazard_class['key']][0]
            elif i == len(hazard_classification['classes']) - 1:
                maximum = thresholds[hazard_class['key']][1]
            else:
                minimum = thresholds[hazard_class['key']][0]
                maximum = thresholds[hazard_class['key']][1]

        label = _format_label(
            hazard_class=hazard_class['name'],
            value=value,
            exposure_unit=exposure_unit['abbreviation'],
            minimum=minimum,
            maximum=maximum,
            hazard_unit=hazard_unit)

        classes[hazard_class['key']] = (hazard_class['color'], label)

    if exposure_definitions['display_not_exposed'] or debug_mode:
        classes[not_exposed_class['key']] = _add_not_exposed(
            analysis_row,
            enable_rounding,
            exposure_definitions['use_population_rounding'],
            exposure_unit['abbreviation'],
            coefficient)

    return classes