diff --git a/city_metrix/layers/layer.py b/city_metrix/layers/layer.py
index 0b2da49..732992f 100644
--- a/city_metrix/layers/layer.py
+++ b/city_metrix/layers/layer.py
@@ -68,9 +68,26 @@ def count(self):
def _zonal_stats(self, stats_func):
if box(*self.zones.total_bounds).area <= MAX_TILE_SIZE**2:
- return self._zonal_stats_tile(self.zones, [stats_func])[stats_func]
+ stats = self._zonal_stats_tile(self.zones, [stats_func])
else:
- return self._zonal_stats_fishnet(stats_func)
+ stats = self._zonal_stats_fishnet(stats_func)
+
+ if self.layer is not None:
+ # decode zone and layer value using bit operations
+ stats["layer"] = stats["zone"].astype("uint32").values >> 16
+ stats["zone"] = stats["zone"].astype("uint32").values & 65535
+
+ # group layer values together into a dictionary per zone
+ def group_layer_values(df):
+ layer_values = df.drop(columns="zone").groupby("layer").sum()
+ layer_dicts = layer_values.to_dict()
+ return layer_dicts[stats_func]
+
+ stats = stats.groupby("zone").apply(group_layer_values)
+
+ return stats
+
+ return stats[stats_func]
def _zonal_stats_fishnet(self, stats_func):
# fishnet GeoDataFrame into smaller tiles
@@ -91,31 +108,42 @@ def _zonal_stats_fishnet(self, stats_func):
tile_funcs = get_stats_funcs(stats_func)
# run zonal stats per data frame
+ print(f"Input covers too much area, splitting into {len(tile_gdfs)} tiles")
tile_stats = pd.concat([
self._zonal_stats_tile(tile_gdf, tile_funcs)
for tile_gdf in tile_gdfs
])
aggregated = tile_stats.groupby("zone").apply(_aggregate_stats, stats_func)
+ aggregated.name = stats_func
- return aggregated
+ return aggregated.reset_index()
def _zonal_stats_tile(self, tile_gdf, stats_func):
bbox = tile_gdf.total_bounds
aggregate_data = self.aggregate.get_data(bbox)
mask_datum = [mask.get_data(bbox) for mask in self.masks]
+ layer_data = self.layer.get_data(bbox) if self.layer is not None else None
# align to highest resolution raster, which should be the largest raster
# since all are clipped to the extent
- raster_data = [data for data in mask_datum + [aggregate_data] if isinstance(data, xr.DataArray)]
+ raster_data = [data for data in mask_datum + [aggregate_data] + [layer_data] if isinstance(data, xr.DataArray)]
align_to = sorted(raster_data, key=lambda data: data.size, reverse=True).pop()
aggregate_data = self._align(aggregate_data, align_to)
mask_datum = [self._align(data, align_to) for data in mask_datum]
+ if self.layer is not None:
+ layer_data = self._align(layer_data, align_to)
+
for mask in mask_datum:
aggregate_data = aggregate_data.where(~np.isnan(mask))
zones = self._rasterize(tile_gdf, align_to)
+
+ if self.layer is not None:
+ # encode layer into zones by bitshifting
+ zones = zones + (layer_data.astype("uint32") << 16)
+
stats = zonal_stats(zones, aggregate_data, stats_funcs=stats_func)
return stats
@@ -228,7 +256,7 @@ def get_image_collection(
)
with ProgressBar():
- print(f"Extracting layer {name} from Google Earth Engine:")
+ print(f"Extracting layer {name} from Google Earth Engine for bbox {bbox}:")
data = ds.compute()
# get in rioxarray format
diff --git a/notebooks/tutorial/compute indicators.ipynb b/notebooks/tutorial/compute indicators.ipynb
index 99f03fd..6fe09bf 100644
--- a/notebooks/tutorial/compute indicators.ipynb
+++ b/notebooks/tutorial/compute indicators.ipynb
@@ -1224,8 +1224,1249 @@
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.13"
+ },
+ "pycharm": {
+ "stem_cell": {
+ "cell_type": "raw",
+ "source": [
+ "{\n",
+ " \"cells\": [\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"cdd83ce4-8281-496b-a27e-c17527387fec\",\n",
+ " \"metadata\": {},\n",
+ " \"source\": [\n",
+ " \"# Introduction\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"9e3282ba-378a-4272-b6ca-dedf965e4172\",\n",
+ " \"metadata\": {},\n",
+ " \"source\": [\n",
+ " \"This tutorial provides instructions on nhow to use `city_metrix` to calcaulte indicators based on user-specific geometry.\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"6f77de84-d7a9-4377-afd5-9cb265112718\",\n",
+ " \"metadata\": {},\n",
+ " \"source\": [\n",
+ " \"Every 'indicator' is defined as separate python function:\\n\",\n",
+ " \"\\n\",\n",
+ " \"| Indicator name | function name | Parameters | Method |\\n\",\n",
+ " \"| ---- | ---- | ---- | ---- |\\n\",\n",
+ " \"| Average tree cover | `mean_tree_cover()` | | |\\n\",\n",
+ " \"| Percent of built land without tree cover | `built_land_without_tree_cover()` | | |\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"48a31f86-c031-4347-be1d-e631ea0f636e\",\n",
+ " \"metadata\": {\n",
+ " \"tags\": []\n",
+ " },\n",
+ " \"source\": [\n",
+ " \"# Setting\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 1,\n",
+ " \"id\": \"dcc7a7b9-cf15-442c-acfd-fef1806ad05e\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [],\n",
+ " \"source\": [\n",
+ " \"import os\\n\",\n",
+ " \"import geopandas as gpd\\n\",\n",
+ " \"from rasterio.plot import show\\n\",\n",
+ " \"import rasterio\\n\",\n",
+ " \"import pandas as pd\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 2,\n",
+ " \"id\": \"6bcc8215-0c19-45bd-8265-2be0c2a83c6b\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [\n",
+ " {\n",
+ " \"data\": {\n",
+ " \"text/plain\": [\n",
+ " \"'/Users/jt/dev/cities-cif'\"\n",
+ " ]\n",
+ " },\n",
+ " \"execution_count\": 2,\n",
+ " \"metadata\": {},\n",
+ " \"output_type\": \"execute_result\"\n",
+ " }\n",
+ " ],\n",
+ " \"source\": [\n",
+ " \"# update the wd path to be able to laod the module\\n\",\n",
+ " \"os.chdir('../..') \\n\",\n",
+ " \"os.getcwd()\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 3,\n",
+ " \"id\": \"4ce04cdf-634c-4c9c-8d20-1e2a3caffac2\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [],\n",
+ " \"source\": [\n",
+ " \"os.environ['GCS_BUCKET']='gee-exports'\\n\",\n",
+ " \"os.environ['GOOGLE_APPLICATION_USER']='developers@citiesindicators.iam.gserviceaccount.com'\\n\",\n",
+ " \"os.environ['GOOGLE_APPLICATION_CREDENTIALS']='C:\\\\\\\\Users\\\\Saif.Shabou\\\\OneDrive - World Resources Institute\\\\Documents\\\\cities-indicators-framework\\\\citymetrix\\\\credentials-citiesindicators.json'\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"67f86f26-b888-4cc2-b500-47ebe9458609\",\n",
+ " \"metadata\": {\n",
+ " \"tags\": []\n",
+ " },\n",
+ " \"source\": [\n",
+ " \"# Get boundaries\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 3,\n",
+ " \"id\": \"acbc5aaa-5f47-44ff-b9ab-b885c06d7424\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [\n",
+ " {\n",
+ " \"data\": {\n",
+ " \"text/html\": [\n",
+ " \"
\\n\",\n",
+ " \"\\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" | \\n\",\n",
+ " \" geo_id | \\n\",\n",
+ " \" geo_level | \\n\",\n",
+ " \" geo_name | \\n\",\n",
+ " \" geo_parent_name | \\n\",\n",
+ " \" creation_date | \\n\",\n",
+ " \" geometry | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" 0 | \\n\",\n",
+ " \" BRA-Salvador_ADM4-union_1 | \\n\",\n",
+ " \" ADM4-union | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \"
\\n\",\n",
+ " \"
\"\n",
+ " ],\n",
+ " \"text/plain\": [\n",
+ " \" geo_id geo_level geo_name geo_parent_name \\\\\\n\",\n",
+ " \"0 BRA-Salvador_ADM4-union_1 ADM4-union BRA-Salvador BRA-Salvador \\n\",\n",
+ " \"\\n\",\n",
+ " \" creation_date geometry \\n\",\n",
+ " \"0 2022-08-03 MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... \"\n",
+ " ]\n",
+ " },\n",
+ " \"execution_count\": 3,\n",
+ " \"metadata\": {},\n",
+ " \"output_type\": \"execute_result\"\n",
+ " }\n",
+ " ],\n",
+ " \"source\": [\n",
+ " \"# load boundary of a region of interest\\n\",\n",
+ " \"boundary_path = 'https://cities-indicators.s3.eu-west-3.amazonaws.com/data/boundaries/boundary-BRA-Salvador-ADM4union.geojson'\\n\",\n",
+ " \"city_gdf_aoi = gpd.read_file(boundary_path, driver='GeoJSON')\\n\",\n",
+ " \"city_gdf_aoi.head()\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 4,\n",
+ " \"id\": \"7af8657e-feed-42b8-b32a-d4ee5754cd4c\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [\n",
+ " {\n",
+ " \"data\": {\n",
+ " \"text/html\": [\n",
+ " \"\\n\",\n",
+ " \"\\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" | \\n\",\n",
+ " \" geo_id | \\n\",\n",
+ " \" geo_level | \\n\",\n",
+ " \" geo_name | \\n\",\n",
+ " \" geo_parent_name | \\n\",\n",
+ " \" creation_date | \\n\",\n",
+ " \" geometry | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" 0 | \\n\",\n",
+ " \" BRA-Salvador_ADM4_1 | \\n\",\n",
+ " \" ADM4 | \\n\",\n",
+ " \" Pituaçu | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.40125 -12.96457, -38.40126... | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" 1 | \\n\",\n",
+ " \" BRA-Salvador_ADM4_2 | \\n\",\n",
+ " \" ADM4 | \\n\",\n",
+ " \" Patamares | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.39898 -12.96269, -38.39898... | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" 2 | \\n\",\n",
+ " \" BRA-Salvador_ADM4_3 | \\n\",\n",
+ " \" ADM4 | \\n\",\n",
+ " \" Piatã | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.37346 -12.93345, -38.37386... | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" 3 | \\n\",\n",
+ " \" BRA-Salvador_ADM4_4 | \\n\",\n",
+ " \" ADM4 | \\n\",\n",
+ " \" Boca do Rio | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.41741 -12.97578, -38.41746... | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" 4 | \\n\",\n",
+ " \" BRA-Salvador_ADM4_5 | \\n\",\n",
+ " \" ADM4 | \\n\",\n",
+ " \" Jardim Armação | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.43383 -12.98742, -38.43386... | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \"
\\n\",\n",
+ " \"
\"\n",
+ " ],\n",
+ " \"text/plain\": [\n",
+ " \" geo_id geo_level geo_name geo_parent_name \\\\\\n\",\n",
+ " \"0 BRA-Salvador_ADM4_1 ADM4 Pituaçu BRA-Salvador \\n\",\n",
+ " \"1 BRA-Salvador_ADM4_2 ADM4 Patamares BRA-Salvador \\n\",\n",
+ " \"2 BRA-Salvador_ADM4_3 ADM4 Piatã BRA-Salvador \\n\",\n",
+ " \"3 BRA-Salvador_ADM4_4 ADM4 Boca do Rio BRA-Salvador \\n\",\n",
+ " \"4 BRA-Salvador_ADM4_5 ADM4 Jardim Armação BRA-Salvador \\n\",\n",
+ " \"\\n\",\n",
+ " \" creation_date geometry \\n\",\n",
+ " \"0 2022-08-03 MULTIPOLYGON (((-38.40125 -12.96457, -38.40126... \\n\",\n",
+ " \"1 2022-08-03 MULTIPOLYGON (((-38.39898 -12.96269, -38.39898... \\n\",\n",
+ " \"2 2022-08-03 MULTIPOLYGON (((-38.37346 -12.93345, -38.37386... \\n\",\n",
+ " \"3 2022-08-03 MULTIPOLYGON (((-38.41741 -12.97578, -38.41746... \\n\",\n",
+ " \"4 2022-08-03 MULTIPOLYGON (((-38.43383 -12.98742, -38.43386... \"\n",
+ " ]\n",
+ " },\n",
+ " \"execution_count\": 4,\n",
+ " \"metadata\": {},\n",
+ " \"output_type\": \"execute_result\"\n",
+ " }\n",
+ " ],\n",
+ " \"source\": [\n",
+ " \"# load boundary of sub-georgaphy\\n\",\n",
+ " \"boundary_path = 'https://cities-indicators.s3.eu-west-3.amazonaws.com/data/boundaries/boundary-BRA-Salvador-ADM4.geojson'\\n\",\n",
+ " \"city_gdf_sub = gpd.read_file(boundary_path, driver='GeoJSON')\\n\",\n",
+ " \"city_gdf_sub.head()\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"788d5679-2fc5-4025-996c-25af1d35b900\",\n",
+ " \"metadata\": {\n",
+ " \"tags\": []\n",
+ " },\n",
+ " \"source\": [\n",
+ " \"# LND-2 Average Tree Cover\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 5,\n",
+ " \"id\": \"8bdaa746-b071-4e9f-8959-c8c57921c73c\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [\n",
+ " {\n",
+ " \"name\": \"stdout\",\n",
+ " \"output_type\": \"stream\",\n",
+ " \"text\": [\n",
+ " \"Authenticating to GEE with configured credentials file.\\n\"\n",
+ " ]\n",
+ " }\n",
+ " ],\n",
+ " \"source\": [\n",
+ " \"from city_metrix.metrics import mean_tree_cover\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 6,\n",
+ " \"id\": \"e69f2674-dc78-4098-b423-0686944eabe8\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [],\n",
+ " \"source\": [\n",
+ " \"from city_metrix import mean_tree_cover\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"7b71f6e7-9e83-4c88-8a98-9d30958a8dc4\",\n",
+ " \"metadata\": {},\n",
+ " \"source\": [\n",
+ " \"## City level - one city\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 9,\n",
+ " \"id\": \"8b85131c\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [\n",
+ " {\n",
+ " \"name\": \"stdout\",\n",
+ " \"output_type\": \"stream\",\n",
+ " \"text\": [\n",
+ " \"Extracting layer tree cover from Google Earth Engine:\\n\",\n",
+ " \"CPU times: user 6.65 s, sys: 1.12 s, total: 7.77 s\\n\",\n",
+ " \"Wall time: 12.5 s\\n\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"data\": {\n",
+ " \"text/html\": [\n",
+ " \"\\n\",\n",
+ " \"\\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" | \\n\",\n",
+ " \" geo_id | \\n\",\n",
+ " \" geo_level | \\n\",\n",
+ " \" geo_name | \\n\",\n",
+ " \" geo_parent_name | \\n\",\n",
+ " \" creation_date | \\n\",\n",
+ " \" geometry | \\n\",\n",
+ " \" mean_tree_cover | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" 0 | \\n\",\n",
+ " \" BRA-Salvador_ADM4-union_1 | \\n\",\n",
+ " \" ADM4-union | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... | \\n\",\n",
+ " \" 0.283668 | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \"
\\n\",\n",
+ " \"
\"\n",
+ " ],\n",
+ " \"text/plain\": [\n",
+ " \" geo_id geo_level geo_name geo_parent_name \\\\\\n\",\n",
+ " \"0 BRA-Salvador_ADM4-union_1 ADM4-union BRA-Salvador BRA-Salvador \\n\",\n",
+ " \"\\n\",\n",
+ " \" creation_date geometry \\\\\\n\",\n",
+ " \"0 2022-08-03 MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... \\n\",\n",
+ " \"\\n\",\n",
+ " \" mean_tree_cover \\n\",\n",
+ " \"0 0.283668 \"\n",
+ " ]\n",
+ " },\n",
+ " \"execution_count\": 9,\n",
+ " \"metadata\": {},\n",
+ " \"output_type\": \"execute_result\"\n",
+ " }\n",
+ " ],\n",
+ " \"source\": [\n",
+ " \"%%time\\n\",\n",
+ " \"\\n\",\n",
+ " \"# for one geography\\n\",\n",
+ " \"city_gdf_aoi[\\\"mean_tree_cover\\\"] = mean_tree_cover(city_gdf_aoi) \\n\",\n",
+ " \"city_gdf_aoi\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"ee63ca6a-a5c5-4ce7-82cd-3a35e52d3cd6\",\n",
+ " \"metadata\": {},\n",
+ " \"source\": [\n",
+ " \"## Sub-city level\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 8,\n",
+ " \"id\": \"71349065-4726-4a12-bbb8-1f998562c338\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [\n",
+ " {\n",
+ " \"name\": \"stdout\",\n",
+ " \"output_type\": \"stream\",\n",
+ " \"text\": [\n",
+ " \"Extracting tree cover layer in bbox [-38.6469891 -13.0171475 -38.30455157 -12.75628844]:\\n\",\n",
+ " \"[########################################] | 100% Completed | 14.55 s\\n\",\n",
+ " \"CPU times: total: 17.1 s\\n\",\n",
+ " \"Wall time: 17.8 s\\n\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"data\": {\n",
+ " \"text/html\": [\n",
+ " \"\\n\",\n",
+ " \"\\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" | \\n\",\n",
+ " \" geo_id | \\n\",\n",
+ " \" geo_level | \\n\",\n",
+ " \" geo_name | \\n\",\n",
+ " \" geo_parent_name | \\n\",\n",
+ " \" creation_date | \\n\",\n",
+ " \" geometry | \\n\",\n",
+ " \" mean_tree_cover | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" 0 | \\n\",\n",
+ " \" BRA-Salvador_ADM4_1 | \\n\",\n",
+ " \" ADM4 | \\n\",\n",
+ " \" Pituaçu | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.40125 -12.96457, -38.40126... | \\n\",\n",
+ " \" 0.523927 | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" 1 | \\n\",\n",
+ " \" BRA-Salvador_ADM4_2 | \\n\",\n",
+ " \" ADM4 | \\n\",\n",
+ " \" Patamares | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.39898 -12.96269, -38.39898... | \\n\",\n",
+ " \" 0.433088 | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" 2 | \\n\",\n",
+ " \" BRA-Salvador_ADM4_3 | \\n\",\n",
+ " \" ADM4 | \\n\",\n",
+ " \" Piatã | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.37346 -12.93345, -38.37386... | \\n\",\n",
+ " \" 0.274104 | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" 3 | \\n\",\n",
+ " \" BRA-Salvador_ADM4_4 | \\n\",\n",
+ " \" ADM4 | \\n\",\n",
+ " \" Boca do Rio | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.41741 -12.97578, -38.41746... | \\n\",\n",
+ " \" 0.157694 | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" 4 | \\n\",\n",
+ " \" BRA-Salvador_ADM4_5 | \\n\",\n",
+ " \" ADM4 | \\n\",\n",
+ " \" Jardim Armação | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.43383 -12.98742, -38.43386... | \\n\",\n",
+ " \" 0.210874 | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \"
\\n\",\n",
+ " \"
\"\n",
+ " ],\n",
+ " \"text/plain\": [\n",
+ " \" geo_id geo_level geo_name geo_parent_name \\\\\\n\",\n",
+ " \"0 BRA-Salvador_ADM4_1 ADM4 Pituaçu BRA-Salvador \\n\",\n",
+ " \"1 BRA-Salvador_ADM4_2 ADM4 Patamares BRA-Salvador \\n\",\n",
+ " \"2 BRA-Salvador_ADM4_3 ADM4 Piatã BRA-Salvador \\n\",\n",
+ " \"3 BRA-Salvador_ADM4_4 ADM4 Boca do Rio BRA-Salvador \\n\",\n",
+ " \"4 BRA-Salvador_ADM4_5 ADM4 Jardim Armação BRA-Salvador \\n\",\n",
+ " \"\\n\",\n",
+ " \" creation_date geometry \\\\\\n\",\n",
+ " \"0 2022-08-03 MULTIPOLYGON (((-38.40125 -12.96457, -38.40126... \\n\",\n",
+ " \"1 2022-08-03 MULTIPOLYGON (((-38.39898 -12.96269, -38.39898... \\n\",\n",
+ " \"2 2022-08-03 MULTIPOLYGON (((-38.37346 -12.93345, -38.37386... \\n\",\n",
+ " \"3 2022-08-03 MULTIPOLYGON (((-38.41741 -12.97578, -38.41746... \\n\",\n",
+ " \"4 2022-08-03 MULTIPOLYGON (((-38.43383 -12.98742, -38.43386... \\n\",\n",
+ " \"\\n\",\n",
+ " \" mean_tree_cover \\n\",\n",
+ " \"0 0.523927 \\n\",\n",
+ " \"1 0.433088 \\n\",\n",
+ " \"2 0.274104 \\n\",\n",
+ " \"3 0.157694 \\n\",\n",
+ " \"4 0.210874 \"\n",
+ " ]\n",
+ " },\n",
+ " \"execution_count\": 8,\n",
+ " \"metadata\": {},\n",
+ " \"output_type\": \"execute_result\"\n",
+ " }\n",
+ " ],\n",
+ " \"source\": [\n",
+ " \"%%time\\n\",\n",
+ " \"\\n\",\n",
+ " \"# for sub geographies\\n\",\n",
+ " \"city_gdf_sub[\\\"mean_tree_cover\\\"] = mean_tree_cover(city_gdf_sub) \\n\",\n",
+ " \"city_gdf_sub.head()\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"6580e18f-50b1-499c-adb7-9ed604c33e81\",\n",
+ " \"metadata\": {},\n",
+ " \"source\": [\n",
+ " \"## Multiple cities\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 9,\n",
+ " \"id\": \"5006d2d3-6ef0-4460-b127-f72522e94585\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [\n",
+ " {\n",
+ " \"data\": {\n",
+ " \"text/html\": [\n",
+ " \"\\n\",\n",
+ " \"\\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" | \\n\",\n",
+ " \" geo_id | \\n\",\n",
+ " \" geo_level | \\n\",\n",
+ " \" geo_name | \\n\",\n",
+ " \" geo_parent_name | \\n\",\n",
+ " \" creation_date | \\n\",\n",
+ " \" geometry | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" 0 | \\n\",\n",
+ " \" BRA-Salvador_ADM4-union_1 | \\n\",\n",
+ " \" ADM4-union | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" 1 | \\n\",\n",
+ " \" IDN-Jakarta_ADM-4-union_1 | \\n\",\n",
+ " \" ADM-4-union | \\n\",\n",
+ " \" IDN-Jakarta | \\n\",\n",
+ " \" IDN-Jakarta | \\n\",\n",
+ " \" 2022-06-27 | \\n\",\n",
+ " \" MULTIPOLYGON (((106.78141 -6.31616, 106.78124 ... | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \"
\\n\",\n",
+ " \"
\"\n",
+ " ],\n",
+ " \"text/plain\": [\n",
+ " \" geo_id geo_level geo_name geo_parent_name \\\\\\n\",\n",
+ " \"0 BRA-Salvador_ADM4-union_1 ADM4-union BRA-Salvador BRA-Salvador \\n\",\n",
+ " \"1 IDN-Jakarta_ADM-4-union_1 ADM-4-union IDN-Jakarta IDN-Jakarta \\n\",\n",
+ " \"\\n\",\n",
+ " \" creation_date geometry \\n\",\n",
+ " \"0 2022-08-03 MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... \\n\",\n",
+ " \"1 2022-06-27 MULTIPOLYGON (((106.78141 -6.31616, 106.78124 ... \"\n",
+ " ]\n",
+ " },\n",
+ " \"execution_count\": 9,\n",
+ " \"metadata\": {},\n",
+ " \"output_type\": \"execute_result\"\n",
+ " }\n",
+ " ],\n",
+ " \"source\": [\n",
+ " \"# Calculate indicator for multiple regions of interest\\n\",\n",
+ " \"\\n\",\n",
+ " \"boundary_path = 'https://cities-indicators.s3.eu-west-3.amazonaws.com/data/boundaries/boundary-BRA-Salvador-ADM4union.geojson'\\n\",\n",
+ " \"city_Salvador = gpd.read_file(boundary_path, driver='GeoJSON')\\n\",\n",
+ " \"\\n\",\n",
+ " \"boundary_path = 'https://cities-indicators.s3.eu-west-3.amazonaws.com/data/boundaries/boundary-IDN-Jakarta-ADM4union.geojson'\\n\",\n",
+ " \"city_Jakarta = gpd.read_file(boundary_path, driver='GeoJSON')\\n\",\n",
+ " \"\\n\",\n",
+ " \"cities = pd.concat([city_Salvador, city_Jakarta])\\n\",\n",
+ " \"cities = cities.reset_index(drop=True)\\n\",\n",
+ " \"cities\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 10,\n",
+ " \"id\": \"47791e3e-3761-404e-96a5-26493cc8ef54\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [\n",
+ " {\n",
+ " \"name\": \"stdout\",\n",
+ " \"output_type\": \"stream\",\n",
+ " \"text\": [\n",
+ " \"Extracting tree cover layer in bbox [-38.6469891 -13.0171475 -38.30455157 -12.75628844]:\\n\",\n",
+ " \"[########################################] | 100% Completed | 16.77 s\\n\",\n",
+ " \"Extracting tree cover layer in bbox [106.685589 -6.3650478 106.8530109 -6.0891749]:\\n\",\n",
+ " \"[########################################] | 100% Completed | 9.38 ss\\n\",\n",
+ " \"Extracting tree cover layer in bbox [106.8530109 -6.3744575 106.973975 -6.0895823]:\\n\",\n",
+ " \"[########################################] | 100% Completed | 8.75 ss\\n\"\n",
+ " ]\n",
+ " }\n",
+ " ],\n",
+ " \"source\": [\n",
+ " \"cities[\\\"mean_tree_cover\\\"] = mean_tree_cover(cities)\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 11,\n",
+ " \"id\": \"d58a38fd-adea-4961-b0f8-abac0d0943cf\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [\n",
+ " {\n",
+ " \"data\": {\n",
+ " \"text/html\": [\n",
+ " \"\\n\",\n",
+ " \"\\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" | \\n\",\n",
+ " \" geo_id | \\n\",\n",
+ " \" geo_level | \\n\",\n",
+ " \" geo_name | \\n\",\n",
+ " \" geo_parent_name | \\n\",\n",
+ " \" creation_date | \\n\",\n",
+ " \" geometry | \\n\",\n",
+ " \" mean_tree_cover | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" 0 | \\n\",\n",
+ " \" BRA-Salvador_ADM4-union_1 | \\n\",\n",
+ " \" ADM4-union | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... | \\n\",\n",
+ " \" 0.283667 | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" 1 | \\n\",\n",
+ " \" IDN-Jakarta_ADM-4-union_1 | \\n\",\n",
+ " \" ADM-4-union | \\n\",\n",
+ " \" IDN-Jakarta | \\n\",\n",
+ " \" IDN-Jakarta | \\n\",\n",
+ " \" 2022-06-27 | \\n\",\n",
+ " \" MULTIPOLYGON (((106.78141 -6.31616, 106.78124 ... | \\n\",\n",
+ " \" 0.159044 | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \"
\\n\",\n",
+ " \"
\"\n",
+ " ],\n",
+ " \"text/plain\": [\n",
+ " \" geo_id geo_level geo_name geo_parent_name \\\\\\n\",\n",
+ " \"0 BRA-Salvador_ADM4-union_1 ADM4-union BRA-Salvador BRA-Salvador \\n\",\n",
+ " \"1 IDN-Jakarta_ADM-4-union_1 ADM-4-union IDN-Jakarta IDN-Jakarta \\n\",\n",
+ " \"\\n\",\n",
+ " \" creation_date geometry \\\\\\n\",\n",
+ " \"0 2022-08-03 MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... \\n\",\n",
+ " \"1 2022-06-27 MULTIPOLYGON (((106.78141 -6.31616, 106.78124 ... \\n\",\n",
+ " \"\\n\",\n",
+ " \" mean_tree_cover \\n\",\n",
+ " \"0 0.283667 \\n\",\n",
+ " \"1 0.159044 \"\n",
+ " ]\n",
+ " },\n",
+ " \"execution_count\": 11,\n",
+ " \"metadata\": {},\n",
+ " \"output_type\": \"execute_result\"\n",
+ " }\n",
+ " ],\n",
+ " \"source\": [\n",
+ " \"cities\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"8aa3590f-b78e-4c57-872b-c5056266ff1a\",\n",
+ " \"metadata\": {\n",
+ " \"tags\": []\n",
+ " },\n",
+ " \"source\": [\n",
+ " \"# HEA-4 Percent of built land without tree cover\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 14,\n",
+ " \"id\": \"e5948b81-cb27-4c97-9567-a297e078cdb5\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [],\n",
+ " \"source\": [\n",
+ " \"from city_metrix.metrics import built_land_without_tree_cover\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 15,\n",
+ " \"id\": \"10e89534-19d7-4dba-bc98-d4f3dd8b95f4\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [\n",
+ " {\n",
+ " \"name\": \"stdout\",\n",
+ " \"output_type\": \"stream\",\n",
+ " \"text\": [\n",
+ " \"Extracting ESA world cover layer in bbox [-38.6469891 -13.0171475 -38.30455157 -12.75628844]:\\n\",\n",
+ " \"[########################################] | 100% Completed | 9.68 ss\\n\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"ename\": \"UnboundLocalError\",\n",
+ " \"evalue\": \"local variable 'stats_funcs_dict' referenced before assignment\",\n",
+ " \"output_type\": \"error\",\n",
+ " \"traceback\": [\n",
+ " \"\\u001b[1;31m---------------------------------------------------------------------------\\u001b[0m\",\n",
+ " \"\\u001b[1;31mUnboundLocalError\\u001b[0m Traceback (most recent call last)\",\n",
+ " \"File \\u001b[1;32m:2\\u001b[0m\\n\",\n",
+ " \"File \\u001b[1;32m~\\\\OneDrive - World Resources Institute\\\\Documents\\\\cities-indicators-framework\\\\citymetrix\\\\cities-cif\\\\city_metrix\\\\metrics\\\\built_land_without_tree_cover.py:16\\u001b[0m, in \\u001b[0;36mbuilt_land_without_tree_cover\\u001b[1;34m(zones)\\u001b[0m\\n\\u001b[0;32m 13\\u001b[0m built_up_land \\u001b[38;5;241m=\\u001b[39m EsaWorldCover(land_cover_class\\u001b[38;5;241m=\\u001b[39mEsaWorldCoverClass\\u001b[38;5;241m.\\u001b[39mBUILT_UP)\\n\\u001b[0;32m 14\\u001b[0m tree_cover \\u001b[38;5;241m=\\u001b[39m TreeCover(min_tree_cover\\u001b[38;5;241m=\\u001b[39m\\u001b[38;5;241m1\\u001b[39m)\\n\\u001b[1;32m---> 16\\u001b[0m built_land \\u001b[38;5;241m=\\u001b[39m \\u001b[43mbuilt_up_land\\u001b[49m\\u001b[38;5;241;43m.\\u001b[39;49m\\u001b[43mgroupby\\u001b[49m\\u001b[43m(\\u001b[49m\\u001b[43mzones\\u001b[49m\\u001b[43m)\\u001b[49m\\u001b[38;5;241;43m.\\u001b[39;49m\\u001b[43mcount\\u001b[49m\\u001b[43m(\\u001b[49m\\u001b[43m)\\u001b[49m\\n\\u001b[0;32m 17\\u001b[0m tree_cover_in_built_land \\u001b[38;5;241m=\\u001b[39m tree_cover\\u001b[38;5;241m.\\u001b[39mmask(built_up_land)\\u001b[38;5;241m.\\u001b[39mgroupby(zones)\\u001b[38;5;241m.\\u001b[39mcount()\\n\\u001b[0;32m 19\\u001b[0m percent_tree_cover_in_built_up_land \\u001b[38;5;241m=\\u001b[39m \\u001b[38;5;241m1\\u001b[39m \\u001b[38;5;241m-\\u001b[39m (tree_cover_in_built_land\\u001b[38;5;241m.\\u001b[39mfillna(\\u001b[38;5;241m0\\u001b[39m) \\u001b[38;5;241m/\\u001b[39m built_land)\\n\",\n",
+ " \"File \\u001b[1;32m~\\\\OneDrive - World Resources Institute\\\\Documents\\\\cities-indicators-framework\\\\citymetrix\\\\cities-cif\\\\city_metrix\\\\layers\\\\layer.py:64\\u001b[0m, in \\u001b[0;36mLayerGroupBy.count\\u001b[1;34m(self)\\u001b[0m\\n\\u001b[0;32m 63\\u001b[0m \\u001b[38;5;28;01mdef\\u001b[39;00m \\u001b[38;5;21mcount\\u001b[39m(\\u001b[38;5;28mself\\u001b[39m):\\n\\u001b[1;32m---> 64\\u001b[0m \\u001b[38;5;28;01mreturn\\u001b[39;00m \\u001b[38;5;28;43mself\\u001b[39;49m\\u001b[38;5;241;43m.\\u001b[39;49m\\u001b[43m_zonal_stats\\u001b[49m\\u001b[43m(\\u001b[49m\\u001b[38;5;124;43m\\\"\\u001b[39;49m\\u001b[38;5;124;43mcount\\u001b[39;49m\\u001b[38;5;124;43m\\\"\\u001b[39;49m\\u001b[43m)\\u001b[49m\\n\",\n",
+ " \"File \\u001b[1;32m~\\\\OneDrive - World Resources Institute\\\\Documents\\\\cities-indicators-framework\\\\citymetrix\\\\cities-cif\\\\city_metrix\\\\layers\\\\layer.py:68\\u001b[0m, in \\u001b[0;36mLayerGroupBy._zonal_stats\\u001b[1;34m(self, stats_func)\\u001b[0m\\n\\u001b[0;32m 66\\u001b[0m \\u001b[38;5;28;01mdef\\u001b[39;00m \\u001b[38;5;21m_zonal_stats\\u001b[39m(\\u001b[38;5;28mself\\u001b[39m, stats_func):\\n\\u001b[0;32m 67\\u001b[0m \\u001b[38;5;28;01mif\\u001b[39;00m box(\\u001b[38;5;241m*\\u001b[39m\\u001b[38;5;28mself\\u001b[39m\\u001b[38;5;241m.\\u001b[39mzones\\u001b[38;5;241m.\\u001b[39mtotal_bounds)\\u001b[38;5;241m.\\u001b[39marea \\u001b[38;5;241m<\\u001b[39m\\u001b[38;5;241m=\\u001b[39m MAX_TILE_SIZE\\u001b[38;5;241m*\\u001b[39m\\u001b[38;5;241m*\\u001b[39m\\u001b[38;5;241m2\\u001b[39m:\\n\\u001b[1;32m---> 68\\u001b[0m \\u001b[38;5;28;01mreturn\\u001b[39;00m \\u001b[38;5;28;43mself\\u001b[39;49m\\u001b[38;5;241;43m.\\u001b[39;49m\\u001b[43m_zonal_stats_tile\\u001b[49m\\u001b[43m(\\u001b[49m\\u001b[38;5;28;43mself\\u001b[39;49m\\u001b[38;5;241;43m.\\u001b[39;49m\\u001b[43mzones\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mstats_func\\u001b[49m\\u001b[43m)\\u001b[49m[stats_func]\\n\\u001b[0;32m 69\\u001b[0m \\u001b[38;5;28;01melse\\u001b[39;00m:\\n\\u001b[0;32m 70\\u001b[0m \\u001b[38;5;28;01mreturn\\u001b[39;00m \\u001b[38;5;28mself\\u001b[39m\\u001b[38;5;241m.\\u001b[39m_zonal_stats_fishnet(stats_func)\\n\",\n",
+ " \"File \\u001b[1;32m~\\\\OneDrive - World Resources Institute\\\\Documents\\\\cities-indicators-framework\\\\citymetrix\\\\cities-cif\\\\city_metrix\\\\layers\\\\layer.py:116\\u001b[0m, in \\u001b[0;36mLayerGroupBy._zonal_stats_tile\\u001b[1;34m(self, tile_gdf, stats_func)\\u001b[0m\\n\\u001b[0;32m 113\\u001b[0m aggregate_data \\u001b[38;5;241m=\\u001b[39m aggregate_data\\u001b[38;5;241m.\\u001b[39mwhere(\\u001b[38;5;241m~\\u001b[39mnp\\u001b[38;5;241m.\\u001b[39misnan(mask))\\n\\u001b[0;32m 115\\u001b[0m zones \\u001b[38;5;241m=\\u001b[39m \\u001b[38;5;28mself\\u001b[39m\\u001b[38;5;241m.\\u001b[39m_rasterize(tile_gdf, align_to)\\n\\u001b[1;32m--> 116\\u001b[0m stats \\u001b[38;5;241m=\\u001b[39m \\u001b[43mzonal_stats\\u001b[49m\\u001b[43m(\\u001b[49m\\u001b[43mzones\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43maggregate_data\\u001b[49m\\u001b[43m,\\u001b[49m\\u001b[43m \\u001b[49m\\u001b[43mstats_funcs\\u001b[49m\\u001b[38;5;241;43m=\\u001b[39;49m\\u001b[43mstats_func\\u001b[49m\\u001b[43m)\\u001b[49m\\n\\u001b[0;32m 118\\u001b[0m \\u001b[38;5;28;01mreturn\\u001b[39;00m stats\\n\",\n",
+ " \"File \\u001b[1;32m~\\\\anaconda3\\\\envs\\\\citymetrix_env\\\\lib\\\\site-packages\\\\xrspatial\\\\zonal.py:579\\u001b[0m, in \\u001b[0;36mstats\\u001b[1;34m(zones, values, zone_ids, stats_funcs, nodata_values, return_type)\\u001b[0m\\n\\u001b[0;32m 568\\u001b[0m stats_funcs_dict \\u001b[38;5;241m=\\u001b[39m stats_funcs\\u001b[38;5;241m.\\u001b[39mcopy()\\n\\u001b[0;32m 570\\u001b[0m mapper \\u001b[38;5;241m=\\u001b[39m ArrayTypeFunctionMapping(\\n\\u001b[0;32m 571\\u001b[0m numpy_func\\u001b[38;5;241m=\\u001b[39m\\u001b[38;5;28;01mlambda\\u001b[39;00m \\u001b[38;5;241m*\\u001b[39margs: _stats_numpy(\\u001b[38;5;241m*\\u001b[39margs, return_type\\u001b[38;5;241m=\\u001b[39mreturn_type),\\n\\u001b[0;32m 572\\u001b[0m dask_func\\u001b[38;5;241m=\\u001b[39m_stats_dask_numpy,\\n\\u001b[1;32m (...)\\u001b[0m\\n\\u001b[0;32m 576\\u001b[0m ),\\n\\u001b[0;32m 577\\u001b[0m )\\n\\u001b[0;32m 578\\u001b[0m result \\u001b[38;5;241m=\\u001b[39m mapper(values)(\\n\\u001b[1;32m--> 579\\u001b[0m zones\\u001b[38;5;241m.\\u001b[39mdata, values\\u001b[38;5;241m.\\u001b[39mdata, zone_ids, \\u001b[43mstats_funcs_dict\\u001b[49m, nodata_values,\\n\\u001b[0;32m 580\\u001b[0m )\\n\\u001b[0;32m 582\\u001b[0m \\u001b[38;5;28;01mif\\u001b[39;00m return_type \\u001b[38;5;241m==\\u001b[39m \\u001b[38;5;124m'\\u001b[39m\\u001b[38;5;124mxarray.DataArray\\u001b[39m\\u001b[38;5;124m'\\u001b[39m:\\n\\u001b[0;32m 583\\u001b[0m \\u001b[38;5;28;01mreturn\\u001b[39;00m xr\\u001b[38;5;241m.\\u001b[39mDataArray(\\n\\u001b[0;32m 584\\u001b[0m result,\\n\\u001b[0;32m 585\\u001b[0m coords\\u001b[38;5;241m=\\u001b[39m{\\u001b[38;5;124m'\\u001b[39m\\u001b[38;5;124mstats\\u001b[39m\\u001b[38;5;124m'\\u001b[39m: \\u001b[38;5;28mlist\\u001b[39m(stats_funcs_dict\\u001b[38;5;241m.\\u001b[39mkeys()), \\u001b[38;5;241m*\\u001b[39m\\u001b[38;5;241m*\\u001b[39mvalues\\u001b[38;5;241m.\\u001b[39mcoords},\\n\\u001b[0;32m 586\\u001b[0m dims\\u001b[38;5;241m=\\u001b[39m(\\u001b[38;5;124m'\\u001b[39m\\u001b[38;5;124mstats\\u001b[39m\\u001b[38;5;124m'\\u001b[39m, \\u001b[38;5;241m*\\u001b[39mvalues\\u001b[38;5;241m.\\u001b[39mdims),\\n\\u001b[0;32m 587\\u001b[0m attrs\\u001b[38;5;241m=\\u001b[39mvalues\\u001b[38;5;241m.\\u001b[39mattrs\\n\\u001b[0;32m 588\\u001b[0m )\\n\",\n",
+ " \"\\u001b[1;31mUnboundLocalError\\u001b[0m: local variable 'stats_funcs_dict' referenced before assignment\"\n",
+ " ]\n",
+ " }\n",
+ " ],\n",
+ " \"source\": [\n",
+ " \"%%time\\n\",\n",
+ " \"\\n\",\n",
+ " \"# for one geography\\n\",\n",
+ " \"city_gdf_aoi[\\\"built_land_without_tree_cover\\\"] = built_land_without_tree_cover(city_gdf_aoi) \\n\",\n",
+ " \"city_gdf_aoi\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"afbb60b1-437f-4af5-99fe-9679559b250b\",\n",
+ " \"metadata\": {},\n",
+ " \"source\": [\n",
+ " \"# HEA-3 Built land with Low Surface reflectivity\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 12,\n",
+ " \"id\": \"3c61a81e-f575-4d24-863d-ca9b7be34ad5\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [],\n",
+ " \"source\": [\n",
+ " \"from city_metrix.metrics import built_land_with_low_surface_reflectivity\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 13,\n",
+ " \"id\": \"748d1d72-c4fe-4c6c-91f6-99dac052bdd8\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [\n",
+ " {\n",
+ " \"name\": \"stdout\",\n",
+ " \"output_type\": \"stream\",\n",
+ " \"text\": [\n",
+ " \"Extracting ESA world cover layer:\\n\",\n",
+ " \"[########################################] | 100% Completed | 8.21 ss\\n\",\n",
+ " \"Calculating albedo layer:\\n\",\n",
+ " \"[########################################] | 100% Completed | 84.36 s\\n\",\n",
+ " \"Extracting ESA world cover layer:\\n\",\n",
+ " \"[########################################] | 100% Completed | 8.32 ss\\n\",\n",
+ " \"CPU times: total: 30.5 s\\n\",\n",
+ " \"Wall time: 1min 49s\\n\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"data\": {\n",
+ " \"text/html\": [\n",
+ " \"\\n\",\n",
+ " \"\\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" | \\n\",\n",
+ " \" geo_id | \\n\",\n",
+ " \" geo_level | \\n\",\n",
+ " \" geo_name | \\n\",\n",
+ " \" geo_parent_name | \\n\",\n",
+ " \" creation_date | \\n\",\n",
+ " \" geometry | \\n\",\n",
+ " \" mean_tree_cover | \\n\",\n",
+ " \" built_land_without_tree_cover | \\n\",\n",
+ " \" built_land_with_low_surface_reflectivity | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" 0 | \\n\",\n",
+ " \" BRA-Salvador_ADM4-union_1 | \\n\",\n",
+ " \" ADM4-union | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... | \\n\",\n",
+ " \" 28.366734 | \\n\",\n",
+ " \" 0.907382 | \\n\",\n",
+ " \" 0.786552 | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \"
\\n\",\n",
+ " \"
\"\n",
+ " ],\n",
+ " \"text/plain\": [\n",
+ " \" geo_id geo_level geo_name geo_parent_name \\\\\\n\",\n",
+ " \"0 BRA-Salvador_ADM4-union_1 ADM4-union BRA-Salvador BRA-Salvador \\n\",\n",
+ " \"\\n\",\n",
+ " \" creation_date geometry \\\\\\n\",\n",
+ " \"0 2022-08-03 MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... \\n\",\n",
+ " \"\\n\",\n",
+ " \" mean_tree_cover built_land_without_tree_cover \\\\\\n\",\n",
+ " \"0 28.366734 0.907382 \\n\",\n",
+ " \"\\n\",\n",
+ " \" built_land_with_low_surface_reflectivity \\n\",\n",
+ " \"0 0.786552 \"\n",
+ " ]\n",
+ " },\n",
+ " \"execution_count\": 13,\n",
+ " \"metadata\": {},\n",
+ " \"output_type\": \"execute_result\"\n",
+ " }\n",
+ " ],\n",
+ " \"source\": [\n",
+ " \"%%time\\n\",\n",
+ " \"\\n\",\n",
+ " \"city_gdf_aoi[\\\"built_land_with_low_surface_reflectivity\\\"] = built_land_with_low_surface_reflectivity(city_gdf_aoi) \\n\",\n",
+ " \"city_gdf_aoi\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"bbfcabaa-2acc-4b9b-bdce-27b415e04354\",\n",
+ " \"metadata\": {},\n",
+ " \"source\": [\n",
+ " \"# HEA-2 Built Land With High LST\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 14,\n",
+ " \"id\": \"6df5d7a3-1c25-49ac-ab33-9081722168c9\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [],\n",
+ " \"source\": [\n",
+ " \"from city_metrix.metrics import built_land_with_high_land_surface_temperature\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 15,\n",
+ " \"id\": \"5288d4e6-e35d-48f4-9ff7-2d84c857b21a\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [\n",
+ " {\n",
+ " \"name\": \"stdout\",\n",
+ " \"output_type\": \"stream\",\n",
+ " \"text\": [\n",
+ " \"Extracting ESA world cover layer:\\n\",\n",
+ " \"[########################################] | 100% Completed | 8.65 ss\\n\",\n",
+ " \"Calculating land surface temperature layer:\\n\",\n",
+ " \"[########################################] | 100% Completed | 2.73 ss\\n\",\n",
+ " \"Extracting ESA world cover layer:\\n\",\n",
+ " \"[########################################] | 100% Completed | 9.16 ss\\n\",\n",
+ " \"CPU times: total: 14.8 s\\n\",\n",
+ " \"Wall time: 37.7 s\\n\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"data\": {\n",
+ " \"text/html\": [\n",
+ " \"\\n\",\n",
+ " \"\\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" | \\n\",\n",
+ " \" geo_id | \\n\",\n",
+ " \" geo_level | \\n\",\n",
+ " \" geo_name | \\n\",\n",
+ " \" geo_parent_name | \\n\",\n",
+ " \" creation_date | \\n\",\n",
+ " \" geometry | \\n\",\n",
+ " \" mean_tree_cover | \\n\",\n",
+ " \" built_land_without_tree_cover | \\n\",\n",
+ " \" built_land_with_low_surface_reflectivity | \\n\",\n",
+ " \" built_land_with_high_land_surface_temperature | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" 0 | \\n\",\n",
+ " \" BRA-Salvador_ADM4-union_1 | \\n\",\n",
+ " \" ADM4-union | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... | \\n\",\n",
+ " \" 28.366734 | \\n\",\n",
+ " \" 0.907382 | \\n\",\n",
+ " \" 0.786552 | \\n\",\n",
+ " \" 0.0961 | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \"
\\n\",\n",
+ " \"
\"\n",
+ " ],\n",
+ " \"text/plain\": [\n",
+ " \" geo_id geo_level geo_name geo_parent_name \\\\\\n\",\n",
+ " \"0 BRA-Salvador_ADM4-union_1 ADM4-union BRA-Salvador BRA-Salvador \\n\",\n",
+ " \"\\n\",\n",
+ " \" creation_date geometry \\\\\\n\",\n",
+ " \"0 2022-08-03 MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... \\n\",\n",
+ " \"\\n\",\n",
+ " \" mean_tree_cover built_land_without_tree_cover \\\\\\n\",\n",
+ " \"0 28.366734 0.907382 \\n\",\n",
+ " \"\\n\",\n",
+ " \" built_land_with_low_surface_reflectivity \\\\\\n\",\n",
+ " \"0 0.786552 \\n\",\n",
+ " \"\\n\",\n",
+ " \" built_land_with_high_land_surface_temperature \\n\",\n",
+ " \"0 0.0961 \"\n",
+ " ]\n",
+ " },\n",
+ " \"execution_count\": 15,\n",
+ " \"metadata\": {},\n",
+ " \"output_type\": \"execute_result\"\n",
+ " }\n",
+ " ],\n",
+ " \"source\": [\n",
+ " \"%%time\\n\",\n",
+ " \"\\n\",\n",
+ " \"city_gdf_aoi[\\\"built_land_with_high_land_surface_temperature\\\"] = built_land_with_high_land_surface_temperature(city_gdf_aoi) \\n\",\n",
+ " \"city_gdf_aoi\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"feb93688-9435-47a5-be31-0a806dd48fe1\",\n",
+ " \"metadata\": {},\n",
+ " \"source\": [\n",
+ " \"# Percent of Natural areas\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 18,\n",
+ " \"id\": \"aee87e06-d16d-4017-a5e1-7fd8cef906d4\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [],\n",
+ " \"source\": [\n",
+ " \"from city_metrix.metrics import natural_areas\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": null,\n",
+ " \"id\": \"026261af-a18d-4c0c-bdb8-b11a3c192ddc\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [],\n",
+ " \"source\": [\n",
+ " \"%%time\\n\",\n",
+ " \"\\n\",\n",
+ " \"# for one geography\\n\",\n",
+ " \"city_gdf_aoi[\\\"natural_areas\\\"] = natural_areas(city_gdf_aoi) \\n\",\n",
+ " \"city_gdf_aoi\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"markdown\",\n",
+ " \"id\": \"b05cef42-67cd-4cdc-a7db-5f34ddd7837b\",\n",
+ " \"metadata\": {},\n",
+ " \"source\": [\n",
+ " \"# Open Space in built up land\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 21,\n",
+ " \"id\": \"b4281469-9ca5-4b2c-a308-32f2e2fd5404\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [],\n",
+ " \"source\": [\n",
+ " \"from city_metrix.metrics import urban_open_space\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": 22,\n",
+ " \"id\": \"db612f31-eb82-4a10-9433-0907f0a64a0e\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [\n",
+ " {\n",
+ " \"name\": \"stdout\",\n",
+ " \"output_type\": \"stream\",\n",
+ " \"text\": [\n",
+ " \"Extracting ESA world cover layer:\\n\",\n",
+ " \"[########################################] | 100% Completed | 12.48 s\\n\",\n",
+ " \"Extracting ESA world cover layer:\\n\",\n",
+ " \"[########################################] | 100% Completed | 9.08 ss\\n\",\n",
+ " \"CPU times: total: 24 s\\n\",\n",
+ " \"Wall time: 31.1 s\\n\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"data\": {\n",
+ " \"text/html\": [\n",
+ " \"\\n\",\n",
+ " \"\\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" | \\n\",\n",
+ " \" geo_id | \\n\",\n",
+ " \" geo_level | \\n\",\n",
+ " \" geo_name | \\n\",\n",
+ " \" geo_parent_name | \\n\",\n",
+ " \" creation_date | \\n\",\n",
+ " \" geometry | \\n\",\n",
+ " \" mean_tree_cover | \\n\",\n",
+ " \" built_land_without_tree_cover | \\n\",\n",
+ " \" built_land_with_low_surface_reflectivity | \\n\",\n",
+ " \" built_land_with_high_land_surface_temperature | \\n\",\n",
+ " \" urban_open_space | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" \\n\",\n",
+ " \" 0 | \\n\",\n",
+ " \" BRA-Salvador_ADM4-union_1 | \\n\",\n",
+ " \" ADM4-union | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" BRA-Salvador | \\n\",\n",
+ " \" 2022-08-03 | \\n\",\n",
+ " \" MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... | \\n\",\n",
+ " \" 28.366734 | \\n\",\n",
+ " \" 0.907382 | \\n\",\n",
+ " \" 0.786552 | \\n\",\n",
+ " \" 0.0961 | \\n\",\n",
+ " \" 0.028378 | \\n\",\n",
+ " \"
\\n\",\n",
+ " \" \\n\",\n",
+ " \"
\\n\",\n",
+ " \"
\"\n",
+ " ],\n",
+ " \"text/plain\": [\n",
+ " \" geo_id geo_level geo_name geo_parent_name \\\\\\n\",\n",
+ " \"0 BRA-Salvador_ADM4-union_1 ADM4-union BRA-Salvador BRA-Salvador \\n\",\n",
+ " \"\\n\",\n",
+ " \" creation_date geometry \\\\\\n\",\n",
+ " \"0 2022-08-03 MULTIPOLYGON (((-38.50135 -13.01134, -38.50140... \\n\",\n",
+ " \"\\n\",\n",
+ " \" mean_tree_cover built_land_without_tree_cover \\\\\\n\",\n",
+ " \"0 28.366734 0.907382 \\n\",\n",
+ " \"\\n\",\n",
+ " \" built_land_with_low_surface_reflectivity \\\\\\n\",\n",
+ " \"0 0.786552 \\n\",\n",
+ " \"\\n\",\n",
+ " \" built_land_with_high_land_surface_temperature urban_open_space \\n\",\n",
+ " \"0 0.0961 0.028378 \"\n",
+ " ]\n",
+ " },\n",
+ " \"execution_count\": 22,\n",
+ " \"metadata\": {},\n",
+ " \"output_type\": \"execute_result\"\n",
+ " }\n",
+ " ],\n",
+ " \"source\": [\n",
+ " \"%%time\\n\",\n",
+ " \"\\n\",\n",
+ " \"# for one geography\\n\",\n",
+ " \"city_gdf_aoi[\\\"urban_open_space\\\"] = urban_open_space(city_gdf_aoi) \\n\",\n",
+ " \"city_gdf_aoi\"\n",
+ " ]\n",
+ " },\n",
+ " {\n",
+ " \"cell_type\": \"code\",\n",
+ " \"execution_count\": null,\n",
+ " \"id\": \"951151f1-e0f5-4a8a-99a7-19a6f7c84591\",\n",
+ " \"metadata\": {},\n",
+ " \"outputs\": [],\n",
+ " \"source\": []\n",
+ " }\n",
+ " ],\n",
+ " \"metadata\": {\n",
+ " \"kernelspec\": {\n",
+ " \"display_name\": \"Python 3 (ipykernel)\",\n",
+ " \"language\": \"python\",\n",
+ " \"name\": \"python3\"\n",
+ " },\n",
+ " \"language_info\": {\n",
+ " \"codemirror_mode\": {\n",
+ " \"name\": \"ipython\",\n",
+ " \"version\": 3\n",
+ " },\n",
+ " \"file_extension\": \".py\",\n",
+ " \"mimetype\": \"text/x-python\",\n",
+ " \"name\": \"python\",\n",
+ " \"nbconvert_exporter\": \"python\",\n",
+ " \"pygments_lexer\": \"ipython3\",\n",
+ " \"version\": \"3.10.13\"\n",
+ " }\n",
+ " },\n",
+ " \"nbformat\": 4,\n",
+ " \"nbformat_minor\": 5\n",
+ "}"
+ ],
+ "metadata": {
+ "collapsed": false
+ }
+ }
}
},
"nbformat": 4,
"nbformat_minor": 5
-}
\ No newline at end of file
+}
diff --git a/notebooks/tutorial/get layers.ipynb b/notebooks/tutorial/get layers.ipynb
index 195deae..883d107 100644
--- a/notebooks/tutorial/get layers.ipynb
+++ b/notebooks/tutorial/get layers.ipynb
@@ -4693,10 +4693,10 @@
"evalue": "name 'TreeCanopyHeight' is not defined",
"output_type": "error",
"traceback": [
- "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
- "\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
- "Cell \u001b[0;32mIn[5], line 2\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[38;5;66;03m# Load 1m Global Tree Canopy Hight layer\u001b[39;00m\n\u001b[0;32m----> 2\u001b[0m city_TreeCanopyHeight \u001b[38;5;241m=\u001b[39m \u001b[43mTreeCanopyHeight\u001b[49m()\u001b[38;5;241m.\u001b[39mget_data(city_gdf\u001b[38;5;241m.\u001b[39mtotal_bounds)\n\u001b[1;32m 3\u001b[0m city_TreeCanopyHeight\n",
- "\u001b[0;31mNameError\u001b[0m: name 'TreeCanopyHeight' is not defined"
+ "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
+ "\u001B[0;31mNameError\u001B[0m Traceback (most recent call last)",
+ "Cell \u001B[0;32mIn[5], line 2\u001B[0m\n\u001B[1;32m 1\u001B[0m \u001B[38;5;66;03m# Load 1m Global Tree Canopy Hight layer\u001B[39;00m\n\u001B[0;32m----> 2\u001B[0m city_TreeCanopyHeight \u001B[38;5;241m=\u001B[39m \u001B[43mTreeCanopyHeight\u001B[49m()\u001B[38;5;241m.\u001B[39mget_data(city_gdf\u001B[38;5;241m.\u001B[39mtotal_bounds)\n\u001B[1;32m 3\u001B[0m city_TreeCanopyHeight\n",
+ "\u001B[0;31mNameError\u001B[0m: name 'TreeCanopyHeight' is not defined"
]
}
],
@@ -5373,4 +5373,4 @@
},
"nbformat": 4,
"nbformat_minor": 5
-}
+}
\ No newline at end of file
diff --git a/tests/conftest.py b/tests/conftest.py
index 7e935f8..b56318c 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -34,6 +34,7 @@ def create_fishnet_grid(min_x, min_y, max_x, max_y, cell_size):
ZONES = create_fishnet_grid(106.7, -6.3, 106.8, -6.2, 0.01).reset_index()
LARGE_ZONES = create_fishnet_grid(106, -7, 107, -6, 0.1).reset_index()
+
class MockLayer(Layer):
"""
Simple mock layer that just rasterizes the zones
@@ -66,6 +67,23 @@ def get_data(self, bbox):
return mask
+class MockGroupByLayer(Layer):
+ """
+ Simple categorical layer with alternating 1s and 2s
+ """
+ def get_data(self, bbox):
+ group_by_gdf = create_fishnet_grid(*bbox, 0.001).reset_index()
+ group_by_gdf['index'] = (group_by_gdf['index'] % 2) + 1
+ group_by = make_geocube(
+ vector_data=group_by_gdf,
+ measurements=['index'],
+ resolution=(0.001, 0.001),
+ output_crs=4326,
+ ).index
+
+ return group_by
+
+
class MockLargeLayer(Layer):
"""
Simple mock layer that just rasterizes the zones
@@ -77,4 +95,22 @@ def get_data(self, bbox):
resolution=(0.01, 0.01),
output_crs=4326,
).index
- return arr
\ No newline at end of file
+ return arr
+
+
+class MockLargeGroupByLayer(Layer):
+ """
+ Large categorical layer with alternating 1s and 2s
+ """
+
+ def get_data(self, bbox):
+ group_by_gdf = create_fishnet_grid(*bbox, 0.01).reset_index()
+ group_by_gdf['index'] = (group_by_gdf['index'] % 2) + 1
+ group_by = make_geocube(
+ vector_data=group_by_gdf,
+ measurements=['index'],
+ resolution=(0.01, 0.01),
+ output_crs=4326,
+ ).index
+
+ return group_by
\ No newline at end of file
diff --git a/tests/layers.py b/tests/layers.py
index ce9fc3f..adf01ea 100644
--- a/tests/layers.py
+++ b/tests/layers.py
@@ -2,8 +2,8 @@
from city_metrix.layers import LandsatCollection2, Albedo, LandSurfaceTemperature, EsaWorldCover, EsaWorldCoverClass, TreeCover, AverageNetBuildingHeight, OpenStreetMap, OpenStreetMapClass, UrbanLandUse, OpenBuildings, TreeCanopyHeight, AlosDSM
from city_metrix.layers.layer import get_image_collection
-from .conftest import MockLayer, MockMaskLayer, ZONES, LARGE_ZONES, MockLargeLayer
-
+from .conftest import MockLayer, MockMaskLayer, ZONES, LARGE_ZONES, MockLargeLayer, MockGroupByLayer, \
+ MockLargeGroupByLayer
import pytest
import numpy as np
@@ -43,6 +43,16 @@ def test_masks():
assert count == 100
+def test_group_by_layer():
+ counts = MockLayer().groupby(ZONES, layer=MockGroupByLayer()).count()
+ assert all([count == {1: 50.0, 2: 50.0} for count in counts])
+
+
+def test_group_by_large_layer():
+ counts = MockLargeLayer().groupby(LARGE_ZONES, layer=MockLargeGroupByLayer()).count()
+ assert all([count == {1: 50.0, 2: 50.0} for count in counts])
+
+
SAMPLE_BBOX = (-38.35530428121955, -12.821710300686393, -38.33813814352424, -12.80363249765361)