Example #1
0
def exposure_summary_layer():
    """Helper method for retrieving exposure summary layer.

    If the analysis is multi-exposure, then it will return the exposure
    summary layer from place exposure analysis.
    """
    project_context_scope = QgsExpressionContextUtils.projectScope(
        QgsProject.instance())
    project = QgsProject.instance()

    key = provenance_layer_analysis_impacted_id['provenance_key']
    analysis_summary_layer = project.mapLayer(
        project_context_scope.variable(key))
    if not analysis_summary_layer:
        key = provenance_layer_analysis_impacted['provenance_key']
        if project_context_scope.hasVariable(key):
            analysis_summary_layer = load_layer(
                project_context_scope.variable(key))[0]

    if not analysis_summary_layer:
        return None

    keywords = KeywordIO.read_keywords(analysis_summary_layer)
    extra_keywords = keywords.get(property_extra_keywords['key'], {})
    is_multi_exposure = extra_keywords.get(extra_keyword_analysis_type['key'])

    key = provenance_layer_exposure_summary_id['provenance_key']
    if is_multi_exposure:
        key = ('{provenance}__{exposure}').format(
            provenance=provenance_multi_exposure_summary_layers_id[
                'provenance_key'],
            exposure=exposure_place['key'])
    if not project_context_scope.hasVariable(key):
        return None

    exposure_summary_layer = project.mapLayer(
        project_context_scope.variable(key))
    if not exposure_summary_layer:
        key = provenance_layer_exposure_summary['provenance_key']
        if is_multi_exposure:
            key = ('{provenance}__{exposure}').format(
                provenance=provenance_multi_exposure_summary_layers[
                    'provenance_key'],
                exposure=exposure_place['key'])
        if project_context_scope.hasVariable(key):
            exposure_summary_layer = load_layer(
                project_context_scope.variable(key))[0]
        else:
            return None

    return exposure_summary_layer
Example #2
0
def exposure_summary_layer():
    """Helper method for retrieving exposure summary layer.

    If the analysis is multi-exposure, then it will return the exposure
    summary layer from place exposure analysis.
    """
    project_context_scope = QgsExpressionContextUtils.projectScope(
        QgsProject.instance())
    project = QgsProject.instance()

    key = provenance_layer_analysis_impacted_id['provenance_key']
    analysis_summary_layer = project.mapLayer(
        project_context_scope.variable(key))
    if not analysis_summary_layer:
        key = provenance_layer_analysis_impacted['provenance_key']
        if project_context_scope.hasVariable(key):
            analysis_summary_layer = load_layer(
                project_context_scope.variable(key))[0]

    if not analysis_summary_layer:
        return None

    keywords = KeywordIO.read_keywords(analysis_summary_layer)
    extra_keywords = keywords.get(property_extra_keywords['key'], {})
    is_multi_exposure = extra_keywords.get(extra_keyword_analysis_type['key'])

    key = provenance_layer_exposure_summary_id['provenance_key']
    if is_multi_exposure:
        key = ('{provenance}__{exposure}').format(
            provenance=provenance_multi_exposure_summary_layers_id[
                'provenance_key'],
            exposure=exposure_place['key'])
    if not project_context_scope.hasVariable(key):
        return None

    exposure_summary_layer = project.mapLayer(
        project_context_scope.variable(key))
    if not exposure_summary_layer:
        key = provenance_layer_exposure_summary['provenance_key']
        if is_multi_exposure:
            key = ('{provenance}__{exposure}').format(
                provenance=provenance_multi_exposure_summary_layers[
                    'provenance_key'],
                exposure=exposure_place['key'])
        if project_context_scope.hasVariable(key):
            exposure_summary_layer = load_layer(
                project_context_scope.variable(key))[0]
        else:
            return None

    return exposure_summary_layer
Example #3
0
    def test_layer_hazard_classification(self):
        """Test layer_hazard_classification method.

        .. versionadded:: 4.0
        """
        layer_paths = self.layer_paths_list
        expected_classifications = [
            generic_hazard_classes,
            earthquake_mmi_scale,
            tsunami_hazard_classes,
            cyclone_au_bom_hazard_classes,
            None,
            None,
            None,
            None,
        ]

        for layer_path, expected_classification in zip(
                layer_paths, expected_classifications):
            path = standard_data_path(*layer_path)
            layer, _ = load_layer(path)
            # inject classification keyword
            if expected_classification:
                layer.keywords['classification'] = (
                    expected_classification['key'])
            actual_classification = layer_hazard_classification(layer)
            try:
                self.assertEqual(expected_classification,
                                 actual_classification)
            except Exception as e:
                LOGGER.error('Layer path: {path}'.format(path=path))
                LOGGER.error(
                    'Expected {name}'.format(**expected_classification))
                LOGGER.error('Actual {name}'.format(**actual_classification))
                raise e
