Example #1
0
    def impact_summary(self):
        """The impact summary as per category

        :returns: The impact summary.
        :rtype: safe.message.Message
        """
        affected_categories = self.affected_road_categories

        message = m.Message(style_class='container')
        table = m.Table(style_class='table table-condensed table-striped')
        table.caption = None

        row = m.Row()
        row.add(m.Cell(tr('Summary by road type'), header=True))
        for _ in affected_categories:
            # Add empty cell as many as affected_categories
            row.add(m.Cell('', header=True))

        if self.add_unaffected_column:
            # Add empty cell for un-affected road
            row.add(m.Cell('', header=True))

        # Add empty cell for total column
        row.add(m.Cell('', header=True))
        table.add(row)

        row = m.Row()
        row.add(m.Cell(tr('Road Type'), header=True))
        for affected_category in affected_categories:
            row.add(m.Cell(affected_category, header=True, align='right'))

        if self.add_unaffected_column:
            row.add(m.Cell(tr('Unaffected'), header=True, align='right'))

        row.add(m.Cell(tr('Total'), header=True, align='right'))
        table.add(row)

        total_affected = [0] * len(affected_categories)
        for (category, road_breakdown) in self.affected_road_lengths.items():
            number_affected = sum(road_breakdown.values())
            count = affected_categories.index(category)
            total_affected[count] = number_affected

        row = m.Row()
        row.add(m.Cell(tr('All (m)')))
        for total_affected_value in total_affected:
            row.add(
                m.Cell(format_int(int(total_affected_value)), align='right'))
        if self.add_unaffected_column:
            row.add(
                m.Cell(format_int(
                    int(self.total_road_length - sum(total_affected))),
                       align='right'))

        row.add(m.Cell(format_int(int(self.total_road_length)), align='right'))
        table.add(row)

        message.add(table)

        return message
Example #2
0
    def test_earthquake_building_impact_function(self):
        """Earthquake Building Impact Function works as expected."""
        # Name file names for hazard level, exposure and expected fatalities
        hazard_filename = '%s/eq_yogya_2006.asc' % HAZDATA
        exposure_filename = '%s/OSM_building_polygons_20110905.shp' % TESTDATA

        # Calculate impact using API
        hazard_layer = read_layer(hazard_filename)
        exposure_layer = read_layer(exposure_filename)

        plugin_name = 'Earthquake Building Impact Function'
        impact_function = get_plugin(plugin_name)

        # Call calculation engine
        impact_layer = calculate_impact(layers=[hazard_layer, exposure_layer],
                                        impact_fcn=impact_function)
        impact_filename = impact_layer.get_filename()

        impact_layer = read_layer(impact_filename)
        # calculated_result = I.get_data()
        # print calculated_result.shape
        keywords = impact_layer.get_keywords()
        impact_summary = keywords['impact_summary']

        # This is the expected number of building might be affected
        # Hazard Level - Buildings Affected
        # Low - 845
        # Medium - 15524
        # High - 122
        message = 'Result not as expected'
        self.assertTrue(format_int(845) in impact_summary, message)
        self.assertTrue(format_int(15524) in impact_summary, message)
        self.assertTrue(format_int(122) in impact_summary, message)
Example #3
0
    def notes(self):
        """Return the notes section of the report.

        :return: The notes that should be attached to this impact report.
        :rtype: list
        """
        population = format_int(population_rounding(self.total_population))
        threshold = format_int(self.parameters['evacuation_percentage'].value)

        if get_needs_provenance_value(self.parameters) is None:
            needs_provenance = ''
        else:
            needs_provenance = tr(get_needs_provenance_value(self.parameters))

        fields = [
            tr('Total population in the analysis area: %s') % population,
            tr('<sup>1</sup>The evacuation threshold used to determine '
               'population needing evacuation is %s%%.') % threshold,
            needs_provenance,
        ]

        if self.no_data_warning:
            fields = fields + no_data_warning
        # include any generic exposure specific notes from definitions.py
        fields = fields + self.exposure_notes()
        # include any generic hazard specific notes from definitions.py
        fields = fields + self.hazard_notes()
        return fields
Example #4
0
    def action_checklist(self):
        """Breakdown by building type.

        :returns: The buildings breakdown report.
        :rtype: safe.messaging.Message
        """
        schools_closed = self.schools_closed
        hospitals_closed = self.hospitals_closed

        message = m.Message(style_class='container')
        message.add(m.Heading(tr('Action checklist'), **styles.INFO_STYLE))
        checklist = m.BulletedList()
        checklist.add(
            tr('Which structures have warning capacity (eg. sirens, speakers, '
               'etc.)?'))
        checklist.add(
            tr('Are the water and electricity services still operating?'))
        checklist.add(tr('Are the health centres still open?'))
        checklist.add(tr('Are the other public services accessible?'))
        checklist.add(tr('Which buildings will be evacuation centres?'))
        checklist.add(tr('Where will we locate the operations centre?'))
        checklist.add(
            tr('Where will we locate warehouse and/or distribution centres?'))
        checklist.add(tr('Are the schools and hospitals still active?'))
        if schools_closed > 0:
            checklist.add(
                tr('Where will the students from the %s closed schools '
                   'go to study?') % format_int(schools_closed))
        if hospitals_closed > 0:
            checklist.add(
                tr('Where will the patients from the %s closed hospitals go '
                   'for treatment and how will we transport them?') %
                format_int(hospitals_closed))
        message.add(checklist)
        return message
    def action_checklist(self):
        """Action Checklist Data.

        :returns: An action list in dictionary format.
        :rtype: dict

        """
        title = tr('Action checklist')
        fields = [
            tr('Which structures have warning capacity (eg. sirens, speakers, '
               'etc.)?'),
            tr('Are the water and electricity services still operating?'),
            tr('Are the health centres still open?'),
            tr('Are the other public services accessible?'),
            tr('Which buildings will be evacuation centres?'),
            tr('Where will we locate the operations centre?'),
            tr('Where will we locate warehouse and/or distribution centres?'),
            tr('Are the schools and hospitals still active?'),
        ]
        if self.schools_closed > 0:
            fields.append(tr(
                'Where will the students from the %s closed schools go to '
                'study?') % format_int(self.schools_closed))
        if self.hospitals_closed > 0:
            fields.append(tr(
                'Where will the patients from the %s closed hospitals go '
                'for treatment and how will we transport them?') % format_int(
                self.hospitals_closed))

        return {
            'title': title,
            'fields': fields
        }
    def action_checklist(self):
        """Breakdown by building type.

        :returns: The buildings breakdown report.
        :rtype: safe.messaging.Message
        """
        schools_closed = self.schools_closed
        hospitals_closed = self.hospitals_closed

        message = m.Message(style_class='container')
        message.add(m.Heading(tr('Action checklist'), **styles.INFO_STYLE))
        checklist = m.BulletedList()
        checklist.add(tr('Are the critical facilities still open?'))
        checklist.add(tr(
            'Which structures have warning capacity (eg. sirens, speakers, '
            'etc.)?'))
        checklist.add(tr('Which buildings will be evacuation centres?'))
        checklist.add(tr('Where will we locate the operations centre?'))
        checklist.add(
            tr('Where will we locate warehouse and/or distribution centres?'))
        if schools_closed > 0:
            checklist.add(tr(
                'Where will the students from the %s closed schools '
                'go to study?') % format_int(schools_closed))
        if hospitals_closed > 0:
            checklist.add(tr(
                'Where will the patients from the %s closed hospitals go '
                'for treatment and how will we transport them?') % format_int(
                    hospitals_closed))
        message.add(checklist)
        return message
Example #7
0
    def action_checklist(self):
        """Action checklist for the itb earthquake fatality report.

        :returns: The action checklist
        :rtype: list
        """
        total_fatalities = self.total_fatalities
        total_displaced = self.total_evacuated
        rounded_displaced = format_int(population_rounding(total_displaced))

        fields = super(ITBFatalityFunction, self).action_checklist()
        if total_fatalities:
            fields.append(
                tr('Are there enough victim identification units available '
                   'for %s people?') %
                (format_int(population_rounding(total_fatalities))))
        if rounded_displaced:
            fields.append(
                tr('Are there enough covered floor areas available for '
                   '%s people?') % rounded_displaced)
            fields.append(
                tr('Are there enough shelters and relief items available for '
                   '%s people?') % rounded_displaced)
            fields.append(
                tr('If yes, where are they located and how will we '
                   'distribute them?'))
            fields.append(
                tr('If no, where can we obtain additional relief items '
                   'from and how will we transport them?'))
            fields.append(
                tr('Are there enough water supply, sanitation, hygiene, food, '
                   'shelter, medicines and relief items available for %s '
                   'displaced people?') % rounded_displaced)

        return fields
