def test_set_gdf(self): """Test setting the GeoDataFrame""" empty_gdf = gpd.GeoDataFrame() gdf_without_geometry = good_exposures().gdf good_exp = good_exposures() good_exp.set_crs(crs='epsg:3395') good_exp.set_geometry_points() gdf_with_geometry = good_exp.gdf probe = Exposures() self.assertRaises(ValueError, probe.set_gdf, pd.DataFrame()) probe.set_gdf(empty_gdf) self.assertTrue(probe.gdf.equals(gpd.GeoDataFrame())) self.assertTrue(u_coord.equal_crs(DEF_CRS, probe.crs)) self.assertIsNone(probe.gdf.crs) probe.set_gdf(gdf_with_geometry) self.assertTrue(probe.gdf.equals(gdf_with_geometry)) self.assertTrue(u_coord.equal_crs('epsg:3395', probe.crs)) self.assertTrue(u_coord.equal_crs('epsg:3395', probe.gdf.crs)) probe.set_gdf(gdf_without_geometry) self.assertTrue(probe.gdf.equals(good_exposures().gdf)) self.assertTrue(u_coord.equal_crs(DEF_CRS, probe.crs)) self.assertIsNone(probe.gdf.crs)
def test_switzerland300_pass(self): """Create LitPop entity for Switzerland on 300 arcsec:""" country_name = ['CHE'] resolution = 300 fin_mode = 'income_group' with self.assertLogs('climada.entity.exposures.litpop', level='INFO') as cm: ent = lp.LitPop.from_countries(country_name, res_arcsec=resolution, fin_mode=fin_mode, reference_year=2016) self.assertIn('LitPop: Init Exposure for country: CHE', cm.output[0]) self.assertEqual(ent.gdf.region_id.min(), 756) self.assertEqual(ent.gdf.region_id.max(), 756) # confirm that the total value is equal to GDP * (income_group+1): self.assertAlmostEqual(ent.gdf.value.sum() / gdp('CHE', 2016)[1], (income_group('CHE', 2016)[1] + 1)) self.assertIn("LitPop Exposure for ['CHE'] at 300 as, year: 2016", ent.tag.description) self.assertIn('income_group', ent.tag.description) self.assertIn('1, 1', ent.tag.description) self.assertTrue(u_coord.equal_crs(ent.crs, 'epsg:4326')) self.assertEqual(ent.meta['width'], 54) self.assertEqual(ent.meta['height'], 23) self.assertTrue(u_coord.equal_crs(ent.meta['crs'], 'epsg:4326')) self.assertAlmostEqual(ent.meta['transform'][0], 0.08333333333333333) self.assertAlmostEqual(ent.meta['transform'][1], 0) self.assertAlmostEqual(ent.meta['transform'][2], 5.9166666666666) self.assertAlmostEqual(ent.meta['transform'][3], 0) self.assertAlmostEqual(ent.meta['transform'][4], -0.08333333333333333) self.assertAlmostEqual(ent.meta['transform'][5], 47.75)
def test_from_vector_file(self): """Test from_vector_file and values_from_vector_files""" shp_file = shapereader.natural_earth(resolution='110m', category='cultural', name='populated_places_simple') centr = Centroids.from_vector_file(shp_file) inten = centr.values_from_vector_files( [shp_file], val_names=['pop_min', 'pop_max']) self.assertTrue(u_coord.equal_crs(centr.geometry.crs, u_coord.NE_EPSG)) self.assertEqual(centr.geometry.size, centr.lat.size) self.assertTrue(u_coord.equal_crs(centr.geometry.crs, u_coord.NE_EPSG)) self.assertAlmostEqual(centr.lon[0], 12.453386544971766) self.assertAlmostEqual(centr.lon[-1], 114.18306345846304) self.assertAlmostEqual(centr.lat[0], 41.903282179960115) self.assertAlmostEqual(centr.lat[-1], 22.30692675357551) self.assertEqual(inten.shape, (2, 243)) # population min self.assertEqual(inten[0, 0], 832) self.assertEqual(inten[0, -1], 4551579) # population max self.assertEqual(inten[1, 0], 832) self.assertEqual(inten[1, -1], 7206000) # Test reading values from file with incompatible geometry shp_file = shapereader.natural_earth(resolution='10m', category='cultural', name='populated_places_simple') with self.assertRaises(ValueError): centr.values_from_vector_files(shp_file, val_names=['pop_min', 'pop_max'])
def test_spain_pass(self): country_name = ['Spain'] ent = BlackMarble() with self.assertLogs('climada.util.finance', level='INFO') as cm: ent.set_countries(country_name, 2013, res_km=1) self.assertIn('GDP ESP 2013: 1.355e+12.', cm.output[0]) self.assertIn('Income group ESP 2013: 4.', cm.output[1]) with self.assertLogs('climada.entity.exposures.black_marble', level='INFO') as cm: ent.set_countries(country_name, 2013, res_km=1) self.assertIn("Nightlights from NOAA's earth observation group for year 2013.", cm.output[0]) self.assertIn("Processing country Spain.", cm.output[1]) self.assertIn("Generating resolution of approx 1 km.", cm.output[2]) self.assertTrue(np.isclose(ent.gdf.value.sum(), 1.355e+12 * (4 + 1), 0.001)) self.assertTrue(equal_crs(ent.crs, 'epsg:4326')) self.assertEqual(ent.meta['width'], 2699) self.assertEqual(ent.meta['height'], 1938) self.assertTrue(equal_crs(ent.meta['crs'], 'epsg:4326')) self.assertAlmostEqual(ent.meta['transform'][0], 0.008333333333333333) self.assertAlmostEqual(ent.meta['transform'][1], 0) self.assertAlmostEqual(ent.meta['transform'][2], -18.1625000000000) self.assertAlmostEqual(ent.meta['transform'][3], 0) self.assertAlmostEqual(ent.meta['transform'][4], -0.008333333333333333) self.assertAlmostEqual(ent.meta['transform'][5], 43.79583333333333)
def test_switzerland300_pass(self): """Create LitPop entity for Switzerland on 300 arcsec:""" country_name = ['CHE'] resolution = 300 fin_mode = 'income_group' ent = LitPop() with self.assertLogs('climada.entity.exposures.litpop', level='INFO') as cm: ent.set_country(country_name, res_arcsec=resolution, fin_mode=fin_mode) # print(cm) self.assertIn('Generating LitPop data at a resolution of 300 arcsec', cm.output[0]) self.assertTrue(ent.region_id.min() == 756) self.assertTrue(ent.region_id.max() == 756) self.assertTrue(np.int(ent.value.sum().round()) == 3350905328146) self.assertIn('LitPop for Switzerland at 300 as, year=2016', ent.tag.description) self.assertIn('financial mode=income_group', ent.tag.description) self.assertIn('GPW-year=2015', ent.tag.description) self.assertIn('BM-year=2016', ent.tag.description) self.assertIn('exp=[1, 1]', ent.tag.description) self.assertTrue(equal_crs(ent.crs['init'], {'init': 'epsg:4326'})) self.assertEqual(ent.meta['width'], 54) self.assertEqual(ent.meta['height'], 23) self.assertTrue(equal_crs(ent.meta['crs'], {'init': 'epsg:4326'})) self.assertAlmostEqual(ent.meta['transform'][0], 0.08333333333333333) self.assertAlmostEqual(ent.meta['transform'][1], 0) self.assertAlmostEqual(ent.meta['transform'][2], 5.9166666666666) self.assertAlmostEqual(ent.meta['transform'][3], 0) self.assertAlmostEqual(ent.meta['transform'][4], -0.08333333333333333) self.assertAlmostEqual(ent.meta['transform'][5], 47.7499999999999)
def test_io_hdf5_pass(self): """write and read hdf5""" exp_df = Exposures(pd.read_excel(ENT_TEMPLATE_XLS), crs="epsg:32632") exp_df.set_geometry_points() exp_df.check() # set metadata exp_df.ref_year = 2020 exp_df.tag = Tag(ENT_TEMPLATE_XLS, 'ENT_TEMPLATE_XLS') exp_df.value_unit = 'XSD' file_name = DATA_DIR.joinpath('test_hdf5_exp.h5') # pd.errors.PerformanceWarning should be suppressed. Therefore, make sure that # PerformanceWarning would result in test failure here import warnings with warnings.catch_warnings(): warnings.simplefilter("error", category=pd.errors.PerformanceWarning) exp_df.write_hdf5(file_name) exp_read = Exposures.from_hdf5(file_name) self.assertEqual(exp_df.ref_year, exp_read.ref_year) self.assertEqual(exp_df.value_unit, exp_read.value_unit) self.assertDictEqual(exp_df.meta, exp_read.meta) self.assertTrue(u_coord.equal_crs(exp_df.crs, exp_read.crs)) self.assertTrue(u_coord.equal_crs(exp_df.gdf.crs, exp_read.gdf.crs)) self.assertEqual(exp_df.tag.file_name, exp_read.tag.file_name) self.assertEqual(exp_df.tag.description, exp_read.tag.description) np.testing.assert_array_equal(exp_df.gdf.latitude.values, exp_read.gdf.latitude.values) np.testing.assert_array_equal(exp_df.gdf.longitude.values, exp_read.gdf.longitude.values) np.testing.assert_array_equal(exp_df.gdf.value.values, exp_read.gdf.value.values) np.testing.assert_array_equal(exp_df.gdf.deductible.values, exp_read.gdf.deductible.values) np.testing.assert_array_equal(exp_df.gdf.cover.values, exp_read.gdf.cover.values) np.testing.assert_array_equal(exp_df.gdf.region_id.values, exp_read.gdf.region_id.values) np.testing.assert_array_equal(exp_df.gdf.category_id.values, exp_read.gdf.category_id.values) np.testing.assert_array_equal(exp_df.gdf.impf_TC.values, exp_read.gdf.impf_TC.values) np.testing.assert_array_equal(exp_df.gdf.centr_TC.values, exp_read.gdf.centr_TC.values) np.testing.assert_array_equal(exp_df.gdf.impf_FL.values, exp_read.gdf.impf_FL.values) np.testing.assert_array_equal(exp_df.gdf.centr_FL.values, exp_read.gdf.centr_FL.values) for point_df, point_read in zip(exp_df.gdf.geometry.values, exp_read.gdf.geometry.values): self.assertEqual(point_df.x, point_read.x) self.assertEqual(point_df.y, point_read.y)
def test_from_lat_lon_pass(self): """Test from_lat_lon""" centr = Centroids.from_lat_lon(VEC_LAT, VEC_LON) self.assertTrue(np.allclose(centr.lat, VEC_LAT)) self.assertTrue(np.allclose(centr.lon, VEC_LON)) self.assertTrue(u_coord.equal_crs(centr.crs, DEF_CRS)) self.assertTrue(u_coord.equal_crs(centr.geometry.crs, DEF_CRS)) self.assertEqual(centr.geometry.size, 0) centr.set_area_pixel() self.assertEqual(centr.geometry.size, centr.lat.size)
def test_to_crs_pass(self): """Test to_crs function copy.""" exp = good_exposures() exp.set_geometry_points() exp.check() exp_tr = exp.to_crs('epsg:3395') self.assertIsInstance(exp, Exposures) self.assertTrue(u_coord.equal_crs(exp.crs, DEF_CRS)) self.assertTrue(u_coord.equal_crs(exp_tr.crs, 'epsg:3395')) self.assertEqual(exp_tr.ref_year, DEF_REF_YEAR) self.assertEqual(exp_tr.value_unit, DEF_VALUE_UNIT) self.assertEqual(exp_tr.tag.description, '') self.assertEqual(exp_tr.tag.file_name, '')
def set_vector_file(self, file_name, inten_name=['intensity'], dst_crs=None): """Read vector file format supported by fiona. Each intensity name is considered an event. Returns intensity array with shape (len(inten_name), len(geometry)). Parameters: file_name (str): vector file with format supported by fiona and 'geometry' field. inten_name (list(str)): list of names of the columns of the intensity of each event. dst_crs (crs, optional): reproject to given crs Returns: np.array """ if not self.geometry.crs: self.lat, self.lon, self.geometry, inten = read_vector(file_name, inten_name, dst_crs) return sparse.csr_matrix(inten) tmp_lat, tmp_lon, tmp_geometry, inten = read_vector(file_name, inten_name, dst_crs) if not equal_crs(tmp_geometry.crs, self.geometry.crs) or \ not np.allclose(tmp_lat, self.lat) or\ not np.allclose(tmp_lon, self.lon): LOGGER.error('Vector data inconsistent with contained vector.') raise ValueError return sparse.csr_matrix(inten)
def set_area_pixel(self): """ Set area_pixel attribute for every pixel or point. area in m*m """ if self.meta: if hasattr(self.meta['crs'], 'linear_units') and \ str.lower(self.meta['crs'].linear_units) in ['m', 'metre', 'meter']: self.area_pixel = np.zeros( (self.meta['height'], self.meta['width'])) self.area_pixel *= abs(self.meta['transform'].a) * abs( self.meta['transform'].e) return if abs( abs(self.meta['transform'].a) - abs(self.meta['transform'].e)) > 1.0e-5: LOGGER.error( 'Area can not be computed for not squared pixels.') raise ValueError res = self.meta['transform'].a else: res = min(get_resolution(self.lat, self.lon)) self.set_geometry_points() LOGGER.debug('Setting area_pixel %s points.', str(self.lat.size)) xy_pixels = self.geometry.buffer(res / 2).envelope if ('units' in self.geometry.crs and \ self.geometry.crs['units'] in ['m', 'metre', 'meter']) or \ equal_crs(self.geometry.crs, {'proj':'cea'}): self.area_pixel = xy_pixels.area.values else: self.area_pixel = xy_pixels.to_crs(crs={'proj': 'cea'}).area.values
def set_area_pixel(self, min_resol=1.0e-8, scheduler=None): """Set area_pixel attribute for every pixel or point. area in m*m Parameters: min_resol (float, optional): if centroids are points, use this minimum resolution in lat and lon. Default: 1.0e-8 scheduler (str): used for dask map_partitions. “threads”, “synchronous” or “processes” """ if self.meta: if hasattr(self.meta['crs'], 'linear_units') and \ str.lower(self.meta['crs'].linear_units) in ['m', 'metre', 'meter']: self.area_pixel = np.zeros((self.meta['height'], self.meta['width'])) self.area_pixel *= abs(self.meta['transform'].a) * abs(self.meta['transform'].e) return if abs(abs(self.meta['transform'].a) - abs(self.meta['transform'].e)) > 1.0e-5: LOGGER.error('Area can not be computed for not squared pixels.') raise ValueError res = self.meta['transform'].a else: res = get_resolution(self.lat, self.lon, min_resol=min_resol) res = np.abs(res).min() self.set_geometry_points(scheduler) LOGGER.debug('Setting area_pixel %s points.', str(self.lat.size)) xy_pixels = self.geometry.buffer(res / 2).envelope is_cea = ('units' in self.geometry.crs and self.geometry.crs['units'] in ['m', 'metre', 'meter'] or equal_crs(self.geometry.crs, {'proj': 'cea'})) if is_cea: self.area_pixel = xy_pixels.area.values else: self.area_pixel = xy_pixels.to_crs(crs={'proj': 'cea'}).area.values
def test_sint_maarten_pass(self): country_name = ['Sint Maarten'] ent = BlackMarble() with self.assertLogs('climada.util.finance', level='INFO') as cm: ent.set_countries(country_name, 2013, res_km=0.2) self.assertIn('GDP SXM 2014: 3.658e+08.', cm.output[0]) self.assertIn('Income group SXM 2013: 4.', cm.output[1]) self.assertTrue(equal_crs(ent.crs['init'], {'init': 'epsg:4326'})) with self.assertLogs('climada.entity.exposures.black_marble', level='INFO') as cm: ent.set_countries(country_name, 2013, res_km=0.2) self.assertIn("Nightlights from NOAA's earth observation group for year 2013.", cm.output[0]) self.assertIn("Processing country Sint Maarten.", cm.output[1]) self.assertIn("Generating resolution of approx 0.2 km.", cm.output[2]) self.assertAlmostEqual(ent.value.sum(), 3.658e+08*(4+1)) self.assertTrue(equal_crs(ent.crs['init'], {'init': 'epsg:4326'}))
def append(self, centr): """ Append raster or points. Raster needs to have the same resolution """ if self.meta and centr.meta: LOGGER.debug('Appending raster') if centr.meta['crs'] != self.meta['crs']: LOGGER.error('Different CRS not accepted.') raise ValueError if self.meta['transform'][0] != centr.meta['transform'][0] or \ self.meta['transform'][4] != centr.meta['transform'][4]: LOGGER.error('Different raster resolutions.') raise ValueError left = min(self.total_bounds[0], centr.total_bounds[0]) bottom = min(self.total_bounds[1], centr.total_bounds[1]) right = max(self.total_bounds[2], centr.total_bounds[2]) top = max(self.total_bounds[3], centr.total_bounds[3]) crs = self.meta['crs'] width = (right - left) / self.meta['transform'][0] height = (bottom - top) / self.meta['transform'][4] self.meta = {'dtype':'float32', 'width':width, 'height':height, 'crs':crs, 'transform':Affine(self.meta['transform'][0], \ 0.0, left, 0.0, self.meta['transform'][4], top)} else: LOGGER.debug('Appending points') if not equal_crs(centr.geometry.crs, self.geometry.crs): LOGGER.error('Different CRS not accepted.') raise ValueError lat = np.append(self.lat, centr.lat) lon = np.append(self.lon, centr.lon) crs = self.geometry.crs self.__init__() self.set_lat_lon(lat, lon, crs)
def test_select_new_attributes(self): """Test if impact has new attributes """ imp = dummy_impact() imp.new_per_ev = ['a', 'b', 'c', 'd', 'e', 'f'] sel_imp = imp.select(event_names=[0, 1, 'two']) self.assertEqual(sel_imp.new_per_ev, ['a', 'b', 'c']) self.assertTrue(u_coord.equal_crs(sel_imp.crs, imp.crs)) self.assertEqual(sel_imp.unit, imp.unit) np.testing.assert_array_equal(sel_imp.event_id, [10, 11, 12]) self.assertEqual(sel_imp.event_name, [0, 1, 'two']) np.testing.assert_array_equal(sel_imp.date, [0, 1, 2]) np.testing.assert_array_almost_equal_nulp(sel_imp.frequency, [1 / 6, 1 / 6, 1]) np.testing.assert_array_equal(sel_imp.at_event, [0, 2, 4]) np.testing.assert_array_equal(sel_imp.imp_mat.todense(), [[0, 0], [1, 1], [2, 2]]) np.testing.assert_array_almost_equal_nulp(sel_imp.eai_exp, [1 / 6 + 2, 1 / 6 + 2]) self.assertEqual(sel_imp.aai_agg, 4 + 2 / 6) self.assertEqual(sel_imp.tot_value, 7) np.testing.assert_array_equal(sel_imp.coord_exp, [[1, 2], [1.5, 2.5]]) self.assertIsInstance(sel_imp, Impact) self.assertIsInstance(sel_imp.imp_mat, sparse.csr_matrix)
def test_select_id_name_dates_pass(self): """Test select by event ids, names, and dates""" imp = dummy_impact() sel_imp = imp.select(event_ids=[0], event_names=[1, 'two'], dates=(0, 2)) self.assertTrue(u_coord.equal_crs(sel_imp.crs, imp.crs)) self.assertEqual(sel_imp.unit, imp.unit) np.testing.assert_array_equal(sel_imp.event_id, [10, 11, 12]) self.assertEqual(sel_imp.event_name, [0, 1, 'two']) np.testing.assert_array_equal(sel_imp.date, [0, 1, 2]) np.testing.assert_array_almost_equal_nulp(sel_imp.frequency, [1 / 6, 1 / 6, 1]) np.testing.assert_array_equal(sel_imp.at_event, [0, 2, 4]) np.testing.assert_array_equal(sel_imp.imp_mat.todense(), [[0, 0], [1, 1], [2, 2]]) np.testing.assert_array_almost_equal_nulp(sel_imp.eai_exp, [1 / 6 + 2, 1 / 6 + 2]) self.assertEqual(sel_imp.aai_agg, 4 + 2 / 6) self.assertEqual(sel_imp.tot_value, 7) np.testing.assert_array_equal(sel_imp.coord_exp, [[1, 2], [1.5, 2.5]]) self.assertIsInstance(sel_imp, Impact) self.assertIsInstance(sel_imp.imp_mat, sparse.csr_matrix)
def test_select_coord_exp_pass(self): """ test select by exp coordinates """ imp = dummy_impact() sel_imp = imp.select(coord_exp=np.array([1, 2])) self.assertTrue(u_coord.equal_crs(sel_imp.crs, imp.crs)) self.assertEqual(sel_imp.unit, imp.unit) np.testing.assert_array_equal(sel_imp.event_id, imp.event_id) self.assertEqual(sel_imp.event_name, imp.event_name) np.testing.assert_array_equal(sel_imp.date, imp.date) np.testing.assert_array_equal(sel_imp.frequency, imp.frequency) np.testing.assert_array_equal(sel_imp.at_event, [0, 1, 2, 3, 30, 31]) np.testing.assert_array_equal(sel_imp.imp_mat.todense(), [[0], [1], [2], [3], [30], [31]]) np.testing.assert_array_almost_equal_nulp( sel_imp.eai_exp, [1 / 6 + 2 + 3 + 1 + 31 / 30]) self.assertEqual(sel_imp.aai_agg, 1 / 6 + 2 + 3 + 1 + 31 / 30) self.assertEqual(sel_imp.tot_value, None) np.testing.assert_array_equal(sel_imp.coord_exp, [[1, 2]]) self.assertIsInstance(sel_imp, Impact) self.assertIsInstance(sel_imp.imp_mat, sparse.csr_matrix)
def test_from_hr_flag_pass(self): """Check from_hr flag in set_countries method.""" country_name = ['Turkey'] ent = BlackMarble() with self.assertLogs('climada.entity.exposures.black_marble', level='INFO') as cm: ent.set_countries(country_name, 2012, res_km=5.0) self.assertTrue('NOAA' in cm.output[-3]) size1 = ent.gdf.value.size self.assertTrue(np.isclose(ent.gdf.value.sum(), 8.740e+11 * (3 + 1), 4)) try: ent = BlackMarble() with self.assertLogs('climada.entity.exposures.black_marble', level='INFO') as cm: ent.set_countries(country_name, 2012, res_km=5.0, from_hr=True) self.assertTrue('NASA' in cm.output[-3]) size2 = ent.gdf.value.size self.assertTrue(size1 < size2) self.assertTrue(np.isclose(ent.gdf.value.sum(), 8.740e+11 * (3 + 1), 4)) except TypeError: print('MemoryError caught') pass ent = BlackMarble() with self.assertLogs('climada.entity.exposures.black_marble', level='INFO') as cm: ent.set_countries(country_name, 2012, res_km=5.0, from_hr=False) self.assertTrue('NOAA' in cm.output[-3]) self.assertTrue(np.isclose(ent.gdf.value.sum(), 8.740e+11 * (3 + 1), 4)) size3 = ent.gdf.value.size self.assertEqual(size1, size3) self.assertTrue(equal_crs(ent.crs, 'epsg:4326'))
def test_write_read_raster_h5(self): """Write and read hdf5 format""" file_name = str(DATA_DIR.joinpath('test_centr.h5')) centr = Centroids() xf_lat, xo_lon, d_lat, d_lon, n_lat, n_lon = 10, 5, -0.5, 0.2, 20, 25 centr.set_raster_from_pix_bounds(xf_lat, xo_lon, d_lat, d_lon, n_lat, n_lon) centr.write_hdf5(file_name) centr_read = Centroids() centr_read.read_hdf5(file_name) self.assertTrue(centr_read.meta) self.assertFalse(centr_read.lat.size) self.assertFalse(centr_read.lon.size) self.assertEqual(centr_read.meta['width'], centr.meta['width']) self.assertEqual(centr_read.meta['height'], centr.meta['height']) self.assertAlmostEqual(centr_read.meta['transform'].a, centr.meta['transform'].a) self.assertAlmostEqual(centr_read.meta['transform'].b, centr.meta['transform'].b) self.assertAlmostEqual(centr_read.meta['transform'].c, centr.meta['transform'].c) self.assertAlmostEqual(centr_read.meta['transform'].d, centr.meta['transform'].d) self.assertAlmostEqual(centr_read.meta['transform'].e, centr.meta['transform'].e) self.assertAlmostEqual(centr_read.meta['transform'].f, centr.meta['transform'].f) self.assertTrue( u_coord.equal_crs(centr_read.meta['crs'], centr.meta['crs']))
def set_vector_file(self, file_name, inten_name=['intensity'], dst_crs=None): """Read vector file format supported by fiona. Each intensity name is considered an event. Parameters ---------- file_name : str vector file with format supported by fiona and 'geometry' field. inten_name : list(str) list of names of the columns of the intensity of each event. dst_crs : crs, optional reproject to given crs Returns ------- inten : scipy.sparse.csr_matrix Sparse intensity array of shape (len(inten_name), len(geometry)). """ if not self.geometry.crs: self.lat, self.lon, self.geometry, inten = u_coord.read_vector( file_name, inten_name, dst_crs) return sparse.csr_matrix(inten) tmp_lat, tmp_lon, tmp_geometry, inten = u_coord.read_vector( file_name, inten_name, dst_crs) if not (u_coord.equal_crs(tmp_geometry.crs, self.geometry.crs) and np.allclose(tmp_lat, self.lat) and np.allclose(tmp_lon, self.lon)): LOGGER.error('Vector data inconsistent with contained vector.') raise ValueError return sparse.csr_matrix(inten)
def assign_centroids(self, hazard, distance='euclidean', threshold=u_coord.NEAREST_NEIGHBOR_THRESHOLD): """Assign for each exposure coordinate closest hazard coordinate. -1 used for disatances > threshold in point distances. If raster hazard, -1 used for centroids outside raster. Parameters ---------- hazard : Hazard Hazard to match (with raster or vector centroids). distance : str, optional Distance to use in case of vector centroids. Possible values are "euclidean", "haversine" and "approx". Default: "euclidean" threshold : float If the distance (in km) to the nearest neighbor exceeds `threshold`, the index `-1` is assigned. Set `threshold` to 0, to disable nearest neighbor matching. Default: 100 (km) See Also -------- climada.util.coordinates.assign_coordinates: method to associate centroids to exposure points Notes ----- The default order of use is: 1. if centroid raster is defined, assign exposures points to the closest raster point. 2. if no raster, assign centroids to the nearest neighbor using euclidian metric Both cases can introduce innacuracies for coordinates in lat/lon coordinates as distances in degrees differ from distances in meters on the Earth surface, in particular for higher latitude and distances larger than 100km. If more accuracy is needed, please use 'haversine' distance metric. This however is slower for (quasi-)gridded data, and works only for non-gridded data. """ LOGGER.info('Matching %s exposures with %s centroids.', str(self.gdf.shape[0]), str(hazard.centroids.size)) if not u_coord.equal_crs(self.crs, hazard.centroids.crs): raise ValueError('Set hazard and exposure to same CRS first!') if hazard.centroids.meta: assigned = u_coord.assign_grid_points( self.gdf.longitude.values, self.gdf.latitude.values, hazard.centroids.meta['width'], hazard.centroids.meta['height'], hazard.centroids.meta['transform']) else: assigned = u_coord.assign_coordinates(np.stack( [self.gdf.latitude.values, self.gdf.longitude.values], axis=1), hazard.centroids.coord, distance=distance, threshold=threshold) self.gdf[INDICATOR_CENTR + hazard.tag.haz_type] = assigned
def equal(self, centr): """ Return true if two centroids equal, false otherwise Parameters: centr (Centroids): centroids to compare Returns: bool """ if self.meta and centr.meta: return equal_crs(self.meta['crs'], centr.meta['crs']) and \ self.meta['height'] == centr.meta['height'] and \ self.meta['width'] == centr.meta['width'] and \ self.meta['transform'] == centr.meta['transform'] return equal_crs(self.geometry.crs, centr.geometry.crs) and \ self.lat.shape == centr.lat.shape and self.lon.shape == centr.lon.shape and \ np.allclose(self.lat, centr.lat) and np.allclose(self.lon, centr.lon)
def test_anguilla_pass(self): country_name = ['Anguilla'] ent = BlackMarble() ent.set_countries(country_name, 2013, res_km=0.2) self.assertEqual(ent.ref_year, 2013) self.assertIn("Anguilla 2013 GDP: 1.754e+08 income group: 3", ent.tag.description) self.assertAlmostEqual(ent.gdf.value.sum(), 1.754e+08 * (3 + 1)) self.assertTrue(equal_crs(ent.crs, 'epsg:4326'))
def append(self, centr): """Append raster or points. Parameters ---------- centr : Centroids If it's a raster, it needs to have the same `meta` attribute. If it's of non-raster form, it's geometry needs to have the same CRS. """ if self.meta and centr.meta: LOGGER.debug('Appending raster') if centr.meta['crs'] != self.meta['crs']: LOGGER.error('Different CRS not accepted.') raise ValueError if self.meta['transform'][0] != centr.meta['transform'][0] \ or self.meta['transform'][4] != centr.meta['transform'][4]: LOGGER.error('Different raster resolutions.') raise ValueError left = min(self.total_bounds[0], centr.total_bounds[0]) bottom = min(self.total_bounds[1], centr.total_bounds[1]) right = max(self.total_bounds[2], centr.total_bounds[2]) top = max(self.total_bounds[3], centr.total_bounds[3]) crs = self.meta['crs'] width = (right - left) / self.meta['transform'][0] height = (bottom - top) / self.meta['transform'][4] self.meta = { 'dtype': 'float32', 'width': width, 'height': height, 'crs': crs, 'transform': rasterio.Affine(self.meta['transform'][0], 0.0, left, 0.0, self.meta['transform'][4], top), } self.lat, self.lon = np.array([]), np.array([]) else: LOGGER.debug('Appending points') if not u_coord.equal_crs(centr.geometry.crs, self.geometry.crs): LOGGER.error('Different CRS not accepted.') raise ValueError self.lat = np.append(self.lat, centr.lat) self.lon = np.append(self.lon, centr.lon) self.meta = dict() # append all 1-dim variables for (var_name, var_val), centr_val in zip(self.__dict__.items(), centr.__dict__.values()): if isinstance(var_val, np.ndarray) and var_val.ndim == 1 and \ var_name not in ('lat', 'lon'): setattr( self, var_name, np.append(var_val, centr_val).astype(var_val.dtype, copy=False))
def test_concat_pass(self): """Test concat function with fake data.""" self.dummy.check() catexp = Exposures.concat([self.dummy, self.dummy.gdf, pd.DataFrame(self.dummy.gdf.values, columns=self.dummy.gdf.columns), self.dummy]) self.assertEqual(self.dummy.gdf.shape, (10,5)) self.assertEqual(catexp.gdf.shape, (40,5)) self.assertTrue(u_coord.equal_crs(catexp.crs, 'epsg:3395'))
def test_set_crs(self): """Test setting the CRS""" empty_gdf = gpd.GeoDataFrame() gdf_without_geometry = good_exposures().gdf good_exp = good_exposures() good_exp.set_geometry_points() gdf_with_geometry = good_exp.gdf probe = Exposures(gdf_without_geometry) self.assertTrue(u_coord.equal_crs(DEF_CRS, probe.crs)) probe.set_crs('epsg:3395') self.assertTrue(u_coord.equal_crs('epsg:3395', probe.crs)) probe = Exposures(gdf_with_geometry) self.assertTrue(u_coord.equal_crs(DEF_CRS, probe.crs)) probe.set_crs(DEF_CRS) self.assertTrue(u_coord.equal_crs(DEF_CRS, probe.crs)) self.assertRaises(ValueError, probe.set_crs, 'epsg:3395') self.assertEqual('EPSG:4326', probe.meta.get('crs'))
def test_sint_maarten_pass(self): country_name = ['Sint Maarten'] ent = BlackMarble() with self.assertLogs('climada.util.finance', level='INFO') as cm: ent.set_countries(country_name, 2013, res_km=0.2) self.assertIn('GDP SXM 2013: 1.023e+09.', cm.output[0]) self.assertIn('Income group SXM 2013: 4.', cm.output[1]) self.assertTrue(u_coord.equal_crs(ent.crs, 'epsg:4326')) with self.assertLogs('climada.entity.exposures.black_marble', level='INFO') as cm: ent.set_countries(country_name, 2013, res_km=0.2) self.assertIn( "Nightlights from NOAA's earth observation group for year 2013.", cm.output[0]) self.assertIn("Processing country Sint Maarten.", cm.output[1]) self.assertIn("Generating resolution of approx 0.2 km.", cm.output[2]) self.assertTrue( np.isclose(ent.gdf.value.sum(), 1.023e+09 * (4 + 1), 0.001)) self.assertTrue(u_coord.equal_crs(ent.crs, 'epsg:4326'))
def test__build_exp(self): """Test that an impact set can be converted to an exposure""" imp = dummy_impact() exp = imp._build_exp() np.testing.assert_array_equal(imp.eai_exp, exp.gdf['value']) np.testing.assert_array_equal(imp.coord_exp[:, 0], exp.gdf['latitude']) np.testing.assert_array_equal(imp.coord_exp[:, 1], exp.gdf['longitude']) self.assertTrue(u_coord.equal_crs(exp.crs, imp.crs)) self.assertEqual(exp.value_unit, imp.unit) self.assertEqual(exp.ref_year, 0)
def _ne_crs_xy(self): """ Return x (lon) and y (lat) in the CRS of Natural Earth Returns: np.array, np.array """ if not self.lat.size or not self.lon.size: self.set_meta_to_lat_lon() if equal_crs(self.geometry.crs, NE_CRS): return self.lon, self.lat self.set_geometry_points() xy_points = self.geometry.to_crs(NE_CRS) return xy_points.geometry[:].x.values, xy_points.geometry[:].y.values
def test_write_read_points_h5(self): file_name = str(DATA_DIR.joinpath('test_centr.h5')) centr = Centroids.from_lat_lon(VEC_LAT, VEC_LON) centr.write_hdf5(file_name) centr_read = Centroids.from_hdf5(file_name) self.assertFalse(centr_read.meta) self.assertTrue(centr_read.lat.size) self.assertTrue(centr_read.lon.size) self.assertTrue(np.allclose(centr_read.lat, centr.lat)) self.assertTrue(np.allclose(centr_read.lon, centr.lon)) self.assertTrue(u_coord.equal_crs(centr_read.crs, centr.crs))
def equal(self, centr): """Return True if two centroids equal, False otherwise Parameters ---------- centr : Centroids centroids to compare Returns ------- eq : bool """ if self.meta and centr.meta: return (u_coord.equal_crs(self.meta['crs'], centr.meta['crs']) and self.meta['height'] == centr.meta['height'] and self.meta['width'] == centr.meta['width'] and self.meta['transform'] == centr.meta['transform']) return (u_coord.equal_crs(self.crs, centr.crs) and self.lat.shape == centr.lat.shape and self.lon.shape == centr.lon.shape and np.allclose(self.lat, centr.lat) and np.allclose(self.lon, centr.lon))