Example #1
0
    def set_style(self):
        # Get requested style for impact layer of either kind
        impact = self.impact_layer
        style = impact.get_style_info()
        style_type = impact.get_style_type()

        # Determine styling for QGIS layer
        qgis_impact_layer = impact.as_qgis_native()
        if impact.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 impact.is_raster:
            LOGGER.debug('myEngineImpactLayer.is_raster')
            if not style:
                qgis_impact_layer.setDrawingStyle("SingleBandPseudoColor")
            else:
                setRasterStyle(qgis_impact_layer, style)
    def test_transparency_of_minimum_value(self):
        """Test that transparency of minimum value works when set to 100%
        """
        # This dataset has all cells with value 1.3
        data_path = test_data_path('other', 'issue126.tif')
        layer, _ = load_layer(data_path)

        # Note the float quantity values below
        style_info = {
            'style_classes': [
                {'colour': '#FFFFFF', 'transparency': 100, 'quantity': 0.0},
                {'colour': '#38A800', 'quantity': 0.038362596547925065,
                 'transparency': 0, 'label': u'Rendah [0 orang/sel]'},
                {'colour': '#79C900', 'transparency': 0,
                 'quantity': 0.07672519309585013},
                {'colour': '#CEED00', 'transparency': 0,
                 'quantity': 0.1150877896437752},
                {'colour': '#FFCC00', 'quantity': 0.15345038619170026,
                 'transparency': 0, 'label': u'Sedang [0 orang/sel]'},
                {'colour': '#FF6600', 'transparency': 0,
                 'quantity': 0.19181298273962533},
                {'colour': '#FF0000', 'transparency': 0,
                 'quantity': 0.23017557928755039},
                {'colour': '#7A0000', 'quantity': 0.26853817583547546,
                 'transparency': 0, 'label': u'Tinggi [0 orang/sel]'}]}

        try:
            setRasterStyle(layer, style_info)
        except Exception, e:
            message = '\nCould not create raster style'
            e.args = (e.args[0] + message,)
            raise
Example #3
0
    def test_issue126(self):
        """Test that non integer transparency ranges fail gracefully.
        .. seealso:: https://github.com/AIFDR/inasafe/issues/126
        """
        # This dataset has all cells with value 1.3
        data_path = test_data_path('other', 'issue126.tif')
        layer, _ = load_layer(data_path)

        # Note the float quantity values below
        style_info = {
            'style_classes': [
                dict(colour='#38A800', quantity=1.1, transparency=100),
                dict(colour='#38A800', quantity=1.4, transparency=0),
                dict(colour='#79C900', quantity=10.1, transparency=0)
            ]
        }

        try:
            setRasterStyle(layer, style_info)
        except Exception, e:
            message = (
                'Setting style info with float based ranges should fail '
                'gracefully.')
            e.args = (e.args[0] + message, )
            raise
Example #4
0
    def test_result_styling(self):
        """Test that colours and opacity from a model are correctly styled."""

        settings = QtCore.QSettings()
        settings.setValue('inasafe/analysis_extents_mode', 'HazardExposure')

        result, message = setup_scenario(
            self.dock,
            hazard='Continuous Flood',
            exposure='Population',
            function='Need evacuation',
            function_id='FloodEvacuationRasterHazardFunction')
        self.assertTrue(result, message)

        # Enable on-the-fly reprojection
        set_canvas_crs(GEOCRS, True)
        set_jakarta_extent(self.dock)

        self.dock.accept()
        safe_layer = self.dock.impact_function.impact
        qgis_layer = read_impact_layer(safe_layer)
        style = safe_layer.get_style_info()
        setRasterStyle(qgis_layer, style)
        # simple test for now - we could test explicitly for style state
        # later if needed.
        message = ('Raster layer was not assigned a Singleband pseudocolor '
                   'renderer as expected.')
        self.assertEquals(qgis_layer.renderer().type(),
                          'singlebandpseudocolor', message)
