Example #1
0
def write_vector_data(data, projection, geometry, filename, keywords=None):
    """Write point data and any associated attributes to vector file

    Input:
        data: List of N dictionaries each with M fields where
              M is the number of attributes.
              A value of None is acceptable.
        projection: WKT projection information
        geometry: List of points or polygons.
        filename: Output filename
        keywords: Optional dictionary

    Note: The only format implemented is GML and SHP so the extension
    must be either .gml or .shp

    # FIXME (Ole): When the GML driver is used,
    #              the spatial reference is not stored.
    #              I suspect this is a bug in OGR.

    Background:
    * http://www.gdal.org/ogr/ogr_apitut.html (last example)
    * http://invisibleroads.com/tutorials/gdal-shapefile-points-save.html
    """

    V = Vector(data, projection, geometry, keywords=keywords)
    V.write_to_file(filename)
Example #2
0
File: io.py Project: uniomni/riab
def write_vector_data(data, projection, geometry, filename, keywords=None):
    """Write point data and any associated attributes to vector file

    Input:
        data: List of N dictionaries each with M fields where
              M is the number of attributes.
              A value of None is acceptable.
        projection: WKT projection information
        geometry: List of points or polygons.
        filename: Output filename
        keywords: Optional dictionary

    Note: The only format implemented is GML and SHP so the extension
    must be either .gml or .shp

    # FIXME (Ole): When the GML driver is used,
    #              the spatial reference is not stored.
    #              I suspect this is a bug in OGR.

    Background:
    * http://www.gdal.org/ogr/ogr_apitut.html (last example)
    * http://invisibleroads.com/tutorials/gdal-shapefile-points-save.html
    """

    V = Vector(data, projection, geometry, keywords=keywords)
    V.write_to_file(filename)
Example #3
0
    def test_instantiation_of_empty_layers(self):
        """Vector and Raster objects can be instantiated with None
        """

        v = Vector(None)
        assert v.get_name().startswith('Vector')

        r = Raster(None)
        assert r.get_name().startswith('Raster')
Example #4
0
def unspecific2bnpb(E, target_attribute='VCLASS'):
    """Map Unspecific point data to BNPB vulnerability classes

    This makes no assumptions about attributes and maps everything to
    URM: Unreinforced Masonry

    Input
        E: Vector object representing the OSM data
        target_attribute: Optional name of the attribute containing
                          the mapped vulnerability class. Default
                          value is 'VCLASS'

    Output:
        Vector object like E, but with one new attribute (e.g. 'VCLASS')
        representing the vulnerability class used in the guidelines
    """

    # Start mapping
    N = len(E)
    attributes = E.get_data()
    count = 0
    for i in range(N):
        # Store new attribute value
        attributes[i][target_attribute] = 'URM'

    # Create new vector instance and return
    V = Vector(data=attributes,
               projection=E.get_projection(),
               geometry=E.get_geometry(),
               name=E.get_name() + ' mapped to BNPB vulnerability class URM',
               keywords=E.get_keywords())
    return V
Example #5
0
def csv2shp(path, lonname='Bujur', latname='Lintang'):

    # Read csv data
    reader = csv.DictReader(open(path, 'r'))
    data = []
    for x in reader:
        data.append(x)

    # Determine latitude and longitude fields
    fieldnames = reader.fieldnames
    msg = ('Could not find requested longitude "%s" in %s. Available '
           'field names are: %s' % (lonname, path, str(fieldnames)))
    assert lonname in fieldnames, msg

    msg = ('Could not find requested latitude "%s" in %s. Available '
           'field names are: %s' % (latname, path, str(fieldnames)))
    assert latname in fieldnames, msg

    # Extract point geometry
    lon = [float(x[lonname]) for x in data]
    lat = [float(x[latname]) for x in data]
    geometry = zip(lon, lat)

    # Replace spaces in attribute names with underscores (issue #177)
    for i, D in enumerate(data):
        D_clean = {}
        for key in D:
            D_clean[key.replace(' ', '_')] = D[key]
        data[i] = D_clean

    # Create vector object
    V = Vector(data=data,
               projection=DEFAULT_PROJECTION,
               geometry=geometry)

    # Write as shapefile
    basename, _ = os.path.splitext(path)
    V.write_to_file(basename + '.shp')

    fid = open(basename + '.keywords', 'w')
    fid.write('category:exposure\n')
    fid.write('subcategory:building\n')
    fid.write('datatype:sigab\n')
    fid.close()
