Impute missing OSM building heights using ArcticDEM raster elevation models and zonal statistics.
Many OpenStreetMap buildings lack height or level tags. This module fills those gaps by sampling a Digital Elevation Model (DEM) — primarily ArcticDEM — and deriving absolute building heights via terrain correction. It supports multiple imputation and terrain correction strategies, automatic tile fetching from NASA Earthdata, and optional orthometric height conversion.
raw DEM sample − terrain elevation = absolute building height
- Three imputation strategies —
max(default),direct, andcoefficient(deprecated) - Multiple DEM sampling modes — mean, max, median, percentile (decile), and more
- Terrain correction — buffer ring, elevation API (Google), or NASA DTM (SRTM / NASADEM)
- Automatic ArcticDEM tile fetching via
pystac-client+ NASA Earthdata auth - Orthometric conversion — EGM2008 via
pyproj+proj-data(enabled by default) - Spatial interpolation of correction coefficients — IDW, KNN, and others (for
coefficientstrategy) - Visualization tools — 3-D building extrusion and rendering for manual QA
rnd-dem-imputation/
├── src/height_imputation/ # Core library
│ ├── height_imputer.py # HeightImputer — main entry point
│ ├── arctic_dem.py # ArcticDEM tile fetch & orthometric reproject
│ ├── dem_sampler.py # Zonal statistics over building polygons
│ └── terrain_correction.py # TerrainCorrector strategies
├── visualization/ # 3-D extrusion & rendering helpers (manual QA)
├── tests/ # pytest test suite
├── environment.yml # Conda/micromamba environment spec
└── setup.sh # One-command environment setup
# 1. Create the environment (micromamba)
bash setup.sh
# 2. Activate
micromamba activate rnd-dem-imputationimport geopandas as gpd
from src.height_imputer import HeightImputer
buildings = gpd.read_file("buildings.geojson")
imputer = HeightImputer(
dem_sampling_strategy="max",
terrain_correction_strategy="buffer",
imputation_strategy="max", # recommended default
arctic_dem_resolution="2m",
earthdata_token="YOUR_TOKEN",
cache_dir="cache/",
verbose=True,
)
buildings_with_heights = imputer.impute(buildings)| Strategy | Description |
|---|---|
max (default) |
height = nanmax(osm_height, levels × floor_height, dem_height) — takes the best available estimate |
direct |
Uses abs_dem_height as-is, no coefficient scaling |
coefficient (deprecated) |
Computes k = osm_height / abs_dem_height for tagged buildings, spatially interpolates k, then estimates heights for untagged buildings |
Absolute DEM building height is always derived as:
abs_dem_height = raw_dem_sample − terrain_elevation
When use_orthometric=True (default), the DEM is converted to EGM2008 orthometric heights before sampling.
| Strategy | Description |
|---|---|
buffer |
Aggregates DEM values in a ring buffer around each building footprint |
elevation_api |
Queries Google Elevation API for ground elevation |
nasa_dtm |
Uses SRTM or NASADEM as a reference terrain surface |
| Parameter | Default | Description |
|---|---|---|
dem_sampling_strategy |
"max" |
Zonal statistic for DEM sampling |
dem_decile |
90 |
Percentile for "decile" sampling |
terrain_correction_strategy |
"buffer" |
Terrain correction method |
buffer_radius |
10 |
Ring-buffer width in metres |
imputation_strategy |
"max" |
Height imputation strategy |
floor_height |
3.0 |
Metres per floor (for building:levels fallback) |
use_orthometric |
True |
Convert DEM to EGM2008 before sampling |
arctic_dem_resolution |
"2m" |
ArcticDEM mosaic resolution |
cache_dir |
None |
Cache directory for DEM tiles |
- Python 3.11
- GDAL ≥ 3.7
proj-datawith EGM2008 grid (required for orthometric conversion)- NASA Earthdata account + token (for ArcticDEM tile download)
- Google Elevation API key (optional, for
elevation_apiterrain correction)
See environment.yml for the full dependency list.
pytest tests/Internal research module — see repository license for terms.