Example #5
0
    def test_result_styling(self):
        """Test that colours and opacity from a model are correctly styled."""

        settings = QtCore.QSettings()
        settings.setValue('inasafe/analysis_extents_mode', 'HazardExposure')

        result, message = setup_scenario(
            self.dock,
            hazard='Continuous Flood',
            exposure='Population',
            function='Need evacuation',
            function_id='FloodEvacuationRasterHazardFunction')
        self.assertTrue(result, message)

        # Enable on-the-fly reprojection
        set_canvas_crs(GEOCRS, True)
        set_jakarta_extent(self.dock)

        self.dock.accept()
        safe_layer = self.dock.impact_function.impact
        qgis_layer = read_impact_layer(safe_layer)
        style = safe_layer.get_style_info()
        setRasterStyle(qgis_layer, style)
        # simple test for now - we could test explicitly for style state
        # later if needed.
        message = (
            'Raster layer was not assigned a Singleband pseudocolor '
            'renderer as expected.')
        self.assertEquals(
            qgis_layer.renderer().type(), 'singlebandpseudocolor', message)
    def test_transparency_of_minimum_value(self):
        """Test that transparency of minimum value works when set to 100%
        """
        # This dataset has all cells with value 1.3
        data_path = standard_data_path('other', 'issue126.tif')
        layer, _ = load_layer(data_path)

        # Note the float quantity values below
        style_info = {
            'style_classes': [
                {'colour': '#FFFFFF', 'transparency': 100, 'quantity': 0.0},
                {'colour': '#38A800', 'quantity': 0.038362596547925065,
                 'transparency': 0, 'label': u'Rendah [0 orang/sel]'},
                {'colour': '#79C900', 'transparency': 0,
                 'quantity': 0.07672519309585013},
                {'colour': '#CEED00', 'transparency': 0,
                 'quantity': 0.1150877896437752},
                {'colour': '#FFCC00', 'quantity': 0.15345038619170026,
                 'transparency': 0, 'label': u'Sedang [0 orang/sel]'},
                {'colour': '#FF6600', 'transparency': 0,
                 'quantity': 0.19181298273962533},
                {'colour': '#FF0000', 'transparency': 0,
                 'quantity': 0.23017557928755039},
                {'colour': '#7A0000', 'quantity': 0.26853817583547546,
                 'transparency': 0, 'label': u'Tinggi [0 orang/sel]'}]}

        try:
            setRasterStyle(layer, style_info)
        except Exception, e:
            message = '\nCould not create raster style'
            e.args = (e.args[0] + message,)
            raise
Example #7
0
    def test_result_styling(self):
        """Test that colours and opacity from a model are correctly styled."""

        # Push OK with the left mouse button

        print '--------------------'
        print combos_to_string(self.dock)

        result, message = setup_scenario(
            self.dock,
            hazard='Continuous Flood',
            exposure='Population',
            function='Need evacuation',
            function_id='FloodEvacuationRasterHazardFunction')
        self.assertTrue(result, message)

        # Enable on-the-fly reprojection
        set_canvas_crs(GEOCRS, True)
        set_jakarta_extent(self.dock)

        self.dock.accept()
        # self.dock.analysis.get_impact_layer()
        safe_layer = self.dock.analysis.impact_layer
        qgis_layer = read_impact_layer(safe_layer)
        style = safe_layer.get_style_info()
        setRasterStyle(qgis_layer, style)
        # simple test for now - we could test explicity for style state
        # later if needed.
        message = (
            'Raster layer was not assigned a Singleband pseudocolor'
            ' renderer as expected.')
        self.assertTrue(
            qgis_layer.renderer().type() == 'singlebandpseudocolor', message)