Example #6
0
def csv2shp(path, lonname='Bujur', latname='Lintang'):

    # Read csv data
    reader = csv.DictReader(open(path, 'r'))
    data = []
    for x in reader:
        data.append(x)

    # Determine latitude and longitude fields
    fieldnames = reader.fieldnames
    msg = ('Could not find requested longitude "%s" in %s. Available '
           'field names are: %s' % (lonname, path, str(fieldnames)))
    assert lonname in fieldnames, msg

    msg = ('Could not find requested latitude "%s" in %s. Available '
           'field names are: %s' % (latname, path, str(fieldnames)))
    assert latname in fieldnames, msg

    # Extract point geometry
    lon = [float(x[lonname]) for x in data]
    lat = [float(x[latname]) for x in data]
    geometry = zip(lon, lat)

    # Replace spaces in attribute names with underscores (issue #177)
    for i, D in enumerate(data):
        D_clean = {}
        for key in D:
            D_clean[key.replace(' ', '_')] = D[key]
        data[i] = D_clean

    # Create vector object
    V = Vector(data=data, projection=DEFAULT_PROJECTION, geometry=geometry)

    # Write as shapefile
    basename, _ = os.path.splitext(path)
    V.write_to_file(basename + '.shp')

    fid = open(basename + '.keywords', 'w')
    fid.write('category:exposure\n')
    fid.write('subcategory:building\n')
    fid.write('datatype:sigab\n')
    fid.close()
Example #7
0
    def test_vector_class(self):
        """Consistency of vector class for point data
        """

        # Read data file
        layername = 'lembang_schools.shp'
        filename = '%s/%s' % (TESTDATA, layername)
        V = read_layer(filename)

        # Make a smaller dataset
        V_ref = V.get_topN('FLOOR_AREA', 5)

        geometry = V_ref.get_geometry()
        data = V_ref.get_data()
        projection = V_ref.get_projection()

        # Create new object from test data
        V_new = Vector(data=data, projection=projection, geometry=geometry)

        # Check
        assert V_new == V_ref
        assert not V_new != V_ref

        # Write this new object, read it again and check
        tmp_filename = unique_filename(suffix='.shp')
        V_new.write_to_file(tmp_filename)

        V_tmp = read_layer(tmp_filename)
        assert V_tmp == V_ref
        assert not V_tmp != V_ref

        # Check that equality raises exception when type is wrong
        try:
            V_tmp == Raster()
        except TypeError:
            pass
        else:
            msg = 'Should have raised TypeError'
            raise Exception(msg)
Example #8
0
def interpolate_raster_vector_points(R, V, name=None):
    """Interpolate from raster layer to point data

    Input
        R: Raster data set (grid)
        V: Vector data set (points)
        name: Name for new attribute.
              If None (default) the name of R is used

    Output
        I: Vector data set; points located as V with values interpolated from R

    """

    msg = ('There are no data points to interpolate to. Perhaps zoom out '
           'and try again')
    assert len(V) > 0, msg

    # Input checks
    assert R.is_raster
    assert V.is_vector
    assert V.is_point_data

    # Get raster data and corresponding x and y axes
    A = R.get_data(nan=True)
    longitudes, latitudes = R.get_geometry()
    assert len(longitudes) == A.shape[1]
    assert len(latitudes) == A.shape[0]

    # Get vector point geometry as Nx2 array
    coordinates = numpy.array(V.get_geometry(), dtype='d', copy=False)

    # Interpolate and create new attribute
    N = len(V)
    attributes = []
    if name is None:
        name = R.get_name()

    values = interpolate_raster(longitudes,
                                latitudes,
                                A,
                                coordinates,
                                mode='linear')

    # Create list of dictionaries for this attribute and return
    for i in range(N):
        attributes.append({name: values[i]})

    return Vector(data=attributes,
                  projection=V.get_projection(),
                  geometry=coordinates)