Example #4
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')
Example #5
0
    def test_retrieve_exposure_classes_lists(self):
        """Test retrieve_exposure_classes_lists method.

        .. versionadded:: 4.0
        """
        layer_paths = self.layer_paths_list
        expected_classes_lists = [
            None, None, None, None, generic_structure_classes['classes'],
            generic_structure_classes['classes'], None,
            generic_road_classes['classes']
        ]

        for layer_path, expected_classes in zip(layer_paths,
                                                expected_classes_lists):
            path = standard_data_path(*layer_path)
            layer, _ = load_layer(path)
            actual_classes = retrieve_exposure_classes_lists(layer.keywords)
            try:
                self.assertEqual(expected_classes, actual_classes)
            except Exception as e:
                LOGGER.error('Layer path: {path}'.format(path=path))
                LOGGER.error(
                    'Expected {classes}'.format(classes=expected_classes))
                LOGGER.error('Actual {classes}'.format(classes=actual_classes))
                raise e
Example #6
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')
Example #7
0
    def test_layer_definition_type(self):
        """Test layer_definition_type method.

        .. versionadded:: 4.0
        """
        layer_paths = self.layer_paths_list
        expected_definitions = [
            hazard_generic,
            hazard_earthquake,
            hazard_tsunami,
            hazard_cyclone,
            exposure_structure,
            exposure_structure,
            exposure_population,
            exposure_road,
        ]
        for layer_path, expected_definition in zip(layer_paths,
                                                   expected_definitions):
            path = standard_data_path(*layer_path)
            layer, _ = load_layer(path)
            actual_definition = layer_definition_type(layer)
            try:
                self.assertEqual(expected_definition, actual_definition)
            except Exception as e:
                LOGGER.error('Layer path: {path}'.format(path=path))
                LOGGER.error('Expected {name}'.format(**expected_definition))
                LOGGER.error('Actual {name}'.format(**actual_definition))
                raise e
Example #8
0
    def test_load_layer_from_uri(self):
        """Test we can load a layer with different parameters."""
        # Without provider
        path = standard_data_path(
            'gisv4', 'aggregation', 'small_grid.geojson')
        layer, purpose = load_layer(path)
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'small_grid')
        self.assertEqual(purpose, 'aggregation')

        layer, purpose = load_layer(path, 'foo')
        self.assertEqual(layer.name(), 'foo')

        # With internal URI
        internal_uri = full_layer_uri(layer)
        self.assertTrue(
            internal_uri.endswith('small_grid.geojson|qgis_provider=ogr'),
            internal_uri
        )
        layer, purpose = load_layer(full_layer_uri(layer))
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'small_grid')
        self.assertEqual(purpose, 'aggregation')

        # path plus extra layer parameter
        path = standard_data_path(
            'gisv4', 'aggregation', 'small_grid.geojson')
        path += '|layerid=0'
        layer, purpose = load_layer(path)
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'small_grid')
        self.assertEqual(purpose, 'aggregation')

        # CSV
        path = standard_data_path(
            'gisv4', 'impacts', 'exposure_summary_table.csv')
        layer, purpose = load_layer(path)
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'exposure_summary_table')
        self.assertEqual(purpose, 'undefined')
        self.assertEqual(len(layer.fields()), 4)
Example #9
0
    def test_load_layer_from_uri(self):
        """Test we can load a layer with different parameters."""
        # Without provider
        path = standard_data_path('gisv4', 'aggregation', 'small_grid.geojson')
        layer, purpose = load_layer(path)
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'small_grid')
        self.assertEqual(purpose, 'aggregation')

        layer, purpose = load_layer(path, 'foo')
        self.assertEqual(layer.name(), 'foo')

        # With internal URI
        internal_uri = full_layer_uri(layer)
        self.assertTrue(
            internal_uri.endswith('small_grid.geojson|qgis_provider=ogr'),
            internal_uri)
        layer, purpose = load_layer(full_layer_uri(layer))
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'small_grid')
        self.assertEqual(purpose, 'aggregation')

        # path plus extra layer parameter
        path = standard_data_path('gisv4', 'aggregation', 'small_grid.geojson')
        path += '|layerid=0'
        layer, purpose = load_layer(path)
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'small_grid')
        self.assertEqual(purpose, 'aggregation')

        # CSV
        path = standard_data_path('gisv4', 'impacts',
                                  'exposure_summary_table.csv')
        layer, purpose = load_layer(path)
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'exposure_summary_table')
        self.assertEqual(purpose, 'undefined')
        self.assertEqual(len(layer.fields()), 4)
