Exemplo n.º 1
0
def read_layer(filename):
    """Read spatial layer from file.
    This can be either raster or vector data.
    """

    _, ext = os.path.splitext(filename)
    if ext in ['.asc', '.tif', '.nc']:
        return Raster(filename)
    elif ext in ['.shp', '.sqlite']:
        return Vector(filename)
    else:
        msg = ('Could not read %s. '
               'Extension "%s" has not been implemented' % (filename, ext))
        raise ReadLayerError(msg)
Exemplo n.º 2
0
Arquivo: core.py Projeto: vck/inasafe
def read_qgis_layer(filename):
    """Read layer from file and return as QgsMapLayer

    :param filename: the layer filename
    :type filename: str

    :return: QGIS Layer
    :rtype: QgsMapLayer
    """
    base_name, ext = os.path.splitext(filename)
    vector_extension = ['.shp', '.sqlite', '.json']
    raster_extension = ['.asc', '.tif', '.nc']

    if ext in vector_extension:
        return QgsVectorLayer(filename, base_name, 'ogr')
    elif ext in raster_extension:
        return QgsRasterLayer(filename, base_name)
    else:
        msg = ('Could not read %s. '
               'Extension "%s" has not been implemented' % (filename, ext))
        raise ReadLayerError(msg)
Exemplo n.º 3
0
    def read_from_file(self, filename):
        """Read and unpack raster data
        """

        # Open data file for reading
        # File must be kept open, otherwise GDAL methods segfault.
        fid = self.fid = gdal.Open(filename, gdal.GA_ReadOnly)
        if fid is None:
            # As gdal doesn't return to us what the problem is we have to
            # figure it out ourselves. Maybe capture stderr?
            if not os.path.exists(filename):
                msg = 'Could not find file %s' % filename
            else:
                msg = ('File %s exists, but could not be read. '
                       'Please check if the file can be opened with '
                       'e.g. qgis or gdalinfo' % filename)
            raise ReadLayerError(msg)

        # Record raster metadata from file
        basename, ext = os.path.splitext(filename)

        # If file is ASCII, check that projection is around.
        # GDAL does not check this nicely, so it is worth an
        # error message
        if ext == '.asc':
            try:
                open(basename + '.prj')
            except IOError:
                msg = ('Projection file not found for %s. You must supply '
                       'a projection file with extension .prj' % filename)
                raise ReadLayerError(msg)

        # Look for any keywords
        self.keywords = read_keywords(basename + '.keywords')

        # Determine name
        if 'title' in self.keywords:
            title = self.keywords['title']

            # Lookup internationalised title if available
            title = tr(title)

            rastername = title
        else:
            # Use basename without leading directories as name
            rastername = os.path.split(basename)[-1]

        if self.name is None:
            self.name = rastername
        self.filename = filename

        self.projection = Projection(self.fid.GetProjection())
        self.geotransform = self.fid.GetGeoTransform()
        self.columns = fid.RasterXSize
        self.rows = fid.RasterYSize
        self.number_of_bands = fid.RasterCount

        # Assume that file contains all data in one band
        msg = 'Only one raster band currently allowed'
        if self.number_of_bands > 1:
            msg = ('WARNING: Number of bands in %s are %i. '
                   'Only the first band will currently be '
                   'used.' % (filename, self.number_of_bands))
            # FIXME(Ole): Let us use python warnings here
            raise ReadLayerError(msg)

        # Get first band.
        band = self.band = fid.GetRasterBand(1)
        if band is None:
            msg = 'Could not read raster band from %s' % filename
            raise ReadLayerError(msg)

        # Force garbage collection to free up any memory we can (TS)
        gc.collect()

        # Read from raster file
        data = band.ReadAsArray()

        # Convert to double precision (issue #75)
        data = numpy.array(data, dtype=numpy.float64)

        # Self check
        M, N = data.shape
        msg = ('Dimensions of raster array do not match those of '
               'raster file %s' % self.filename)
        verify(M == self.rows, msg)
        verify(N == self.columns, msg)
        nodata = self.band.GetNoDataValue()
        if nodata is None:
            nodata = -9999

        if nodata is not numpy.nan:
            NaN = numpy.ones((M, N), numpy.float64) * numpy.nan
            data = numpy.where(data == nodata, NaN, data)

        self.data = data
