Skip to main content

OctreeCity

Voxel cities that stay small. OctreeCity stores a city as columns of label runs (ground up to 1 m, building up to 67 m, air above, tree canopy with air under it...). It builds adaptive octrees from them on demand, for any application: storage, ray analyses, machine learning, visualization, CFD.

All of Osaka at 1 m

All of Osaka: 556,724 buildings, 228 km² at 1 m, built in 26 s into one 37 MB file (a dense voxel grid would be 14.6 GB).

Why

Dense voxel grids (as in VoxCity) grow with volume: 1 m cells over a city is gigabytes, so people fall back to 5 m cells. City geometry is mostly vertical walls, flat roofs and layers, so OctreeCity stores runs along z. Size then follows the footprint outlines, not the volume.

20 Osaka tiles, 1 m dense grid octree columns
zipped on disk 662 kB 575 kB 228 kB
in memory 113 MB 55 MB 20 MB
build per 256 m tile 17 ms 1.2 ms

What it does

Module
columns ColumnCity: the storage format (CSR runs per column), any number of layers per column, exact round trip to dense grids
easy city_from_osm(lat, lon, size_m): one call, any place, data downloaded from OpenStreetMap
sources readers: CityGML (LoD0-2, streamed), GeoJSON, OSM Overpass JSON, footprint lists
builder CityBuilder: terrain, land cover (water, grass, roads...), tree canopies over air, buildings on the terrain
tiles tiled store (one zip, random access per tile), build_tiled in parallel, region() stitching
octree LinearOctree: Morton-ordered leaves, point location, 2:1 balance, refinement near surfaces, 2 bytes per leaf on disk
city build_city(heights, pixel_size, min_cell, max_cell): user-chosen min/max cell size in metres
adapt split-and-merge adaptation to any field (wind, sun hours, noise, ML output) with min/max size, buffer layers, cell budget, value transfer
analysis sky view factor, shadows, sun position, sun hours; surface or exact rays (light passes under canopies)
exports OBJ meshes (merged faces, one material per label), 2D/3D tensors for ML
foam CFD plugin: OpenFOAM polyMesh of the fluid cells, with hanging-node faces
viz interactive 3D (plotly): show(city), results on the street, adaptive cells on a cut
render shaded top views and sections (images)

Sky view factor and winter sun hours, downtown Osaka

Install

pip install octreecity              # core: storage, builders, analysis, exports
pip install "octreecity[viz]"       # + interactive 3D views and images
pip install "octreecity[notebook]"  # + JupyterLab, to run the tutorial notebook

From source: git clone https://github.com/MahmoudAbdelRahman/octreecity && cd octreecity && uv sync.

Start in one minute

from octreecity.easy import city_from_osm
from octreecity.analysis import street_points, sky_view_factor

city = city_from_osm(37.4979, 127.0276, size_m=800)   # any place: OSM buildings, land cover, trees, roads
pts, _ = street_points(city, every=2)
svf = sky_view_factor(city, pts)

Notebook: notebooks/octreecity_quickstart.ipynb (3D views, step by step). Full docs: quickstart, 3D views, inputs, analysis, octrees and adaptation, exports, whole cities, command line, file formats.

Gangnam from one call

Run the notebook (and demo it without surprises)

cd octreecity
./demo.sh

demo.sh installs everything and opens the quickstart notebook in the project's own JupyterLab. That JupyterLab includes the plotly plugin, so the 3D views draw offline, without a "trust" step. In VS Code, open the notebook and choose the project's .venv kernel.

To avoid blank 3D views:

  • Start Jupyter from the project (./demo.sh or uv run jupyter lab), not with uv run --with jupyterlab .... That starts JupyterLab from a separate environment without the plotly plugin.
  • The notebook's first cell calls setup_notebook(). It also sends each view as a web page, so other front ends (classic Jupyter, nbviewer) still show it when online.
  • Before a talk, run all cells once (Kernel > Restart and Run All, about 40 s). The OSM download is then cached in data/, and the demo works with no internet.
  • Backup: a web-page version of the notebook can be built with uv run python scripts/notebook_report.py (writes outputs/report/quickstart_page.html).

Use with your own data

from octreecity.sources import read_citygml
from octreecity.builder import CityBuilder
from octreecity.analysis import street_points, sky_view_factor

bld = read_citygml("buildings.gml.gz").clip(x0, y0, x0 + 1000, y0 + 1000)
b = CityBuilder(x0, y0, 1000, 1000, cell=1.0)
b.add_terrain(dem)             # raster or callable(x, y), metres
b.add_buildings(bld)
city = b.build()               # ColumnCity
city.save("city.npz")

pts, _ = street_points(city, every=2)
svf = sky_view_factor(city, pts)
tree = city.to_octree(5)       # adaptive cells, 1 m to 32 m

Command line:

octreecity tiles --wkb-pickle buildings.pkl.gz --cell 1 -o city.ocz
octreecity info city.ocz
octreecity svf city.ocz --region 40 46 44 50 -o svf.png
octreecity sun city.npz --lat 34.69 --lon 135.5 --tz 9 --date 2026-12-21 -o sun.png
octreecity obj city.npz -o city.obj
octreecity foam city.npz --max-cell 16 --near 8 -o case/

All lengths are metres, in the projected CRS of the input data.

Status: alpha (0.1)

Works and is tested (56 tests, Python 3.10 to 3.13) on Osaka (PLATEAU) and Daejeon (V-World CityGML plus OpenStreetMap). Known gaps:

  • No DEM reader yet. The KAIST demo estimates terrain from building base heights.
  • The OpenFOAM export passes the package's own closedness and volume checks, but has not been run through OpenFOAM checkMesh yet. It takes about 24 s for 1.7 M cells (binary files).
  • Ray analyses: direct sun and sky visibility only (no reflections or diffuse light), trees opaque, grid north taken as true north.
  • The tiled builder takes buildings and land cover, not yet trees or terrain.
  • File formats may still change before 1.0.

Data credits

Demo data, not included in the repository: PLATEAU (MLIT Japan) for Osaka, V-World (Korea) for Daejeon buildings, and © OpenStreetMap contributors (ODbL) for land cover, trees and roads in the KAIST images.

License

MIT, see LICENSE.

Metadata

Release files for octreecity 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for octreecity 0.1.0
File Size Uploaded Provenance
octreecity-0.1.0.tar.gz 47.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for octreecity 0.1.0
File Interpreter ABI Platform
octreecity-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 102.1 kB

Release files / octreecity-0.1.0.tar.gz

Download URL octreecity-0.1.0.tar.gz
Size 47.2 kB
Tags Source
SHA-256 checksum
How to use checksums
950cf0a328e2ed65197a14ea4baccdaaffd6c7a6896b3c84702d0f86e513fd97
BLAKE2b-256 checksum
How to use checksums
648afed21e78dbf9042d317459742cf32c427fe82a80cbaf10875b2224a48fbf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / octreecity-0.1.0-py3-none-any.whl

Download URL octreecity-0.1.0-py3-none-any.whl
Size 54.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ccf5cf81fc6ac8ff42a5073a84b3a1cd16630b690bd91472863a86d3af295e74
BLAKE2b-256 checksum
How to use checksums
35a5851d56c03361dc8008766c4dec0720b9726d2133bfcb6525c5ed43685a2c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for octreecity 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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page