Example #9
0
def read_layer(filename):
    """Read spatial layer from file.
    This can be either raster or vector data.
    """

    _, ext = os.path.splitext(filename)
    if ext in ['.asc', '.tif']:
        return Raster(filename)
    elif ext in ['.shp', '.gml']:
        return Vector(filename)
    else:
        msg = ('Could not read %s. '
               'Extension "%s" has not been implemented' % (filename, ext))
        raise Exception(msg)
Example #10
0
    def run(layers):
        """Risk plugin for earthquake school damage
        """

        # Extract data
        # FIXME (Ole): This will be replaced by a helper function
        #              to separate hazard from exposure using keywords
        H = layers[0]  # Ground shaking
        E = layers[1]  # Building locations

        # Interpolate hazard level to building locations
        H = H.interpolate(E)

        # Extract relevant numerical data
        coordinates = E.get_geometry()
        shaking = H.get_data()

        # Calculate building damage
        building_damage = []
        for i in range(len(shaking)):
            x = float(shaking[i].values()[0])
            if x < 6.0:
                value = 0.0
            else:
                value = (0.692 * (x**4) - 15.82 * (x**3) + 135.0 * (x**2) -
                         509.0 * x + 714.4)

            building_damage.append({'DAMAGE': value, 'MMI': x})

        # FIXME (Ole): Need helper to generate new layer using
        #              correct spatial reference
        #              (i.e. sensibly wrap the following lines)
        projection = E.get_projection()

        V = Vector(data=building_damage,
                   projection=E.get_projection(),
                   geometry=coordinates,
                   name='Estimated pct damage')
        return V
    def run(self, layers):
        """Risk plugin for earthquake school damage
        """

        # Extract data
        H = layers[0]  # Ground shaking
        E = layers[1]  # Building locations

        # print
        # print 'kw', E.get_keywords()
        # print
        # FIXME (Ole): Why doesn't this layer have keywords? See issue #164
        # Need keyword identifier for each kind of building dataset.
        # if 'osm' in E.get_keywords('type'):
        # FIXME (Ole): Not very robust way of deciding
        if E.get_name().lower().startswith('osm'):
            # Map from OSM attributes to the padang building classes
            E = osm2padang(E)
            vclass_tag = 'VCLASS'
        else:
            vclass_tag = 'TestBLDGCl'

        # Interpolate hazard level to building locations
        H = H.interpolate(E)

        # Extract relevant numerical data
        coordinates = E.get_geometry()
        shaking = H.get_data()
        N = len(shaking)

        # List attributes to carry forward to result layer
        attributes = E.get_attribute_names()

        # Calculate building damage
        count50 = 0
        count25 = 0
        count10 = 0
        count0 = 0
        building_damage = []
        for i in range(N):
            mmi = float(shaking[i].values()[0])

            building_class = E.get_data(vclass_tag, i)

            building_type = str(int(building_class))
            damage_params = damage_curves[building_type]
            percent_damage = scipy.stats.lognorm.cdf(mmi,
                                                     damage_params['beta'],
                                                     scale=damage_params['median']) * 100

            # Collect shake level and calculated damage
            result_dict = {self.target_field: percent_damage,
                           'MMI': mmi}

            # Carry all orginal attributes forward
            for key in attributes:
                result_dict[key] = E.get_data(key, i)

            # Record result for this feature
            building_damage.append(result_dict)

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

            if 10 <= percent_damage < 25:
                count10 += 1

            if 25 <= percent_damage < 50:
                count25 += 1

            if 50 <= percent_damage:
                count50 += 1

        # Create report
        caption = ('<font size="3"> <table border="0" width="320px">'
                   '   <tr><th><b>%s</b></th><th><b>%s</b></th></th>'
                    '   <tr></tr>'
                    '   <tr><td>%s&#58;</td><td>%i</td></tr>'
                    '   <tr><td>%s (<10%%)&#58;</td><td>%i</td></tr>'
                    '   <tr><td>%s (10-25%%)&#58;</td><td>%i</td></tr>'
                    '   <tr><td>%s (25-50%%)&#58;</td><td>%i</td></tr>'
                    '   <tr><td>%s (50-100%%)&#58;</td><td>%i</td></tr>'
                    '</table></font>' % (_('Buildings'), _('Total'),
                                  _('All'), N,
                                  _('No damage'), count0,
                                  _('Low damage'), count10,
                                  _('Medium damage'), count25,
                                  _('High damage'), count50))

        # Create vector layer and return
        V = Vector(data=building_damage,
                   projection=E.get_projection(),
                   geometry=coordinates,
                   name='Estimated pct damage',
                   keywords={'caption': caption})
        return V