Example #8
0
    def _tabulate_notes(self, minimum_needs, table_body, total, total_impact,
                        no_data_warning):
        # Extend impact report for on-screen display
        table_body.extend([
            TableRow(tr('Notes'), header=True),
            tr('Map shows population count in high, medium, and low hazard '
               'area.'),
            tr('Total population: %s') % format_int(total),
            TableRow(
                tr('Table below shows the minimum needs for all '
                   'affected people'))
        ])
        if no_data_warning:
            table_body.extend([
                tr('The layers contained `no data`. This missing data was '
                   'carried through to the impact layer.'),
                tr('`No data` values in the impact layer were treated as 0 '
                   'when counting the affected or total population.')
            ])

        total_needs = evacuated_population_needs(total_impact, minimum_needs)
        for frequency, needs in total_needs.items():
            table_body.append(
                TableRow([
                    tr('Needs should be provided %s' % frequency),
                    tr('Total')
                ],
                         header=True))
            for resource in needs:
                table_body.append(
                    TableRow([
                        tr(resource['table name']),
                        format_int(resource['amount'])
                    ]))
        return table_body, total_needs
Example #9
0
    def action_checklist(self):
        """Action checklist for the itb earthquake fatality report.

        :returns: The action checklist
        :rtype: list
        """
        total_fatalities = self.total_fatalities
        total_displaced = self.total_evacuated
        rounded_displaced = format_int(population_rounding(total_displaced))
        message = m.Message(style_class='container')
        message.add(m.Heading(tr('Action checklist'), **styles.INFO_STYLE))
        checklist = m.BulletedList()
        if total_fatalities:
            checklist.add(tr(
                'Are there enough victim identification units available '
                'for %s people?') % (
                    format_int(population_rounding(total_fatalities))))
        if total_displaced:
            checklist.add(tr(
                'Are there enough shelters and relief items available for '
                '%s people?') % rounded_displaced)
        if rounded_displaced:
            checklist.add(tr(
                'If yes, where are they located and how will we '
                'distribute them?'))
        if total_displaced:
            checklist.add(tr(
                'If no, where can we obtain additional relief items '
                'from and how will we transport them?'))
        message.add(checklist)
        return message
Example #10
0
    def action_checklist(self):
        """Action checklist for the itb earthquake fatality report.

        :returns: The action checklist
        :rtype: list
        """
        total_fatalities = self.total_fatalities
        total_displaced = self.total_evacuated
        rounded_displaced = format_int(population_rounding(total_displaced))
        message = m.Message(style_class='container')
        message.add(m.Heading(tr('Action checklist'), **styles.INFO_STYLE))
        checklist = m.BulletedList()
        if total_fatalities:
            checklist.add(tr(
                'Are there enough victim identification units available '
                'for %s people?') % (
                    format_int(population_rounding(total_fatalities))))
        if total_displaced:
            checklist.add(tr(
                'Are there enough shelters and relief items available for '
                '%s people?') % rounded_displaced)
        if rounded_displaced:
            checklist.add(tr(
                'If yes, where are they located and how will we '
                'distribute them?'))
        if total_displaced:
            checklist.add(tr(
                'If no, where can we obtain additional relief items '
                'from and how will we transport them?'))
        message.add(checklist)
        return message
Example #11
0
    def action_checklist(self):
        """Action checklist for the itb earthquake fatality report.

        :returns: The action checklist
        :rtype: list
        """
        total_fatalities = self.total_fatalities
        total_displaced = self.total_evacuated
        rounded_displaced = format_int(population_rounding(total_displaced))

        fields = super(ITBFatalityFunction, self).action_checklist()
        if total_fatalities:
            fields.append(
                tr("Are there enough victim identification units available " "for %s people?")
                % (format_int(population_rounding(total_fatalities)))
            )
        if rounded_displaced:
            fields.append(tr("Are there enough covered floor areas available for " "%s people?") % rounded_displaced)
            fields.append(
                tr("Are there enough shelters and relief items available for " "%s people?") % rounded_displaced
            )
            fields.append(tr("If yes, where are they located and how will we " "distribute them?"))
            fields.append(
                tr("If no, where can we obtain additional relief items " "from and how will we transport them?")
            )
            fields.append(
                tr(
                    "Are there enough water supply, sanitation, hygiene, food, "
                    "shelter, medicines and relief items available for %s "
                    "displaced people?"
                )
                % rounded_displaced
            )

        return fields
    def _tabulate(self, counts, evacuated, minimum_needs, question, rounding,
                  thresholds, total, no_data_warning):
        # noinspection PyListCreation
        table_body = [
            question,
            TableRow([(tr('People in %.1f m of water') % thresholds[-1]),
                      '%s*' % format_int(evacuated)],
                     header=True),
            TableRow(
                tr('* Number is rounded up to the nearest %s') % rounding),
            TableRow(tr('Map shows the numbers of people needing evacuation'))]
        total_needs = evacuated_population_needs(
            evacuated, minimum_needs)
        for frequency, needs in total_needs.items():
            table_body.append(TableRow(
                [
                    tr('Needs should be provided %s' % frequency),
                    tr('Total')
                ],
                header=True))
            for resource in needs:
                table_body.append(TableRow([
                    tr(resource['table name']),
                    format_int(resource['amount'])]))
        table_body.append(TableRow(tr('Action Checklist:'), header=True))
        table_body.append(TableRow(tr('How will warnings be disseminated?')))
        table_body.append(TableRow(tr('How will we reach stranded people?')))
        table_body.append(TableRow(tr('Do we have enough relief items?')))
        table_body.append(TableRow(tr('If yes, where are they located and how '
                                      'will we distribute them?')))
        table_body.append(TableRow(tr(
            'If no, where can we obtain additional relief items from and how '
            'will we transport them to here?')))
        # Extend impact report for on-screen display
        table_body.extend([
            TableRow(tr('Notes'), header=True),
            tr('Total population: %s') % format_int(total),
            tr('People need evacuation if tsunami levels exceed %(eps).1f m') %
            {'eps': thresholds[-1]},
            tr('Minimum needs are defined in BNPB regulation 7/2008'),
            tr('All values are rounded up to the nearest integer in order to '
               'avoid representing human lives as fractions.')])
        if len(counts) > 1:
            table_body.append(TableRow(tr('Detailed breakdown'), header=True))

            for i, val in enumerate(counts[:-1]):
                s = (tr('People in %(lo).1f m to %(hi).1f m of water: %(val)i')
                     % {'lo': thresholds[i],
                        'hi': thresholds[i + 1],
                        'val': format_int(val[0])})
                table_body.append(TableRow(s))
        if no_data_warning:
            table_body.extend([
                tr('The layers contained `no data`. This missing data was '
                   'carried through to the impact layer.'),
                tr('`No data` values in the impact layer were treated as 0 '
                   'when counting the affected or total population.')
            ])

        return table_body, total_needs
Example #13
0
    def test_format_int(self):
        """Test formatting integer
        """
        my_int = 10000000
        lang = os.getenv('LANG')
        my_formated_int = format_int(my_int)
        if lang == 'id':
            expected_str = '10.000.000'
        else:
            expected_str = '10,000,000'
        my_msg = 'Format integer is not valid'
        assert (my_formated_int == expected_str
                or my_formated_int == str(my_int)), my_msg

        my_int = 1234
        lang = os.getenv('LANG')
        print lang
        my_formated_int = format_int(my_int)
        if lang == 'id':
            expected_str = '1.234'
        else:
            expected_str = '1,234'
        my_msg = 'Format integer %s is not valid' % my_formated_int
        assert (my_formated_int == expected_str
                or my_formated_int == str(my_int)), my_msg
Example #14
0
    def test_format_int(self):
        """Test formatting integer
        """
        my_int = 10000000
        lang = os.getenv('LANG')
        my_formated_int = format_int(my_int)
        if lang == 'id':
            expected_str = '10.000.000'
        else:
            expected_str = '10,000,000'
        my_msg = 'Format integer is not valid'
        assert (my_formated_int == expected_str or
                my_formated_int == str(my_int)), my_msg

        my_int = 1234
        lang = os.getenv('LANG')
        print lang
        my_formated_int = format_int(my_int)
        if lang == 'id':
            expected_str = '1.234'
        else:
            expected_str = '1,234'
        my_msg = 'Format integer %s is not valid' % my_formated_int
        assert (my_formated_int == expected_str or
                my_formated_int == str(my_int)), my_msg
