zero2geospatial3d-sdk
Headless 3D terrain and building analysis in Python: sun hours, shadows, sky view factor, solar PV, UTCI/PET comfort, wind, noise and air-quality screening, daylight rules, terrain sections, flooding and cut/fill.
zero2geospatial3d-sdk is the scriptable, QGIS-free engine behind the
02 Geo3D Analyzer QGIS plugin (zero2geospatial3d). The plugin runs its
analyses on the GPU in a browser; this package ports the same mathematics to
NumPy so they run in notebooks, batch jobs, servers and CI pipelines. Scene
packages are interchangeable: a scene exported by the plugin loads in Python,
and a scene built in Python opens in the bundled browser viewer.
Installation
# Core: NumPy only
pip install zero2geospatial3d-sdk
# Optional geospatial extras (GeoTIFF output with rasterio, pyproj, shapely, matplotlib)
pip install "zero2geospatial3d-sdk[geo]"
Python 3.9 to 3.13. The import name is zero2geospatial3d.
Quickstart (runs offline)
import numpy as np
from zero2geospatial3d import Building, Scene, shading, comfort, terrain
from zero2geospatial3d.results import aggregate_by_id
# A 200 m x 200 m level site in Izmir (UTC+3) with a 2 m grid and two buildings.
scene = Scene.flat(200, 200, cell=2.0, lat=38.42, lon=27.14, utc_offset=3.0)
for cx, h in ((-30, 24.0), (30, 12.0)):
ring = [[cx - 15, -10], [cx + 15, -10], [cx + 15, 10], [cx - 15, 10], [cx - 15, -10]]
scene.buildings.append(Building([[ring]], height=h))
surface = scene.surface() # terrain + buildings as a Grid
_, ids = scene.building_rasters() # building id per cell (0 = ground)
# BRE 209: sun hours on 21 March
hours = shading.sun_hours(surface, scene.lat, scene.lon, scene.utc_offset, month=3, day=21)
open_ground = hours[ids == 0]
print(f"open ground with >= 2 h of sun: {100 * np.mean(open_ground >= 2):.0f} %")
# Sky view factor and per-building roof statistics
svf = shading.sky_view_factor(surface, n_azimuths=16)
print(aggregate_by_id(ids, svf, cell_area=4.0)[1]["mean"])
# Thermal comfort for one set of conditions
print(comfort.utci(32.0, 55.0, 1.5, 40.0), comfort.pet(32.0, 55.0, 1.5, 40.0))
# Terrain: slope, flooding and earthworks on the DEM
slope, aspect = terrain.slope_aspect(scene.terrain)
pad = [[-20, -20], [20, -20], [20, 20], [-20, 20], [-20, -20]]
print(terrain.cut_fill(scene.terrain, pad, design_level=0.5).fill)
Command line
zero2geospatial3d sun --lat 38.42 --lon 27.14 --date 2026-06-21 --tz 3
zero2geospatial3d comfort --ta 32 --tr 55 --v 1.5 --rh 40
zero2geospatial3d stations --lat 41.01 --lon 28.97 -n 3 # nearest TMYx stations
zero2geospatial3d epw --lat 41.01 --lon 28.97 --out istanbul.epw # download the nearest one
zero2geospatial3d demo --out demo_scene # synthetic scene package
zero2geospatial3d osm --lat 38.4237 --lon 27.1428 --half-size 250 --out izmir_scene
zero2geospatial3d analyze demo_scene sun-hours --date 2026-03-21 --out sun.asc
zero2geospatial3d analyze demo_scene svf --azimuths 36 --out svf.npy
zero2geospatial3d analyze demo_scene irradiation --epw istanbul.epw --out kwh.tif # .tif needs [geo]
zero2geospatial3d analyze demo_scene flood --level 12 --out depth.asc
zero2geospatial3d view demo_scene --results results/ # bundled 3D viewer
analyze supports sun-hours, shadow, svf, viewshed, irradiation,
slope, aspect, hillshade and flood, and prints summary statistics as
JSON. view serves the plugin's three.js viewer on 127.0.0.1 (your data
stays on your computer); results sent from the viewer are saved to --results.
How the 3D analyses work headlessly
The plugin renders depth maps of the full 3D scene on the GPU. The SDK works on
a 2.5-D surface: the DEM plus the heights of buildings (and optionally tree
crowns) rasterised onto the same grid. Sun visibility is tested by marching
rays across this surface with bilinear sampling, the sky view factor is
1 - mean(sin^2(horizon)) over azimuth sectors, and irradiation combines
direct sun (from EPW or clear-sky sun-direction bins), isotropic diffuse sky
and ground reflection, exactly as the plugin's solarRadiation runner does.
Overhangs and facade receivers are not represented in 2.5-D.
Public API
| Module | Main contents |
|---|---|
grid |
Grid (values, cell, min_x, max_y; sample, coords, index_of), make_grid |
scene |
Scene (flat, from_osm, surface, building_rasters, tree_raster, export), Building, Tree, Road, load_scene, rasterize_polygons |
solar |
solar_position, sunrise_sunset, sun_path, sky_hemisphere, sun_vector, day_of_year |
shading |
shadow_mask, sun_hours, shadow_study, horizon_angles, sky_view_factor, viewshed, directional_irradiation, solar_irradiation, pv_yield |
comfort |
utci, pet, mean_radiant_temperature, sky_temperature, projected_area_factor, utci_category, pet_category |
weather |
Weather, parse_epw, read_epw, monthly_summary, wind_rose, clear_sky_year, annual_sun_bins, conditions_at, typical_doy |
epw |
nearest_stations, load_index, download_station, extract_epw, read_header |
microclimate |
surface_temperature, canopy_transmittance, canopy_cooling_grid, diurnal_point_profile, SURFACE_MATERIALS |
wind |
wind_ratio, lawson_class, OPEN_PEDESTRIAN_FACTOR |
morphology |
distance_to_built, macdonald, classify_lcz, block_indicators |
dispersion |
ventilation_efficiency, pollutant_dispersion, ventilation_class, air_quality_class |
acoustics |
noise_propagation, building_facade_noise, maekawa_diffraction, noise_class |
road_sources |
sample_road_lines, street_centrelines, road_weight |
daylight |
prepare_rule, check_rule, vsc_long, allowed_angle, reach25, wall_samples (BRE 209) |
urban_form |
green_view_index, solar_envelope, gvi_class |
walkability |
pedestrian_walkability_index, find_cool_route, subscores |
terrain |
slope_aspect, hillshade, contours, profile, flood, cut_fill, balanced_level, curvature, tpi, ruggedness, aspect_classes, flow_accumulation, wetness, crop_grid |
classify |
equal_breaks, quantile_breaks, jenks_breaks, ramp_stops, ramp_color, RAMPS |
nsga2 |
Problem, nsga2, dominates, non_dominated_sort, crowding_distance |
osm, osm_tags |
fetch (Overpass, timeouts, cache), payload_to_features, building_height, road_traffic |
geo |
lonlat_to_local, local_to_lonlat, bbox_around, utm_epsg_for, grid_shape |
results |
aggregate_by_id, grid_stats, write_ascii_grid, write_grid_npy, write_geotiff, save_result |
server |
serve_scene, ViewerServer, viewer_root |
All grids are NumPy arrays of shape (rows, cols) with row 0 at the north
edge; coordinates are local metres (x east, y north). Angles from solar are
radians with azimuth clockwise from north.
Validation
The test suite reproduces the numeric assertions of the plugin's JavaScript
tests (tests/js/*.test.mjs): the NREL SPA reference sun position, UTCI and
PET reference values, EPW parsing and wind roses, surface energy balance and
canopy cooling, Maekawa diffraction and traffic-noise scaling, ventilation and
dispersion, BRE 209 VSC closed forms, solar envelopes and green view, terrain
curvature, TPI, TRI, flow accumulation and wetness, flood and cut/fill
volumes, Jenks breaks, and the seeded NSGA-II run. The shading engines are
checked against closed forms (canyon sky view factor, wall shadow length).
Development and testing
git clone https://github.com/YusufEminoglu/zero2geospatial3d_sdk.git
cd zero2geospatial3d_sdk
pip install -e ".[dev]"
python -m pytest --cov=zero2geospatial3d
python -m ruff check .
python -m mypy src
Academic citation
@software{eminoglu_zero2geospatial3d_sdk,
author = {Eminoğlu, Yusuf},
title = {zero2geospatial3d-sdk: headless 3D terrain and building analysis in Python},
year = {2026},
version = {0.1.0},
url = {https://github.com/YusufEminoglu/zero2geospatial3d_sdk}
}
See also CITATION.cff.
License
MIT, see LICENSE. The bundled viewer includes three.js (MIT) and the UTCI polynomial follows pythermalcomfort (MIT); the station index credits Climate.OneBuilding.Org. Details in THIRD_PARTY_NOTICES.md.
Metadata
Release files for zero2geospatial3d-sdk 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| zero2geospatial3d_sdk-0.1.0.tar.gz | 1.2 MB | With provenance | Details for zero2geospatial3d_sdk-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| zero2geospatial3d_sdk-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for zero2geospatial3d_sdk-0.1.0-py3-none-any.whl |
Total release size: 2.3 MB
Release files / zero2geospatial3d_sdk-0.1.0.tar.gz
| Download URL | zero2geospatial3d_sdk-0.1.0.tar.gz |
|---|---|
| Size | 1.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6ca2bac43b3fc75d6955ba1765cc937e523b729cd77aeb2d5f2a339444acc810
|
|
BLAKE2b-256 checksum How to use checksums |
0d1b0ea233093195303c4ff45e562f71fe770d126bf507713fce6839d6a82090
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 8, 2026.
Transparency logRelease files / zero2geospatial3d_sdk-0.1.0-py3-none-any.whl
| Download URL | zero2geospatial3d_sdk-0.1.0-py3-none-any.whl |
|---|---|
| Size | 1.2 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b5610ec517169ff04dacc837e86b73df6613d7453f1a6c9ff0a105e15ae3a395
|
|
BLAKE2b-256 checksum How to use checksums |
f257806afe229b8f1010682a16863edf504a3421e8539b16d486c1e745fe5a91
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 8, 2026.
Transparency logSecurity for zero2geospatial3d-sdk 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
Both files in this release have been uploaded with provenance metadata.
Attestation for zero2geospatial3d_sdk-0.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 8, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.