Exemplo n.º 4
0
    def read_from_file(self, filename):
        """Read and unpack vector data.

        It is assumed that the file contains only one layer with the
        pertinent features. Further it is assumed for the moment that
        all geometries are points.

        * A feature is a geometry and a set of attributes.
        * A geometry refers to location and can be point, line, polygon or
          combinations thereof.
        * The attributes or obtained through GetField()

        The full OGR architecture is documented at
        * http://www.gdal.org/ogr/ogr_arch.html
        * http://www.gdal.org/ogr/ogr_apitut.html

        Examples are at
        * danieljlewis.org/files/2010/09/basicpythonmap.pdf
        * http://invisibleroads.com/tutorials/gdal-shapefile-points-save.html
        * http://www.packtpub.com/article/geospatial-data-python-geometry

        Limitation of the Shapefile are documented in
        http://resources.esri.com/help/9.3/ArcGISDesktop/com/Gp_ToolRef/
        geoprocessing_tool_reference/
        geoprocessing_considerations_for_shapefile_output.htm

        :param filename: a fully qualified location to the file
        :type filename: str

        :raises: ReadLayerError
        """

        base_name = os.path.splitext(filename)[0]

        # Look for any keywords
        self.keywords = read_keywords(base_name + '.keywords')

        # FIXME (Ole): Should also look for style file to populate style_info

        # Determine name
        if 'title' in self.keywords:
            title = self.keywords['title']

            # Lookup internationalised title if available
            title = safe_tr(title)

            vector_name = title
        else:
            # Use base_name without leading directories as name
            vector_name = os.path.split(base_name)[-1]

        if self.name is None:
            self.name = vector_name
        self.filename = filename
        self.geometry_type = None  # In case there are no features

        fid = ogr.Open(filename)
        if fid is None:
            msg = 'Could not open %s' % filename
            raise ReadLayerError(msg)

        # Assume that file contains all data in one layer
        msg = 'Only one vector layer currently allowed'
        if fid.GetLayerCount() > 1 and self.sublayer is None:
            msg = ('WARNING: Number of layers in %s are %i. '
                   'Only the first layer will currently be '
                   'used. Specify sublayer when creating '
                   'the Vector if you wish to use a different layer.' %
                   (filename, fid.GetLayerCount()))
            LOGGER.warn(msg)
            # Why do we raise an exception if it is only a warning? TS
            raise ReadLayerError(msg)

        if self.sublayer is not None:
            layer = fid.GetLayerByName(self.sublayer)
        else:
            layer = fid.GetLayerByIndex(0)

        # Get spatial extent
        self.extent = layer.GetExtent()

        # Get projection
        p = layer.GetSpatialRef()
        self.projection = Projection(p)

        layer.ResetReading()

        # Extract coordinates and attributes for all features
        geometry = []
        data = []
        # Use feature iterator
        for feature in layer:
            # Record coordinates ordered as Longitude, Latitude
            G = feature.GetGeometryRef()
            if G is None:
                msg = ('Geometry was None in filename %s ' % filename)
                raise ReadLayerError(msg)
            else:
                self.geometry_type = G.GetGeometryType()
                if self.is_point_data:
                    geometry.append((G.GetX(), G.GetY()))
                elif self.is_line_data:
                    ring = get_ring_data(G)
                    geometry.append(ring)
                elif self.is_polygon_data:
                    polygon = get_polygon_data(G)
                    geometry.append(polygon)
                elif self.is_multi_polygon_data:
                    try:
                        G = ogr.ForceToPolygon(G)
                    except:
                        msg = ('Got geometry type Multipolygon (%s) for '
                               'filename %s and could not convert it to '
                               'singlepart. However, you can use QGIS '
                               'functionality to convert multipart vector '
                               'data to singlepart (Vector -> Geometry Tools '
                               '-> Multipart to Singleparts and use the '
                               'resulting dataset.' %
                               (ogr.wkbMultiPolygon, filename))
                        raise ReadLayerError(msg)
                    else:
                        # Read polygon data as single part
                        self.geometry_type = ogr.wkbPolygon
                        polygon = get_polygon_data(G)
                        geometry.append(polygon)
                else:
                    msg = ('Only point, line and polygon geometries are '
                           'supported. '
                           'Geometry type in filename %s '
                           'was %s.' % (filename, self.geometry_type))
                    raise ReadLayerError(msg)

            # Record attributes by name
            number_of_fields = feature.GetFieldCount()
            fields = {}
            for j in range(number_of_fields):
                name = feature.GetFieldDefnRef(j).GetName()

                # FIXME (Ole): Ascertain the type of each field?
                #              We need to cast each appropriately?
                #              This is issue #66
                #              (https://github.com/AIFDR/riab/issues/66)
                #feature_type = feature.GetFieldDefnRef(j).GetType()
                fields[name] = feature.GetField(j)

                # We do this because there is NaN problem on windows
                # NaN value must be converted to _pseudo_in to solve the
                # problem. But, when InaSAFE read the file, it'll be
                # converted back to NaN value, so that NaN in InaSAFE is a
                # numpy.nan
                # please check https://github.com/AIFDR/inasafe/issues/269
                # for more information
                if fields[name] == _pseudo_inf:
                    fields[name] = float('nan')
                #print 'Field', name, feature_type, j, fields[name]

            data.append(fields)
        # Store geometry coordinates as a compact numeric array
        self.geometry = geometry
        self.data = data