Example #15
0
    def notes(self):
        """Return the notes section of the report.

        :return: The notes that should be attached to this impact report.
        :rtype: list
        """
        population = format_int(population_rounding(self.total_population))
        threshold = format_int(self.parameters['evacuation_percentage'].value)

        if get_needs_provenance_value(self.parameters) is None:
            needs_provenance = ''
        else:
            needs_provenance = tr(get_needs_provenance_value(self.parameters))

        fields = [
            tr('Total population in the analysis area: %s') % population,
            tr('<sup>1</sup>The evacuation threshold used to determine '
               'population needing evacuation is %s%%.') % threshold,
            needs_provenance,
        ]

        if self.no_data_warning:
            fields = fields + no_data_warning
        # include any generic exposure specific notes from definitions.py
        fields = fields + self.exposure_notes()
        # include any generic hazard specific notes from definitions.py
        fields = fields + self.hazard_notes()
        return fields
    def test_volcano_circle_population_impact(self):
        """Volcano function runs circular evacuation zone."""
        # Name file names for hazard level, exposure and expected fatalities
        hazard_filename = '%s/Merapi_alert.shp' % TESTDATA
        exposure_filename = ('%s/glp10ag.asc' % EXPDATA)

        # Calculate impact using API
        hazard_layer = read_layer(hazard_filename)
        exposure_layer = read_layer(exposure_filename)

        plugin_name = 'Volcano Polygon Hazard Population'
        impact_function = get_plugin(plugin_name)

        impact_layer = calculate_impact(
            layers=[hazard_layer, exposure_layer], impact_fcn=impact_function)
        impact_filename = impact_layer.get_filename()

        impact_layer = read_layer(impact_filename)
        keywords = impact_layer.get_keywords()
        print keywords
        # This is the expected number of people affected
        # Distance [km]	Total	Cumulative
        # 3	     15.800	15.800
        # 5	     17.300	33.100
        # 10	125.000	158.000
        message = 'Result not as expected'
        impact_summary = keywords['impact_summary']
        self.assertTrue(format_int(15800) in impact_summary, message)
        self.assertTrue(format_int(17300) in impact_summary, message)
        self.assertTrue(format_int(125000) in impact_summary, message)
    def format_breakdown(self):
        """Breakdown by road type.

        :returns: The roads breakdown report.
        :rtype: safe.message.Message
        """
        road_breakdown = self.roads_breakdown
        attributes = road_breakdown['attributes']
        fields = road_breakdown['fields']

        message = m.Message(style_class='container')
        table = m.Table(style_class='table table-condensed table-striped')
        table.caption = None

        row = m.Row()
        row.add(m.Cell(tr('Breakdown by road type'), header=True))
        for _ in attributes:
            # Add empty cell as many as affected_categories
            row.add(m.Cell('', header=True))

        # Add empty cell for total column
        row.add(m.Cell('', header=True))
        table.add(row)

        row = m.Row()
        # We align left the first column, then right.
        row.add(m.Cell(tr(attributes[0]), header=True))
        for attribute in attributes[1:]:
            row.add(m.Cell(tr(attribute), header=True, align='right'))
        table.add(row)

        for field in fields:
            row = m.Row()
            # First column
            # proper format for i186
            row.add(m.Cell(
                tr('%(road_type)s (m)') % {
                    'road_type': tr(field[0].capitalize())}))
            # Start from second column
            for value in field[1:]:
                row.add(m.Cell(
                    format_int(int(value)), align='right'))
            table.add(row)

        impact_summary_fields = self.impact_summary['fields']

        row = m.Row()
        row.add(m.Cell(tr('Total (m)'), header=True))
        for field in impact_summary_fields:
            for value in field:
                row.add(m.Cell(
                    format_int(int(value)),
                    align='right',
                    header=True))

        table.add(row)

        message.add(table)

        return message
    def test_earthquake_building_impact_function(self):
        """Earthquake Building Impact Function works as expected."""
        # Name file names for hazard level, exposure and expected fatalities
        hazard_filename = '%s/eq_yogya_2006.asc' % HAZDATA
        exposure_filename = '%s/OSM_building_polygons_20110905.shp' % TESTDATA

        # Calculate impact using API
        hazard_layer = read_layer(hazard_filename)
        exposure_layer = read_layer(exposure_filename)

        plugin_name = 'Earthquake Building Impact Function'
        impact_function = get_plugin(plugin_name)

        # Call calculation engine
        impact_layer = calculate_impact(
            layers=[hazard_layer, exposure_layer], impact_fcn=impact_function)
        impact_filename = impact_layer.get_filename()

        impact_layer = read_layer(impact_filename)
        # calculated_result = I.get_data()
        # print calculated_result.shape
        keywords = impact_layer.get_keywords()
        impact_summary = keywords['impact_summary']

        # This is the expected number of building might be affected
        # Hazard Level - Buildings Affected
        # Low - 845
        # Medium - 15524
        # High - 122
        message = 'Result not as expected'
        self.assertTrue(format_int(845) in impact_summary, message)
        self.assertTrue(format_int(15524) in impact_summary, message)
        self.assertTrue(format_int(122) in impact_summary, message)
Example #19
0
    def action_checklist(self):
        """Action checklist for the itb earthquake fatality report.

        :returns: The action checklist
        :rtype: list
        """
        total_fatalities = self.total_fatalities
        total_displaced = self.total_evacuated
        rounded_displaced = format_int(population_rounding(total_displaced))

        fields = super(ITBFatalityFunction, self).action_checklist()
        if total_fatalities:
            fields.append(tr(
                'Are there enough victim identification units available '
                'for %s people?') % (
                    format_int(population_rounding(total_fatalities))))
        if total_displaced:
            fields.append(tr(
                'Are there enough shelters and relief items available for '
                '%s people?') % rounded_displaced)
        if rounded_displaced:
            fields.append(tr(
                'If yes, where are they located and how will we '
                'distribute them?'))
        if total_displaced:
            fields.append(tr(
                'If no, where can we obtain additional relief items '
                'from and how will we transport them?'))

        return fields
    def roads_breakdown(self):
        """Breakdown by road type.

        :returns: The roads breakdown report.
        :rtype: list
        """
        category_names = self.affected_road_categories
        roads_breakdown_report = [({"content": (tr("Breakdown by road type")), "header": True})]
        for road_type in self.road_lengths:
            affected_by_usage = []
            for category in category_names:
                if road_type in self.affected_road_lengths[category]:
                    affected_by_usage.append(self.affected_road_lengths[category][road_type])
                else:
                    affected_by_usage.append(0)
            road_detail = (
                # building type
                [road_type.capitalize()]
                +
                # categories
                [format_int(int(x)) for x in affected_by_usage]
                +
                # total
                [format_int(int(self.road_lengths[road_type]))]
            )
            roads_breakdown_report.append({"content": road_detail})

        return roads_breakdown_report
