@@ -117,7 +117,7 @@ def fill_centroids(self):
117117
118118 @staticmethod
119119 def _set_one_country (cntry_info , nightlight , coord_nl , fn_nl , res_fact ,
120- res_km , admin1 = None ):
120+ res_km , admin1 ):
121121 """ Model one country.
122122
123123 Parameters:
@@ -130,7 +130,7 @@ def _set_one_country(cntry_info, nightlight, coord_nl, fn_nl, res_fact,
130130 fn_nl (str): file name of considered nightlight with path
131131 res_fact (float): resampling factor
132132 res_km (float): wished resolution in km
133- admin1 (list, optional ): list of admin1 to filter
133+ admin1 (list): list of admin1 to filter
134134 """
135135 exp_bkmrb = BlackMarble ()
136136
@@ -139,7 +139,7 @@ def _set_one_country(cntry_info, nightlight, coord_nl, fn_nl, res_fact,
139139
140140 _set_econ_indicators (exp_bkmrb , cntry_info [4 ], cntry_info [5 ])
141141
142- if admin1 is not None :
142+ if admin1 :
143143 _filter_admin1 (exp_bkmrb , admin1 )
144144
145145 exp_bkmrb .id = np .arange (1 , exp_bkmrb .value .size + 1 )
@@ -170,33 +170,39 @@ def country_iso_geom(countries, shp_file):
170170 countries_shp = {}
171171 list_records = list (shp_file .records ())
172172 for info_idx , info in enumerate (list_records ):
173- std_name = info .attributes ['ADMIN' ].title ()
174- countries_shp [std_name ] = info_idx
173+ countries_shp [info .attributes ['ADMIN' ].title ()] = info_idx
175174
176- if isinstance (countries , list ):
177- cntry_list = countries
178- else :
179- cntry_list = countries .keys ()
175+ admin1_rec = shapereader .natural_earth (resolution = '10m' ,
176+ category = 'cultural' ,
177+ name = 'admin_1_states_provinces' )
178+ admin1_rec = shapereader .Reader (admin1_rec )
179+ admin1_rec = list (admin1_rec .records ())
180+
181+ num_codes = [iso3 for iso3 in wb .country_codes if len (iso3 ) == 3 ]
180182
181183 cntry_info = dict ()
182184 cntry_admin1 = dict ()
183- for country_name in cntry_list :
184- country_tit = country_name .title ()
185- country_idx = countries_shp .get (country_tit )
185+ if isinstance (countries , list ):
186+ countries = {cntry : [] for cntry in countries }
187+
188+ for country_name , prov_list in countries .items ():
189+ country_idx = countries_shp .get (country_name .title ())
186190 if country_idx is None :
187191 options = [country_opt for country_opt in countries_shp
188- if country_tit in country_opt ]
192+ if country_name . title () in country_opt ]
189193 if not options :
190194 options = list (countries_shp .keys ())
191195 LOGGER .error ('Country %s not found. Possible options: %s' ,
192196 country_name , options )
193197 raise ValueError
194198 iso3 = list_records [country_idx ].attributes ['ADM0_A3' ]
195- cntry_info [iso3 ] = [country_idx + 1 , country_tit , \
196- list_records [country_idx ].geometry ]
197- cntry_admin1 [iso3 ] = None
198- if isinstance (countries , dict ):
199- cntry_admin1 [iso3 ] = _fill_admin1_geom (countries [country_name ])
199+ try :
200+ iso_num = num_codes .index (iso3 )
201+ except ValueError :
202+ iso_num = len (num_codes )
203+ cntry_info [iso3 ] = [iso_num , country_name .title (),
204+ list_records [country_idx ].geometry ]
205+ cntry_admin1 [iso3 ] = _fill_admin1_geom (iso3 , admin1_rec , prov_list )
200206
201207 return cntry_info , cntry_admin1
202208
@@ -319,19 +325,40 @@ def add_sea(exp, sea_res):
319325 exp .deductible = np .zeros (exp .value .size )
320326 exp .cover = exp .value .copy ()
321327
322- def _fill_admin1_geom (countries ):
323- """Get admin1 polygons for each country.
328+ def _fill_admin1_geom (iso3 , admin1_rec , prov_list ):
329+ """Get admin1 polygons for each input province of country iso3 .
324330
325331 Parameters:
326-
332+ iso3 (str): admin0 country name in alpha3
333+ admin1_rec (list): list of admin1 records
334+ prov_list (list): province names
327335 Returns:
328-
336+ list
329337 """
330- raise NotImplementedError
338+ prov_geom = list ()
339+ for prov in prov_list :
340+ found = False
341+ for rec in admin1_rec :
342+ if prov in rec .attributes ['name' ] and \
343+ rec .attributes ['adm0_a3' ] == iso3 :
344+ found = True
345+ prov_geom .append (rec .geometry )
346+ if not found :
347+ options = [rec .attributes ['name' ] for rec in admin1_rec \
348+ if rec .attributes ['adm0_a3' ] == iso3 ]
349+ LOGGER .error ('%s not found. Possible provinces of %s are: %s' ,
350+ prov , iso3 , options )
351+ raise ValueError
352+
353+ return prov_geom
331354
332- def _filter_admin1 (exp_bkmrb , admin1 ):
355+ def _filter_admin1 (exp_bkmrb , admin1_geom ):
333356 """ Filter points contained in admin1 geometries."""
334- raise NotImplementedError
357+ prov_geom = shapely .ops .cascaded_union (admin1_geom )
358+ on_prov = shapely .vectorized .contains (prov_geom , exp_bkmrb .coord .lon ,
359+ exp_bkmrb .coord .lat )
360+ exp_bkmrb .value = exp_bkmrb .value [on_prov ]
361+ exp_bkmrb .coord = exp_bkmrb .coord [on_prov ]
335362
336363def _get_income_group (cntry_info , ref_year , shp_file ):
337364 """ Append country's income group from World Bank's data at a given year,
0 commit comments