Example #12
0
    def run(self, layers):
        """Risk plugin for tsunami population
        """

        # Extract data
        # FIXME (Ole): This will be replaced by a helper function
        #              to separate hazard from exposure using keywords
        H = layers[0]  # Depth
        E = layers[1]  # Building locations

        # Interpolate hazard level to building locations
        H = H.interpolate(E)

        # Extract relevant numerical data
        coordinates = E.get_geometry()
        depth = H.get_data()
        N = len(depth)

        # List attributes to carry forward to result layer
        attributes = E.get_attribute_names()

        #print attributes
        #print 'Number of population points', N

        # Calculate population impact
        count = 0
        building_impact = []
        for i in range(N):
            dep = float(depth[i].values()[0])

            # Tag and count
            if dep > 0.1:
                affected = 99.5
                count += 1
            else:
                affected = 0

            # Collect depth and calculated damage
            result_dict = {'AFFECTED': affected, 'DEPTH': dep}

            # Carry all original attributes forward
            for key in attributes:
                result_dict[key] = E.get_data(key, i)

            # Record result for this feature
            building_impact.append(result_dict)

        # Create report
        caption = ('<table border="0" width="320px">'
                   '   <tr><th><b>%s</b></th><th><b>%s</b></th></th>'
                   '   <tr></tr>'
                   '   <tr><td>%s&#58;</td><td>%i</td></tr>'
                   '   <tr><td>%s (> 10 cm) &#58;</td><td>%i</td></tr>'
                   '   <tr><td>%s (< 10 cm) &#58;</td><td>%i</td></tr>'
                   '</table>' %
                   (_('Buildings'), _('Total'), _('All'), N, _('Inundated'),
                    count, _('Not inundated'), N - count))

        # Create vector layer and return
        V = Vector(data=building_impact,
                   projection=E.get_projection(),
                   geometry=coordinates,
                   name='Estimated buildings affected',
                   keywords={'caption': caption})
        return V
Example #13
0
    def run(self, layers):
        """Risk plugin for tsunami population
        """

        # Extract data
        H = layers[0]  # Depth
        E = layers[1]  # Building locations

        #print 'Number of polygons', len(E)

        # Interpolate hazard level to building locations
        H = H.interpolate(E)

        # Extract relevant numerical data
        coordinates = E.get_geometry()
        depth = H.get_data()
        N = len(depth)

        # List attributes to carry forward to result layer
        attributes = E.get_attribute_names()

        # Calculate building impact according to guidelines
        count3 = 0
        count1 = 0
        count0 = 0
        population_impact = []
        for i in range(N):

            # Get depth
            dep = float(depth[i].values()[0])

            # Classify buildings according to depth
            if dep >= 3:
                affected = 3  # FIXME: Colour upper bound is 100 but
                count3 += 1  # does not catch affected == 100
            elif 1 <= dep < 3:
                affected = 2
                count1 += 1
            else:
                affected = 1
                count0 += 1

            # Collect depth and calculated damage
            result_dict = {self.target_field: affected, 'DEPTH': dep}

            # Carry all original attributes forward
            for key in attributes:
                result_dict[key] = E.get_data(key, i)

            # Record result for this feature
            population_impact.append(result_dict)

        # Create report
        caption = ('<table border="0" width="320px">'
                   '   <tr><th><b>%s</b></th><th><b>%s</b></th></th>'
                   '   <tr></tr>'
                   '   <tr><td>%s&#58;</td><td>%i</td></tr>'
                   '   <tr><td>%s&#58;</td><td>%i</td></tr>'
                   '   <tr><td>%s&#58;</td><td>%i</td></tr>'
                   '</table>' %
                   ('ketinggian tsunami', 'Jumlah gedung', '< 1 m', count0,
                    '1 - 3 m', count1, '> 3 m', count3))

        # Create vector layer and return
        V = Vector(data=population_impact,
                   projection=E.get_projection(),
                   geometry=coordinates,
                   name='Estimate of buildings affected',
                   keywords={'caption': caption})
        return V