Example #21
0
    def test_volcano_circle_population_impact(self):
        """Volcano function runs circular evacuation zone."""
        # Name file names for hazard level, exposure and expected fatalities
        hazard_filename = '%s/Merapi_alert.shp' % TESTDATA
        exposure_filename = ('%s/glp10ag.asc' % EXPDATA)

        # Calculate impact using API
        hazard_layer = read_layer(hazard_filename)
        exposure_layer = read_layer(exposure_filename)

        plugin_name = 'Volcano Polygon Hazard Population'
        impact_function = get_plugin(plugin_name)

        impact_layer = calculate_impact(layers=[hazard_layer, exposure_layer],
                                        impact_fcn=impact_function)
        impact_filename = impact_layer.get_filename()

        impact_layer = read_layer(impact_filename)
        keywords = impact_layer.get_keywords()
        print keywords
        # This is the expected number of people affected
        # Distance [km]	Total	Cumulative
        # 3	     15.800	15.800
        # 5	     17.300	33.100
        # 10	125.000	158.000
        message = 'Result not as expected'
        impact_summary = keywords['impact_summary']
        self.assertTrue(format_int(15800) in impact_summary, message)
        self.assertTrue(format_int(17300) in impact_summary, message)
        self.assertTrue(format_int(125000) in impact_summary, message)
    def hazard_table(self, hazard_table):
        """ Return updated hazard table.

        :param hazard_table: hazard table.
        :type hazard_table: Table

        :returns hazard_table: Updated Hazard Table
        :rtype area_name: Table
        """
        hazard_table.caption = None

        for key, value in self.hazard_levels.iteritems():

            name = self.hazard_class_mapping[key][0]
            # This skips reporting people not affected in No zone
            if key == 'wet':
                row = m.Row()
                row.add(m.Cell(tr(
                    'People within hazard field ("%s") of value "%s"')
                               % (self.hazard_class_field, name),
                               header=True))
                value = format_int(population_rounding(value))
                row.add(m.Cell(value, align='right'))
            elif key == 'dry':
                continue
            else:
                row = m.Row()
                row.add(m.Cell(name, header=True))
                value = format_int(population_rounding(value))
                row.add(m.Cell(value, align='right'))
            hazard_table.add(row)

        # Total affected population
        row = m.Row()
        row.add(m.Cell(
            tr('Total affected people'),
            header=True))
        affected = format_int(
            population_rounding(self.total_affected_population))
        row.add(m.Cell(affected, align='right'))
        hazard_table.add(row)

        # Non affected population
        row = m.Row()
        unaffected = format_int(
            population_rounding(self.unaffected_population))
        row.add(m.Cell(tr('Unaffected people'), header=True))
        row.add(m.Cell(unaffected, align='right'))
        hazard_table.add(row)

        # Total Population
        row = m.Row()
        total_population = format_int(
            population_rounding(self.total_population))
        row.add(m.Cell(tr('Total people'), header=True))
        row.add(m.Cell(total_population, align='right'))
        hazard_table.add(row)

        return hazard_table
    def impact_summary(self):
        """The impact summary as per category

        :returns: The impact summary.
        :rtype: safe.message.Message
        """
        affected_categories = self.affected_road_categories

        message = m.Message(style_class='container')
        table = m.Table(style_class='table table-condensed table-striped')
        table.caption = None

        row = m.Row()
        row.add(m.Cell(tr('Summary by road type'), header=True))
        for _ in affected_categories:
            # Add empty cell as many as affected_categories
            row.add(m.Cell('', header=True))

        if self.add_unaffected_column:
            # Add empty cell for un-affected road
            row.add(m.Cell('', header=True))

        # Add empty cell for total column
        row.add(m.Cell('', header=True))
        table.add(row)

        row = m.Row()
        row.add(m.Cell(tr('Road Type'), header=True))
        for affected_category in affected_categories:
            row.add(m.Cell(affected_category, header=True, align='right'))

        if self.add_unaffected_column:
            row.add(m.Cell(tr('Unaffected'), header=True, align='right'))

        row.add(m.Cell(tr('Total'), header=True, align='right'))
        table.add(row)

        total_affected = [0] * len(affected_categories)
        for (category, road_breakdown) in self.affected_road_lengths.items():
            number_affected = sum(road_breakdown.values())
            count = affected_categories.index(category)
            total_affected[count] = number_affected

        row = m.Row()
        row.add(m.Cell(tr('All (m)')))
        for total_affected_value in total_affected:
            row.add(m.Cell(
                format_int(int(total_affected_value)), align='right'))
        if self.add_unaffected_column:
            row.add(m.Cell(format_int(int(
                self.total_road_length - sum(total_affected))), align='right'))

        row.add(m.Cell(format_int(int(self.total_road_length)), align='right'))
        table.add(row)

        message.add(table)

        return message
    def hazard_table(self, hazard_table):
        """ Return updated hazard table.

        :param hazard_table: hazard table.
        :type hazard_table: Table

        :returns hazard_table: Updated Hazard Table
        :rtype area_name: Table
        """
        hazard_table.caption = None

        for key, value in self.hazard_levels.iteritems():

            name = self.hazard_class_mapping[key][0]
            # This skips reporting people not affected in No zone
            if key == 'wet':
                row = m.Row()
                row.add(
                    m.Cell(
                        tr('People within hazard field ("%s") of value "%s"') %
                        (self.hazard_class_field, name),
                        header=True))
                value = format_int(population_rounding(value))
                row.add(m.Cell(value, align='right'))
            elif key == 'dry':
                continue
            else:
                row = m.Row()
                row.add(m.Cell(name, header=True))
                value = format_int(population_rounding(value))
                row.add(m.Cell(value, align='right'))
            hazard_table.add(row)

        # Total affected population
        row = m.Row()
        row.add(m.Cell(tr('Total affected people'), header=True))
        affected = format_int(
            population_rounding(self.total_affected_population))
        row.add(m.Cell(affected, align='right'))
        hazard_table.add(row)

        # Non affected population
        row = m.Row()
        unaffected = format_int(population_rounding(
            self.unaffected_population))
        row.add(m.Cell(tr('Unaffected people'), header=True))
        row.add(m.Cell(unaffected, align='right'))
        hazard_table.add(row)

        # Total Population
        row = m.Row()
        total_population = format_int(
            population_rounding(self.total_population))
        row.add(m.Cell(tr('Total people'), header=True))
        row.add(m.Cell(total_population, align='right'))
        hazard_table.add(row)

        return hazard_table
    def _tabulate(self, affected_population, evacuated, minimum_needs,
                  question, rounding, rounding_evacuated):
        # People Affected
        table_body = [
            question,
            TableRow(
                [tr('People affected'), '%s*' % (
                    format_int(int(affected_population)))],
                header=True)]
        if self.use_affected_field:
            table_body.append(
                TableRow(
                    tr('* People are considered to be affected if they are '
                       'within the area where the value of the hazard field ('
                       '"%s") is "%s"') %
                    (self.parameters['affected_field'],
                     self.parameters['affected_value'])))
        else:
            table_body.append(
                TableRow(
                    tr('* People are considered to be affected if they are '
                       'within any polygons.')))
        table_body.append(
            TableRow([TableCell(
                tr('* Number is rounded up to the nearest %s') % rounding,
                col_span=2)]))

        # People Needing Evacuation
        table_body.append(
            TableRow([tr('People needing evacuation'), '%s*' % (
                format_int(int(evacuated)))], header=True))
        table_body.append(TableRow(
            [TableCell(
                tr('* Number is rounded up to the nearest %s') %
                rounding_evacuated, col_span=2)]))
        table_body.append(
            TableRow(
                [tr('Evacuation threshold'), '%s%%' % format_int(
                    self.parameters['evacuation_percentage'])], header=True))
        table_body.append(
            TableRow(tr('Table below shows the weekly minimum needs for all '
                        'evacuated people')))

        total_needs = evacuated_population_needs(evacuated, minimum_needs)
        for frequency, needs in total_needs.items():
            table_body.append(TableRow(
                [
                    tr('Needs should be provided %s' % frequency),
                    tr('Total')
                ],
                header=True))
            for resource in needs:
                table_body.append(TableRow([
                    tr(resource['table name']),
                    format_int(resource['amount'])]))
        return table_body, total_needs
Example #26
0
    def notes(self):
        """Return the notes section of the report.

        :return: The notes that should be attached to this impact report.
        :rtype: list
        """
        notes = [
            {'content': tr('Notes'), 'header': True},
            {
                'content': tr('Total population: %s') % format_int(
                    population_rounding(self.total_population))
            },
            {
                'content': tr(
                    '<sup>1</sup>The evacuation threshold used to determine '
                    'population needing evacuation is %s%%.'),
                'arguments': format_int(
                    self.parameters['evacuation_percentage'].value)
            },
            {
                'content': tr(
                    ''
                    'are within any polygons.'),
                'condition': not self.use_affected_field
            },
            {
                'content': tr(
                    'The layers contained `no data`. This missing data was '
                    'carried through to the impact layer.'),
                'condition': self.no_data_warning
            },
            {
                'content': tr(
                    '`No data` values in the impact layer were treated as 0 '
                    'when counting the affected or total population.'),
                'condition': self.no_data_warning
            },
            {
                'content': get_needs_provenance_value(self.parameters)
            },
            {
                'content': tr(
                    'All values are rounded up to the nearest integer in '
                    'order to avoid representing human lives as fractions.'),
            },
            {
                'content': tr(
                    'Population rounding is applied to all population '
                    'values, which may cause discrepancies when adding '
                    'values.'
                )
            }
        ]
        return notes
    def impact_row(
            area_name,
            affected,
            percent_affected,
            single_total_area,
            number_people_affected,
            percent_people_affected,
            area_population):
        """Adds the calculated results into respective impact row

        :param area_name: Area Name
        :type area_name: str

        :param affected: table with first and second row
        :type affected: Table

        :param percent_affected: percentage of affected area
        :type percent_affected: float

        :param single_total_area: total area of the land
        :type single_total_area: float

        :param number_people_affected: number of people affected
        :type number_people_affected: float

        :param percent_people_affected: percentage of people affected
        in the area
        :type percent_people_affected: float

        :param area_population: Population of the area
        :type area_population: float

        :return row: the new impact row
        :rtype row: Row
        """

        row = m.Row()
        row.add(m.Cell(area_name))
        row.add(m.Cell(format_int(int(affected)), align='right'))
        row.add(m.Cell(
            "%.1f%%" % percent_affected, align='right'))
        row.add(m.Cell(
            format_int(int(single_total_area)), align='right'))
        row.add(m.Cell(
            format_int(int(number_people_affected)),
            align='right'))
        row.add(m.Cell("%.1f%%" % percent_people_affected, align='right'))
        row.add(m.Cell(
            format_int(int(area_population)),
            align='right'))

        return row
    def format_postprocessing(self):
        """Format postprocessing.

        :returns: The postprocessing.
        :rtype: safe.messaging.Message
        """
        if not self.postprocessing:
            return False
        message = m.Message()
        for k, v in self.postprocessing.items():
            table = m.Table(
                style_class='table table-condensed table-striped')
            table.caption = v['caption']
            attributes = v['attributes']

            if attributes:
                header = m.Row()
                # Bold and align left the 1st one.

                header.add(m.Cell(attributes[0], header=True, align='left'))
                for attribute in attributes[1:]:
                    # Bold and align right.
                    header.add(m.Cell(attribute, header=True, align='right'))
                header.add(m.Cell('Total', header=True, align='right'))
                table.add(header)

                for field in v['fields']:
                    row = m.Row()
                    # First column is string
                    row.add(m.Cell(field[0]))
                    total = 0
                    for value in field[1:]:
                        try:
                            val = int(value)
                            total += val
                            # Align right integers.
                            row.add(m.Cell(format_int(val), align='right'))
                        except ValueError:
                            # Catch no data value. Align left strings.
                            row.add(m.Cell(value, align='left'))

                    row.add(m.Cell(
                        format_int(int(round(total))), align='right'))
                    table.add(row)

            message.add(table)

            for note in v['notes']:
                message.add(m.EmphasizedText(note))

        return message
    def impact_summary(self):
        """Create impact summary as data.

        :returns: Impact Summary in dictionary format.
        :rtype: dict
        """
        attributes = ['category', 'value']
        fields = []

        # Breakdown by hazard level (if available)
        if len(self.impact_category_ordering):
            for category in self.impact_category_ordering:
                population_in_category = self.lookup_category(category)
                population_in_category = format_int(population_rounding(
                    population_in_category
                ))
                row = [tr(category), population_in_category]
                fields.append(row)

        # Total affected population
        row = [
            tr('Total affected population'),
            format_int(population_rounding(self.total_affected_population))
        ]
        fields.append(row)

        # Non affected population
        row = [
            tr('Unaffected population'),
            format_int(population_rounding(self.unaffected_population))
        ]
        fields.append(row)

        # Total Population
        row = [
            tr('Total population'),
            format_int(population_rounding(self.total_population))
        ]
        fields.append(row)

        # Population needing evacuation
        row = [
            tr('Population needing evacuation <sup>1</sup>'),
            format_int(population_rounding(self.total_evacuated))
        ]
        fields.append(row)

        return {
            'attributes': attributes,
            'fields': fields
        }