Example #8
0
    def test_result_styling(self):
        """Test that ouputs from a model are correctly styled (colours and
        opacity. """

        # Push OK with the left mouse button

        print '--------------------'
        print combos_to_string(DOCK)

        result, message = setup_scenario(
            DOCK,
            hazard='A flood in Jakarta like in 2007',
            exposure='People',
            function='Need evacuation',
            function_id='Flood Evacuation Function')
        self.assertTrue(result, message)

        # Enable on-the-fly reprojection
        set_canvas_crs(GEOCRS, True)
        set_jakarta_extent(DOCK)

        DOCK.accept()
        # DOCK.analysis.get_impact_layer()
        safe_layer = DOCK.analysis.get_impact_layer()
        qgis_layer = read_impact_layer(safe_layer)
        style = safe_layer.get_style_info()
        setRasterStyle(qgis_layer, style)
        # simple test for now - we could test explicity for style state
        # later if needed.
        message = ('Raster layer was not assigned a Singleband pseudocolor'
                   ' renderer as expected.')
        self.assertTrue(
            qgis_layer.renderer().type() == 'singlebandpseudocolor', message)
Example #9
0
def generate_styles(safe_impact_layer, qgis_impact_layer):
    # 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':
            set_vector_categorized_style(qgis_impact_layer, style)
        elif style_type == 'graduatedSymbol':
            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)
Example #10
0
def generate_styles(safe_impact_layer, qgis_impact_layer):
    # 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':
            set_vector_categorized_style(qgis_impact_layer, style)
        elif style_type == 'graduatedSymbol':
            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)
Example #11
0
    def test_issue126(self):
        """Test that non integer transparency ranges fail gracefully.
        .. seealso:: https://github.com/AIFDR/inasafe/issues/126
        """
        # This dataset has all cells with value 1.3
        data_path = test_data_path('other', 'issue126.tif')
        layer, _ = load_layer(data_path)

        # Note the float quantity values below
        style_info = {
            'style_classes': [
                dict(colour='#38A800', quantity=1.1, transparency=100),
                dict(colour='#38A800', quantity=1.4, transparency=0),
                dict(colour='#79C900', quantity=10.1, transparency=0)]}

        try:
            setRasterStyle(layer, style_info)
        except Exception, e:
            message = (
                'Setting style info with float based ranges should fail '
                'gracefully.')
            e.args = (e.args[0] + message,)
            raise
Example #12
0
    def set_impact_style(cls, impact):
        # Determine styling for QGIS layer
        qgis_impact_layer = impact.as_qgis_native()
        style = impact.get_style_info()
        style_type = impact.get_style_type()
        if impact.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 impact.is_raster:
            LOGGER.debug("myEngineImpactLayer.is_raster")
            if not style:
                qgis_impact_layer.setDrawingStyle("SingleBandPseudoColor")
            else:
                setRasterStyle(qgis_impact_layer, style)