Exemplo n.º 5
0
    def read_from_file(self, filename):
        """Read and unpack raster data
        """

        # Open data file for reading
        # File must be kept open, otherwise GDAL methods segfault.
        fid = self.fid = gdal.Open(filename, gdal.GA_ReadOnly)
        if fid is None:
            # As gdal doesn't return to us what the problem is we have to
            # figure it out ourselves. Maybe capture stderr?
            if not os.path.exists(filename):
                msg = 'Could not find file %s' % filename
            else:
                msg = ('File %s exists, but could not be read. '
                       'Please check if the file can be opened with '
                       'e.g. qgis or gdalinfo' % filename)
            raise ReadLayerError(msg)

        # Record raster metadata from file
        basename, ext = os.path.splitext(filename)

        # If file is ASCII, check that projection is around.
        # GDAL does not check this nicely, so it is worth an
        # error message
        if ext == '.asc':
            try:
                open(basename + '.prj')
            except IOError:
                msg = ('Projection file not found for %s. You must supply '
                       'a projection file with extension .prj' % filename)
                raise ReadLayerError(msg)

        # Look for any keywords
        self.keywords = read_keywords(basename + '.keywords')

        # Determine name
        if 'title' in self.keywords:
            title = self.keywords['title']

            # Lookup internationalised title if available
            title = safe_tr(title)

            rastername = title
        else:
            # Use basename without leading directories as name
            rastername = os.path.split(basename)[-1]

        if self.name is None:
            self.name = rastername
        self.filename = filename

        self.projection = Projection(self.fid.GetProjection())
        self.geotransform = self.fid.GetGeoTransform()
        self.columns = fid.RasterXSize
        self.rows = fid.RasterYSize
        self.number_of_bands = fid.RasterCount

        # Assume that file contains all data in one band
        msg = 'Only one raster band currently allowed'
        if self.number_of_bands > 1:
            msg = ('WARNING: Number of bands in %s are %i. '
                   'Only the first band will currently be '
                   'used.' % (filename, self.number_of_bands))
            # FIXME(Ole): Let us use python warnings here
            raise ReadLayerError(msg)

        # Get first band.
        band = self.band = fid.GetRasterBand(1)
        if band is None:
            msg = 'Could not read raster band from %s' % filename
            raise ReadLayerError(msg)