Example #30
0
    def generate_analysis_result_html(self):
        """Return a HTML table of the analysis result

        :return: A file path to the html file saved to disk.
        """
        message = m.Message(style_class='report')
        # Table for affected population
        table = m.Table(style_class='table table-condensed table-striped')
        row = m.Row()
        total_people = self.tr('%s') % format_int(population_rounding(
            self.impact_data.total_affected_population))
        estimates_idp = self.tr('%s') % format_int(population_rounding(
            self.impact_data.estimates_idp))
        row.add(m.Cell(
            self.tr('Total affected population (people)'), header=True))
        row.add(m.Cell(total_people, style_class="text-right"))
        table.add(row)
        row = m.Row()
        row.add(m.Cell(self.tr('Estimates of IDP (people)'), header=True))
        row.add(m.Cell(estimates_idp, style_class="text-right"))
        table.add(row)
        message.add(table)
        # Table for minimum needs
        for k, v in self.impact_data.minimum_needs.iteritems():
            section = self.tr('Relief items to be provided %s :') % k
            # text = m.Text(section)
            row = m.Row(style_class='alert-info')
            row.add(m.Cell(section, header=True, attributes='colspan=2'))
            # message.add(text)
            table = m.Table(
                header=row,
                style_class='table table-condensed table-striped')
            for e in v:
                row = m.Row()
                need_name = self.tr(e['name'])
                need_number = format_int(
                    population_rounding(e['amount']))
                need_unit = self.tr(e['unit']['abbreviation'])
                if need_unit:
                    need_string = '%s (%s)' % (need_name, need_unit)
                else:
                    need_string = need_name
                row.add(m.Cell(need_string, header=True))
                row.add(m.Cell(need_number, style_class="text-right"))
                table.add(row)
            message.add(table)

        path = self.write_html_table('impact_analysis_report.html', message)
        return path
Example #31
0
    def impact_summary(self):
        """The impact summary as per category.

        :returns: The impact summary.
        :rtype: safe.messaging.Message
        """
        affect_types = self._impact_breakdown
        message = m.Message(style_class='container')
        table = m.Table(style_class='table table-condensed table-striped')
        table.caption = None
        row = m.Row()
        row.add(m.Cell('', header=True))  # intentionally empty top left cell
        row.add(m.Cell('Buildings affected', header=True))
        for (category, building_breakdown) in self.affected_buildings.items():
            total_affected = [0] * len(affect_types)
            for affected_breakdown in building_breakdown.values():
                for affect_type, number_affected in affected_breakdown.items():
                    count = affect_types.index(affect_type)
                    total_affected[count] += number_affected
            row = m.Row()
            row.add(m.Cell(tr(category), header=True))
            for affected in total_affected:
                row.add(m.Cell(format_int(affected), align='right'))
            table.add(row)

        if len(self._affected_categories) > 1:
            row = m.Row()
            row.add(m.Cell(tr('Affected buildings'), header=True))
            row.add(
                m.Cell(format_int(self.total_affected_buildings),
                       align='right'))
            table.add(row)

        # Only show not affected building row if the IF does not use custom
        # affected categories
        if self._affected_categories == self.affected_buildings.keys():
            row = m.Row()
            row.add(m.Cell(tr('Not affected buildings'), header=True))
            row.add(
                m.Cell(format_int(self.total_unaffected_buildings),
                       align='right'))
            table.add(row)

        row = m.Row()
        row.add(m.Cell(tr('Total'), header=True))
        row.add(m.Cell(format_int(self.total_buildings), align='right'))
        table.add(row)
        message.add(table)
        return message
Example #32
0
    def format_impact_table(self):
        """Impact detailed report.

        :returns: The detailed report.
        :rtype: safe.messaging.Message
        """
        message = m.Message(style_class='container')
        table = m.Table(style_class='table table-condensed table-striped')
        table.caption = None

        # Table header
        row = m.Row()
        attributes = self.impact_table['attributes']
        # Bold and align left the 1st one.
        row.add(m.Cell(attributes[0], header=True, align='left'))
        for attribute in attributes[1:]:
            # Bold and align right.
            row.add(m.Cell(attribute, header=True, align='right'))
        table.add(row)

        # Fields
        for record in self.impact_table['fields'][:-1]:
            row = m.Row()
            # Bold and align left the 1st one.
            row.add(m.Cell(record[0], header=True, align='left'))
            for content in record[1:-1]:
                # Align right.
                row.add(m.Cell(format_int(int(content)), align='right'))
            # Bold and align right the last one.
            row.add(
                m.Cell(format_int(int(record[-1])), header=True,
                       align='right'))
            table.add(row)

        # Total Row
        row = m.Row()
        last_row = self.impact_table['fields'][-1]
        # Bold and align left the 1st one.
        row.add(m.Cell(last_row[0], header=True, align='left'))
        for content in last_row[1:]:
            # Bold and align right.
            row.add(
                m.Cell(format_int(int(content)), header=True, align='right'))
        table.add(row)

        message.add(table)

        return message
    def impact_summary(self):
        """The impact summary as per category.

        :returns: The impact summary.
        :rtype: safe.messaging.Message
        """
        affect_types = self._impact_breakdown
        message = m.Message(style_class='container')
        table = m.Table(style_class='table table-condensed table-striped')
        table.caption = None
        row = m.Row()
        row.add(m.Cell('', header=True))  # intentionally empty top left cell
        row.add(m.Cell('Buildings affected', header=True))
        for (category, building_breakdown) in self.affected_buildings.items():
            total_affected = [0] * len(affect_types)
            for affected_breakdown in building_breakdown.values():
                for affect_type, number_affected in affected_breakdown.items():
                    count = affect_types.index(affect_type)
                    total_affected[count] += number_affected
            row = m.Row()
            row.add(m.Cell(tr(category), header=True))
            for affected in total_affected:
                row.add(m.Cell(format_int(affected), align='right'))
            table.add(row)

        if len(self._affected_categories) > 1:
            row = m.Row()
            row.add(m.Cell(tr('Affected buildings'), header=True))
            row.add(m.Cell(
                format_int(self.total_affected_buildings), align='right'))
            table.add(row)

        # Only show not affected building row if the IF does not use custom
        # affected categories
        if self._affected_categories == self.affected_buildings.keys():
            row = m.Row()
            row.add(m.Cell(tr('Not affected buildings'), header=True))
            row.add(m.Cell(
                format_int(self.total_unaffected_buildings), align='right'))
            table.add(row)

        row = m.Row()
        row.add(m.Cell(tr('Total'), header=True))
        row.add(m.Cell(
            format_int(self.total_buildings), align='right'))
        table.add(row)
        message.add(table)
        return message