Example #13
0
    def set_style(self):
        # get requested style of impact

        qml_path = self.flood_fixtures_dir('impact-template.qml')
        target_style_path = os.path.join(self.report_path,
                                         'population_aggregate.qml')
        keyword_io = KeywordIO()
        qgis_exposure_layer = self.exposure_layer.as_qgis_native()
        attribute_field = keyword_io.read_keywords(qgis_exposure_layer,
                                                   'field')
        with open(qml_path) as f_template:
            str_template = f_template.read()

            # search max_population in an RW
            # use generator for memory efficiency
            maximum_population = max(
                f[attribute_field] for f in qgis_exposure_layer.getFeatures())
            range_increment = maximum_population / 5
            legend_expressions = {}
            for i in range(5):
                if i == 0:
                    marker_label = '< %s' % format_int(range_increment)
                elif i < 4:
                    marker_label = '%s - %s' % (format_int(
                        range_increment *
                        i), format_int(range_increment * (i + 1)))
                else:
                    marker_label = '> %s' % format_int(range_increment * 4)
                marker_size = \
                    'scale_linear(' \
                    'attribute($currentfeature, &quot;%s&quot;) ' \
                    ', %d, %d, %d, %d)' % (
                        self.affect_field,
                        int(range_increment * i),
                        int(range_increment * (i + 1)),
                        i * 2,
                        (i + 1) * 2,
                    )
                marker_color = \
                    "set_color_part(" \
                    "set_color_part('0,0,255','saturation', %d ), 'alpha', " \
                    "if(attribute($currentfeature, '%s') = 0, " \
                    "0, 255))" % (i * 20, self.affect_field)
                marker_border = \
                    "set_color_part(" \
                    "'0,0,0','alpha', " \
                    "if (to_int(attribute(" \
                    "$currentfeature, '%s')) = 0, 0, 255))" % \
                    self.affect_field

                legend_expressions['marker-min-range-%d' % i] = \
                    '%s' % (range_increment * i)
                legend_expressions['marker-max-range-%d' % i] = \
                    '%s' % (range_increment * (i + 1))
                legend_expressions['marker-label-%d' % i] = marker_label
                legend_expressions['marker-size-%d' % i] = marker_size
                legend_expressions['marker-color-%d' % i] = marker_color
                legend_expressions['marker-border-%d' % i] = marker_border

            for k, v in legend_expressions.iteritems():
                str_template = str_template.replace('[%s]' % k, v)

            with open(target_style_path, mode='w') as target_f:
                target_f.write(str_template)

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

        # Determine styling for QGIS layer
        qgis_impact_layer = impact.as_qgis_native()
        if impact.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 impact.is_raster:
            LOGGER.debug('myEngineImpactLayer.is_raster')
            if not style:
                qgis_impact_layer.setDrawingStyle("SingleBandPseudoColor")
            else:
                setRasterStyle(qgis_impact_layer, style)
Example #14
0
    def set_style(self):
        # get requested style of impact

        qml_path = self.flood_fixtures_dir(
            'impact-template.qml')
        target_style_path = os.path.join(
            self.report_path, 'population_aggregate.qml')
        keyword_io = KeywordIO()
        qgis_exposure_layer = self.exposure_layer.as_qgis_native()
        attribute_field = keyword_io.read_keywords(
            qgis_exposure_layer, 'field')
        with open(qml_path) as f_template:
            str_template = f_template.read()

            # search max_population in an RW
            # use generator for memory efficiency
            maximum_population = max(
                f[attribute_field] for f
                in qgis_exposure_layer.getFeatures()
            )
            range_increment = maximum_population / 5
            legend_expressions = {}
            for i in range(5):
                if i == 0:
                    marker_label = '&lt; %s' % format_int(range_increment)
                elif i < 4:
                    marker_label = '%s - %s' % (
                        format_int(range_increment * i),
                        format_int(range_increment * (i + 1))
                    )
                else:
                    marker_label = '> %s' % format_int(range_increment * 4)
                marker_size = \
                    'scale_linear(' \
                    'attribute($currentfeature, &quot;%s&quot;) ' \
                    ', %d, %d, %d, %d)' % (
                        self.affect_field,
                        int(range_increment * i),
                        int(range_increment * (i + 1)),
                        i * 2,
                        (i + 1) * 2,
                    )
                marker_color = \
                    "set_color_part(" \
                    "set_color_part('0,0,255','saturation', %d ), 'alpha', " \
                    "if(attribute($currentfeature, '%s') = 0, " \
                    "0, 255))" % (i * 20, self.affect_field)
                marker_border = \
                    "set_color_part(" \
                    "'0,0,0','alpha', " \
                    "if (to_int(attribute(" \
                    "$currentfeature, '%s')) = 0, 0, 255))" % \
                    self.affect_field

                legend_expressions['marker-min-range-%d' % i] = \
                    '%s' % (range_increment * i)
                legend_expressions['marker-max-range-%d' % i] = \
                    '%s' % (range_increment * (i + 1))
                legend_expressions['marker-label-%d' % i] = marker_label
                legend_expressions['marker-size-%d' % i] = marker_size
                legend_expressions['marker-color-%d' % i] = marker_color
                legend_expressions['marker-border-%d' % i] = marker_border

            for k, v in legend_expressions.iteritems():
                str_template = str_template.replace('[%s]' % k, v)

            with open(target_style_path, mode='w') as target_f:
                target_f.write(str_template)

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

        # Determine styling for QGIS layer
        qgis_impact_layer = impact.as_qgis_native()
        if impact.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 impact.is_raster:
            LOGGER.debug('myEngineImpactLayer.is_raster')
            if not style:
                qgis_impact_layer.setDrawingStyle("SingleBandPseudoColor")
            else:
                setRasterStyle(qgis_impact_layer, style)