Example #10
0
def earthquake_contour_preprocessor(impact_function):
    """Preprocessor to create contour from an earthquake

    :param impact_function: Impact function to run.
    :type impact_function: ImpactFunction

    :return: The contour layer.
    :rtype: QgsMapLayer
    """
    contour_path = create_smooth_contour(impact_function.hazard)

    if os.path.exists(contour_path):
        from safe.gis.tools import load_layer
        return load_layer(contour_path, tr('Contour'), 'ogr')[0]
Example #11
0
def earthquake_contour_preprocessor(impact_function):
    """Preprocessor to create contour from an earthquake

    :param impact_function: Impact function to run.
    :type impact_function: ImpactFunction

    :return: The contour layer.
    :rtype: QgsMapLayer
    """
    contour_path = create_smooth_contour(impact_function.hazard)

    if os.path.exists(contour_path):
        from safe.gis.tools import load_layer
        return load_layer(contour_path, tr('Contour'), 'ogr')[0]
Example #12
0
def load_layers(
        layer_list,
        clear_flag=True,
        dock=None):
    """Helper function to load layers as defined in a python list.

    :param dock: A valid dock instance.
    :type dock: Dock

    :param clear_flag: Whether to clear currently loaded layers before loading
        the new layers.
    :type clear_flag: bool

    :param layer_list: A list of layer's paths to load.
    :type layer_list: list(str)
    """
    # First unload any layers that may already be loaded
    if clear_flag:
        # noinspection PyArgumentList
        QgsProject.instance().removeAllMapLayers()

    # Now go ahead and load our layers
    exposure_layer_count = 0
    hazard_layer_count = 0
    map_layer_list = []
    # Now create our new layers
    for layer_file in layer_list:

        layer, layer_type = load_layer(layer_file)
        if layer_type == 'hazard':
            hazard_layer_count += 1
        elif layer_type == 'exposure':
            exposure_layer_count += 1

        # Add layer to the registry (that Qgis knows about) a slot
        # in qgis_interface will also ensure it gets added to the canvas

        # noinspection PyArgumentList
        map_layer_list.append(layer)

    # noinspection PyArgumentList
    QgsProject.instance().addMapLayers(map_layer_list)

    if dock is not None:
        dock.get_layers()

    # Add MCL's to the CANVAS
    return hazard_layer_count, exposure_layer_count
Example #13
0
def load_layers(
        layer_list,
        clear_flag=True,
        dock=None):
    """Helper function to load layers as defined in a python list.

    :param dock: A valid dock instance.
    :type dock: Dock

    :param clear_flag: Whether to clear currently loaded layers before loading
        the new layers.
    :type clear_flag: bool

    :param layer_list: A list of layer's paths to load.
    :type layer_list: list(str)
    """
    # First unload any layers that may already be loaded
    if clear_flag:
        # noinspection PyArgumentList
        QgsProject.instance().removeAllMapLayers()

    # Now go ahead and load our layers
    exposure_layer_count = 0
    hazard_layer_count = 0
    map_layer_list = []
    # Now create our new layers
    for layer_file in layer_list:

        layer, layer_type = load_layer(layer_file)
        if layer_type == 'hazard':
            hazard_layer_count += 1
        elif layer_type == 'exposure':
            exposure_layer_count += 1

        # Add layer to the registry (that Qgis knows about) a slot
        # in qgis_interface will also ensure it gets added to the canvas

        # noinspection PyArgumentList
        map_layer_list.append(layer)

    # noinspection PyArgumentList
    QgsProject.instance().addMapLayers(map_layer_list)

    if dock is not None:
        dock.get_layers()

    # Add MCL's to the CANVAS
    return hazard_layer_count, exposure_layer_count
