def test_filtering_of_impact_functions(self): """Impact functions are filtered correctly """ # Keywords matching F1 and F3 haz_keywords1 = dict(category='test_cat1', subcategory='flood', layertype='raster', unit='m') exp_keywords1 = dict(category='test_cat2', subcategory='population', layertype='raster', datatype='population') # Keywords matching F2 and F3 haz_keywords2 = dict(category='test_cat1', subcategory='flood', layertype='raster', unit='m') exp_keywords2 = dict(category='test_cat2', subcategory='building') # Check correct matching of keyword set 1 plugins = get_admissible_plugins([haz_keywords1, exp_keywords1]) msg = 'Expected impact functions F1 and F3 in %s' % str(plugins.keys()) self.assertIn('F1', plugins, msg) self.assertIn('F3', plugins, msg) self.assertNotIn('F2', plugins, msg) # Check correctness of title attribute self.assertEqual(get_function_title(plugins['F1']), 'Title for F1') self.assertEqual(get_function_title(plugins['F3']), 'F3') # Check correct matching of keyword set 2 plugins = get_admissible_plugins([haz_keywords2, exp_keywords2]) msg = 'Expected impact functions F2 and F3 in %s' % str(plugins.keys()) self.assertIn('F2', plugins, msg) self.assertIn('F3', plugins, msg) self.assertNotIn('F1', plugins, msg) # Check correctness of title attribute self.assertEqual(get_function_title(plugins['F2']), 'Title for F2') self.assertEqual(get_function_title(plugins['F3']), 'F3') # Check empty call returns all plugins = get_admissible_plugins([]) msg = ('Expected at least impact functions F1, F2 and F3 in %s' % str(plugins.keys())) self.assertIn('F1', plugins, msg) self.assertIn('F2', plugins, msg) self.assertIn('F3', plugins, msg)
def test_get_plugins(self): """Plugins can be collected.""" os.environ['LANG'] = 'en' plugin_list = get_plugins() assert(len(plugin_list) > 0) # Obtain string representation string_rep = admissible_plugins_to_str(plugin_list) # Check each plugin for plugin in plugin_list.values(): # Check that it's name appeears in string representation title = get_function_title(plugin) msg = ('Expected title %s in string representation: %s' % (title, string_rep)) assert title in string_rep, msg # Check that every plugin has a requires line requirements = requirements_collect(plugin) msg = 'There were no requirements in plugin %s' % plugin assert(len(requirements) > 0), msg for req_str in requirements: msg = 'All plugins should return True or False' assert(requirement_check({'category': 'hazard', 'subcategory': 'earthquake', 'layerType': 'raster'}, req_str) in [True, False]), msg
def test_get_plugins(self): """Plugins can be collected.""" os.environ['LANG'] = 'en' plugin_list = get_plugins() self.assertGreater(len(plugin_list), 0) # Obtain string representation string_rep = admissible_plugins_to_str(plugin_list) # Check each plugin for plugin in plugin_list.values(): # Check that it's name appears in string representation title = get_function_title(plugin) message = ('Expected title %s in string representation: %s' % (title, string_rep)) assert title in string_rep, message # Check that every plugin has a requires line requirements = requirements_collect(plugin) message = 'There were no requirements in plugin %s' % plugin assert (len(requirements) > 0), message for required_string in requirements: message = 'All plugins should return True or False' assert (requirement_check( { 'category': 'hazard', 'subcategory': 'earthquake', 'layerType': 'raster' }, required_string) in [True, False]), message
def test_filtering_of_impact_functions(self): """Impact functions are filtered correctly """ # Keywords matching F1 and F3 haz_keywords1 = dict(category='test_cat1', subcategory='flood', layertype='raster', unit='m') exp_keywords1 = dict(category='test_cat2', subcategory='population', layertype='raster', datatype='population') # Keywords matching F2 and F3 haz_keywords2 = dict(category='test_cat1', subcategory='flood', layertype='raster', unit='m') exp_keywords2 = dict(category='test_cat2', subcategory='building') # Check correct matching of keyword set 1 plugins = get_admissible_plugins([haz_keywords1, exp_keywords1]) msg = 'Expected impact functions F1 and F3 in %s' % str(plugins.keys()) self.assertIn('F1', plugins, msg) self.assertIn('F3', plugins, msg) self.assertNotIn('F2', plugins, msg) # Check correctness of title attribute self.assertEqual(get_function_title(plugins['F1']), 'Title for F1') self.assertEqual(get_function_title(plugins['F3']), 'F3') # Check correct matching of keyword set 2 plugins = get_admissible_plugins([haz_keywords2, exp_keywords2]) msg = 'Expected impact functions F2 and F3 in %s' % str( plugins.keys()) self.assertIn('F2', plugins, msg) self.assertIn('F3', plugins, msg) self.assertNotIn('F1', plugins, msg) # Check correctness of title attribute self.assertEqual(get_function_title(plugins['F2']), 'Title for F2') self.assertEqual(get_function_title(plugins['F3']), 'F3') # Check empty call returns all plugins = get_admissible_plugins([]) msg = ('Expected at least impact functions F1, F2 and F3 in %s' % str(plugins.keys())) self.assertIn('F1', plugins, msg) self.assertIn('F2', plugins, msg) self.assertIn('F3', plugins, msg)
def test_filtering_of_impact_functions(self): """Impact functions are filtered correctly """ # Keywords matching F1 and F3 haz_keywords1 = dict(category='test_cat1', subcategory='flood', layertype='raster', unit='m') exp_keywords1 = dict(category='test_cat2', subcategory='population', layertype='raster', datatype='population') # Keywords matching F2 and F3 haz_keywords2 = dict(category='test_cat1', subcategory='flood', layertype='raster', unit='m') exp_keywords2 = dict(category='test_cat2', subcategory='building') # Check correct matching of keyword set 1 P = get_admissible_plugins([haz_keywords1, exp_keywords1]) msg = 'Expected impact functions F1 and F3 in %s' % str(P.keys()) assert 'F1' in P and 'F3' in P, msg # Check correctness of title attribute assert get_function_title(P['F1']) == 'Title for F1' assert get_function_title(P['F3']) == 'F3' # Check correct matching of keyword set 2 P = get_admissible_plugins([haz_keywords2, exp_keywords2]) msg = 'Expected impact functions F2 and F3 in %s' % str(P.keys()) assert 'F2' in P and 'F3' in P, msg # Check correctness of title attribute assert get_function_title(P['F2']) == 'Title for F2' assert get_function_title(P['F3']) == 'F3' # Check empty call returns all P = get_admissible_plugins([]) msg = ('Expected at least impact functions F1, F2 and F3 in %s' % str(P.keys())) assert 'F1' in P and 'F2' in P and 'F3' in P, msg
def Xtest_dynamic_translation_function_title(self): """Test for dynamic translations for function title.""" plugins_dict = get_plugins() plugin_name = 'Volcano Building Impact' message = '%s not found in %s' % (plugin_name, str(plugins_dict)) self.assertIn(plugin_name, plugins_dict, message) function = plugins_dict[plugin_name] # English function_title = get_function_title(function) expected_title = 'Be affected' message = 'Expected %s but I got %s' % (expected_title, function_title) self.assertEqual(expected_title, function_title, message) # Indonesia os.environ['LANG'] = 'id' function_title = get_function_title(function) expected_title = 'Terkena dampak' message = ('expected %s but got %s, in lang = %s' % (expected_title, function_title, os.environ['LANG'])) self.assertEqual(expected_title, function_title, message) # Set back to en os.environ['LANG'] = 'en'
def run(self, layers): """Plugin for impact of population as derived by categorised hazard Input layers: List of layers expected to contain my_hazard: Raster layer of categorised hazard my_exposure: Raster layer of population data Counts number of people exposed to each category of the hazard Return Map of population exposed to high category Table with number of people in each category """ # The 3 category high_t = 1 medium_t = 0.66 low_t = 0.34 # Identify hazard and exposure layers my_hazard = get_hazard_layer(layers) # Categorised Hazard my_exposure = get_exposure_layer(layers) # Population Raster question = get_question(my_hazard.get_name(), my_exposure.get_name(), self) # Extract data as numeric arrays C = my_hazard.get_data(nan=0.0) # Category # Calculate impact as population exposed to each category P = my_exposure.get_data(nan=0.0, scaling=True) H = numpy.where(C == high_t, P, 0) M = numpy.where(C > medium_t, P, 0) L = numpy.where(C < low_t, P, 0) # Count totals total = int(numpy.sum(P)) high = int(numpy.sum(H)) medium = int(numpy.sum(M)) - int(numpy.sum(H)) low = int(numpy.sum(L)) - int(numpy.sum(M)) total_impact = high + medium + low # Don't show digits less than a 1000 total = round_thousand(total) total_impact = round_thousand(total_impact) high = round_thousand(high) medium = round_thousand(medium) low = round_thousand(low) # Generate impact report for the pdf map table_body = [question, TableRow([tr('People impacted '), '%s' % format_int(total_impact)], header=True), TableRow([tr('People in high hazard area '), '%s' % format_int(high)], header=True), TableRow([tr('People in medium hazard area '), '%s' % format_int(medium)], header=True), TableRow([tr('People in low hazard area'), '%s' % format_int(low)], header=True)] impact_table = Table(table_body).toNewlineFreeString() # Extend impact report for on-screen display table_body.extend([TableRow(tr('Notes'), header=True), tr('Map shows population density in high or medium ' 'hazard area'), tr('Total population: %s') % format_int(total)]) impact_summary = Table(table_body).toNewlineFreeString() map_title = tr('People in high hazard areas') # Generate 8 equidistant classes across the range of flooded population # 8 is the number of classes in the predefined flood population style # as imported # noinspection PyTypeChecker classes = numpy.linspace(numpy.nanmin(M.flat[:]), numpy.nanmax(M.flat[:]), 8) # Modify labels in existing flood style to show quantities style_classes = style_info['style_classes'] style_classes[1]['label'] = tr('Low [%i people/cell]') % classes[1] style_classes[4]['label'] = tr('Medium [%i people/cell]') % classes[4] style_classes[7]['label'] = tr('High [%i people/cell]') % classes[7] style_info['legend_title'] = tr('Population Density') # Create raster object and return R = Raster(M, projection=my_hazard.get_projection(), geotransform=my_hazard.get_geotransform(), name=tr('Population which %s') % get_function_title(self), keywords={'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title}, style_info=style_info) return R
def run(self, layers): """Plugin for impact of population as derived by categorised hazard. :param layers: List of layers expected to contain * hazard_layer: Raster layer of categorised hazard * exposure_layer: Raster layer of population data Counts number of people exposed to each category of the hazard :returns: Map of population exposed to high category Table with number of people in each category """ # The 3 category high_t = self.parameters['Categorical thresholds'][2] medium_t = self.parameters['Categorical thresholds'][1] low_t = self.parameters['Categorical thresholds'][0] # Identify hazard and exposure layers hazard_layer = get_hazard_layer(layers) # Categorised Hazard exposure_layer = get_exposure_layer(layers) # Population Raster question = get_question( hazard_layer.get_name(), exposure_layer.get_name(), self) # Extract data as numeric arrays C = hazard_layer.get_data(nan=0.0) # Category # Calculate impact as population exposed to each category P = exposure_layer.get_data(nan=0.0, scaling=True) H = numpy.where(C <= high_t, P, 0) M = numpy.where(C < medium_t, P, 0) L = numpy.where(C < low_t, P, 0) # Count totals total = int(numpy.sum(P)) high = int(numpy.sum(H)) - int(numpy.sum(M)) medium = int(numpy.sum(M)) - int(numpy.sum(L)) low = int(numpy.sum(L)) total_impact = high + medium + low # Don't show digits less than a 1000 total = population_rounding(total) total_impact = population_rounding(total_impact) high = population_rounding(high) medium = population_rounding(medium) low = population_rounding(low) minimum_needs = [ parameter.serialize() for parameter in self.parameters['minimum needs'] ] # Generate impact report for the pdf map table_body = [ question, TableRow([tr('People impacted '), '%s' % format_int(total_impact)], header=True), TableRow([tr('People in high hazard area '), '%s' % format_int(high)], header=True), TableRow([tr('People in medium hazard area '), '%s' % format_int(medium)], header=True), TableRow([tr('People in low hazard area'), '%s' % format_int(low)], header=True)] impact_table = Table(table_body).toNewlineFreeString() # Extend impact report for on-screen display table_body.extend([ TableRow(tr('Notes'), header=True), tr('Map shows population count in high or medium hazard area'), tr('Total population: %s') % format_int(total), TableRow(tr( 'Table below shows the minimum needs for all ' 'affected people'))]) 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'])])) impact_summary = Table(table_body).toNewlineFreeString() map_title = tr('People in high hazard areas') # Generate 8 equidistant classes across the range of flooded population # 8 is the number of classes in the predefined flood population style # as imported # noinspection PyTypeChecker classes = numpy.linspace( numpy.nanmin(M.flat[:]), numpy.nanmax(M.flat[:]), 8) # Modify labels in existing flood style to show quantities style_classes = style_info['style_classes'] style_classes[1]['label'] = tr('Low [%i people/cell]') % classes[1] style_classes[4]['label'] = tr('Medium [%i people/cell]') % classes[4] style_classes[7]['label'] = tr('High [%i people/cell]') % classes[7] style_info['legend_title'] = tr('Population Count') # Create raster object and return raster_layer = Raster( M, projection=hazard_layer.get_projection(), geotransform=hazard_layer.get_geotransform(), name=tr('Population which %s') % ( get_function_title(self).lower()), keywords={ 'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title, 'total_needs': total_needs}, style_info=style_info) return raster_layer
def run(self, layers): """Risk plugin for flood population evacuation Input layers: List of layers expected to contain H: Raster layer of flood depth P: Raster layer of population data on the same grid as H Counts number of people exposed to flood levels exceeding specified threshold. Return Map of population exposed to flood levels exceeding the threshold Table with number of people evacuated and supplies required """ # Depth above which people are regarded affected [m] threshold = 1.0 # Threshold [m] # Identify hazard and exposure layers inundation = get_hazard_layer(layers) # Flood inundation [m] population = get_exposure_layer(layers) question = get_question(inundation.get_name(), population.get_name(), self) # Extract data as numeric arrays D = inundation.get_data(nan=0.0) # Depth # Calculate impact as population exposed to depths > threshold P = population.get_data(nan=0.0, scaling=True) I = numpy.where(D > threshold, P, 0) M = numpy.where(D > 0.5, P, 0) L = numpy.where(D > 0.3, P, 0) # Count totals total = int(numpy.sum(P)) evacuated = int(numpy.sum(I)) medium = int(numpy.sum(M)) - int(numpy.sum(I)) low = int(numpy.sum(L)) - int(numpy.sum(M)) # Don't show digits less than a 1000 if total > 1000: total = total // 1000 * 1000 if evacuated > 1000: evacuated = evacuated // 1000 * 1000 if medium > 1000: medium = medium // 1000 * 1000 if low > 1000: low = low // 1000 * 1000 # Calculate estimated needs based on BNPB Perka 7/2008 minimum bantuan rice = evacuated * 2.8 drinking_water = evacuated * 17.5 water = evacuated * 67 family_kits = evacuated / 5 toilets = evacuated / 20 # Generate impact report for the pdf map table_body = [question, TableRow([tr('People needing evacuation'), '%i' % evacuated], header=True), TableRow(tr('Map shows population density needing ' 'evacuation'))] #, ## TableRow([tr('People in 50cm to 1m of water '), ## '%i' % medium], ## header=True), ## TableRow([tr('People in 30cm to 50cm of water'), ## '%i' % low], ## header=True)] ## TableRow([tr('Needs per week'), tr('Total')], ## header=True), ## [tr('Rice [kg]'), int(rice)], ## [tr('Drinking Water [l]'), int(drinking_water)], ## [tr('Clean Water [l]'), int(water)], ## [tr('Family Kits'), int(family_kits)], ## [tr('Toilets'), int(toilets)]] impact_table = Table(table_body).toNewlineFreeString() # Extend impact report for on-screen display table_body.extend([TableRow(tr('Notes:'), header=True), tr('Total population: %i') % total, tr('People need evacuation if flood levels ' 'exceed %(eps)i m') % {'eps': threshold}, tr('People in 50cm to 1m of water: %i') % medium, tr('People in 30cm to 50cm of water: %i') % low]) ## tr('Minimum needs are defined in BNPB ' ## 'regulation 7/2008')]) impact_summary = Table(table_body).toNewlineFreeString() map_title = tr('People in need of evacuation') style_info['legend_title'] = tr('Population Density') # Create raster object and return R = Raster(I, projection=inundation.get_projection(), geotransform=inundation.get_geotransform(), name=tr('Population which %s') % ( get_function_title(self).lower()), keywords={'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title}, style_info=style_info) return R
def run(self, layers): """Plugin for impact of population as derived by categorised hazard Input layers: List of layers expected to contain H: Raster layer of categorised hazard P: Raster layer of population data Counts number of people exposed to each category of the hazard Return Map of population exposed to high category Table with number of people in each category """ # The 3 category high_t = 1 medium_t = 0.66 low_t = 0.34 # Identify hazard and exposure layers inundation = get_hazard_layer(layers) # Categorised Hazard population = get_exposure_layer(layers) # Population Raster question = get_question(inundation.get_name(), population.get_name(), self) # Extract data as numeric arrays C = inundation.get_data(nan=0.0) # Category # Calculate impact as population exposed to each category P = population.get_data(nan=0.0, scaling=True) H = numpy.where(C == high_t, P, 0) M = numpy.where(C > medium_t, P, 0) L = numpy.where(C < low_t, P, 0) # Count totals total = int(numpy.sum(P)) high = int(numpy.sum(H)) medium = int(numpy.sum(M)) - int(numpy.sum(H)) low = int(numpy.sum(L)) - int(numpy.sum(M)) total_impact = high + medium + low # Don't show digits less than a 1000 if total > 1000: total = total // 1000 * 1000 if total_impact > 1000: total_impact = total_impact // 1000 * 1000 if high > 1000: high = high // 1000 * 1000 if medium > 1000: medium = medium // 1000 * 1000 if low > 1000: low = low // 1000 * 1000 # Calculate estimated needs based on BNPB Perka 7/2008 minimum bantuan ## rice = evacuated * 2.8 ## drinking_water = evacuated * 17.5 ## water = evacuated * 67 ## family_kits = evacuated / 5 ## toilets = evacuated / 20 # Generate impact report for the pdf map table_body = [question, TableRow([tr('People impacted '), '%i' % total_impact], header=True), TableRow([tr('People in high hazard area '), '%i' % high], header=True), TableRow([tr('People in medium hazard area '), '%i' % medium], header=True), TableRow([tr('People in low hazard area'), '%i' % low], header=True)] ## TableRow([tr('Needs per week'), tr('Total')], ## header=True), ## [tr('Rice [kg]'), int(rice)], ## [tr('Drinking Water [l]'), int(drinking_water)], ## [tr('Clean Water [l]'), int(water)], ## [tr('Family Kits'), int(family_kits)], ## [tr('Toilets'), int(toilets)]] impact_table = Table(table_body).toNewlineFreeString() # Extend impact report for on-screen display table_body.extend([TableRow(tr('Notes'), header=True), tr('Map shows population density in high or medium ' 'hazard area'), tr('Total population: %i') % total]) ## tr('Minimum needs are defined in BNPB ' ## 'regulation 7/2008')]) impact_summary = Table(table_body).toNewlineFreeString() map_title = tr('People in high hazard areas') # Generare 8 equidistant classes across the range of flooded population # 8 is the number of classes in the predefined flood population style # as imported classes = numpy.linspace(numpy.nanmin(M.flat[:]), numpy.nanmax(M.flat[:]), 8) # Modify labels in existing flood style to show quantities style_classes = style_info['style_classes'] style_classes[1]['label'] = tr('Low [%i people/cell]') % classes[1] style_classes[4]['label'] = tr('Medium [%i people/cell]') % classes[4] style_classes[7]['label'] = tr('High [%i people/cell]') % classes[7] style_info['legend_title'] = tr('Population Density') # Create raster object and return R = Raster(M, projection=inundation.get_projection(), geotransform=inundation.get_geotransform(), name=tr('Population which %s') % get_function_title(self), keywords={'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title}, style_info=style_info) return R
def run(self, layers): """Plugin for impact of population as derived by categorised hazard. Input layers: List of layers expected to contain hazard_layer: Raster layer of categorised hazard exposure_layer: Raster layer of population data Counts number of people exposed to each category of the hazard Return Map of population exposed to high category Table with number of people in each category """ # The 3 category high_t = self.parameters['Categorical thresholds'][2] medium_t = self.parameters['Categorical thresholds'][1] low_t = self.parameters['Categorical thresholds'][0] # Identify hazard and exposure layers hazard_layer = get_hazard_layer(layers) # Categorised Hazard exposure_layer = get_exposure_layer(layers) # Population Raster question = get_question( hazard_layer.get_name(), exposure_layer.get_name(), self) # Extract data as numeric arrays C = hazard_layer.get_data(nan=0.0) # Category # Calculate impact as population exposed to each category P = exposure_layer.get_data(nan=0.0, scaling=True) H = numpy.where(C <= high_t, P, 0) M = numpy.where(C < medium_t, P, 0) L = numpy.where(C < low_t, P, 0) # Count totals total = int(numpy.sum(P)) high = int(numpy.sum(H)) - int(numpy.sum(M)) medium = int(numpy.sum(M)) - int(numpy.sum(L)) low = int(numpy.sum(L)) total_impact = high + medium + low # Don't show digits less than a 1000 total = round_thousand(total) total_impact = round_thousand(total_impact) high = round_thousand(high) medium = round_thousand(medium) low = round_thousand(low) # Calculate estimated minimum needs minimum_needs = self.parameters['minimum needs'] tot_needs = evacuated_population_weekly_needs( total_impact, minimum_needs) # Generate impact report for the pdf map table_body = [ question, TableRow([tr('People impacted '), '%s' % format_int(total_impact)], header=True), TableRow([tr('People in high hazard area '), '%s' % format_int(high)], header=True), TableRow([tr('People in medium hazard area '), '%s' % format_int(medium)], header=True), TableRow([tr('People in low hazard area'), '%s' % format_int(low)], header=True)] impact_table = Table(table_body).toNewlineFreeString() # Extend impact report for on-screen display table_body.extend([ TableRow(tr('Notes'), header=True), tr('Map shows population density in high or medium hazard area'), tr('Total population: %s') % format_int(total), TableRow(tr( 'Table below shows the weekly minimum needs for all ' 'affected people')), TableRow([tr('Needs per week'), tr('Total')], header=True), [tr('Rice [kg]'), format_int(tot_needs['rice'])], [tr('Drinking Water [l]'), format_int(tot_needs['drinking_water'])], [tr('Clean Water [l]'), format_int(tot_needs['water'])], [tr('Family Kits'), format_int(tot_needs['family_kits'])], [tr('Toilets'), format_int(tot_needs['toilets'])] ]) impact_summary = Table(table_body).toNewlineFreeString() map_title = tr('People in high hazard areas') # Generate 8 equidistant classes across the range of flooded population # 8 is the number of classes in the predefined flood population style # as imported # noinspection PyTypeChecker classes = numpy.linspace( numpy.nanmin(M.flat[:]), numpy.nanmax(M.flat[:]), 8) # Modify labels in existing flood style to show quantities style_classes = style_info['style_classes'] style_classes[1]['label'] = tr('Low [%i people/cell]') % classes[1] style_classes[4]['label'] = tr('Medium [%i people/cell]') % classes[4] style_classes[7]['label'] = tr('High [%i people/cell]') % classes[7] style_info['legend_title'] = tr('Population Density') # Create raster object and return raster_layer = Raster( M, projection=hazard_layer.get_projection(), geotransform=hazard_layer.get_geotransform(), name=tr('Population which %s') % ( get_function_title(self).lower()), keywords={ 'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title}, style_info=style_info) return raster_layer
def run(self, layers): """Plugin for impact of population as derived by categorised hazard. :param layers: List of layers expected to contain * hazard_layer: Raster layer of categorised hazard * exposure_layer: Raster layer of population data Counts number of people exposed to each category of the hazard :returns: Map of population exposed to high category Table with number of people in each category """ # The 3 category high_t = self.parameters['Categorical thresholds'][2] medium_t = self.parameters['Categorical thresholds'][1] low_t = self.parameters['Categorical thresholds'][0] # Identify hazard and exposure layers hazard_layer = get_hazard_layer(layers) # Categorised Hazard exposure_layer = get_exposure_layer(layers) # Population Raster question = get_question(hazard_layer.get_name(), exposure_layer.get_name(), self) # Extract data as numeric arrays C = hazard_layer.get_data(nan=0.0) # Category # Calculate impact as population exposed to each category P = exposure_layer.get_data(nan=0.0, scaling=True) H = numpy.where(C <= high_t, P, 0) M = numpy.where(C < medium_t, P, 0) L = numpy.where(C < low_t, P, 0) # Count totals total = int(numpy.sum(P)) high = int(numpy.sum(H)) - int(numpy.sum(M)) medium = int(numpy.sum(M)) - int(numpy.sum(L)) low = int(numpy.sum(L)) total_impact = high + medium + low # Don't show digits less than a 1000 total = population_rounding(total) total_impact = population_rounding(total_impact) high = population_rounding(high) medium = population_rounding(medium) low = population_rounding(low) minimum_needs = [ parameter.serialize() for parameter in self.parameters['minimum needs'] ] # Generate impact report for the pdf map table_body = [ question, TableRow([tr('People impacted '), '%s' % format_int(total_impact)], header=True), TableRow( [tr('People in high hazard area '), '%s' % format_int(high)], header=True), TableRow([ tr('People in medium hazard area '), '%s' % format_int(medium) ], header=True), TableRow([tr('People in low hazard area'), '%s' % format_int(low)], header=True) ] impact_table = Table(table_body).toNewlineFreeString() # Extend impact report for on-screen display table_body.extend([ TableRow(tr('Notes'), header=True), tr('Map shows population count in high or medium hazard area'), tr('Total population: %s') % format_int(total), TableRow( tr('Table below shows the minimum needs for all ' 'affected people')) ]) 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']) ])) impact_summary = Table(table_body).toNewlineFreeString() map_title = tr('People in high hazard areas') # Generate 8 equidistant classes across the range of flooded population # 8 is the number of classes in the predefined flood population style # as imported # noinspection PyTypeChecker classes = numpy.linspace(numpy.nanmin(M.flat[:]), numpy.nanmax(M.flat[:]), 8) # Modify labels in existing flood style to show quantities style_classes = style_info['style_classes'] style_classes[1]['label'] = tr('Low [%i people/cell]') % classes[1] style_classes[4]['label'] = tr('Medium [%i people/cell]') % classes[4] style_classes[7]['label'] = tr('High [%i people/cell]') % classes[7] style_info['legend_title'] = tr('Population Count') # Create raster object and return raster_layer = Raster(M, projection=hazard_layer.get_projection(), geotransform=hazard_layer.get_geotransform(), name=tr('Population which %s') % (get_function_title(self).lower()), keywords={ 'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title, 'total_needs': total_needs }, style_info=style_info) return raster_layer
def run(self, layers): """Plugin for impact of population as derived by categorised hazard. Input :param layers: List of layers expected to contain * hazard_layer: Raster layer of categorised hazard * exposure_layer: Raster layer of population data Counts number of people exposed to each category of the hazard Return Map of population exposed to high category Table with number of people in each category """ # The 3 category high_t = self.parameters['high_thresholds'] medium_t = self.parameters['medium_thresholds'] low_t = self.parameters['low_thresholds'] # Identify hazard and exposure layers hazard_layer = get_hazard_layer(layers) # Categorised Hazard exposure_layer = get_exposure_layer(layers) # Population Raster question = get_question( hazard_layer.get_name(), exposure_layer.get_name(), self) # Extract data as numeric arrays data = hazard_layer.get_data(nan=0.0) # Category # Calculate impact as population exposed to each category population = exposure_layer.get_data(nan=0.0, scaling=True) if high_t == 0: hi = numpy.where(0, population, 0) else: hi = numpy.where(data == high_t, population, 0) if medium_t == 0: med = numpy.where(0, population, 0) else: med = numpy.where(data == medium_t, population, 0) if low_t == 0: lo = numpy.where(0, population, 0) else: lo = numpy.where(data == low_t, population, 0) if high_t == 0: impact = numpy.where( (data == low_t) + (data == medium_t), population, 0) elif medium_t == 0: impact = numpy.where( (data == low_t) + (data == high_t), population, 0) elif low_t == 0: impact = numpy.where( (data == medium_t) + (data == high_t), population, 0) else: impact = numpy.where( (data == low_t) + (data == medium_t) + (data == high_t), population, 0) # Count totals total = int(numpy.sum(population)) high = int(numpy.sum(hi)) medium = int(numpy.sum(med)) low = int(numpy.sum(lo)) total_impact = int(numpy.sum(impact)) # Perform population rounding based on number of people no_impact = population_rounding(total - total_impact) total = population_rounding(total) total_impact = population_rounding(total_impact) high = population_rounding(high) medium = population_rounding(medium) low = population_rounding(low) minimum_needs = [ parameter.serialize() for parameter in self.parameters['minimum needs'] ] # Generate impact report for the pdf map table_body = [question, TableRow([tr('Total Population Affected '), '%s' % format_int(total_impact)], header=True), TableRow([tr('Population in High risk areas '), '%s' % format_int(high)]), TableRow([tr('Population in Medium risk areas '), '%s' % format_int(medium)]), TableRow([tr('Population in Low risk areas '), '%s' % format_int(low)]), TableRow([tr('Population Not Affected'), '%s' % format_int(no_impact)]), TableRow(tr('Table below shows the minimum ' 'needs for all evacuated people'))] 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'])])) impact_table = Table(table_body).toNewlineFreeString() 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 areas'), tr('Total population: %s') % format_int(total) ]) impact_summary = Table(table_body).toNewlineFreeString() # Create style colours = [ '#FFFFFF', '#38A800', '#79C900', '#CEED00', '#FFCC00', '#FF6600', '#FF0000', '#7A0000'] classes = create_classes(impact.flat[:], len(colours)) interval_classes = humanize_class(classes) style_classes = [] for i in xrange(len(colours)): style_class = dict() if i == 1: label = create_label(interval_classes[i], 'Low') elif i == 4: label = create_label(interval_classes[i], 'Medium') elif i == 7: label = create_label(interval_classes[i], 'High') else: label = create_label(interval_classes[i]) style_class['label'] = label style_class['quantity'] = classes[i] if i == 0: transparency = 30 else: transparency = 30 style_class['transparency'] = transparency style_class['colour'] = colours[i] style_classes.append(style_class) style_info = dict( target_field=None, style_classes=style_classes, style_type='rasterStyle') # For printing map purpose map_title = tr('Population affected by each category') legend_notes = tr( 'Thousand separator is represented by %s' % get_thousand_separator()) legend_units = tr('(people per cell)') legend_title = tr('Number of People') # Create raster object and return raster_layer = Raster( impact, projection=hazard_layer.get_projection(), geotransform=hazard_layer.get_geotransform(), name=tr('Population which %s') % ( get_function_title(self).lower()), keywords={ 'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title, 'legend_notes': legend_notes, 'legend_units': legend_units, 'legend_title': legend_title, 'total_needs': total_needs}, style_info=style_info) return raster_layer
def run(self, layers): """Risk plugin for flood population evacuation Input layers: List of layers expected to contain my_hazard: Raster layer of flood depth my_exposure: Raster layer of population data on the same grid as my_hazard Counts number of people exposed to flood levels exceeding specified threshold. Return Map of population exposed to flood levels exceeding the threshold Table with number of people evacuated and supplies required """ # Identify hazard and exposure layers my_hazard = get_hazard_layer(layers) # Flood inundation [m] my_exposure = get_exposure_layer(layers) question = get_question(my_hazard.get_name(), my_exposure.get_name(), self) # Determine depths above which people are regarded affected [m] # Use thresholds from inundation layer if specified thresholds = self.parameters['thresholds [m]'] verify(isinstance(thresholds, list), 'Expected thresholds to be a list. Got %s' % str(thresholds)) # Extract data as numeric arrays D = my_hazard.get_data(nan=0.0) # Depth # Calculate impact as population exposed to depths > max threshold P = my_exposure.get_data(nan=0.0, scaling=True) # Calculate impact to intermediate thresholds counts = [] # merely initialize my_impact = None for i, lo in enumerate(thresholds): if i == len(thresholds) - 1: # The last threshold my_impact = M = numpy.where(D >= lo, P, 0) else: # Intermediate thresholds hi = thresholds[i + 1] M = numpy.where((D >= lo) * (D < hi), P, 0) # Count val = int(numpy.sum(M)) # Don't show digits less than a 1000 val = round_thousand(val) counts.append(val) # Count totals evacuated = counts[-1] total = int(numpy.sum(P)) # Don't show digits less than a 1000 total = round_thousand(total) # Calculate estimated minimum needs # The default value of each logistic is based on BNPB Perka 7/2008 # minimum bantuan minimum_needs = self.parameters['minimum needs'] mn_rice = minimum_needs['Rice'] mn_drinking_water = minimum_needs['Drinking Water'] mn_water = minimum_needs['Water'] mn_family_kits = minimum_needs['Family Kits'] mn_toilets = minimum_needs['Toilets'] rice = int(evacuated * mn_rice) drinking_water = int(evacuated * mn_drinking_water) water = int(evacuated * mn_water) family_kits = int(evacuated * mn_family_kits) toilets = int(evacuated * mn_toilets) # Generate impact report for the pdf map table_body = [ question, TableRow([(tr('People in %.1f m of water') % thresholds[-1]), '%s*' % format_int(evacuated)], header=True), TableRow(tr('* Number is rounded to the nearest 1000'), header=False), TableRow(tr('Map shows population density needing evacuation')), TableRow([tr('Needs per week'), tr('Total')], header=True), [tr('Rice [kg]'), format_int(rice)], [tr('Drinking Water [l]'), format_int(drinking_water)], [tr('Clean Water [l]'), format_int(water)], [tr('Family Kits'), format_int(family_kits)], [tr('Toilets'), format_int(toilets)] ] 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 flood 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 fractionals.') ]) 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) }) table_body.append(TableRow(s, header=False)) # Result impact_summary = Table(table_body).toNewlineFreeString() impact_table = impact_summary # check for zero impact if numpy.nanmax(my_impact) == 0 == numpy.nanmin(my_impact): table_body = [ question, TableRow([(tr('People in %.1f m of water') % thresholds[-1]), '%s' % format_int(evacuated)], header=True) ] my_message = Table(table_body).toNewlineFreeString() raise ZeroImpactException(my_message) # Create style colours = [ '#FFFFFF', '#38A800', '#79C900', '#CEED00', '#FFCC00', '#FF6600', '#FF0000', '#7A0000' ] classes = create_classes(my_impact.flat[:], len(colours)) interval_classes = humanize_class(classes) style_classes = [] for i in xrange(len(colours)): style_class = dict() if i == 1: label = create_label(interval_classes[i], 'Low') elif i == 4: label = create_label(interval_classes[i], 'Medium') elif i == 7: label = create_label(interval_classes[i], 'High') else: label = create_label(interval_classes[i]) style_class['label'] = label style_class['quantity'] = classes[i] if i == 0: transparency = 100 else: transparency = 0 style_class['transparency'] = transparency style_class['colour'] = colours[i] style_classes.append(style_class) style_info = dict(target_field=None, style_classes=style_classes, style_type='rasterStyle') # For printing map purpose map_title = tr('People in need of evacuation') legend_notes = tr('Thousand separator is represented by %s' % get_thousand_separator()) legend_units = tr('(people per cell)') legend_title = tr('Population density') # Create raster object and return R = Raster(my_impact, projection=my_hazard.get_projection(), geotransform=my_hazard.get_geotransform(), name=tr('Population which %s') % get_function_title(self), keywords={ 'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title, 'legend_notes': legend_notes, 'legend_units': legend_units, 'legend_title': legend_title }, style_info=style_info) return R
def run(self, layers): """Risk plugin for flood population evacuation Input layers: List of layers expected to contain H: Raster layer of flood depth P: Raster layer of population data on the same grid as H Counts number of people exposed to flood levels exceeding specified threshold. Return Map of population exposed to flood levels exceeding the threshold Table with number of people evacuated and supplies required """ # Identify hazard and exposure layers inundation = get_hazard_layer(layers) # Flood inundation [m] population = get_exposure_layer(layers) question = get_question(inundation.get_name(), population.get_name(), self) # Determine depths above which people are regarded affected [m] # Use thresholds from inundation layer if specified thresholds = self.parameters["thresholds"] verify(isinstance(thresholds, list), "Expected thresholds to be a list. Got %s" % str(thresholds)) # Extract data as numeric arrays D = inundation.get_data(nan=0.0) # Depth # Calculate impact as population exposed to depths > max threshold P = population.get_data(nan=0.0, scaling=True) # Calculate impact to intermediate thresholds counts = [] for i, lo in enumerate(thresholds): if i == len(thresholds) - 1: # The last threshold I = M = numpy.where(D >= lo, P, 0) else: # Intermediate thresholds hi = thresholds[i + 1] M = numpy.where((D >= lo) * (D < hi), P, 0) # Count val = int(numpy.sum(M)) # Don't show digits less than a 1000 if val > 1000: val = val // 1000 * 1000 counts.append(val) # Count totals evacuated = counts[-1] total = int(numpy.sum(P)) # Don't show digits less than a 1000 if total > 1000: total = total // 1000 * 1000 # Calculate estimated needs based on BNPB Perka 7/2008 minimum bantuan # FIXME: Refactor and share # 400g per person per day rice = int(evacuated * 2.8) # 2.5L per person per day drinking_water = int(evacuated * 17.5) # 15L per person per day water = int(evacuated * 105) # assume 5 people per family (not in perka) family_kits = int(evacuated / 5) # 20 people per toilet toilets = int(evacuated / 20) # Generate impact report for the pdf map table_body = [ question, TableRow([(tr("People in %.1f m of water") % thresholds[-1]), "%s" % format_int(evacuated)], header=True), TableRow(tr("Map shows population density needing " "evacuation")), TableRow([tr("Needs per week"), tr("Total")], header=True), [tr("Rice [kg]"), format_int(rice)], [tr("Drinking Water [l]"), format_int(drinking_water)], [tr("Clean Water [l]"), format_int(water)], [tr("Family Kits"), format_int(family_kits)], [tr("Toilets"), format_int(toilets)], ] impact_table = Table(table_body).toNewlineFreeString() 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 flood levels " "exceed %(eps).1f m") % {"eps": thresholds[-1]}, tr("Minimum needs are defined in BNPB " "regulation 7/2008"), ] ) 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), } table_body.append(TableRow(s, header=False)) impact_summary = Table(table_body).toNewlineFreeString() map_title = tr("People in need of evacuation") # Generate 8 equidistant classes across the range of flooded population # 8 is the number of classes in the predefined flood population style # as imported classes = numpy.linspace(numpy.nanmin(I.flat[:]), numpy.nanmax(I.flat[:]), 8) # Work out how many decimals to use # Modify labels in existing flood style to show quantities style_classes = style_info["style_classes"] style_classes[1]["label"] = tr("Low [%.2f people/cell]") % classes[1] style_classes[4]["label"] = tr("Medium [%.2f people/cell]") % classes[4] style_classes[7]["label"] = tr("High [%.2f people/cell]") % classes[7] # Override associated quantities in colour style for i in range(len(classes)): if i == 0: transparency = 100 else: transparency = 0 style_classes[i]["quantity"] = classes[i] style_classes[i]["transparency"] = transparency # Title style_info["legend_title"] = tr("Population Density") # Create raster object and return R = Raster( I, projection=inundation.get_projection(), geotransform=inundation.get_geotransform(), name=tr("Population which %s") % get_function_title(self), keywords={"impact_summary": impact_summary, "impact_table": impact_table, "map_title": map_title}, style_info=style_info, ) return R
def run(self, layers): """Plugin for impact of population as derived by categorised hazard Input layers: List of layers expected to contain my_hazard: Raster layer of categorised hazard my_exposure: Raster layer of population data Counts number of people exposed to each category of the hazard Return Map of population exposed to high category Table with number of people in each category """ # The 3 category high_t = 1 medium_t = 0.66 low_t = 0.34 # Identify hazard and exposure layers my_hazard = get_hazard_layer(layers) # Categorised Hazard my_exposure = get_exposure_layer(layers) # Population Raster question = get_question(my_hazard.get_name(), my_exposure.get_name(), self) # Extract data as numeric arrays C = my_hazard.get_data(nan=0.0) # Category # Calculate impact as population exposed to each category P = my_exposure.get_data(nan=0.0, scaling=True) H = numpy.where(C == high_t, P, 0) M = numpy.where(C > medium_t, P, 0) L = numpy.where(C < low_t, P, 0) # Count totals total = int(numpy.sum(P)) high = int(numpy.sum(H)) medium = int(numpy.sum(M)) - int(numpy.sum(H)) low = int(numpy.sum(L)) - int(numpy.sum(M)) total_impact = high + medium + low # Don't show digits less than a 1000 total = round_thousand(total) total_impact = round_thousand(total_impact) high = round_thousand(high) medium = round_thousand(medium) low = round_thousand(low) # Generate impact report for the pdf map table_body = [ question, TableRow([tr('People impacted '), '%s' % format_int(total_impact)], header=True), TableRow( [tr('People in high hazard area '), '%s' % format_int(high)], header=True), TableRow([ tr('People in medium hazard area '), '%s' % format_int(medium) ], header=True), TableRow([tr('People in low hazard area'), '%s' % format_int(low)], header=True) ] impact_table = Table(table_body).toNewlineFreeString() # Extend impact report for on-screen display table_body.extend([ TableRow(tr('Notes'), header=True), tr('Map shows population density in high or medium ' 'hazard area'), tr('Total population: %s') % format_int(total) ]) impact_summary = Table(table_body).toNewlineFreeString() map_title = tr('People in high hazard areas') # Generate 8 equidistant classes across the range of flooded population # 8 is the number of classes in the predefined flood population style # as imported # noinspection PyTypeChecker classes = numpy.linspace(numpy.nanmin(M.flat[:]), numpy.nanmax(M.flat[:]), 8) # Modify labels in existing flood style to show quantities style_classes = style_info['style_classes'] style_classes[1]['label'] = tr('Low [%i people/cell]') % classes[1] style_classes[4]['label'] = tr('Medium [%i people/cell]') % classes[4] style_classes[7]['label'] = tr('High [%i people/cell]') % classes[7] style_info['legend_title'] = tr('Population Density') # Create raster object and return R = Raster(M, projection=my_hazard.get_projection(), geotransform=my_hazard.get_geotransform(), name=tr('Population which %s') % (get_function_title(self).lower()), keywords={ 'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title }, style_info=style_info) return R
def run(self, layers): """Risk plugin for flood population evacuation Input layers: List of layers expected to contain H: Raster layer of flood depth P: Raster layer of population data on the same grid as H Counts number of people exposed to flood levels exceeding specified threshold. Return Map of population exposed to flood levels exceeding the threshold Table with number of people evacuated and supplies required """ # Identify hazard and exposure layers inundation = get_hazard_layer(layers) # Flood inundation [m] population = get_exposure_layer(layers) question = get_question(inundation.get_name(), population.get_name(), self) # Determine depths above which people are regarded affected [m] # Use thresholds from inundation layer if specified thresholds = get_thresholds(inundation) if len(thresholds) == 0: # Default threshold thresholds = [1.0] verify(isinstance(thresholds, list), 'Expected thresholds to be a list. Got %s' % str(thresholds)) # Extract data as numeric arrays D = inundation.get_data(nan=0.0) # Depth # Calculate impact as population exposed to depths > max threshold P = population.get_data(nan=0.0, scaling=True) # Calculate impact to intermediate thresholds counts = [] for i, lo in enumerate(thresholds): if i == len(thresholds) - 1: # The last threshold I = M = numpy.where(D >= lo, P, 0) else: # Intermediate thresholds hi = thresholds[i + 1] M = numpy.where((D >= lo) * (D < hi), P, 0) # Count val = int(numpy.sum(M)) # Don't show digits less than a 1000 if val > 1000: val = val // 1000 * 1000 counts.append(val) # Count totals evacuated = counts[-1] total = int(numpy.sum(P)) # Don't show digits less than a 1000 if total > 1000: total = total // 1000 * 1000 # Calculate estimated needs based on BNPB Perka 7/2008 minimum bantuan rice = evacuated * 2.8 drinking_water = evacuated * 17.5 water = evacuated * 67 family_kits = evacuated / 5 toilets = evacuated / 20 # Generate impact report for the pdf map table_body = [ question, TableRow([_('People needing evacuation'), '%i' % evacuated], header=True), TableRow(_('Map shows population density needing ' 'evacuation')), TableRow([_('Needs per week'), _('Total')], header=True), [_('Rice [kg]'), int(rice)], [_('Drinking Water [l]'), int(drinking_water)], [_('Clean Water [l]'), int(water)], [_('Family Kits'), int(family_kits)], [_('Toilets'), int(toilets)] ] impact_table = Table(table_body).toNewlineFreeString() # Extend impact report for on-screen display table_body.extend([ TableRow(_('Notes'), header=True), _('Total population: %i') % total, _('People need evacuation if flood levels ' 'exceed %(eps).1f m') % { 'eps': thresholds[-1] }, _('Minimum needs are defined in BNPB ' 'regulation 7/2008') ]) if len(counts) > 1: table_body.append(TableRow(_('Detailed breakdown'), header=True)) for i, val in enumerate(counts[:-1]): s = ( _('People in %(lo).1f m to %(hi).1f m of water: %(val)i') % { 'lo': thresholds[i], 'hi': thresholds[i + 1], 'val': val }) table_body.append(TableRow(s, header=False)) impact_summary = Table(table_body).toNewlineFreeString() map_title = _('People in need of evacuation') # Generate 8 equidistant classes across the range of flooded population # 8 is the number of classes in the predefined flood population style # as imported classes = numpy.linspace(numpy.nanmin(I.flat[:]), numpy.nanmax(I.flat[:]), 8) # Modify labels in existing flood style to show quantities style_classes = style_info['style_classes'] style_classes[1]['label'] = _('Low [%i people/cell]') % classes[1] style_classes[4]['label'] = _('Medium [%i people/cell]') % classes[4] style_classes[7]['label'] = _('High [%i people/cell]') % classes[7] style_info['legend_title'] = _('Population Density') # Create raster object and return R = Raster(I, projection=inundation.get_projection(), geotransform=inundation.get_geotransform(), name=_('Population which %s') % get_function_title(self), keywords={ 'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title }, style_info=style_info) return R
def run(self, layers): """Impact function for flood population evacuation Input layers: List of layers expected to contain H: Raster layer of flood depth P: Raster layer of population data on the same grid as H Counts number of people exposed to flood levels exceeding specified threshold. Return Map of population exposed to flood levels exceeding the threshold Table with number of people evacuated and supplies required """ # Identify hazard and exposure layers inundation = get_hazard_layer(layers) # Flood inundation [m] population = get_exposure_layer(layers) question = get_question(inundation.get_name(), population.get_name(), self) # Determine depths above which people are regarded affected [m] # Use thresholds from inundation layer if specified threshold = self.parameters['threshold'] # Extract data as numeric arrays D = inundation.get_data(nan=0.0) # Depth # Calculate impact as population exposed to depths > max threshold P = population.get_data(nan=0.0, scaling=True) # Create new array with positive population counts only for # pixels where inundation exceeds threshold. I = numpy.where(D >= threshold, P, 0) # Count population thus exposed to inundation evacuated = int(numpy.sum(I)) # Count total population total = int(numpy.sum(P)) # Calculate estimated needs based on BNPB Perka 7/2008 minimum bantuan # 400g per person per day rice = int(evacuated * 2.8) # 2.5L per person per day drinking_water = int(evacuated * 17.5) # 15L per person per day water = int(evacuated * 105) # assume 5 people per family (not in perka) family_kits = int(evacuated / 5) # 20 people per toilet toilets = int(evacuated / 20) # Generate impact report for the pdf map table_body = [question, TableRow([('People in %.1f m of water' % threshold), '%s' % evacuated], header=True), TableRow('Map shows population density needing ' 'evacuation'), TableRow(['Needs per week', 'Total'], header=True), ['Rice [kg]', rice], ['Drinking Water [l]', drinking_water], ['Clean Water [l]', water], ['Family Kits', family_kits], ['Toilets', toilets]] impact_table = Table(table_body).toNewlineFreeString() # Extend impact report for on-screen display table_body.extend([TableRow('Notes', header=True), 'Total population: %s' % total, 'People need evacuation if flood levels ' 'exceed %(eps).1f m' % {'eps': threshold}, 'Minimum needs are defined in BNPB ' 'regulation 7/2008']) impact_summary = Table(table_body).toNewlineFreeString() map_title = 'People in need of evacuation' # Generate 8 equidistant classes across the range of flooded population # 8 is the number of classes in the predefined flood population style # as imported classes = numpy.linspace(numpy.nanmin(I.flat[:]), numpy.nanmax(I.flat[:]), 8) # Define 8 colours - on for each class colours = ['#FFFFFF', '#38A800', '#79C900', '#CEED00', '#FFCC00', '#FF6600', '#FF0000', '#7A0000'] # Create style associating each class with a colour and transparency. style_classes = [] for i, cls in enumerate(classes): if i == 0: # Smallest class has 100% transparency transparency = 100 else: # All the others are solid transparency = 0 # Create labels for three of the classes if i == 1: label = 'Low [%.2f people/cell]' % cls elif i == 4: label = 'Medium [%.2f people/cell]' % cls elif i == 7: label = 'High [%.2f people/cell]' % cls else: label = '' # Style dictionary for this class d = dict(colour=colours[i], quantity=cls, transparency=transparency, label=label) style_classes.append(d) # Create style info for impact layer style_info = dict(target_field=None, # Only for vector data legend_title='Population Density', style_classes=style_classes) # Create raster object and return R = Raster(I, projection=inundation.get_projection(), geotransform=inundation.get_geotransform(), name='Population which %s' % get_function_title(self), keywords={'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title}, style_info=style_info) return R
def run(self, layers): """Risk plugin for flood population evacuation Input layers: List of layers expected to contain H: Raster layer of flood depth P: Raster layer of population data on the same grid as H Counts number of people exposed to flood levels exceeding specified threshold. Return Map of population exposed to flood levels exceeding the threshold Table with number of people evacuated and supplies required """ # Depth above which people are regarded affected [m] threshold = 1.0 # Threshold [m] # Identify hazard and exposure layers inundation = get_hazard_layer(layers) # Flood inundation [m] population = get_exposure_layer(layers) question = get_question(inundation.get_name(), population.get_name(), self) # Extract data as numeric arrays D = inundation.get_data(nan=0.0) # Depth # Calculate impact as population exposed to depths > threshold P = population.get_data(nan=0.0, scaling=True) I = numpy.where(D > threshold, P, 0) M = numpy.where(D > 0.5, P, 0) L = numpy.where(D > 0.3, P, 0) # Count totals total = int(numpy.sum(P)) evacuated = int(numpy.sum(I)) medium = int(numpy.sum(M)) - int(numpy.sum(I)) low = int(numpy.sum(L)) - int(numpy.sum(M)) # Don't show digits less than a 1000 if total > 1000: total = total // 1000 * 1000 if evacuated > 1000: evacuated = evacuated // 1000 * 1000 if medium > 1000: medium = medium // 1000 * 1000 if low > 1000: low = low // 1000 * 1000 # Calculate estimated needs based on BNPB Perka 7/2008 minimum bantuan rice = evacuated * 2.8 drinking_water = evacuated * 17.5 water = evacuated * 67 family_kits = evacuated / 5 toilets = evacuated / 20 # Generate impact report for the pdf map table_body = [ question, TableRow([tr('People needing evacuation'), '%i' % evacuated], header=True), TableRow(tr('Map shows population density needing ' 'evacuation')) ] #, ## TableRow([tr('People in 50cm to 1m of water '), ## '%i' % medium], ## header=True), ## TableRow([tr('People in 30cm to 50cm of water'), ## '%i' % low], ## header=True)] ## TableRow([tr('Needs per week'), tr('Total')], ## header=True), ## [tr('Rice [kg]'), int(rice)], ## [tr('Drinking Water [l]'), int(drinking_water)], ## [tr('Clean Water [l]'), int(water)], ## [tr('Family Kits'), int(family_kits)], ## [tr('Toilets'), int(toilets)]] impact_table = Table(table_body).toNewlineFreeString() # Extend impact report for on-screen display table_body.extend([ TableRow(tr('Notes:'), header=True), tr('Total population: %i') % total, tr('People need evacuation if flood levels ' 'exceed %(eps)i m') % { 'eps': threshold }, tr('People in 50cm to 1m of water: %i') % medium, tr('People in 30cm to 50cm of water: %i') % low ]) ## tr('Minimum needs are defined in BNPB ' ## 'regulation 7/2008')]) impact_summary = Table(table_body).toNewlineFreeString() map_title = tr('People in need of evacuation') style_info['legend_title'] = tr('Population Density') # Create raster object and return R = Raster(I, projection=inundation.get_projection(), geotransform=inundation.get_geotransform(), name=tr('Population which %s') % get_function_title(self), keywords={ 'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title }, style_info=style_info) return R
def run(self, layers): inundation = get_hazard_layer(layers) population = get_exposure_layer(layers) question = get_question(inundation.get_name(), population.get_name(), self) threshold = self.parameters['threshold'] D = inundation.get_data(nan=0.0) P = population.get_data(nan=0.0, scaling=True) #Do the calculation where we compute for the sum of all the pixels affected(depth >= threshold) I = numpy.where(D >= threshold, P, 0) evacuated = int(numpy.sum(I)) total = int(numpy.sum(P)) rice = int(evacuated * 2.8) drinking_water = int(evacuated * 105) water = int(evacuated * 105) family_kits = int(evacuated / 5) toilets = int(evacuated / 20) #Generate reports to be put on the pdf table_body = [ question, TableRow([('People in %.1f m of water' % threshlod), '%s' % evacuated], header=True), TableRow('Map shows population density needing evacuation'), TableRow(['Needs per week', 'Total'], header=True), ['Rice [kg]', rice], ['Drinking Water [l]', drinking_water], ['Clean Water [l]', water], ['Family Kits', family_kits], ['Toilets', toilets] ] impact_table = Table(table_body).toNewlineFreeString() table_body.extend([ TableRow('Notes', header=True), 'Total population: %s' % total, 'People need evacuation if flood levels ' 'exceed %(eps).1f m' % { 'eps': threshold }, 'Minimum needs are defined in |BNPB| ' 'regulation 7/2008' ]) impact_summary = Table(table_body).toNewlineFreeString() map_title = 'People in need of evacuation' colours = [ '#FFFFFF', '#38A800', '#79C900', '#CEED00', '#FFCC00', '#FF6600', '#FF0000', '#7A0000' ] classes = create_classes(my_impact.flat[:], len(colours)) interval_classes = humanize_class(classes) style_classes = [] for i in xrange(len(colours)): style_class = dict() if i == 1: label = create_label(interval_classes[i], 'Low') elif i == 4: label = create_label(interval_classes[i], 'Medium') elif i == 7: label = create_label(interval_classes[i], 'High') else: label = create_label(interval_classes[i], 'High') style_class['label'] = label style_class['quantity'] = classes[i] if i == 0: transparency = 100 else: transparency = 0 style_class['transparency'] = transparency style_class['colour'] = colours[i] style_classes.append(style_class) style_info = dict(target_field=None, style_classes=style_classes, style_type='rasterStyle') #For map printing purpose map_title = tr('People in need of evacuation') legend_notes = tr('Thousand separator is represented by \'.\'') legend_units = tr('(people per cell)') legend_title = tr('Population density') R = Raster(my_impact, projection=my_hazard.get_projection(), geotransform=my_hazard.get_geotransform(), name=tr('Population which %s') % get_function_title(self), keywords={ 'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title, 'legend_notes': legend_notes, 'legend_units': legend_units, 'legend_title': legend_title }, style_info=style_info) return R
def run(self, layers): """Risk plugin for flood population evacuation Input layers: List of layers expected to contain H: Raster layer of flood depth P: Raster layer of population data on the same grid as H Counts number of people exposed to flood levels exceeding specified threshold. Return Map of population exposed to flood levels exceeding the threshold Table with number of people evacuated and supplies required """ # Identify hazard and exposure layers inundation = get_hazard_layer(layers) # Flood inundation [m] population = get_exposure_layer(layers) question = get_question(inundation.get_name(), population.get_name(), self) # Determine depths above which people are regarded affected [m] # Use thresholds from inundation layer if specified thresholds = get_thresholds(inundation) if len(thresholds) == 0: # Default threshold thresholds = [1.0] verify(isinstance(thresholds, list), 'Expected thresholds to be a list. Got %s' % str(thresholds)) # Extract data as numeric arrays D = inundation.get_data(nan=0.0) # Depth # Calculate impact as population exposed to depths > max threshold P = population.get_data(nan=0.0, scaling=True) # Calculate impact to intermediate thresholds counts = [] for i, lo in enumerate(thresholds): if i == len(thresholds) - 1: # The last threshold I = M = numpy.where(D >= lo, P, 0) else: # Intermediate thresholds hi = thresholds[i + 1] M = numpy.where((D >= lo) * (D < hi), P, 0) # Count val = int(numpy.sum(M)) # Don't show digits less than a 1000 if val > 1000: val = val // 1000 * 1000 counts.append(val) # Count totals evacuated = counts[-1] total = int(numpy.sum(P)) # Don't show digits less than a 1000 if total > 1000: total = total // 1000 * 1000 # Calculate estimated needs based on BNPB Perka 7/2008 minimum bantuan rice = evacuated * 2.8 drinking_water = evacuated * 17.5 water = evacuated * 67 family_kits = evacuated / 5 toilets = evacuated / 20 # Generate impact report for the pdf map table_body = [question, TableRow([_('People needing evacuation'), '%i' % evacuated], header=True), TableRow(_('Map shows population density needing ' 'evacuation')), TableRow([_('Needs per week'), _('Total')], header=True), [_('Rice [kg]'), int(rice)], [_('Drinking Water [l]'), int(drinking_water)], [_('Clean Water [l]'), int(water)], [_('Family Kits'), int(family_kits)], [_('Toilets'), int(toilets)]] impact_table = Table(table_body).toNewlineFreeString() # Extend impact report for on-screen display table_body.extend([TableRow(_('Notes'), header=True), _('Total population: %i') % total, _('People need evacuation if flood levels ' 'exceed %(eps).1f m') % {'eps': thresholds[-1]}, _('Minimum needs are defined in BNPB ' 'regulation 7/2008')]) if len(counts) > 1: table_body.append(TableRow(_('Detailed breakdown'), header=True)) for i, val in enumerate(counts[:-1]): s = (_('People in %(lo).1f m to %(hi).1f m of water: %(val)i') % {'lo': thresholds[i], 'hi': thresholds[i + 1], 'val': val}) table_body.append(TableRow(s, header=False)) impact_summary = Table(table_body).toNewlineFreeString() map_title = _('People in need of evacuation') # Generate 8 equidistant classes across the range of flooded population # 8 is the number of classes in the predefined flood population style # as imported classes = numpy.linspace(numpy.nanmin(I.flat[:]), numpy.nanmax(I.flat[:]), 8) # Modify labels in existing flood style to show quantities style_classes = style_info['style_classes'] style_classes[1]['label'] = _('Low [%i people/cell]') % classes[1] style_classes[4]['label'] = _('Medium [%i people/cell]') % classes[4] style_classes[7]['label'] = _('High [%i people/cell]') % classes[7] style_info['legend_title'] = _('Population Density') # Create raster object and return R = Raster(I, projection=inundation.get_projection(), geotransform=inundation.get_geotransform(), name=_('Population which %s') % get_function_title(self), keywords={'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title}, style_info=style_info) return R
def run(self, layers): """Risk plugin for tsunami population evacuation. :param layers: List of layers expected to contain hazard_layer: Raster layer of tsunami depth exposure_layer: Raster layer of population data on the same grid as hazard_layer Counts number of people exposed to tsunami levels exceeding specified threshold. :returns: Map of population exposed to tsunami levels exceeding the threshold. Table with number of people evacuated and supplies required. :rtype: tuple """ # Identify hazard and exposure layers hazard_layer = get_hazard_layer(layers) # Tsunami inundation [m] exposure_layer = get_exposure_layer(layers) question = get_question( hazard_layer.get_name(), exposure_layer.get_name(), self) # Determine depths above which people are regarded affected [m] # Use thresholds from inundation layer if specified thresholds = self.parameters['thresholds [m]'] verify( isinstance(thresholds, list), 'Expected thresholds to be a list. Got %s' % str(thresholds)) # Extract data as numeric arrays data = hazard_layer.get_data(nan=0.0) # Depth # Calculate impact as population exposed to depths > max threshold population = exposure_layer.get_data(nan=0.0, scaling=True) # Calculate impact to intermediate thresholds counts = [] # merely initialize impact = None for i, lo in enumerate(thresholds): if i == len(thresholds) - 1: # The last threshold impact = medium = numpy.where(data >= lo, population, 0) else: # Intermediate thresholds hi = thresholds[i + 1] medium = numpy.where((data >= lo) * (data < hi), population, 0) # Count val = int(numpy.sum(medium)) # Sensible rounding val, rounding = population_rounding_full(val) counts.append([val, rounding]) # Count totals evacuated, rounding = counts[-1] total = int(numpy.sum(population)) # Don't show digits less than a 1000 total = population_rounding(total) minimum_needs = [ parameter.serialize() for parameter in self.parameters['minimum needs'] ] # Generate impact report for the pdf map # 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)) # Result impact_summary = Table(table_body).toNewlineFreeString() impact_table = impact_summary # check for zero impact if numpy.nanmax(impact) == 0 == numpy.nanmin(impact): table_body = [ question, TableRow([(tr('People in %.1f m of water') % thresholds[-1]), '%s' % format_int(evacuated)], header=True)] my_message = Table(table_body).toNewlineFreeString() raise ZeroImpactException(my_message) # Create style colours = [ '#FFFFFF', '#38A800', '#79C900', '#CEED00', '#FFCC00', '#FF6600', '#FF0000', '#7A0000'] classes = create_classes(impact.flat[:], len(colours)) interval_classes = humanize_class(classes) style_classes = [] for i in xrange(len(colours)): style_class = dict() if i == 1: label = create_label(interval_classes[i], 'Low') elif i == 4: label = create_label(interval_classes[i], 'Medium') elif i == 7: label = create_label(interval_classes[i], 'High') else: label = create_label(interval_classes[i]) style_class['label'] = label style_class['quantity'] = classes[i] if i == 0: transparency = 100 else: transparency = 0 style_class['transparency'] = transparency style_class['colour'] = colours[i] style_classes.append(style_class) style_info = dict( target_field=None, style_classes=style_classes, style_type='rasterStyle') # For printing map purpose map_title = tr('People in need of evacuation') legend_notes = tr( 'Thousand separator is represented by %s' % get_thousand_separator()) legend_units = tr('(people per cell)') legend_title = tr('Population') # Create raster object and return raster = Raster( impact, projection=hazard_layer.get_projection(), geotransform=hazard_layer.get_geotransform(), name=tr('Population which %s') % ( get_function_title(self).lower()), keywords={ 'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title, 'legend_notes': legend_notes, 'legend_units': legend_units, 'legend_title': legend_title, 'evacuated': evacuated, 'total_needs': total_needs}, style_info=style_info) return raster
def run(self, layers): """Risk plugin for tsunami population evacuation. :param layers: List of layers expected to contain hazard_layer: Raster layer of tsunami depth exposure_layer: Raster layer of population data on the same grid as hazard_layer Counts number of people exposed to tsunami levels exceeding specified threshold. :returns: Map of population exposed to tsunami levels exceeding the threshold. Table with number of people evacuated and supplies required. :rtype: tuple """ # Identify hazard and exposure layers hazard_layer = get_hazard_layer(layers) # Tsunami inundation [m] exposure_layer = get_exposure_layer(layers) question = get_question(hazard_layer.get_name(), exposure_layer.get_name(), self) # Determine depths above which people are regarded affected [m] # Use thresholds from inundation layer if specified thresholds = self.parameters['thresholds [m]'] verify(isinstance(thresholds, list), 'Expected thresholds to be a list. Got %s' % str(thresholds)) # Extract data as numeric arrays data = hazard_layer.get_data(nan=0.0) # Depth # Calculate impact as population exposed to depths > max threshold population = exposure_layer.get_data(nan=0.0, scaling=True) # Calculate impact to intermediate thresholds counts = [] # merely initialize impact = None for i, lo in enumerate(thresholds): if i == len(thresholds) - 1: # The last threshold impact = medium = numpy.where(data >= lo, population, 0) else: # Intermediate thresholds hi = thresholds[i + 1] medium = numpy.where((data >= lo) * (data < hi), population, 0) # Count val = int(numpy.sum(medium)) # Sensible rounding val, rounding = population_rounding_full(val) counts.append([val, rounding]) # Count totals evacuated, rounding = counts[-1] total = int(numpy.sum(population)) # Don't show digits less than a 1000 total = population_rounding(total) minimum_needs = [ parameter.serialize() for parameter in self.parameters['minimum needs'] ] # Generate impact report for the pdf map # 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)) # Result impact_summary = Table(table_body).toNewlineFreeString() impact_table = impact_summary # check for zero impact if numpy.nanmax(impact) == 0 == numpy.nanmin(impact): table_body = [ question, TableRow([(tr('People in %.1f m of water') % thresholds[-1]), '%s' % format_int(evacuated)], header=True) ] my_message = Table(table_body).toNewlineFreeString() raise ZeroImpactException(my_message) # Create style colours = [ '#FFFFFF', '#38A800', '#79C900', '#CEED00', '#FFCC00', '#FF6600', '#FF0000', '#7A0000' ] classes = create_classes(impact.flat[:], len(colours)) interval_classes = humanize_class(classes) style_classes = [] for i in xrange(len(colours)): style_class = dict() if i == 1: label = create_label(interval_classes[i], 'Low') elif i == 4: label = create_label(interval_classes[i], 'Medium') elif i == 7: label = create_label(interval_classes[i], 'High') else: label = create_label(interval_classes[i]) style_class['label'] = label style_class['quantity'] = classes[i] if i == 0: transparency = 100 else: transparency = 0 style_class['transparency'] = transparency style_class['colour'] = colours[i] style_classes.append(style_class) style_info = dict(target_field=None, style_classes=style_classes, style_type='rasterStyle') # For printing map purpose map_title = tr('People in need of evacuation') legend_notes = tr('Thousand separator is represented by %s' % get_thousand_separator()) legend_units = tr('(people per cell)') legend_title = tr('Population') # Create raster object and return raster = Raster(impact, projection=hazard_layer.get_projection(), geotransform=hazard_layer.get_geotransform(), name=tr('Population which %s') % (get_function_title(self).lower()), keywords={ 'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title, 'legend_notes': legend_notes, 'legend_units': legend_units, 'legend_title': legend_title, 'evacuated': evacuated, 'total_needs': total_needs }, style_info=style_info) return raster
def run(self, layers): """Plugin for impact of population as derived by classified hazard. Input :param layers: List of layers expected to contain * hazard_layer: Raster layer of classified hazard * exposure_layer: Raster layer of population data Counts number of people exposed to each class of the hazard Return Map of population exposed to high class Table with number of people in each class """ # The 3 classes low_t = self.parameters['low_hazard_class'] medium_t = self.parameters['medium_hazard_class'] high_t = self.parameters['high_hazard_class'] # Identify hazard and exposure layers hazard_layer = get_hazard_layer(layers) # Classified Hazard exposure_layer = get_exposure_layer(layers) # Population Raster question = get_question(hazard_layer.get_name(), exposure_layer.get_name(), self) # Extract data as numeric arrays data = hazard_layer.get_data(nan=0.0) # Class # Calculate impact as population exposed to each class population = exposure_layer.get_data(nan=0.0, scaling=True) if high_t == 0: hi = numpy.where(0, population, 0) else: hi = numpy.where(data == high_t, population, 0) if medium_t == 0: med = numpy.where(0, population, 0) else: med = numpy.where(data == medium_t, population, 0) if low_t == 0: lo = numpy.where(0, population, 0) else: lo = numpy.where(data == low_t, population, 0) if high_t == 0: impact = numpy.where((data == low_t) + (data == medium_t), population, 0) elif medium_t == 0: impact = numpy.where((data == low_t) + (data == high_t), population, 0) elif low_t == 0: impact = numpy.where((data == medium_t) + (data == high_t), population, 0) else: impact = numpy.where( (data == low_t) + (data == medium_t) + (data == high_t), population, 0) # Count totals total = int(numpy.sum(population)) high = int(numpy.sum(hi)) medium = int(numpy.sum(med)) low = int(numpy.sum(lo)) total_impact = int(numpy.sum(impact)) # Perform population rounding based on number of people no_impact = population_rounding(total - total_impact) total = population_rounding(total) total_impact = population_rounding(total_impact) high = population_rounding(high) medium = population_rounding(medium) low = population_rounding(low) minimum_needs = [ parameter.serialize() for parameter in self.parameters['minimum needs'] ] # Generate impact report for the pdf map table_body = [ question, TableRow([ tr('Total Population Affected '), '%s' % format_int(total_impact) ], header=True), TableRow([ tr('Population in High hazard class areas '), '%s' % format_int(high) ]), TableRow([ tr('Population in Medium hazard class areas '), '%s' % format_int(medium) ]), TableRow([ tr('Population in Low hazard class areas '), '%s' % format_int(low) ]), TableRow( [tr('Population Not Affected'), '%s' % format_int(no_impact)]), TableRow( tr('Table below shows the minimum needs for all ' 'evacuated people')) ] 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']) ])) impact_table = Table(table_body).toNewlineFreeString() 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) ]) impact_summary = Table(table_body).toNewlineFreeString() # Create style colours = [ '#FFFFFF', '#38A800', '#79C900', '#CEED00', '#FFCC00', '#FF6600', '#FF0000', '#7A0000' ] classes = create_classes(impact.flat[:], len(colours)) interval_classes = humanize_class(classes) style_classes = [] for i in xrange(len(colours)): style_class = dict() if i == 1: label = create_label(interval_classes[i], 'Low') elif i == 4: label = create_label(interval_classes[i], 'Medium') elif i == 7: label = create_label(interval_classes[i], 'High') else: label = create_label(interval_classes[i]) style_class['label'] = label style_class['quantity'] = classes[i] if i == 0: transparency = 30 else: transparency = 30 style_class['transparency'] = transparency style_class['colour'] = colours[i] style_classes.append(style_class) style_info = dict(target_field=None, style_classes=style_classes, style_type='rasterStyle') # For printing map purpose map_title = tr('Population affected by each class') legend_notes = tr('Thousand separator is represented by %s' % get_thousand_separator()) legend_units = tr('(people per cell)') legend_title = tr('Number of People') # Create raster object and return raster_layer = Raster(impact, projection=hazard_layer.get_projection(), geotransform=hazard_layer.get_geotransform(), name=tr('Population which %s') % (get_function_title(self).lower()), keywords={ 'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title, 'legend_notes': legend_notes, 'legend_units': legend_units, 'legend_title': legend_title, 'total_needs': total_needs }, style_info=style_info) return raster_layer
def run(self, layers): """Risk plugin for flood population evacuation Input layers: List of layers expected to contain my_hazard: Raster layer of flood depth my_exposure: Raster layer of population data on the same grid as my_hazard Counts number of people exposed to flood levels exceeding specified threshold. Return Map of population exposed to flood levels exceeding the threshold Table with number of people evacuated and supplies required """ # Identify hazard and exposure layers my_hazard = get_hazard_layer(layers) # Flood inundation [m] my_exposure = get_exposure_layer(layers) question = get_question(my_hazard.get_name(), my_exposure.get_name(), self) # Determine depths above which people are regarded affected [m] # Use thresholds from inundation layer if specified thresholds = self.parameters['thresholds [m]'] verify(isinstance(thresholds, list), 'Expected thresholds to be a list. Got %s' % str(thresholds)) # Extract data as numeric arrays D = my_hazard.get_data(nan=0.0) # Depth # Calculate impact as population exposed to depths > max threshold P = my_exposure.get_data(nan=0.0, scaling=True) # Calculate impact to intermediate thresholds counts = [] # merely initialize my_impact = None for i, lo in enumerate(thresholds): if i == len(thresholds) - 1: # The last threshold my_impact = M = numpy.where(D >= lo, P, 0) else: # Intermediate thresholds hi = thresholds[i + 1] M = numpy.where((D >= lo) * (D < hi), P, 0) # Count val = int(numpy.sum(M)) # Don't show digits less than a 1000 val = round_thousand(val) counts.append(val) # Count totals evacuated = counts[-1] total = int(numpy.sum(P)) # Don't show digits less than a 1000 total = round_thousand(total) # Calculate estimated minimum needs # The default value of each logistic is based on BNPB Perka 7/2008 # minimum bantuan minimum_needs = self.parameters['minimum needs'] tot_needs = evacuated_population_weekly_needs(evacuated, minimum_needs) # Generate impact report for the pdf map # noinspection PyListCreation table_body = [ question, TableRow([(tr('People in %.1f m of water') % thresholds[-1]), '%s%s' % (format_int(evacuated), ( '*' if evacuated >= 1000 else ''))], header=True), TableRow(tr('* Number is rounded to the nearest 1000'), header=False), TableRow(tr('Map shows population density needing evacuation')), TableRow(tr('Table below shows the weekly minium needs for all ' 'evacuated people')), TableRow([tr('Needs per week'), tr('Total')], header=True), [tr('Rice [kg]'), format_int(tot_needs['rice'])], [tr('Drinking Water [l]'), format_int(tot_needs['drinking_water'])], [tr('Clean Water [l]'), format_int(tot_needs['water'])], [tr('Family Kits'), format_int(tot_needs['family_kits'])], [tr('Toilets'), format_int(tot_needs['toilets'])]] 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 flood 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 fractionals.')]) 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)}) table_body.append(TableRow(s, header=False)) # Result impact_summary = Table(table_body).toNewlineFreeString() impact_table = impact_summary # check for zero impact if numpy.nanmax(my_impact) == 0 == numpy.nanmin(my_impact): table_body = [ question, TableRow([(tr('People in %.1f m of water') % thresholds[-1]), '%s' % format_int(evacuated)], header=True)] my_message = Table(table_body).toNewlineFreeString() raise ZeroImpactException(my_message) # Create style colours = ['#FFFFFF', '#38A800', '#79C900', '#CEED00', '#FFCC00', '#FF6600', '#FF0000', '#7A0000'] classes = create_classes(my_impact.flat[:], len(colours)) interval_classes = humanize_class(classes) style_classes = [] for i in xrange(len(colours)): style_class = dict() if i == 1: label = create_label(interval_classes[i], 'Low') elif i == 4: label = create_label(interval_classes[i], 'Medium') elif i == 7: label = create_label(interval_classes[i], 'High') else: label = create_label(interval_classes[i]) style_class['label'] = label style_class['quantity'] = classes[i] if i == 0: transparency = 100 else: transparency = 0 style_class['transparency'] = transparency style_class['colour'] = colours[i] style_classes.append(style_class) style_info = dict(target_field=None, style_classes=style_classes, style_type='rasterStyle') # For printing map purpose map_title = tr('People in need of evacuation') legend_notes = tr('Thousand separator is represented by %s' % get_thousand_separator()) legend_units = tr('(people per cell)') legend_title = tr('Population density') # Create raster object and return R = Raster(my_impact, projection=my_hazard.get_projection(), geotransform=my_hazard.get_geotransform(), name=tr('Population which %s') % ( get_function_title(self).lower()), keywords={'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title, 'legend_notes': legend_notes, 'legend_units': legend_units, 'legend_title': legend_title}, style_info=style_info) return R
def run(self, layers): """Risk plugin for flood population evacuation Input layers: List of layers expected to contain H: Raster layer of flood depth P: Raster layer of population data on the same grid as H Counts number of people exposed to flood levels exceeding specified threshold. Return Map of population exposed to flood levels exceeding the threshold Table with number of people evacuated and supplies required """ # Identify hazard and exposure layers my_hazard = get_hazard_layer(layers) # Flood inundation [m] my_exposure = get_exposure_layer(layers) question = get_question(my_hazard.get_name(), my_exposure.get_name(), self) # Determine depths above which people are regarded affected [m] # Use thresholds from inundation layer if specified thresholds = self.parameters['thresholds [m]'] verify(isinstance(thresholds, list), 'Expected thresholds to be a list. Got %s' % str(thresholds)) # Extract data as numeric arrays D = my_hazard.get_data(nan=0.0) # Depth # Calculate impact as population exposed to depths > max threshold P = my_exposure.get_data(nan=0.0, scaling=True) # Calculate impact to intermediate thresholds counts = [] for i, lo in enumerate(thresholds): if i == len(thresholds) - 1: # The last threshold my_impact = M = numpy.where(D >= lo, P, 0) else: # Intermediate thresholds hi = thresholds[i + 1] M = numpy.where((D >= lo) * (D < hi), P, 0) # Count val = int(numpy.sum(M)) # Don't show digits less than a 1000 val = round_thousand(val) counts.append(val) # Count totals evacuated = counts[-1] total = int(numpy.sum(P)) # Don't show digits less than a 1000 total = round_thousand(total) # Calculate estimated needs based on BNPB Perka 7/2008 minimum bantuan # FIXME: Refactor and share # 400g per person per day rice = int(evacuated * 2.8) # 2.5L per person per day drinking_water = int(evacuated * 17.5) # 15L per person per day water = int(evacuated * 105) # assume 5 people per family (not in perka) family_kits = int(evacuated / 5) # 20 people per toilet toilets = int(evacuated / 20) # Generate impact report for the pdf map table_body = [question, TableRow([(tr('People in %.1f m of water') % thresholds[-1]), '%s*' % format_int(evacuated)], header=True), TableRow(tr('* Number is rounded to the nearest 1000'), header=False), TableRow(tr('Map shows population density needing ' 'evacuation')), TableRow([tr('Needs per week'), tr('Total')], header=True), [tr('Rice [kg]'), format_int(rice)], [tr('Drinking Water [l]'), format_int(drinking_water)], [tr('Clean Water [l]'), format_int(water)], [tr('Family Kits'), format_int(family_kits)], [tr('Toilets'), format_int(toilets)]] impact_table = Table(table_body).toNewlineFreeString() 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 flood levels ' 'exceed %(eps).1f m') % {'eps': thresholds[-1]}, tr('Minimum needs are defined in BNPB ' 'regulation 7/2008')]) 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)}) table_body.append(TableRow(s, header=False)) impact_summary = Table(table_body).toNewlineFreeString() map_title = tr('People in need of evacuation') # Generate 8 equidistant classes across the range of flooded population # 8 is the number of classes in the predefined flood population style # as imported classes = numpy.linspace(numpy.nanmin(my_impact.flat[:]), numpy.nanmax(my_impact.flat[:]), 8) # Work out how many decimals to use # Modify labels in existing flood style to show quantities style_classes = style_info['style_classes'] style_classes[1]['label'] = tr('Low [%.2f people/cell]') % classes[1] style_classes[4]['label'] = tr('Medium [%.2f people/cell]')\ % classes[4] style_classes[7]['label'] = tr('High [%.2f people/cell]') % classes[7] # Override associated quantities in colour style for i in range(len(classes)): if i == 0: transparency = 100 else: transparency = 0 style_classes[i]['quantity'] = classes[i] style_classes[i]['transparency'] = transparency # Title style_info['legend_title'] = tr('Population Density') # Create raster object and return R = Raster(my_impact, projection=my_hazard.get_projection(), geotransform=my_hazard.get_geotransform(), name=tr('Population which %s') % get_function_title(self), keywords={'impact_summary': impact_summary, 'impact_table': impact_table, 'map_title': map_title}, style_info=style_info) return R