Exemplo n.º 6
0
    def show_results(self, qgis_impact_layer, engine_impact_layer):
        """Helper function for slot activated when the process is done.

        .. note:: Adapted from the dock

        :param qgis_impact_layer: A QGIS layer representing the impact.
        :type qgis_impact_layer: QgsMapLayer, QgsVectorLayer, QgsRasterLayer

        :param engine_impact_layer: A safe_layer representing the impact.
        :type engine_impact_layer: ReadLayer

        :returns: Provides a report for writing to the dock.
        :rtype: str
        """
        keywords = self.keyword_io.read_keywords(qgis_impact_layer)

        # write postprocessing report to keyword
        output = self.analysis.postprocessor_manager.get_output(
            self.analysis.aggregator.aoi_mode)
        keywords['postprocessing_report'] = output.to_html(
            suppress_newlines=True)
        self.keyword_io.write_keywords(qgis_impact_layer, keywords)

        # Get tabular information from impact layer
        report = m.Message()
        report.add(LOGO_ELEMENT)
        report.add(m.Heading(self.tr('Analysis Results'), **INFO_STYLE))
        report.add(
            self.keyword_io.read_keywords(qgis_impact_layer, 'impact_summary'))

        # Get requested style for impact layer of either kind
        style = engine_impact_layer.get_style_info()
        style_type = engine_impact_layer.get_style_type()

        # Determine styling for QGIS layer
        if engine_impact_layer.is_vector:
            LOGGER.debug('myEngineImpactLayer.is_vector')
            if not style:
                # Set default style if possible
                pass
            elif style_type == 'categorizedSymbol':
                LOGGER.debug('use categorized')
                set_vector_categorized_style(qgis_impact_layer, style)
            elif style_type == 'graduatedSymbol':
                LOGGER.debug('use graduated')
                set_vector_graduated_style(qgis_impact_layer, style)

        elif engine_impact_layer.is_raster:
            LOGGER.debug('myEngineImpactLayer.is_raster')
            if not style:
                qgis_impact_layer.setDrawingStyle("SingleBandPseudoColor")
                # qgis_impact_layer.setColorShadingAlgorithm(
                #    QgsRasterLayer.PseudoColorShader)
            else:
                setRasterStyle(qgis_impact_layer, style)

        else:
            message = self.tr(
                'Impact layer %s was neither a raster or a vector layer') % (
                    qgis_impact_layer.source())
            # noinspection PyExceptionInherit
            raise ReadLayerError(message)

        # Add layers to QGIS
        layers_to_add = []
        if self.show_intermediate_layers:
            layers_to_add.append(self.analysis.aggregator.layer)
        layers_to_add.append(qgis_impact_layer)
        QgsMapLayerRegistry.instance().addMapLayers(layers_to_add)
        # make sure it is active in the legend - needed since QGIS 2.4
        self.iface.setActiveLayer(qgis_impact_layer)
        # then zoom to it
        if self.zoom_to_impact_flag:
            self.iface.zoomToActiveLayer()
        if self.hide_exposure_flag:
            exposure_layer = self.parent.get_exposure_layer()
            legend = self.iface.legendInterface()
            legend.setLayerVisible(exposure_layer, False)

        # append postprocessing report
        report.add(output.to_html())
        # Layer attribution comes last
        report.add(impact_attribution(keywords).to_html(True))
        # Return text to display in report panel
        return report
