def run(self, layers):
        """Risk plugin for Padang building survey
        """

        # Extract data
        H = get_hazard_layer(layers)    # Ground shaking
        E = get_exposure_layer(layers)  # Building locations

        question = get_question(H.get_name(),
                                E.get_name(),
                                self)

        # Map from different kinds of datasets to Padang vulnerability classes
        datatype = E.get_keywords()['datatype']
        vclass_tag = 'VCLASS'
        if datatype.lower() == 'osm':
            # Map from OSM attributes
            Emap = osm2padang(E)
        elif datatype.lower() == 'sigab':
            # Map from SIGAB attributes
            Emap = sigab2padang(E)
        else:
            Emap = E

        # Interpolate hazard level to building locations
        I = assign_hazard_values_to_exposure_data(H, Emap,
                                                  attribute_name='MMI')

        # Extract relevant numerical data
        attributes = I.get_data()
        N = len(I)

        # Calculate building damage
        count_high = count_medium = count_low = count_none = 0
        for i in range(N):
            mmi = float(attributes[i]['MMI'])

            building_type = Emap.get_data(vclass_tag, i)
            damage_params = damage_curves[building_type]
            beta = damage_params['beta']
            median = damage_params['median']
            percent_damage = lognormal_cdf(mmi,
                                           median=median,
                                           sigma=beta) * 100

            # Add calculated impact to existing attributes
            attributes[i][self.target_field] = percent_damage

            # Calculate statistics
            if percent_damage < 10:
                count_none += 1

            if 10 <= percent_damage < 33:
                count_low += 1

            if 33 <= percent_damage < 66:
                count_medium += 1

            if 66 <= percent_damage:
                count_high += 1

        # Generate impact report
        table_body = [question,
                      TableRow([_('Buildings'), _('Total')],
                               header=True),
                      TableRow([_('All'), N]),
                      TableRow([_('No damage'), count_none]),
                      TableRow([_('Low damage'), count_low]),
                      TableRow([_('Medium damage'), count_medium]),
                      TableRow([_('High damage'), count_high])]

        table_body.append(TableRow(_('Notes'), header=True))
        table_body.append(_('Levels of impact are defined by post 2009 '
                            'Padang earthquake survey conducted by Geoscience '
                            'Australia and Institute of Teknologi Bandung.'))
        table_body.append(_('Unreinforced masonry is assumed where no '
                            'structural information is available.'))

        impact_summary = Table(table_body).toNewlineFreeString()
        impact_table = impact_summary
        map_title = _('Earthquake damage to buildings')

        # Create style
        style_classes = [dict(label=_('No damage'), min=0, max=10,
                              colour='#00ff00', transparency=1),
                         dict(label=_('Low damage'), min=10, max=33,
                              colour='#ffff00', transparency=1),
                         dict(label=_('Medium damage'), min=33, max=66,
                              colour='#ffaa00', transparency=1),
                         dict(label=_('High damage'), min=66, max=100,
                              colour='#ff0000', transparency=1)]
        style_info = dict(target_field=self.target_field,
                          style_classes=style_classes)

        # Create vector layer and return
        V = Vector(data=attributes,
                   projection=E.get_projection(),
                   geometry=E.get_geometry(),
                   name='Estimated pct damage',
                   keywords={'impact_summary': impact_summary,
                             'impact_table': impact_table,
                             'map_title': map_title},
                   style_info=style_info)
        return V
示例#2
0
    def run(self, layers):
        """Risk plugin for Padang building survey
        """

        # Extract data
        H = get_hazard_layer(layers)  # Ground shaking
        E = get_exposure_layer(layers)  # Building locations

        question = get_question(H.get_name(), E.get_name(), self)

        # Map from different kinds of datasets to Padang vulnerability classes
        datatype = E.get_keywords()['datatype']
        vclass_tag = 'VCLASS'
        if datatype.lower() == 'osm':
            # Map from OSM attributes
            Emap = osm2padang(E)
        elif datatype.lower() == 'sigab':
            # Map from SIGAB attributes
            Emap = sigab2padang(E)
        else:
            Emap = E

        # Interpolate hazard level to building locations
        I = assign_hazard_values_to_exposure_data(H,
                                                  Emap,
                                                  attribute_name='MMI')

        # Extract relevant numerical data
        attributes = I.get_data()
        N = len(I)

        # Calculate building damage
        count_high = count_medium = count_low = count_none = 0
        for i in range(N):
            mmi = float(attributes[i]['MMI'])

            building_type = Emap.get_data(vclass_tag, i)
            damage_params = damage_curves[building_type]
            beta = damage_params['beta']
            median = damage_params['median']
            percent_damage = log_normal_cdf(mmi, median=median,
                                            sigma=beta) * 100

            # Add calculated impact to existing attributes
            attributes[i][self.target_field] = percent_damage

            # Calculate statistics
            if percent_damage < 10:
                count_none += 1

            if 10 <= percent_damage < 33:
                count_low += 1

            if 33 <= percent_damage < 66:
                count_medium += 1

            if 66 <= percent_damage:
                count_high += 1

        # Generate impact report
        table_body = [
            question,
            TableRow([tr('Buildings'), tr('Total')], header=True),
            TableRow([tr('All'), N]),
            TableRow([tr('No damage'), format_int(count_none)]),
            TableRow([tr('Low damage'),
                      format_int(count_low)]),
            TableRow([tr('Medium damage'),
                      format_int(count_medium)]),
            TableRow([tr('High damage'),
                      format_int(count_high)])
        ]

        table_body.append(TableRow(tr('Notes'), header=True))
        table_body.append(
            tr('Levels of impact are defined by post 2009 '
               'Padang earthquake survey conducted by Geoscience '
               'Australia and Institute of Teknologi Bandung.'))
        table_body.append(
            tr('Unreinforced masonry is assumed where no '
               'structural information is available.'))

        impact_summary = Table(table_body).toNewlineFreeString()
        impact_table = impact_summary
        map_title = tr('Earthquake damage to buildings')

        # Create style
        style_classes = [
            dict(label=tr('No damage'),
                 min=0,
                 max=10,
                 colour='#00ff00',
                 transparency=0),
            dict(label=tr('Low damage'),
                 min=10,
                 max=33,
                 colour='#ffff00',
                 transparency=0),
            dict(label=tr('Medium damage'),
                 min=33,
                 max=66,
                 colour='#ffaa00',
                 transparency=0),
            dict(label=tr('High damage'),
                 min=66,
                 max=100,
                 colour='#ff0000',
                 transparency=0)
        ]
        style_info = dict(target_field=self.target_field,
                          style_classes=style_classes)

        # Create vector layer and return
        V = Vector(data=attributes,
                   projection=E.get_projection(),
                   geometry=E.get_geometry(),
                   name='Estimated pct damage',
                   keywords={
                       'impact_summary': impact_summary,
                       'impact_table': impact_table,
                       'map_title': map_title,
                       'target_field': self.target_field
                   },
                   style_info=style_info)
        return V