Example #14
0
def osm2padang(E):
    """Map OSM attributes to Padang vulnerability classes

    This maps attributes collected in the OpenStreetMap exposure data
    (data.kompetisiosm.org) to 9 vulnerability classes identified by
    Geoscience Australia and ITB in the post 2009 Padang earthquake
    survey (http://trove.nla.gov.au/work/38470066).
    The mapping was developed by Abigail Baca, GFDRR.

    Input
        E: Vector object representing the OSM data

    Output:
        Vector object like E, but with one new attribute ('VCLASS')
        representing the vulnerability class used in the Padang dataset


    Algorithm

    1. Class the "levels" field into height bands where 1-3 = low,
       4-10 = mid, >10 = high
    2. Where height band = mid then building type = 4
       "RC medium rise Frame with Masonry in-fill walls"
    3. Where height band = high then building type = 6
       "Concrete Shear wall high rise* Hazus C2H"
    4. Where height band = low and structure = (plastered or
       reinforced_masonry) then building type = 7
       "RC low rise Frame with Masonry in-fill walls"
    5. Where height band = low and structure = confined_masonry then
       building type = 8 "Confined Masonry"
    6. Where height band = low and structure = unreinforced_masonry then
       building type = 2 "URM with Metal Roof"
    """

    # Input check
    required = ['levels', 'structure']
    actual = E.get_attribute_names()
    msg = ('Input data to osm2padang must have attributes %s. '
           'It has %s' % (str(required), str(actual)))
    for attribute in required:
        assert attribute in actual, msg

    # Start mapping
    N = len(E)
    attributes = E.get_data()
    count = 0
    for i in range(N):
        levels = E.get_data('levels', i)
        structure = E.get_data('structure', i)
        if levels is None or structure is None:
            vulnerability_class = 2
            count += 1
        else:
            if levels >= 10:
                # High
                vulnerability_class = 6  # Concrete shear
            elif 4 <= levels < 10:
                # Mid
                vulnerability_class = 4  # RC mid
            elif 1 <= levels < 4:
                # Low
                if structure in [
                        'plastered', 'reinforced masonry', 'reinforced_masonry'
                ]:
                    vulnerability_class = 7  # RC low
                elif structure == 'confined_masonry':
                    vulnerability_class = 8  # Confined
                elif 'kayu' in structure or 'wood' in structure:
                    vulnerability_class = 9  # Wood
                else:
                    vulnerability_class = 2  # URM
            elif numpy.allclose(levels, 0):
                # A few buildings exist with 0 levels.

                # In general, we should be assigning here the most
                # frequent building in the area which could be defined
                # by admin boundaries.
                vulnerability_class = 2
            else:
                msg = 'Unknown number of levels: %s' % levels
                raise Exception(msg)

        # Store new attribute value
        attributes[i]['VCLASS'] = vulnerability_class

        # Selfcheck for use with osm_080811.shp
        if E.get_name() == 'osm_080811':
            if levels > 0:
                msg = ('Got %s expected %s. levels = %f, structure = %s' %
                       (vulnerability_class, attributes[i]['TestBLDGCl'],
                        levels, structure))
                assert numpy.allclose(attributes[i]['TestBLDGCl'],
                                      vulnerability_class), msg

    #print 'Got %i without levels or structure (out of %i total)' % (count, N)

    # Create new vector instance and return
    V = Vector(data=attributes,
               projection=E.get_projection(),
               geometry=E.get_geometry(),
               name=E.get_name() + ' mapped to Padang vulnerability classes',
               keywords=E.get_keywords())
    return V
    def run(self, layers):
        """Risk plugin for earthquake school damage
        """

        # Extract data
        H = layers[0]  # Ground shaking
        E = layers[1]  # Building locations

        # Map from OSM attributes to the guideline classes (URM and RM)
        # FIXME (Ole): Not very robust way of deciding
        # Need keyword identifier for each kind of building dataset.
        if E.get_name().lower().startswith('osm'):
            # Map from OSM attributes to the padang building classes
            E = osm2bnpb(E, target_attribute=self.vclass_tag)
        else:
            E = unspecific2bnpb(E, target_attribute=self.vclass_tag)

        # Interpolate hazard level to building locations
        H = H.interpolate(E)

        # Extract relevant numerical data
        coordinates = E.get_geometry()
        shaking = H.get_data()
        N = len(shaking)

        # List attributes to carry forward to result layer
        attributes = E.get_attribute_names()

        # Calculate building damage
        count3 = 0
        count2 = 0
        count1 = 0
        building_damage = []
        for i in range(N):
            mmi = float(shaking[i].values()[0])

            building_class = E.get_data(self.vclass_tag, i)
            lo, hi = damage_parameters[building_class]

            if mmi < lo:
                damage = 1  # Low
                count1 += 1
            elif lo <= mmi < hi:
                damage = 2  # Medium
                count2 += 1
            else:
                damage = 3  # High
                count3 += 1

            # Collect shake level and calculated damage
            result_dict = {self.target_field: damage, 'MMI': mmi}

            # Carry all orginal attributes forward
            for key in attributes:
                result_dict[key] = E.get_data(key, i)

            # Record result for this feature
            building_damage.append(result_dict)

        # Create report
        caption = (
            '<table border="0" width="320px">'
            '   <tr><th><b>%s</b></th><th><b>%s</b></th></th>'
            '   <tr></tr>'
            '   <tr><td>%s&#58;</td><td>%i</td></tr>'
            '   <tr><td>%s (10-25%%)&#58;</td><td>%i</td></tr>'
            '   <tr><td>%s (25-50%%)&#58;</td><td>%i</td></tr>'
            '   <tr><td>%s (50-100%%)&#58;</td><td>%i</td></tr>'
            '</table>' %
            (_('Buildings'), _('Total'), _('All'), N, _('Low damage'), count1,
             _('Medium damage'), count2, _('High damage'), count3))

        # Create vector layer and return
        V = Vector(data=building_damage,
                   projection=E.get_projection(),
                   geometry=coordinates,
                   name='Estimated damage level',
                   keywords={'caption': caption})

        return V