Exemplo n.º 7
0
    def read_from_file(self, filename):
        """Read and unpack vector data.

        It is assumed that the file contains only one layer with the
        pertinent features. Further it is assumed for the moment that
        all geometries are points.

        * A feature is a geometry and a set of attributes.
        * A geometry refers to location and can be point, line, polygon or
          combinations thereof.
        * The attributes or obtained through GetField()

        The full OGR architecture is documented at
        * http://www.gdal.org/ogr/ogr_arch.html
        * http://www.gdal.org/ogr/ogr_apitut.html

        Examples are at
        * danieljlewis.org/files/2010/09/basicpythonmap.pdf
        * http://invisibleroads.com/tutorials/gdal-shapefile-points-save.html
        * http://www.packtpub.com/article/geospatial-data-python-geometry
        """

        basename = os.path.splitext(filename)[0]

        # Look for any keywords
        self.keywords = read_keywords(basename + '.keywords')

        # FIXME (Ole): Should also look for style file to populate style_info

        # Determine name
        if 'title' in self.keywords:
            title = self.keywords['title']

            # Lookup internationalised title if available
            if title in internationalised_titles:
                title = internationalised_titles[title]

            vectorname = title
        else:
            # Use basename without leading directories as name
            vectorname = os.path.split(basename)[-1]

        self.name = vectorname
        self.filename = filename
        self.geometry_type = None  # In case there are no features

        fid = ogr.Open(filename)
        if fid is None:
            msg = 'Could not open %s' % filename
            raise ReadLayerError(msg)

        # Assume that file contains all data in one layer
        msg = 'Only one vector layer currently allowed'
        if fid.GetLayerCount() > 1 and self.sublayer is None:
            msg = ('WARNING: Number of layers in %s are %i. '
                   'Only the first layer will currently be '
                   'used. Specify sublayer when creating '
                   'the Vector if you wish to use a different layer.' %
                   (filename, fid.GetLayerCount()))
            # Why do we raise an exception if it is only a warning? TS
            raise ReadLayerError(msg)

        if self.sublayer is not None:
            layer = fid.GetLayerByName(self.sublayer)
        else:
            layer = fid.GetLayerByIndex(0)

        # Get spatial extent
        self.extent = layer.GetExtent()

        # Get projection
        p = layer.GetSpatialRef()
        self.projection = Projection(p)

        layer.ResetReading()

        # Get number of features
        # N = layer.GetFeatureCount()

        # Extract coordinates and attributes for all features
        geometry = []
        data = []
        # Use feature iterator
        for feature in layer:
            # Record coordinates ordered as Longitude, Latitude
            G = feature.GetGeometryRef()
            if G is None:
                msg = ('Geometry was None in filename %s ' % filename)
                raise ReadLayerError(msg)
            else:
                self.geometry_type = G.GetGeometryType()
                if self.is_point_data:
                    geometry.append((G.GetX(), G.GetY()))
                elif self.is_line_data:
                    M = G.GetPointCount()
                    coordinates = []
                    for j in range(M):
                        coordinates.append((G.GetX(j), G.GetY(j)))

                    # Record entire line as an Mx2 numpy array
                    geometry.append(
                        numpy.array(coordinates, dtype='d', copy=False))
                elif self.is_polygon_data:
                    ring = G.GetGeometryRef(0)
                    M = ring.GetPointCount()
                    coordinates = []
                    for j in range(M):
                        coordinates.append((ring.GetX(j), ring.GetY(j)))

                    # Record entire polygon ring as an Mx2 numpy array
                    geometry.append(
                        numpy.array(coordinates, dtype='d', copy=False))
                elif self.is_multi_polygon_data:
                    msg = ('Got geometry type Multipolygon (%s) for filename '
                           '%s which is not yet supported. Only point, line '
                           'and polygon geometries are supported. However, '
                           'you can use QGIS functionality to convert '
                           'multipart vector data to singlepart (Vector -> '
                           'Geometry Tools -> Multipart to Singleparts and '
                           'use the resulting dataset.' %
                           (ogr.wkbMultiPolygon, filename))
                    raise ReadLayerError(msg)

                #    # FIXME: Unpact multiple polygons to simple polygons
                #    # For hints on how to unpack see
#http://osgeo-org.1803224.n2.nabble.com/
#gdal-dev-Shapefile-Multipolygon-with-interior-rings-td5391090.html
#http://osdir.com/ml/gdal-development-gis-osgeo/2010-12/msg00107.html

#    ring = G.GetGeometryRef(0)
#    M = ring.GetPointCount()
#    coordinates = []
#    for j in range(M):
#        coordinates.append((ring.GetX(j), ring.GetY(j)))

#    # Record entire polygon ring as an Mx2 numpy array
#    geometry.append(numpy.array(coordinates,
#                                dtype='d',
#                                copy=False))

                else:
                    msg = ('Only point, line and polygon geometries are '
                           'supported. '
                           'Geometry type in filename %s '
                           'was %s.' % (filename, self.geometry_type))
                    raise ReadLayerError(msg)

            # Record attributes by name
            number_of_fields = feature.GetFieldCount()
            fields = {}
            for j in range(number_of_fields):
                name = feature.GetFieldDefnRef(j).GetName()

                # FIXME (Ole): Ascertain the type of each field?
                #              We need to cast each appropriately?
                #              This is issue #66
                #              (https://github.com/AIFDR/riab/issues/66)
                #feature_type = feature.GetFieldDefnRef(j).GetType()
                fields[name] = feature.GetField(j)
                #print 'Field', name, feature_type, j, fields[name]

            data.append(fields)

        # Store geometry coordinates as a compact numeric array
        self.geometry = geometry
        self.data = data