Example #14
0
    def test_load_layer_from_uri(self):
        """Test we can load a layer with different parameters."""
        # Without provider
        path = standard_data_path(
            'gisv4', 'aggregation', 'small_grid.geojson')
        layer, purpose = load_layer(path)
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'small_grid')
        self.assertEqual(purpose, 'aggregation')

        layer, purpose = load_layer(path, 'foo')
        self.assertEqual(layer.name(), 'foo')

        # With internal URI
        internal_uri = full_layer_uri(layer)
        self.assertTrue(
            internal_uri.endswith('small_grid.geojson|qgis_provider=ogr'),
            internal_uri
        )
        layer, purpose = load_layer(full_layer_uri(layer))
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'small_grid')
        self.assertEqual(purpose, 'aggregation')

        # path plus extra layer parameter
        path = standard_data_path(
            'gisv4', 'aggregation', 'small_grid.geojson')
        path += '|layerid=0'
        layer, purpose = load_layer(path)
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'small_grid')
        self.assertEqual(purpose, 'aggregation')

        # CSV
        path = standard_data_path(
            'gisv4', 'impacts', 'exposure_summary_table.csv')
        layer, purpose = load_layer(path)
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'exposure_summary_table')
        self.assertEqual(purpose, 'undefined')
        self.assertEqual(len(layer.fields()), 4)

        # QLR
        # This QLR contains a file based reference layer to
        # small_grid.geojson, and it should work the same way
        # as if we load small_grid.geojson
        # In practice we could put the non file-based layer (PostGIS/WFS)
        # and load it from QLR
        path = standard_data_path(
            'gisv4', 'aggregation', 'small_grid.qlr')
        layer, purpose = load_layer(path)
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'small_grid')
        self.assertEqual(purpose, 'aggregation')
Example #15
0
    def test_load_layer_from_uri_with_postgis(self):
        """Test we can load a layer with different parameters in POSTGIS."""
        uri = ('dbname=\'stdm\' '
               'host=localhost '
               'port=5433 '
               'user=\'etienne\' '
               'sslmode=disable '
               'key=\'id\' '
               'srid=4326 '
               'type=MultiPolygon '
               'table="public"."buildings" (geom) sql=')
        layer, purpose = load_layer(uri)
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'buildings')
        self.assertEqual(purpose, 'undefined')

        expected = '"public"."buildings" (geom) sql=|qgis_provider=postgres'
        internal_uri = full_layer_uri(layer)
        self.assertTrue(internal_uri.endswith(expected), internal_uri)
Example #16
0
    def test_load_layer_from_uri_with_postgis(self):
        """Test we can load a layer with different parameters in POSTGIS."""
        uri = (
            'dbname=\'stdm\' '
            'host=localhost '
            'port=5433 '
            'user=\'etienne\' '
            'sslmode=disable '
            'key=\'id\' '
            'srid=4326 '
            'type=MultiPolygon '
            'table="public"."buildings" (geom) sql='
        )
        layer, purpose = load_layer(uri)
        self.assertTrue(layer.isValid())
        self.assertEqual(layer.name(), 'buildings')
        self.assertEqual(purpose, 'undefined')

        expected = '"public"."buildings" (geom) sql=|qgis_provider=postgres'
        internal_uri = full_layer_uri(layer)
        self.assertTrue(
            internal_uri.endswith(expected), internal_uri)