Example #34
0
    def format_impact_table(self):
        """Impact detailed report.

        :returns: The detailed report.
        :rtype: safe.messaging.Message
        """
        message = m.Message(style_class='container')
        table = m.Table(style_class='table table-condensed table-striped')
        table.caption = None

        # Table header
        row = m.Row()
        attributes = self.impact_table['attributes']
        # Bold and align left the 1st one.
        row.add(m.Cell(attributes[0], header=True, align='left'))
        for attribute in attributes[1:]:
            # Bold and align right.
            row.add(m.Cell(attribute, header=True, align='right'))
        table.add(row)

        # Fields
        for record in self.impact_table['fields'][:-1]:
            row = m.Row()
            # Bold and align left the 1st one.
            row.add(m.Cell(record[0], header=True, align='left'))
            for content in record[1:-1]:
                # Align right.
                row.add(m.Cell(format_int(int(content)), align='right'))
            # Bold and align right the last one.
            row.add(
                m.Cell(
                    format_int(int(record[-1])), header=True, align='right'))
            table.add(row)

        # Total Row
        row = m.Row()
        last_row = self.impact_table['fields'][-1]
        # Bold and align left the 1st one.
        row.add(m.Cell(last_row[0], header=True, align='left'))
        for content in last_row[1:]:
            # Bold and align right.
            row.add(
                m.Cell(format_int(int(content)), header=True, align='right'))
        table.add(row)

        message.add(table)

        return message
Example #35
0
    def notes(self):
        """Notes and caveats for the IF report.

        :returns: Dicts containing notes.
        :rtype: list
        """
        fields = [
            tr('Total population in the analysis area: %s') %
            format_int(population_rounding(self.total_population)),
            tr('<sup>1</sup>People are displaced if they experience and '
               'survive a shake level of more than 5 on the MMI scale.'),
            tr('The fatality calculation assumes that no fatalities occur for '
               'shake levels below 4 and fatality counts of less than 50 are '
               'disregarded.')
        ]
        if self.__class__ != ITBFatalityFunction:
            fields.append(tr(
                'Fatality model is from Institut Teknologi Bandung 2012.'))
            fields.append(tr(
                'Fatality model is from the Population Vulnerability '
                'Pager Model.'))
        fields.extend([
            tr('Map shows the estimation of displaced population.'),
        ])
        # include any generic exposure specific notes from definitions.py
        fields = fields + self.exposure_notes()
        # include any generic hazard specific notes from definitions.py
        fields = fields + self.hazard_notes()
        return fields
    def minimum_needs_breakdown(self):
        """Breakdown by population.

        :returns: The population breakdown report.
        :rtype: list
        """
        message = m.Message(style_class='container')
        message.add(m.Heading(
            tr('Evacuated population minimum needs'),
            **styles.INFO_STYLE))
        table = m.Table(
            style_class='table table-condensed table-striped')
        table.caption = None
        total_needs = self.total_needs
        for frequency, needs in total_needs.items():
            row = m.Row()
            row.add(m.Cell(
                tr('Relief items to be provided %s' % frequency),
                header=True
            ))
            row.add(m.Cell(tr('Total'), header=True, align='right'))
            table.add(row)
            for resource in needs:
                row = m.Row()
                row.add(m.Cell(tr(resource['table name'])))
                row.add(m.Cell(
                    tr(format_int(resource['amount'])),
                    align='right'
                ))
                table.add(row)
        message.add(table)
        return message
Example #37
0
    def notes(self):
        """Return the notes section of the report.

        :return: The notes that should be attached to this impact report.
        :rtype: list
        """
        if get_needs_provenance_value(self.parameters) is None:
            needs_provenance = ''
        else:
            needs_provenance = tr(get_needs_provenance_value(self.parameters))

        if self.volcano_names:
            sorted_volcano_names = ', '.join(sorted(self.volcano_names))
        else:
            sorted_volcano_names = tr('Not specified in data')

        fields = [
            tr('Map shows buildings affected in each of the volcano buffered '
               'zones.'),
            tr('Total population in the analysis area: %s') %
            format_int(population_rounding(self.total_population)),
            tr('<sup>1</sup>People need evacuation if they are within the '
               'volcanic hazard zones.'),
            tr('Volcanoes considered: %s.') % sorted_volcano_names,
        ]
        if needs_provenance:
            fields.append(needs_provenance)

        if self.no_data_warning:
            fields = fields + no_data_warning
        # include any generic exposure specific notes from definitions.py
        fields = fields + self.exposure_notes()
        # include any generic hazard specific notes from definitions.py
        fields = fields + self.hazard_notes()
        return fields
Example #38
0
    def format_int(number):
        """Get the correct integer format.

        :param number: The number to format
        :type number: float or integer
        """
        return format_int(int(number))
Example #39
0
    def test_issue47(self):
        """Issue47: Hazard & exposure data are in different proj to viewport.

        See https://github.com/AIFDR/inasafe/issues/47"""

        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(GOOGLECRS, True)
        set_jakarta_google_extent(self.dock)

        # Press RUN
        self.dock.accept()

        result = self.dock.wvResults.page_to_text()

        message = 'Result not as expected: %s' % result
        # searching for values 6700 clean water [l] in result
        self.assertTrue(format_int(6700) in result, message)
    def minimum_needs_breakdown(self):
        """Breakdown by population.

        :returns: The population breakdown report.
        :rtype: list
        """
        message = m.Message(style_class='container')
        message.add(
            m.Heading(tr('Evacuated population minimum needs'),
                      **styles.INFO_STYLE))
        table = m.Table(style_class='table table-condensed table-striped')
        table.caption = None
        total_needs = self.total_needs
        for frequency, needs in total_needs.items():
            row = m.Row()
            row.add(
                m.Cell(tr('Relief items to be provided %s' % frequency),
                       header=True))
            row.add(m.Cell(tr('Total'), header=True, align='right'))
            table.add(row)
            for resource in needs:
                row = m.Row()
                row.add(m.Cell(tr(resource['table name'])))
                row.add(
                    m.Cell(tr(format_int(resource['amount'])), align='right'))
                table.add(row)
        message.add(table)
        return message
Example #41
0
    def notes(self):
        """Return the notes section of the report.

        :return: The notes that should be attached to this impact report.
        :rtype: safe.messaging.Message
        """
        message = m.Message(style_class='container')
        message.add(m.Heading(tr('Notes and assumptions'),
                              **styles.INFO_STYLE))
        checklist = m.BulletedList()
        population = format_int(population_rounding(self.total_population))
        checklist.add(
            tr('Total population in the analysis area: %s') % population)
        checklist.add(
            tr('<sup>1</sup>People need evacuation if they are in a '
               'hazard zone.'))
        checklist.add(
            tr('Map shows population count in high, medium, and low '
               'hazard areas.'))
        checklist.add(
            tr('All values are rounded up to the nearest integer in '
               'order to avoid representing human lives as fractions.'))
        checklist.add(
            tr('Population rounding is applied to all population '
               'values, which may cause discrepancies when adding values.'))
        message.add(checklist)
        return message
Example #42
0
    def test_volcano_population_evacuation_impact(self):
        """Population impact from volcanic hazard is computed correctly."""
        # Name file names for hazard level, exposure and expected fatalities
        hazard_filename = '%s/donut.shp' % TESTDATA
        exposure_filename = ('%s/pop_merapi_clip.tif' % TESTDATA)

        # Calculate impact using API
        hazard_layer = read_layer(hazard_filename)
        exposure_layer = read_layer(exposure_filename)

        plugin_name = 'Volcano Polygon Hazard Population'
        impact_function = get_plugin(plugin_name)

        impact_layer = calculate_impact(layers=[hazard_layer, exposure_layer],
                                        impact_fcn=impact_function)
        impact_filename = impact_layer.get_filename()

        impact_layer = read_layer(impact_filename)

        keywords = impact_layer.get_keywords()

        # Check for expected results:
        for value in ['Merapi', 192055, 56514, 68568, 66971]:
            if isinstance(value, int):
                x = format_int(population_rounding(value))
            else:
                x = value
            summary = keywords['impact_summary']
            msg = ('Did not find expected value %s in summary %s' %
                   (x, summary))
            assert x in summary, msg
Example #43
0
    def _tabulate_action_checklist(self, table_body, total, nan_warning):
        # Action Checklist
        table_body.append(TableRow(tr('Action Checklist:'), header=True))
        table_body.append(TableRow(tr('How will warnings be disseminated?')))
        table_body.append(TableRow(tr('How will we reach stranded people?')))
        table_body.append(TableRow(tr('Do we have enough relief items?')))
        table_body.append(
            TableRow(
                'If yes, where are they located and how will we distribute '
                'them?'))
        table_body.append(
            TableRow(
                'If no, where can we obtain additional relief items from and '
                'how will we transport them to here?'))

        # Notes
        table_body.append(TableRow(tr('Notes'), header=True))
        table_body.append(
            TableRow(tr('Total population: %s') % format_int(total)))
        table_body.append(TableRow(self.parameters['provenance']))
        if nan_warning:
            table_body.extend([
                tr('The population layer contained `no data`. This missing '
                   'data was carried through to the impact layer.'),
                tr('`No data` values in the impact layer were treated as 0 '
                   'when counting the affected or total population.')
            ])
    def format_impact_summary(self):
        """The impact summary as per category

        :returns: The impact summary.
        :rtype: safe.message.Message
        """
        attributes = self.impact_summary['attributes']
        fields = self.impact_summary['fields']

        message = m.Message(style_class='container')
        table = m.Table(style_class='table table-condensed table-striped')
        table.caption = None

        row = m.Row()
        row.add(m.Cell(tr('Summary by road type'), header=True))
        for _ in attributes:
            row.add(m.Cell('', header=True))

        row = m.Row()
        row.add(m.Cell(tr('Road Type'), header=True))
        for affected_category in attributes:
            row.add(m.Cell(tr(affected_category), header=True, align='right'))
        table.add(row)

        row = m.Row()
        row.add(m.Cell(tr('All (m)')))
        for total_affected_value in fields[0]:
            row.add(m.Cell(
                format_int(int(total_affected_value)), align='right'))

        table.add(row)

        message.add(table)

        return message