Exemplo n.º 8
0
    def show_results(self):
        """Helper function for slot activated when the process is done.

        .. versionchanged:: 3.4 - removed parameters.

        .. note:: If you update this function, please report your change to
            safe.gui.widgets.dock.show_results too.

        :returns: Provides a report for writing to the dock.
        :rtype: str
        """
        qgis_exposure = self.impact_function.exposure.qgis_layer()
        qgis_hazard = self.impact_function.hazard.qgis_layer()
        qgis_aggregation = self.impact_function.aggregation.qgis_layer()

        safe_impact_layer = self.impact_function.impact
        qgis_impact_layer = read_impact_layer(safe_impact_layer)

        keywords = self.keyword_io.read_keywords(qgis_impact_layer)
        json_path = os.path.splitext(qgis_impact_layer.source())[0] + '.json'

        # write postprocessing report to keyword
        postprocessor_data = self.impact_function.postprocessor_manager.\
            get_json_data(self.impact_function.aggregator.aoi_mode)
        post_processing_report = m.Message()
        if os.path.exists(json_path):
            with open(json_path) as json_file:
                impact_data = json.load(json_file,
                                        object_pairs_hook=OrderedDict)
                impact_data['post processing'] = postprocessor_data
                write_json(impact_data, json_path)
        else:
            post_processing_report = self.impact_function.\
                postprocessor_manager.get_output(
                    self.impact_function.aggregator.aoi_mode)
            keywords['postprocessing_report'] = post_processing_report.to_html(
                suppress_newlines=True)
            self.keyword_io.write_keywords(qgis_impact_layer, keywords)

        # Get tabular information from impact layer
        report = m.Message()
        report.add(LOGO_ELEMENT)
        report.add(m.Heading(self.tr('Analysis Results'), **INFO_STYLE))
        # If JSON Impact Data Exist, use JSON
        json_path = qgis_impact_layer.source()[:-3] + 'json'
        LOGGER.debug('JSON Path %s' % json_path)
        if os.path.exists(json_path):
            impact_template = get_report_template(json_file=json_path)
            impact_report = impact_template.generate_message_report()
            report.add(impact_report)
        else:
            report.add(
                self.keyword_io.read_keywords(qgis_impact_layer,
                                              'impact_summary'))
            # append postprocessing report
            report.add(post_processing_report.to_html())

        # Layer attribution comes last
        report.add(impact_attribution(keywords).to_html(True))

        # Get requested style for impact layer of either kind
        style = safe_impact_layer.get_style_info()
        style_type = safe_impact_layer.get_style_type()

        # Determine styling for QGIS layer
        if safe_impact_layer.is_vector:
            if not style:
                # Set default style if possible
                pass
            elif style_type == 'categorizedSymbol':
                LOGGER.debug('use categorized')
                set_vector_categorized_style(qgis_impact_layer, style)
            elif style_type == 'graduatedSymbol':
                LOGGER.debug('use graduated')
                set_vector_graduated_style(qgis_impact_layer, style)

        elif safe_impact_layer.is_raster:
            if not style:
                qgis_impact_layer.setDrawingStyle("SingleBandPseudoColor")
            else:
                setRasterStyle(qgis_impact_layer, style)

        else:
            message = self.tr(
                'Impact layer %s was neither a raster or a vector layer') % (
                    qgis_impact_layer.source())
            # noinspection PyExceptionInherit
            raise ReadLayerError(message)

        legend = self.iface.legendInterface()

        # Insert the aggregation output above the input aggregation layer
        if self.show_intermediate_layers:
            add_above_layer(self.impact_function.aggregator.layer,
                            qgis_aggregation)
            legend.setLayerVisible(self.impact_function.aggregator.layer, True)

        if self.hide_exposure_flag:
            # Insert the impact always above the hazard
            add_above_layer(qgis_impact_layer, qgis_hazard)
        else:
            # Insert the impact above the hazard and the exposure if
            # we don't hide the exposure. See #2899
            add_above_layer(qgis_impact_layer, qgis_exposure, qgis_hazard)

        # In QGIS 2.14.2 and GDAL 1.11.3, if the exposure is in 3857,
        # the impact layer is in 54004, we need to change it. See issue #2790.
        if qgis_exposure.crs().authid() == 'EPSG:3857':
            if qgis_impact_layer.crs().authid() != 'EPSG:3857':
                epsg_3857 = QgsCoordinateReferenceSystem(3857)
                qgis_impact_layer.setCrs(epsg_3857)

        # make sure it is active in the legend - needed since QGIS 2.4
        self.iface.setActiveLayer(qgis_impact_layer)
        # then zoom to it
        if self.zoom_to_impact_flag:
            self.iface.zoomToActiveLayer()
        if self.hide_exposure_flag:
            exposure_layer = self.get_exposure_layer()
            legend.setLayerVisible(exposure_layer, False)

        # Make the layer visible. Might be hidden by default. See #2925
        legend.setLayerVisible(qgis_impact_layer, True)

        # Return text to display in report panel
        return report