Quickstart¶
This walks through both ways of telling CityMetrix where you want data, and the two main things you can do once you have an AOI: pull a layer, or compute a metric.
Option A: AOI from your own polygon¶
If you already have a city or district boundary as a GeoDataFrame, just use it directly:
import geopandas as gpd
from city_metrix.layers import TreeCover
city_gdf = gpd.read_file("jakarta.geojson")
mean_cover = TreeCover().groupby(city_gdf).mean()
print(mean_cover)
Option B: AOI from a WRI city ID¶
If you want to use a boundary already known to the Cities Data API, build a GeoExtent/GeoZone from a city_id + aoi_id JSON snippet instead:
from city_metrix.metrix_model import GeoZone
from city_metrix.layers import TreeCover
geo_zone = GeoZone('{"city_id": "BRA-Florianopolis", "aoi_id": "city_admin_level"}')
mean_cover = TreeCover().groupby(geo_zone).mean()
aoi_id can be city_centroid, urban_extent, or city_admin_level. You can look up valid city_id values via the Cities Indicators API.
Pulling a layer's raw data¶
Every layer implements get_data(), which returns a raster (xarray.DataArray) or vector (GeoDataFrame) clipped to a bounding box:
from city_metrix.metrix_model import GeoExtent
from city_metrix.layers import EsaWorldCover
bbox = GeoExtent(bbox=(106.78, -6.23, 106.84, -6.17)) # min_x, min_y, max_x, max_y
land_cover = EsaWorldCover().get_data(bbox)
Combining layers: masks and zonal stats¶
Layers can be chained: use one layer as a mask over another, then run zonal statistics with .groupby(...).mean()/.count()/.sum():
from city_metrix.layers import TreeCover, EsaWorldCover, EsaWorldCoverClass
result = (
TreeCover(min_tree_cover=10)
.mask(EsaWorldCover(land_cover_class=EsaWorldCoverClass.BUILT_UP))
.groupby(city_gdf)
.count()
)
Using a pre-built metric¶
Most common indicators are already implemented as Metric classes in city_metrix.metrics, so you don't need to assemble the layer chain yourself:
from city_metrix.metrics import MeanTreeCover__Percent
mean_cover = MeanTreeCover__Percent().get_metric(geo_zone=city_gdf)
Metric class names follow a Name__Unit convention — see Working with Metrics.
Writing results to a file¶
TreeCover().write(bbox, target_file_path="tree_cover.tif")
MeanTreeCover__Percent().write(city_gdf, target_file_path="mean_tree_cover.csv")
Next: read Core Concepts to understand what's actually happening under the hood.