Example #45
0
 def _tabulate_action_checklist(self, table_body, total, no_data_warning):
     table_body.append(TableRow(tr('Action Checklist:'), header=True))
     table_body.append(TableRow(tr('How will warnings be disseminated?')))
     table_body.append(TableRow(tr('How will we reach stranded people?')))
     table_body.append(TableRow(tr('Do we have enough relief items?')))
     table_body.append(
         TableRow(
             tr('If yes, where are they located and how will we distribute '
                'them?')))
     table_body.append(
         TableRow(
             tr('If no, where can we obtain additional relief items from '
                'and how will we transport them to here?')))
     # Extend impact report for on-screen display
     table_body.extend([
         TableRow(tr('Notes'), header=True),
         tr('Map shows the numbers of people in high, medium, and low '
            'hazard class areas'),
         tr('Total population: %s') % format_int(total)
     ])
     if no_data_warning:
         table_body.extend([
             tr('The layers contained `no data`. This missing data was '
                'carried through to the impact layer.'),
             tr('`No data` values in the impact layer were treated as 0 '
                'when counting the affected or total population.')
         ])
     return table_body
    def notes(self):
        """Return the notes section of the report.

        :return: The notes that should be attached to this impact report.
        :rtype: safe.messaging.Message
        """
        message = m.Message(style_class="container")
        message.add(m.Heading(tr("Notes and assumptions"), **styles.INFO_STYLE))
        checklist = m.BulletedList()
        population = format_int(population_rounding(self.total_population))
        checklist.add(tr("Total population in the analysis area: %s") % population)
        checklist.add(tr("<sup>1</sup>People need evacuation if they are in a " "hazard zone."))
        checklist.add(tr("Map shows population count in high, medium, and low " "hazard areas."))
        checklist.add(
            tr(
                "All values are rounded up to the nearest integer in "
                "order to avoid representing human lives as fractions."
            )
        )
        checklist.add(
            tr(
                "Population rounding is applied to all population "
                "values, which may cause discrepancies when adding values."
            )
        )
        message.add(checklist)
        return message
    def _append_result(self, name, result, metadata=None):
        """add an indicator results to the postprocessors result.

        internal method to be used by the postprocessors to add an indicator
        results to the postprocessors result

        Args:
            * name: str the name of the indicator
            * result the value calculated by the indicator
            * metadata Dict of metadata
        Returns:
            None
        Raises:
            None
        """

        if metadata is None:
            metadata = dict()
        # LOGGER.debug('name : ' + str(name) + '\nresult : ' + str(result))
        if result is not None and result != self.NO_DATA_TEXT:
            try:
                result = format_int(result)
            except ValueError as e:
                LOGGER.debug(e)
                result = result
        self._results[name] = {'value': result,
                               'metadata': metadata}
Example #48
0
    def _append_result(self, name, result, metadata=None):
        """add an indicator results to the postprocessors result.

        internal method to be used by the postprocessors to add an indicator
        results to the postprocessors result

        Args:
            * name: str the name of the indicator
            * result the value calculated by the indicator
            * metadata Dict of metadata
        Returns:
            None
        Raises:
            None
        """
        if metadata is None:
            metadata = dict()
        LOGGER.debug('name : ' + str(name) + '\nresult : ' + str(result))
        if result is not None and result != self.NO_DATA_TEXT:
            try:
                result = format_int(result)
            except ValueError as e:
                LOGGER.debug(e)
                result = result
        self._results[name] = {'value': result, 'metadata': metadata}
    def test_volcano_building_impact(self):
        """Building impact from volcanic hazard is computed correctly."""
        # Name file names for hazard level, exposure and expected fatalities
        hazard_filename = os.path.join(TESTDATA, 'donut.shp')
        exposure_filename = test_data_path('exposure', 'bangunan.shp')

        # Calculate impact using API
        hazard = read_layer(hazard_filename)
        exposure = read_layer(exposure_filename)

        plugin_name = 'Volcano Building Impact'
        impact_function = get_plugin(plugin_name)
        impact_function.parameters['name attribute'] = 'GUNUNG'
        print 'Calculating'
        # Call calculation engine
        impact_layer = calculate_impact(
            layers=[hazard, exposure], impact_fcn=impact_function)
        impact_filename = impact_layer.get_filename()

        impact = read_layer(impact_filename)

        keywords = impact.get_keywords()

        # Check for expected results:
        for value in ['Merapi', 5, 86, 91, 1, 21, 22, 6, 107, 113]:
            if isinstance(value, int):
                x = format_int(value)
            else:
                x = value
            summary = keywords['impact_summary']
            message = (
                'Did not find expected value %s in summary %s' % (x, summary))
            self.assertIn(x, summary, message)
Example #50
0
    def notes(self):
        """Return the notes section of the report.

        :return: The notes that should be attached to this impact report.
        :rtype: list
        """
        population = format_int(population_rounding(self.total_population))
        thresholds = self.parameters['thresholds'].value

        if get_needs_provenance_value(self.parameters) is None:
            needs_provenance = ''
        else:
            needs_provenance = tr(get_needs_provenance_value(self.parameters))

        fields = [
            tr('Total population in the analysis area: %s') % population,
            tr('<sup>1</sup>People need evacuation if flood levels exceed '
               '%(eps).1f m.') % {
                   'eps': thresholds[-1]
               },
            needs_provenance,
        ]

        if self.no_data_warning:
            fields = fields + no_data_warning
        # include any generic exposure specific notes from definitions.py
        fields = fields + self.exposure_notes()
        # include any generic hazard specific notes from definitions.py
        fields = fields + self.hazard_notes()
        return fields
Example #51
0
    def notes(self):
        """Return the notes section of the report.

        :return: The notes that should be attached to this impact report.
        :rtype: list
        """
        if get_needs_provenance_value(self.parameters) is None:
            needs_provenance = ''
        else:
            needs_provenance = tr(get_needs_provenance_value(self.parameters))

        if self.volcano_names:
            sorted_volcano_names = ', '.join(sorted(self.volcano_names))
        else:
            sorted_volcano_names = tr('Not specified in data')

        fields = [
            tr('Total population in the analysis area: %s') %
            format_int(population_rounding(self.total_population)),
            tr('<sup>1</sup>People need evacuation if they are within the '
               'volcanic hazard zones.'),
            tr('Volcanoes considered: %s.') % sorted_volcano_names
        ]

        if needs_provenance:
            fields.append(needs_provenance)

        if self.no_data_warning:
            fields = fields + no_data_warning

        # include any generic exposure specific notes from definitions.py
        fields = fields + self.exposure_notes()
        # include any generic hazard specific notes from definitions.py
        fields = fields + self.hazard_notes()
        return fields
Example #52
0
    def format_int(number):
        """Get the correct integer format.

        :param number: The number to format
        :type number: float or integer
        """
        return format_int(int(number))
Example #53
0
    def generate_analysis_result_html(self):
        """Return a HTML table of the analysis result

        :return: A file path to the html file saved to disk.
        """
        message = m.Message(style_class='report')
        # Table for affected population
        table = m.Table(style_class='table table-condensed table-striped')
        row = m.Row()
        total_people = self.tr('%s') % format_int(
            population_rounding(self.impact_data.total_affected_population))
        estimates_idp = self.tr('%s') % format_int(
            population_rounding(self.impact_data.estimates_idp))
        row.add(
            m.Cell(self.tr('Total affected population (people)'), header=True))
        row.add(m.Cell(total_people, style_class="text-right"))
        table.add(row)
        row = m.Row()
        row.add(m.Cell(self.tr('Estimates of IDP (people)'), header=True))
        row.add(m.Cell(estimates_idp, style_class="text-right"))
        table.add(row)
        message.add(table)
        # Table for minimum needs
        for k, v in self.impact_data.minimum_needs.iteritems():
            section = self.tr('Relief items to be provided %s :') % k
            # text = m.Text(section)
            row = m.Row(style_class='alert-info')
            row.add(m.Cell(section, header=True, attributes='colspan=2'))
            # message.add(text)
            table = m.Table(header=row,
                            style_class='table table-condensed table-striped')
            for e in v:
                row = m.Row()
                need_name = self.tr(e['name'])
                need_number = format_int(population_rounding(e['amount']))
                need_unit = self.tr(e['unit']['abbreviation'])
                if need_unit:
                    need_string = '%s (%s)' % (need_name, need_unit)
                else:
                    need_string = need_name
                row.add(m.Cell(need_string, header=True))
                row.add(m.Cell(need_number, style_class="text-right"))
                table.add(row)
            message.add(table)

        path = self.write_html_table('impact_analysis_report.html', message)
        return path