Example #15
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
Example #16
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
                with open(json_path, 'w') as json_file_2:
                    json.dump(impact_data, json_file_2, indent=2)
        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
Example #17
0
class StylingTest(unittest.TestCase):
    """Tests for qgis styling related functions.
    """
    def setUp(self):
        os.environ['LANG'] = 'en'

    def tearDown(self):
        pass

    def test_issue126(self):
        """Test that non integer transparency ranges fail gracefully.
        .. seealso:: https://github.com/AIFDR/inasafe/issues/126
        """
        # This dataset has all cells with value 1.3
        data_path = test_data_path('other', 'issue126.tif')
        layer, _ = load_layer(data_path)

        # Note the float quantity values below
        style_info = {
            'style_classes': [
                dict(colour='#38A800', quantity=1.1, transparency=100),
                dict(colour='#38A800', quantity=1.4, transparency=0),
                dict(colour='#79C900', quantity=10.1, transparency=0)
            ]
        }

        try:
            setRasterStyle(layer, style_info)
        except Exception, e:
            message = (
                'Setting style info with float based ranges should fail '
                'gracefully.')
            e.args = (e.args[0] + message, )
            raise
        # Now validate the transparency values were set to 255 because
        # they are floats and we cant specify pixel ranges to floats
        # Note we don't test on the exact interval because 464c6171dd55
        value1 = layer.renderer().rasterTransparency().alphaValue(1.2)
        value2 = layer.renderer().rasterTransparency().alphaValue(1.5)
        message = ('Transparency should be ignored when style class '
                   'quantities are floats')
        assert value1 == value2 == 255, message

        # Now run the same test again for int intervals
        style_info['style_classes'] = [
            dict(colour='#38A800', quantity=2, transparency=100),
            dict(colour='#38A800', quantity=4, transparency=0),
            dict(colour='#79C900', quantity=10, transparency=0)
        ]
        message = ('Setting style info with generate valid transparent '
                   'pixel entries.')
        try:
            setRasterStyle(layer, style_info)
        except:
            raise Exception(message)
        # Now validate the transparency values were set to 255 because
        # they are floats and we cant specify pixel ranges to floats
        value1 = layer.renderer().rasterTransparency().alphaValue(1)
        value2 = layer.renderer().rasterTransparency().alphaValue(3)
        message1 = message + 'Expected 0 got %i' % value1
        message2 = message + 'Expected 255 got %i' % value2
        assert value1 == 0, message1
        assert value2 == 255, message2

        # Verify that setRasterStyle doesn't break when floats coincide with
        # integers
        # See https://github.com/AIFDR/inasafe/issues/126#issuecomment-5978416
        style_info['style_classes'] = [
            dict(colour='#38A800', quantity=2.0, transparency=100),
            dict(colour='#38A800', quantity=4.0, transparency=0),
            dict(colour='#79C900', quantity=10.0, transparency=0)
        ]

        try:
            setRasterStyle(layer, style_info)
        except Exception, e:  # pylint: disable=broad-except
            message = (
                'Broken: Setting style info with generate valid transparent '
                'floating point pixel entries such as 2.0, 3.0')
            e.args = (e.args[0] + message, )
            raise
    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.analysis.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
Example #19
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