Example #16
0
    def run(layers):
        """Risk plugin for tsunami building damage
        """

        # Extract data
        # FIXME (Ole): This will be replaced by a helper function
        #              to separate hazard from exposure using keywords
        H = layers[0]  # Ground shaking
        E = layers[1]  # Building locations

        # Interpolate hazard level to building locations
        H = H.interpolate(E)

        # Extract relevant numerical data
        coordinates = E.get_geometry()
        inundation = H.get_data()

        # Calculate
        N = len(H)
        impact = []
        for i in range(N):

            #-------------------
            # Extract parameters
            #-------------------
            depth = float(inundation[i].values()[0])
            shore_distance = E.get_data('SHORE_DIST', i)

            # FIXME: Get rid of the type casting when
            #        issue #66 is done
            number_of_people_in_building = int(E.get_data('NEXIS_PEOP', i))
            wall_type = E.get_data('WALL_TYPE', i)
            contents_value = E.get_data('CONT_VALUE', i)
            structure_value = E.get_data('STR_VALUE', i)

            #------------------------
            # Compute people affected
            #------------------------
            if 0.01 < depth < 1.0:
                people_affected = number_of_people_in_building
            else:
                people_affected = 0

            if depth >= 1.0:
                people_severely_affected = number_of_people_in_building
            else:
                people_severely_affected = 0

            #----------------------------------------
            # Compute impact on buldings and contents
            #----------------------------------------
            depth_floor = depth - 0.3  # Adjust for floor height

            if depth_floor >= 0.0:
                buildings_inundated = 1
            else:
                buildings_inundated = 0

            if depth_floor < 0.0:
                structural_damage = contents_damage = 0.0
            else:
                # Water is deep enough to cause damage
                if wall_type in struct_damage_curve:
                    curve = struct_damage_curve[wall_type]
                else:
                    # Establish default for unknown wall type
                    curve = struct_damage_curve['Brick veneer']

                structural_damage = curve(depth_floor)
                contents_damage = contents_damage_curve(depth_floor)

            #---------------
            # Compute losses
            #---------------
            structural_loss = structural_damage * structure_value
            contents_loss = contents_damage * contents_value

            #-------
            # Return
            #-------
            impact.append({
                'NEXIS_PEOP': number_of_people_in_building,
                'PEOPLE_AFFECTED': people_affected,
                'PEOPLE_SEV_AFFECTED': people_severely_affected,
                'STRUCT_INUNDATED': buildings_inundated,
                'STRUCT_DAMAGE_fraction': structural_damage,
                'CONTENTS_DAMAGE_fraction': contents_damage,
                'STRUCT_LOSS_AUD': structural_loss,
                'CONTENTS_LOSS_AUD': contents_loss,
                'DEPTH': depth
            })

        # FIXME (Ole): Need helper to generate new layer using
        #              correct spatial reference
        #              (i.e. sensibly wrap the following lines)
        V = Vector(data=impact,
                   projection=E.get_projection(),
                   geometry=coordinates,
                   name='Estimated tsunami impact')
        return V