Example #54
0
 def _tabulate_zero_impact(self, evacuated, question, table_body,
                           thresholds):
     table_body = [
         question,
         TableRow([(tr('People in %.1f m of water') % thresholds[-1]),
                   '%s' % format_int(evacuated)],
                  header=True)]
     return table_body
    def impact_summary(self):
        """The impact summary as per category

        :returns: The impact summary.
        :rtype: list
        """
        affect_types = self._impact_breakdown
        impact_summary_report = [{
            'content': [tr('Hazard Category')] + affect_types,
            'header': True
        }]
        for (category, building_breakdown) in self.affected_buildings.items():
            total_affected = [0] * len(affect_types)
            for affected_breakdown in building_breakdown.values():
                for affect_type, number_affected in affected_breakdown.items():
                    count = affect_types.index(affect_type)
                    total_affected[count] += number_affected
            total_affected_formatted = [
                format_int(affected) for affected in total_affected
            ]
            impact_summary_report.append(
                {'content': [tr(category)] + total_affected_formatted})
        if len(self._affected_categories) > 1:
            impact_summary_report.append({
                'content': [
                    tr(tr('Total Buildings Affected')),
                    format_int(self.total_affected_buildings)
                ],
                'header':
                True
            })
        impact_summary_report.append({
            'content': [
                tr('Buildings Not Affected'),
                format_int(self.total_unaffected_buildings)
            ],
            'header':
            True
        })
        impact_summary_report.append({
            'content': [tr('All Buildings'),
                        format_int(self.total_buildings)],
            'header':
            True
        })
        return impact_summary_report
Example #56
0
    def test_issue160(self):
        """Test that multipart features can be used in a scenario - issue #160
        """

        exposure = test_data_path('exposure', 'buildings.shp')
        hazard = test_data_path('hazard', 'flood_multipart_polygons.shp')
        # See https://github.com/AIFDR/inasafe/issues/71
        # Push OK with the left mouse button
        # print 'Using QGIS: %s' % qgis_version()
        self.tearDown()
        button = DOCK.pbnRunStop
        # First part of scenario should have enabled run
        file_list = [hazard, exposure]
        hazard_layer_count, exposure_layer_count = load_layers(file_list)

        message = ('Incorrect number of Hazard layers: expected 1 got %s' %
                   hazard_layer_count)
        self.assertTrue(hazard_layer_count == 1, message)

        message = ('Incorrect number of Exposure layers: expected 1 got %s' %
                   exposure_layer_count)
        self.assertTrue(exposure_layer_count == 1, message)

        message = 'Run button was not enabled'
        self.assertTrue(button.isEnabled(), message)

        # Second part of scenario - run disabled when adding invalid layer
        # and select it - run should be disabled
        path = os.path.join(TESTDATA, 'issue71.tif')
        file_list = [path]  # This layer has incorrect keywords
        clear_flag = False
        _, _ = load_layers(file_list, clear_flag)

        result, message = setup_scenario(
            DOCK,
            hazard='Flood Polygon',
            exposure='Buildings',
            function='Be flooded',
            function_id='FloodPolygonBuildingFunction')
        self.assertTrue(result, message)

        # Enable on-the-fly reprojection
        set_canvas_crs(GEOCRS, True)
        expected_extent = QgsRectangle(106.80801, -6.19531, 106.83456946836641,
                                       -6.167526)
        CANVAS.setExtent(expected_extent)

        crs = QgsCoordinateReferenceSystem('EPSG:4326')
        DOCK.define_user_analysis_extent(expected_extent, crs)

        # Press RUN
        # noinspection PyCallByClass,PyCallByClass,PyTypeChecker
        DOCK.accept()
        result = DOCK.wvResults.page_to_text()

        message = 'Result not as expected: %s' % result
        self.assertTrue(format_int(33) in result, message)
    def impact_summary(self):
        """The impact summary as per category

        :returns: The impact summary.
        :rtype: safe.messaging.Message
        """
        message = m.Message(style_class='container')
        table = m.Table(style_class='table table-condensed table-striped')
        table.caption = None
        row = m.Row()
        row.add(
            m.Cell(tr('Population needing evacuation <sup>1</sup>'),
                   header=True))
        evacuated = format_int(population_rounding(self.total_evacuated))
        row.add(m.Cell(evacuated, align='right'))
        table.add(row)
        if len(self.impact_category_ordering):
            table.add(m.Row())  # add a blank line
            row = m.Row()
            row.add(m.Cell(tr('Total affected population'), header=True))
            affected = format_int(
                population_rounding(self.total_affected_population))
            row.add(m.Cell(affected, align='right'))
            table.add(row)

            for category in self.impact_category_ordering:
                population_in_category = self.lookup_category(category)
                population_in_category = format_int(
                    population_rounding(population_in_category))
                row = m.Row()
                row.add(m.Cell(tr(category), header=True))
                row.add(m.Cell(population_in_category, align='right'))
                table.add(row)

        table.add(m.Row())  # add a blank line

        row = m.Row()
        unaffected = format_int(population_rounding(
            self.unaffected_population))
        row.add(m.Cell(tr('Unaffected population'), header=True))
        row.add(m.Cell(unaffected, align='right'))
        table.add(row)
        message.add(table)
        return message
Example #58
0
    def test_itb_earthquake_fatality_estimation(self):
        """Fatalities from ground shaking can be computed correctly using the
            ITB fatality model (Test data from Hadi Ghasemi)."""
        # Name file names for hazard level, exposure and expected fatalities
        hazard_filename = '%s/itb_test_mmi.asc' % TESTDATA
        exposure_filename = '%s/itb_test_pop.asc' % TESTDATA

        # Calculate impact using API
        hazard_layer = read_layer(hazard_filename)
        exposure_layer = read_layer(exposure_filename)

        plugin_name = 'ITB Fatality Function'
        impact_function = get_plugin(plugin_name)

        # Call calculation engine
        impact_layer = calculate_impact(layers=[hazard_layer, exposure_layer],
                                        impact_fcn=impact_function)
        impact_filename = impact_layer.get_filename()

        impact_layer = read_layer(impact_filename)
        # calculated_result = I.get_data()
        # print calculated_result.shape
        keywords = impact_layer.get_keywords()
        # print "keywords", keywords
        population = float(keywords['total_population'])
        fatalities = float(keywords['total_fatalities'])

        # Check aggregated values
        expected_population = population_rounding(85424650.0)
        msg = ('Expected population was %f, I got %f' %
               (expected_population, population))
        assert population == expected_population, msg

        expected_fatalities = population_rounding(40871.3028)
        msg = ('Expected fatalities was %f, I got %f' %
               (expected_fatalities, fatalities))

        assert numpy.allclose(fatalities, expected_fatalities,
                              rtol=1.0e-5), msg

        # Check that aggregated number of fatilites is as expected
        all_numbers = int(
            numpy.sum([
                31.8937368131, 2539.26369372, 1688.72362573, 17174.9261705,
                19436.834531
            ]))
        msg = ('Aggregated number of fatalities not as expected: %i' %
               all_numbers)
        assert all_numbers == 40871, msg

        x = population_rounding(all_numbers)
        msg = ('Did not find expected fatality value %i in summary %s' %
               (x, keywords['impact_summary']))
        assert format_int(x) in keywords['impact_summary'], msg
Example #59
0
    def notes(self):
        """Return the notes section of the report.

        :return: The notes that should be attached to this impact report.
        :rtype: safe.messaging.Message
        """
        if get_needs_provenance_value(self.parameters) is None:
            needs_provenance = ''
        else:
            needs_provenance = tr(get_needs_provenance_value(self.parameters))

        message = m.Message(style_class='container')

        message.add(
            m.Heading(tr('Notes and assumptions'), **styles.INFO_STYLE))
        checklist = m.BulletedList()
        population = format_int(population_rounding(self.total_population))
        checklist.add(tr(
            'Total population in the analysis area: %s') % population)
        threshold = format_int(self.parameters['evacuation_percentage'].value)
        checklist.add(tr(
            '<sup>1</sup>The evacuation threshold used to determine '
            'population needing evacuation is %s%%.') % threshold)

        checklist.add(needs_provenance)
        if self.no_data_warning:
            checklist.add(tr(
                'The layers contained "no data" values. This missing data '
                'was carried through to the impact layer.'))
            checklist.add(tr(
                '"No data" values in the impact layer were treated as 0 '
                'when counting the affected or total population.'))
        checklist.add(tr(
            'All values are rounded up to the nearest integer in '
            'order to avoid representing human lives as fractions.'))
        checklist.add(tr(
            'Population rounding is applied to all population '
            'values, which may cause discrepancies when adding values.'))

        message.add(checklist)
        return message