def test_osm2bnpb(self): """OSM structure types maps to BNPB vulnerability curves """ # hazard_filename = '%s/Shakemap_Padang_2009.asc' % HAZDATA exposure_filename = ('%s/jakarta_OSM_building.shp' % EXPDATA) # Calculate impact using API E = read_layer(exposure_filename) # Map from OSM attributes to the padang building classes Emap = osm2bnpb(E, target_attribute='VCLASS') for i, feature in enumerate(E.get_data()): try: vclass = Emap.get_data('VCLASS', i) except KeyError: # print # print i, Emap.get_data()[i] # import sys; sys.exit() pass levels = feature['building_l'] structure = feature['building_s'] msg = ('Unexpected VCLASS %s. ' 'I have levels == %s and structure == %s.' % (vclass, levels, structure)) if levels is None or structure is None: assert vclass == 'URM', msg continue # Map string variable levels to integer if levels.endswith('+'): levels = 100 try: levels = int(levels) except ValueError: # E.g. 'ILP jalan' assert vclass == 'URM', msg continue levels = int(levels) # Check the main cases if levels >= 4: assert vclass == 'RM', msg elif 1 <= levels < 4: if structure in ['reinforced_masonry', 'confined_masonry']: assert vclass == 'RM', msg elif 'kayu' in structure or 'wood' in structure: assert vclass == 'RM', msg else: assert vclass == 'URM', msg else: assert vclass == 'URM', msg
def run(self, layers): """Risk plugin for earthquake school damage """ # Extract data H = get_hazard_layer(layers) # Ground shaking E = get_exposure_layer(layers) # Building locations keywords = E.get_keywords() if 'datatype' in keywords: datatype = keywords['datatype'] if datatype.lower() == 'osm': # Map from OSM attributes to the guideline classes (URM and RM) E = osm2bnpb(E, target_attribute=self.vclass_tag) elif datatype.lower() == 'sigab': # Map from SIGAB attributes to the guideline classes # (URM and RM) E = sigab2bnpb(E) else: E = unspecific2bnpb(E, target_attribute=self.vclass_tag) else: E = unspecific2bnpb(E, target_attribute=self.vclass_tag) # Interpolate hazard level to building locations H = assign_hazard_values_to_exposure_data(H, E, attribute_name='MMI') # 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 count_unknown = 0 building_damage = [] for i in range(N): mmi = float(shaking[i]['MMI']) building_class = E.get_data(self.vclass_tag, i) lo, hi = damage_parameters[building_class] if numpy.isnan(mmi): # If we don't know the shake level assign Not-a-Number damage = numpy.nan count_unknown += 1 elif mmi < lo: damage = 1 # Low count1 += 1 elif lo <= mmi < hi: damage = 2 # Medium count2 += 1 elif mmi >= hi: damage = 3 # High count3 += 1 else: msg = 'Undefined shakelevel %s' % str(mmi) raise Exception(msg) # 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 impact_summary = ('<table border="0" width="320px">' ' <tr><th><b>%s</b></th><th><b>%s</b></th></th>' ' <tr></tr>' ' <tr><td>%s:</td><td>%s</td></tr>' ' <tr><td>%s (10-25%%):</td><td>%s</td></tr>' ' <tr><td>%s (25-50%%):</td><td>%s</td></tr>' ' <tr><td>%s (50-100%%):</td><td>%s</td></tr>' % (tr('Buildings'), tr('Total'), tr('All'), format_int(N), tr('Low damage'), format_int(count1), tr('Medium damage'), format_int(count2), tr('High damage'), format_int(count3))) impact_summary += (' <tr><td>%s (NaN):</td><td>%s</td></tr>' % ('Unknown', format_int(count_unknown))) impact_summary += '</table>' # Create style style_classes = [dict(label=tr('Low damage'), min=0.5, max=1.5, colour='#fecc5c', transparency=0), dict(label=tr('Medium damage'), min=1.5, max=2.5, colour='#fd8d3c', transparency=0), dict(label=tr('High damage'), min=2.5, max=3.5, colour='#f31a1c', transparency=0)] style_info = dict(target_field=self.target_field, style_classes=style_classes) # Create vector layer and return V = Vector(data=building_damage, projection=E.get_projection(), geometry=coordinates, name='Estimated damage level', keywords={'impact_summary': impact_summary}, style_info=style_info) return V
def run(self, layers): """Risk plugin for earthquake school damage """ # Extract data H = get_hazard_layer(layers) # Ground shaking E = get_exposure_layer(layers) # Building locations keywords = E.get_keywords() if 'datatype' in keywords: datatype = keywords['datatype'] if datatype.lower() == 'osm': # Map from OSM attributes to the guideline classes (URM and RM) E = osm2bnpb(E, target_attribute=self.vclass_tag) elif datatype.lower() == 'sigab': # Map from SIGAB attributes to the guideline classes # (URM and RM) E = sigab2bnpb(E) else: E = unspecific2bnpb(E, target_attribute=self.vclass_tag) else: E = unspecific2bnpb(E, target_attribute=self.vclass_tag) # Interpolate hazard level to building locations H = assign_hazard_values_to_exposure_data(H, E, attribute_name='MMI') # 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 count_unknown = 0 building_damage = [] for i in range(N): mmi = float(shaking[i]['MMI']) building_class = E.get_data(self.vclass_tag, i) lo, hi = damage_parameters[building_class] if numpy.isnan(mmi): # If we don't know the shake level assign Not-a-Number damage = numpy.nan count_unknown += 1 elif mmi < lo: damage = 1 # Low count1 += 1 elif lo <= mmi < hi: damage = 2 # Medium count2 += 1 elif mmi >= hi: damage = 3 # High count3 += 1 else: msg = 'Undefined shakelevel %s' % str(mmi) raise Exception(msg) # 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 impact_summary = ( '<table border="0" width="320px">' ' <tr><th><b>%s</b></th><th><b>%s</b></th></th>' ' <tr></tr>' ' <tr><td>%s:</td><td>%s</td></tr>' ' <tr><td>%s (10-25%%):</td><td>%s</td></tr>' ' <tr><td>%s (25-50%%):</td><td>%s</td></tr>' ' <tr><td>%s (50-100%%):</td><td>%s</td></tr>' % (tr('Buildings'), tr('Total'), tr('All'), format_int(N), tr('Low damage'), format_int(count1), tr('Medium damage'), format_int(count2), tr('High damage'), format_int(count3))) impact_summary += (' <tr><td>%s (NaN):</td><td>%s</td></tr>' % ('Unknown', format_int(count_unknown))) impact_summary += '</table>' # Create style style_classes = [ dict(label=tr('Low damage'), min=0.5, max=1.5, colour='#fecc5c', transparency=0), dict(label=tr('Medium damage'), min=1.5, max=2.5, colour='#fd8d3c', transparency=0), dict(label=tr('High damage'), min=2.5, max=3.5, colour='#f31a1c', transparency=0) ] style_info = dict(target_field=self.target_field, style_classes=style_classes) # Create vector layer and return V = Vector(data=building_damage, projection=E.get_projection(), geometry=coordinates, name='Estimated damage level', keywords={'impact_summary': impact_summary}, style_info=style_info) return V