Example #17
0
    def run(layers):
        """Risk plugin for tephra impact
        """

        # Extract data
        H = layers[0]  # Ash load
        E = layers[1]  # Building locations

        # Interpolate hazard level to building locations
        H = H.interpolate(E, 'load')

        # Calculate building damage
        count3 = 0
        count2 = 0
        count1 = 0
        count0 = 0
        result = []
        for i in range(len(E)):

            #-------------------
            # Extract parameters
            #-------------------
            load = H.get_data('load', i)

            #------------------------
            # Compute damage level
            #------------------------

            # FIXME: The thresholds have been greatly reduced
            # for the purpose of demonstration. Any real analyis
            # should bring them back to 0, 90, 150, 300
            if 0.01 <= load < 0.5:
                # Loss of crops and livestock
                impact = 0
                count0 += 1
            elif 0.5 <= load < 2.0:
                # Cosmetic damage
                impact = 1
                count1 += 1
            elif 2.0 <= load < 10.0:
                # Partial building collapse
                impact = 2
                count2 += 1
            elif load >= 10.0:
                # Complete building collapse
                impact = 3
                count3 += 1
            else:
                impact = 0
                count0 += 1

            result.append({'DAMAGE': impact, 'ASHLOAD': load})

        # Create report
        caption = ('<font size="3"> <table border="0" width="320px">'
                   '   <tr><th><b>%s</b></th><th><b>%s</b></th></th>'
                   '   <tr></tr>'
                   '   <tr><td>%s&#58;</td><td>%i</td></tr>'
                   '   <tr><td>%s&#58;</td><td>%i</td></tr>'
                   '   <tr><td>%s&#58;</td><td>%i</td></tr>'
                   '   <tr><td>%s&#58;</td><td>%i</td></tr>'
                   '</table></font>' %
                   ('Beban abu', 'Gedung dampak', '< 0.5 kg/m2', count0,
                    '0.5 - 2 kg/m2', count1, '2 - 10 kg/m2', count2,
                    '> 10 kg/m2', count3))
        #'</table>' % ('Beban abu', 'Gedung dampak',
        #              'Gangguan (< 90 kg/m2)', count0,
        #              'Kerusakan kosmetik (90 - 150 kg/m2', count1,
        #              'parsial runtuhnya (150 - 300 kg/m2', count2,
        #              'runtuhnya lengkap (> 300 kg/m2', count3))

        V = Vector(data=result,
                   projection=E.get_projection(),
                   geometry=E.get_geometry(),
                   name='Estimated ashload damage',
                   keywords={'caption': caption})
        return V