Example #17
0
def add_layers_to_canvas_with_custom_orders(
        order, impact_function, iface=None):
    """Helper to add layers to the map canvas following a specific order.

    From top to bottom in the legend:
        [
            ('FromCanvas', layer name, full layer URI, QML),
            ('FromAnalysis', layer purpose, layer group, None),
            ...
        ]

        The full layer URI is coming from our helper.

    :param order: Special structure the list of layers to add.
    :type order: list

    :param impact_function: The multi exposure impact function used.
    :type impact_function: MultiExposureImpactFunction

    :param iface: QGIS QgisAppInterface instance.
    :type iface: QgisAppInterface
    """
    root = QgsProject.instance().layerTreeRoot()
    # Make all layers hidden.
    for child in root.children():
        child.setItemVisibilityChecked(False)

    group_analysis = root.insertGroup(0, impact_function.name)
    group_analysis.setItemVisibilityChecked(True)
    group_analysis.setCustomProperty(MULTI_EXPOSURE_ANALYSIS_FLAG, True)

    # Insert layers in the good order in the group.
    for layer_definition in order:
        if layer_definition[0] == FROM_CANVAS['key']:
            style = QDomDocument()
            style.setContent(layer_definition[3])
            layer = load_layer(layer_definition[2], layer_definition[1])[0]
            layer.importNamedStyle(style)
            QgsProject.instance().addMapLayer(layer, False)
            layer_node = group_analysis.addLayer(layer)
            layer_node.setItemVisibilityChecked(True)
        else:
            if layer_definition[2] == impact_function.name:
                for layer in impact_function.outputs:
                    if layer.keywords['layer_purpose'] == layer_definition[1]:
                        QgsProject.instance().addMapLayer(
                            layer, False)
                        layer_node = group_analysis.addLayer(layer)
                        layer_node.setItemVisibilityChecked(True)
                        try:
                            title = layer.keywords['title']
                            if qgis_version() >= 21800:
                                layer.setName(title)
                            else:
                                layer.setLayerName(title)
                        except KeyError:
                            pass
                        break
            else:
                for sub_impact_function in impact_function.impact_functions:
                    # Iterate over each sub impact function used in the
                    # multi exposure analysis.
                    if sub_impact_function.name == layer_definition[2]:
                        for layer in sub_impact_function.outputs:
                            purpose = layer_definition[1]
                            if layer.keywords['layer_purpose'] == purpose:
                                QgsProject.instance().addMapLayer(
                                    layer, False)
                                layer_node = group_analysis.addLayer(
                                    layer)
                                layer_node.setItemVisibilityChecked(True)
                                try:
                                    title = layer.keywords['title']
                                    if qgis_version() >= 21800:
                                        layer.setName(title)
                                    else:
                                        layer.setLayerName(title)
                                except KeyError:
                                    pass
                                break

    if iface:
        iface.setActiveLayer(impact_function.analysis_impacted)
Example #18
0
def add_layers_to_canvas_with_custom_orders(order,
                                            impact_function,
                                            iface=None):
    """Helper to add layers to the map canvas following a specific order.

    From top to bottom in the legend:
        [
            ('FromCanvas', layer name, full layer URI, QML),
            ('FromAnalysis', layer purpose, layer group, None),
            ...
        ]

        The full layer URI is coming from our helper.

    :param order: Special structure the list of layers to add.
    :type order: list

    :param impact_function: The multi exposure impact function used.
    :type impact_function: MultiExposureImpactFunction

    :param iface: QGIS QGisAppInterface instance.
    :type iface: QGisAppInterface
    """
    root = QgsProject.instance().layerTreeRoot()
    root.setVisible(False)  # Make all layers hidden.

    group_analysis = root.insertGroup(0, impact_function.name)
    group_analysis.setVisible(Qt.Checked)
    group_analysis.setCustomProperty(MULTI_EXPOSURE_ANALYSIS_FLAG, True)

    # Insert layers in the good order in the group.
    for layer_definition in order:
        if layer_definition[0] == FROM_CANVAS['key']:
            style = QDomDocument()
            style.setContent(get_string(layer_definition[3]))
            layer = load_layer(layer_definition[2], layer_definition[1])[0]
            layer.importNamedStyle(style)
            QgsMapLayerRegistry.instance().addMapLayer(layer, False)
            layer_node = group_analysis.addLayer(layer)
            layer_node.setVisible(Qt.Checked)
        else:
            if layer_definition[2] == impact_function.name:
                for layer in impact_function.outputs:
                    if layer.keywords['layer_purpose'] == layer_definition[1]:
                        QgsMapLayerRegistry.instance().addMapLayer(
                            layer, False)
                        layer_node = group_analysis.addLayer(layer)
                        layer_node.setVisible(Qt.Checked)
                        try:
                            title = layer.keywords['title']
                            if qgis_version() >= 21800:
                                layer.setName(title)
                            else:
                                layer.setLayerName(title)
                        except KeyError:
                            pass
                        break
            else:
                for sub_impact_function in impact_function.impact_functions:
                    # Iterate over each sub impact function used in the
                    # multi exposure analysis.
                    if sub_impact_function.name == layer_definition[2]:
                        for layer in sub_impact_function.outputs:
                            purpose = layer_definition[1]
                            if layer.keywords['layer_purpose'] == purpose:
                                QgsMapLayerRegistry.instance().addMapLayer(
                                    layer, False)
                                layer_node = group_analysis.addLayer(layer)
                                layer_node.setVisible(Qt.Checked)
                                try:
                                    title = layer.keywords['title']
                                    if qgis_version() >= 21800:
                                        layer.setName(title)
                                    else:
                                        layer.setLayerName(title)
                                except KeyError:
                                    pass
                                break

    if iface:
        iface.setActiveLayer(impact_function.analysis_impacted)