1515import requests
1616import shapely .vectorized
1717from cartopy .io import shapereader
18+ from iso3166 import countries as iso_cntry
1819
1920from climada .entity .exposures .base import Exposures
2021from climada .util .files_handler import download_file
5960
6061class BlackMarble (Exposures ):
6162 """Defines exposures from night light intensity, GDP and income group.
63+ Attribute region_id is defined as:
64+ - United Nations Statistics Division (UNSD) 3-digit equivalent numeric code
65+ - 0 if country not found in UNSD.
66+ - -1 for water
6267 """
6368
6469 def __init__ (self ):
6570 """ Empty initializer. """
6671 Exposures .__init__ (self )
6772
68- def set_countries (self , countries , \
69- ref_year = CONFIG ['entity' ]['present_ref_year' ], res_km = 1 , \
70- sea_res = (0 , 1 ), from_hr = None , ** kwargs ):
73+ def set_countries (self , countries ,
74+ ref_year = CONFIG ['entity' ]['present_ref_year' ],
75+ res_km = 1 , sea_res = (0 , 1 ), from_hr = None , ** kwargs ):
7176 """ Model countries using values at reference year. If GDP or income
7277 group not available for that year, consider the value of the closest
7378 available year.
@@ -80,10 +85,11 @@ def set_countries(self, countries, \
8085 res_km (float, optional): approx resolution in km. Default: 1km.
8186 sea_res (tuple, optional): (sea_coast_km, sea_res_km), where first
8287 parameter is distance from coast to fill with water and second
83- parameter is resolution between sea points
84- from_hr (bool, optional)
88+ parameter is resolution between sea points.
89+ from_hr (bool, optional): force to use higher resolution image,
90+ independently of its year of acquisition.
8591 kwargs (optional): 'gdp' and 'inc_grp' dictionaries with keys the
86- country ISO_alpha3 code. If provided, these are used
92+ country ISO_alpha3 code. If provided, these are used.
8793 """
8894 self .clear ()
8995 shp_file = shapereader .natural_earth (resolution = '10m' ,
@@ -97,23 +103,38 @@ def set_countries(self, countries, \
97103 nightlight , coord_nl , fn_nl , res_fact = get_nightlight (ref_year , \
98104 cntry_info , res_km , from_hr )
99105
100- # TODO parallize per thread?
101106 for cntry_iso , cntry_val in cntry_info .items ():
102107 LOGGER .info ('Processing country %s.' , cntry_val [1 ])
103108 self .append (self ._set_one_country (cntry_val , nightlight , \
104109 coord_nl , fn_nl , res_fact , res_km , cntry_admin1 [cntry_iso ]))
105110
106111 add_sea (self , sea_res )
107112
108- def set_region (self , centroids , ref_year = 2013 , resolution = 1 ):
113+ def set_region (self , centroids ,
114+ ref_year = CONFIG ['entity' ]['present_ref_year' ], res_km = 1 ):
109115 """ Model a specific region given by centroids."""
110116 # TODO: accept input centroids as well
111117 raise NotImplementedError
112118
113- def fill_centroids (self ):
114- """ From coordinates information, generate Centroids instance."""
115- # add sea in lower resolution
116- raise NotImplementedError
119+ def select_region (self , reg_id ):
120+ """ Select exposures with input region.
121+
122+ Parameters:
123+ reg_id (int, str): integer iso equivalent country numeric code or
124+ string iso alpha-3 or alpha-2 code or country name.
125+
126+ Returns:
127+ Exposures
128+ """
129+ if isinstance (reg_id , int ):
130+ return Exposures .select_region (self , reg_id )
131+
132+ try :
133+ return Exposures .select_region (self , \
134+ int (iso_cntry .get (reg_id ).numeric ))
135+ except KeyError :
136+ LOGGER .info ('No country %s found.' , reg_id )
137+ return None
117138
118139 @staticmethod
119140 def _set_one_country (cntry_info , nightlight , coord_nl , fn_nl , res_fact ,
@@ -155,8 +176,9 @@ def _set_one_country(cntry_info, nightlight, coord_nl, fn_nl, res_fact,
155176 return exp_bkmrb
156177
157178def country_iso_geom (countries , shp_file ):
158- """ Get country ISO alpha_3, country id (defined as country appearance
159- order in natural earth shape file) and country's geometry.
179+ """ Get country ISO alpha_3, country id (defined as the United Nations
180+ Statistics Division (UNSD) 3-digit equivalent numeric codes and 0 if
181+ country not found) and country's geometry shape.
160182
161183 Parameters:
162184 countries (list or dict): list of country names (admin0) or dict
@@ -172,8 +194,6 @@ def country_iso_geom(countries, shp_file):
172194 for info_idx , info in enumerate (list_records ):
173195 countries_shp [info .attributes ['ADMIN' ].title ()] = info_idx
174196
175- num_codes = [iso3 for iso3 in wb .country_codes if len (iso3 ) == 3 ]
176-
177197 cntry_info = dict ()
178198 cntry_admin1 = dict ()
179199 if isinstance (countries , list ):
@@ -198,10 +218,10 @@ def country_iso_geom(countries, shp_file):
198218 raise ValueError
199219 iso3 = list_records [country_idx ].attributes ['ADM0_A3' ]
200220 try :
201- iso_num = num_codes . index (iso3 )
202- except ValueError :
203- iso_num = len ( num_codes )
204- cntry_info [iso3 ] = [iso_num , country_name .title (),
221+ cntry_id = int ( iso_cntry . get (iso3 ). numeric )
222+ except KeyError :
223+ cntry_id = 0
224+ cntry_info [iso3 ] = [cntry_id , country_name .title (),
205225 list_records [country_idx ].geometry ]
206226 cntry_admin1 [iso3 ] = _fill_admin1_geom (iso3 , admin1_rec , prov_list )
207227
@@ -261,7 +281,7 @@ def get_nightlight(ref_year, cntry_info, res_km, from_hr=None):
261281 else :
262282 nl_year = 2012
263283 LOGGER .info ("Nightlights from NASA's earth observatory for " + \
264- "year %s." , nl_year )
284+ "year %s." , str ( nl_year ) )
265285 res_fact = DEF_RES_NASA_KM / res_km
266286 geom = [info [2 ] for info in cntry_info .values ()]
267287 geom = shapely .ops .cascaded_union (geom )
@@ -281,7 +301,7 @@ def get_nightlight(ref_year, cntry_info, res_km, from_hr=None):
281301 elif ref_year > 2013 :
282302 nl_year = 2013
283303 LOGGER .info ("Nightlights from NOAA's earth observation group " + \
284- "for year %s." , nl_year )
304+ "for year %s." , str ( nl_year ) )
285305 res_fact = DEF_RES_NOAA_KM / res_km
286306 # nightlight intensity with 30 arcsec resolution
287307 nightlight , coord_nl , fn_nl = nl_utils .load_nightlight_noaa (nl_year )
@@ -301,7 +321,7 @@ def add_sea(exp, sea_res):
301321 return
302322
303323 LOGGER .info ("Adding sea at %s km resolution and %s km distance from " + \
304- "coast." , sea_res [1 ], sea_res [0 ])
324+ "coast." , str ( sea_res [1 ]), str ( sea_res [0 ]) )
305325
306326 sea_res = (sea_res [0 ]/ ONE_LAT_KM , sea_res [1 ]/ ONE_LAT_KM )
307327
0 commit comments