Example #18
0
    def run(self, layers, a=0.97429, b=11.037):
        """Risk plugin for earthquake fatalities

        Input
          layers: List of layers expected to contain
                  H: Raster layer of MMI ground shaking
                  E: Polygon population data
          a: Parameter for Allen impact function
          b: Parameter for Allen impact function
        """

        # Identify input layers
        H = layers[0]  # Intensity
        E = layers[1]  # Exposure - population counts

        # Interpolate hazard level to building locations
        H = H.interpolate(E)

        # Extract relevant numerical data
        coordinates = E.get_geometry()  # Stay with polygons
        shaking = H.get_data()
        N = len(shaking)

        # List attributes to carry forward to result layer
        attributes = E.get_attribute_names()

        # Calculate fatilities
        count = 0
        total = 0

        result_feature_set = []
        for i in range(N):
            mmi = float(shaking[i].values()[0])
            if mmi < 0.0:
                # FIXME: Hack until interpolation is fixed
                mmi = 0.0

            population_count = E.get_data('Jumlah_Pen', i)

            # Calculate impact
            F = 10**(a * mmi - b) * population_count

            # Collect shake level and calculated damage
            result_dict = {self.target_field: F, 'MMI': mmi}

            # Carry all orginal attributes forward
            for key in attributes:
                result_dict[key] = E.get_data(key, i)

            # Record result for this feature
            result_feature_set.append(result_dict)

            # Calculate statistics
            if not numpy.isnan(F):
                count += F
            total += population_count

        # Create report
        caption = ('<table border="0" width="320px">'
                   '   <tr><td>%s&#58;</td><td>%i</td></tr>'
                   '   <tr><td>%s&#58;</td><td>%i</td></tr>'
                   '</table>' % ('Jumlah Penduduk', int(total),
                                 'Perkiraan Orang Meninggal', int(count)))

        # Create vector layer and return
        V = Vector(data=result_feature_set,
                   projection=E.get_projection(),
                   geometry=coordinates,
                   name='Estimated fatalities',
                   keywords={'caption': caption})

        return V
Example #19
0
def osm2bnpb(E, target_attribute='VCLASS'):
    """Map OSM attributes to BNPB vulnerability classes

    This maps attributes collected in the OpenStreetMap exposure data
    (data.kompetisiosm.org) to 2 vulnerability classes identified by
    BNPB in Kajian Risiko Gempabumi VERS 1.0, 2011. They are
    URM: Unreinforced Masonry and RM: Reinforced Masonry

    Input
        E: Vector object representing the OSM data
        target_attribute: Optional name of the attribute containing
                          the mapped vulnerability class. Default
                          value is 'VCLASS'

    Output:
        Vector object like E, but with one new attribute (e.g. 'VCLASS')
        representing the vulnerability class used in the guidelines
    """

    # Input check
    required = ['levels', 'structure']
    actual = E.get_attribute_names()
    msg = ('Input data to osm2bnpb must have attributes %s. '
           'It has %s' % (str(required), str(actual)))
    for attribute in required:
        assert attribute in actual, msg

    # Start mapping
    N = len(E)
    attributes = E.get_data()
    count = 0
    for i in range(N):
        levels = E.get_data('levels', i)
        structure = E.get_data('structure', i)
        if levels is None or structure is None:
            vulnerability_class = 'URM'
            count += 1
        else:
            if levels >= 4:
                # High
                vulnerability_class = 'RM'
            elif 1 <= levels < 4:
                # Low
                if structure in ['reinforced masonry', 'reinforced_masonry']:
                    vulnerability_class = 'RM'
                elif structure == 'confined_masonry':
                    vulnerability_class = 'RM'
                elif 'kayu' in structure or 'wood' in structure:
                    vulnerability_class = 'RM'
                else:
                    vulnerability_class = 'URM'
            elif numpy.allclose(levels, 0):
                # A few buildings exist with 0 levels.

                # In general, we should be assigning here the most
                # frequent building in the area which could be defined
                # by admin boundaries.
                vulnerability_class = 'URM'
            else:
                msg = 'Unknown number of levels: %s' % levels
                raise Exception(msg)

        # Store new attribute value
        attributes[i][target_attribute] = vulnerability_class

    #print 'Got %i without levels or structure (out of %i total)' % (count, N)

    # Create new vector instance and return
    V = Vector(data=attributes,
               projection=E.get_projection(),
               geometry=E.get_geometry(),
               name=E.get_name() + ' mapped to BNPB vulnerability classes',
               keywords=E.get_keywords())
    return V