Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1,217 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VoxCity

Generate grid-based 3D city models anywhere on Earth from open geospatial data —
then simulate solar, view, and microclimate.

PyPI version Python versions License Downloads
Documentation Status codecov DOI GitHub stars

🚀 Try in Colab · 📖 Docs · 🎬 Video · 📄 Paper · 💬 Issues

VoxCity pipeline: download geospatial layers, voxelize each urban element, integrate them into a voxel city model, and simulate the urban environment (e.g., solar irradiance and green view index)


Table of Contents


Why VoxCity?

VoxCity turns open geospatial data into a single, simulation-ready 3D voxel model of any place on Earth — in a few lines of Python.

  • 🌍 Global by default — automatically selects the best open data source for any location worldwide.
  • 🧱 One integrated voxel model — buildings, trees, land cover, and terrain fused into a single semantic 3D grid.
  • ☀️ Built-in simulation — solar irradiance, sky/green view index, landmark visibility, and network analysis.
  • 🔄 Export anywhere — ENVI-met (INX/EDB), OBJ (Blender/Rhino/Twinmotion), and MagicaVoxel (VOX).
  • 🧩 Reproducible & open — open data with documented provenance and a peer-reviewed method.

The generator module downloads building heights, tree canopy heights, land cover, and terrain elevation for a target area and voxelizes them into an integrated voxel city model. The simulator module runs environmental analyses such as solar radiation and view index. Try it in the Google Colab Demo or locally, and see the documentation for the full API reference and tutorials.

Gallery


☀️ Solar irradiance

👁️ Sky / Green view index

🌡️ ENVI-met microclimate

🏙️ OBJ in Rhino / Blender

🧊 MagicaVoxel

🕸️ Network analysis

Quick Start

pip install voxcity   # see Installation for GDAL + Earth Engine setup
import ee
from voxcity.generator import get_voxcity

ee.Initialize(project="your-project-id")

# A ~450 m box in Seattle (lon, lat corners)
rectangle_vertices = [
    (-122.3359, 47.5983), (-122.3359, 47.6028),
    (-122.3292, 47.6028), (-122.3292, 47.5983),
]

# Auto-selects the best data sources for the location
voxcity = get_voxcity(rectangle_vertices, meshsize=5)

That's it — see the Usage Guide to visualize, export, and simulate your model.

Installation

Make sure you have Python 3.12 installed. GDAL is the one dependency best installed via conda; everything else comes from pip.

For Local Environment

conda create --name voxcity python=3.12
conda activate voxcity
conda install -c conda-forge gdal timezonefinder
pip install voxcity

For Google Colab

!pip install voxcity

Setup for Earth Engine

Many data sources are served through Google Earth Engine. Set up an Earth Engine enabled Cloud Project by following the official guide, then authenticate:

# Local environment
earthengine authenticate
# Google Colab: click the displayed link, generate a token, then paste it
!earthengine authenticate --auth_mode=notebook

Tutorial

Google Colab Demos

Demo Description Link
Basic Generate a voxel city model, visualize, and export Open in Colab
ENVI-met Export Export a VoxCity model to ENVI-met INX format Open in Colab

YouTube Video

VoxCity Tutorial — Click to watch on YouTube

Tutorial video by Xiucheng Liang

Key Features

  • Integration of Multiple Data Sources:
    Combines building footprints, land cover data, canopy height maps, and DEMs to generate a consistent 3D voxel representation of an urban scene.

  • Flexible Input Sources:
    Supports various building and terrain data sources including:

    • Building Footprints: OpenStreetMap, Overture, EUBUCCO, Microsoft Building Footprints, Open Building 2.5D
    • Land Cover: UrbanWatch, OpenEarthMap Japan, ESA WorldCover, ESRI Land Cover, Dynamic World, OpenStreetMap
    • Canopy Height: High Resolution 1m Global Canopy Height Maps, ETH Global Sentinel-2 10m
    • DEM: DeltaDTM, FABDEM, NASA, COPERNICUS, and more

    Detailed information about each data source can be found in the References of Data Sources section.

  • Customizable Domain and Resolution:
    Easily define a target area by drawing a rectangle on a map or specifying center coordinates and dimensions. Adjust the mesh size to meet resolution needs.

  • Integration with Earth Engine:
    Leverages Google Earth Engine for large-scale geospatial data processing (authentication and project setup required).

  • Output Formats:

    • ENVI-MET: Export INX and EDB files suitable for ENVI-MET microclimate simulations.
    • MagicaVoxel: Export vox files for 3D editing and visualization in MagicaVoxel.
    • OBJ: Export wavefront OBJ for rendering and integration into other workflows.
  • Analytical Tools:

    • View Index Simulations: Compute sky view index (SVI) and green view index (GVI) from a specified viewpoint.
    • Landmark Visibility Maps: Assess the visibility of selected landmarks within the voxelized environment.

Usage Guide

Authenticate Earth Engine, define an area, generate the model, then export or simulate. The core path is shown open; advanced steps are collapsed.

1. Authenticate Earth Engine

import ee
ee.Authenticate()
ee.Initialize(project='your-project-id')

2. Define Target Area

🗺️ Three ways to define your target area (coordinates, draw, or center + size)

You can define your target area in three ways:

Option 1: Direct Coordinate Input

Define the target area by directly specifying the coordinates of the rectangle vertices.

rectangle_vertices = [
    (-122.33587348582083, 47.59830044521263),  # Southwest corner (longitude, latitude)
    (-122.33587348582083, 47.60279755390168),  # Northwest corner (longitude, latitude) 
    (-122.32922451417917, 47.60279755390168),  # Northeast corner (longitude, latitude)
    (-122.32922451417917, 47.59830044521263)   # Southeast corner (longitude, latitude)
]

Option 2: Draw a Rectangle (for Jupyter Notebook)

Use the GUI map interface to draw a rectangular domain of interest.

from voxcity.geoprocessor.draw import draw_rectangle_map_cityname

cityname = "tokyo"
m, rectangle_vertices = draw_rectangle_map_cityname(cityname, zoom=15)
m

Option 3: Specify Center and Dimensions (for Jupyter Notebook)

Choose the width and height in meters and select the center point on the map.

from voxcity.geoprocessor.draw import center_location_map_cityname

width = 500
height = 500
m, rectangle_vertices = center_location_map_cityname(cityname, width, height, zoom=15)
m

Draw Rectangle on Map GUI

Coordinate system

VoxCity arrays follow one convention everywhere, and every saved file declares it:

  • Array axes: grid[i, j] / voxels[i, j, k] with axis 0 = north (row 0 is the south edge, i increases northward), axis 1 = east, axis 2 = up. Note this differs from the common (x=east, y=north) habit — component 0 of a direction vector is the northward one.
  • Azimuths are compass degrees clockwise from north, toward directions. Meteorological from-directions must be converted first — e.g. for wind: az_toward = az_from + 180, then d = voxcity.direction_to_axis_vector(az_toward) gives (d_north, d_east, d_up).
  • Rotated AOIs: files store the axes / rotation_angle attribute pair. The axis tokens apply in the frame rotated clockwise by rotation_angle degrees; for axis-aligned AOIs (rotation_angle = 0) they are literally true.
  • Vertical datum: k indexes cells above the domain base plane; a cell centre sits at height (k + 0.5) * meshsize. The DEM is filled in as solid voxels, so height-above-ground requires subtracting local terrain.
  • Self-describing files: HDF5 outputs are voxcity_results.v3 — they carry axes = "north,east,up", rotation_angle, and the rectangle_vertices geometry. Assert the contract from any consumer with voxcity.check_axes(path). Files from VoxCity 1.x must be converted once: python -m voxcity.migrate old_results.h5.
  • Named-dimension access: prefer city.to_xarray() over raw-array indexing — dims are ("north", "east", "up"), so ds.dem.isel(north=0) is unambiguously the south edge and silent transposes are impossible.

3. Set Parameters

Define mesh size (required) and optional data sources:

meshsize = 5  # Grid cell size in meters (required)

# Optional: Specify output directory and other settings
kwargs = {
    "output_dir": "output",   # Directory to save output files
    "dem_interpolation": True # Enable DEM interpolation
}

4. Get voxcity Output

Generate voxel data grids and a corresponding building GeoDataFrame.

Option 1: Automatic Mode (Recommended)

Data sources are automatically selected based on location:

from voxcity.generator import get_voxcity

# Auto mode: all data sources selected automatically based on location
voxcity = get_voxcity(
    rectangle_vertices,
    meshsize,
    **kwargs
)

Option 2: Custom Mode

Specify data sources explicitly:

# Custom mode: specify all data sources
voxcity = get_voxcity(
    rectangle_vertices,
    meshsize,
    building_source='OpenStreetMap',
    land_cover_source='OpenStreetMap',
    canopy_height_source='High Resolution 1m Global Canopy Height Maps',
    dem_source='DeltaDTM',
    **kwargs
)

Option 3: Hybrid Mode

Specify some sources, auto-select others:

# Hybrid mode: specify building source, auto-select others
voxcity = get_voxcity(
    rectangle_vertices,
    meshsize,
    building_source='Overture',  # Custom
    # land_cover_source, canopy_height_source, dem_source auto-selected
    **kwargs
)

Interactive 3D Demo (Plotly)

5. Exporting Files

Export your model to the format your downstream tool expects — each target is collapsed below.

🌡️ ENVI-met (INX/EDB) — microclimate simulation

ENVI-MET INX/EDB Files:

ENVI-MET is an advanced microclimate simulation software specialized in modeling urban environments. It simulates the interactions between buildings, vegetation, and various climate parameters like temperature, wind flow, humidity, and radiation. The software is used widely in urban planning, architecture, and environmental studies (Commercial, offers educational licenses).

from voxcity.exporter.envimet import export_inx, generate_edb_file

envimet_kwargs = {
    "output_directory": "output",            # Directory where output files will be saved
    "file_basename": "voxcity",              # Base name (without extension) for INX
    "author_name": "your name",              # Name of the model author
    "model_description": "generated with voxcity",  # Description for the model
    "domain_building_max_height_ratio": 2,   # Max ratio between domain height and tallest building
    "useTelescoping_grid": True,             # Enable telescoping grid
    "verticalStretch": 20,                   # Vertical grid stretching factor (%)
    "min_grids_Z": 20,                       # Minimum number of vertical grid cells
    "lad": 1.0                               # Leaf Area Density (m2/m3) for EDB generation
}

# Optional: specify land cover source used for export (otherwise taken from voxcity.extras when available)
land_cover_source = 'OpenStreetMap'

# Export INX by passing the VoxCity object directly
export_inx(
    voxcity,
    output_directory=envimet_kwargs["output_directory"],
    file_basename=envimet_kwargs["file_basename"],
    land_cover_source=land_cover_source,
    author_name=envimet_kwargs["author_name"],
    model_description=envimet_kwargs["model_description"],
    domain_building_max_height_ratio=envimet_kwargs["domain_building_max_height_ratio"],
    useTelescoping_grid=envimet_kwargs["useTelescoping_grid"],
    verticalStretch=envimet_kwargs["verticalStretch"],
    min_grids_Z=envimet_kwargs["min_grids_Z"],
)

# Generate plant database (EDB) for vegetation
generate_edb_file(lad=envimet_kwargs["lad"])

Generated 3D City Model on Envi-MET GUI

Example Output Exported in INX and Inported in ENVI-met

🏙️ OBJ — Blender / Rhino / Twinmotion

OBJ Files:

from voxcity.exporter.obj import export_obj

output_directory = "output"  # Directory where output files will be saved
output_file_name = "voxcity" # Base name for the output OBJ file
# Pass the VoxCity object directly (voxel size inferred)
export_obj(voxcity, output_directory, output_file_name)

The generated OBJ files can be opened and rendered in the following 3D visualization software:

  • Twinmotion: Real-time visualization tool (Free for personal use)
  • Blender: Professional-grade 3D creation suite (Free)
  • Rhino: Professional 3D modeling software (Commercial, offers educational licenses)

OBJ 3D City Model Rendered in Rhino

Example Output Exported in OBJ and Rendered in Rhino

📥 Import Rhino / OBJ buildings into a model

Importing Rhino Models (OBJ):

You can import buildings authored in Rhino into a VoxCity model:

from voxcity.importer import add_buildings_from_obj

voxcity = add_buildings_from_obj(
    voxcity, "design.obj",
    anchor_lonlat=(139.7536, 35.6841),  # world (lon, lat) of the model anchor
    anchor_elevation=12.0,              # world elevation (m) of the anchor
    rotation=0.0, units="m",
)

See docs/guides/rhino_obj_import.md for the full Rhino export guide.

🧊 MagicaVoxel (VOX) — voxel art editor

MagicaVoxel VOX Files:

MagicaVoxel is a lightweight and user-friendly voxel art editor. It allows users to create, edit, and render voxel-based 3D models with an intuitive interface, making it perfect for modifying and visualizing voxelized city models. The software is free and available for Windows and Mac.

from voxcity.exporter.magicavoxel import export_magicavoxel_vox

output_path = "output"
base_filename = "voxcity"
# Pass the VoxCity object directly
export_magicavoxel_vox(voxcity, output_path, base_filename=base_filename)

Generated 3D City Model on MagicaVoxel GUI

Example Output Exported in VOX and Rendered in MagicaVoxel

6. Additional Use Cases

Run environmental analyses directly on the generated voxel model. Each is collapsed below.

☀️ Solar irradiance (instantaneous & cumulative)

Compute Solar Irradiance:

from voxcity.simulator.solar import get_global_solar_irradiance_using_epw

solar_kwargs = {
    "download_nearest_epw": True,  # Whether to automatically download nearest EPW weather file based on location from Climate.OneBuilding.Org
    # "epw_file_path": "./output/new.york-downtown.manhattan.heli_ny_usa_1.epw",  # Path to EnergyPlus Weather (EPW) file containing climate data. Set if you already have an EPW file.
    "calc_time": "01-01 12:00:00",  # Time for instantaneous calculation in format "MM-DD HH:MM:SS"
    "view_point_height": 1.5,  # Height of view point in meters for calculating solar access. Default: 1.5 m
    "tree_k": 0.6,    # Static extinction coefficient - controls how much sunlight is blocked by trees (higher = more blocking)
    "tree_lad": 1.0,    # Leaf area density of trees - density of leaves/branches that affect shading (higher = denser foliage)
    "colormap": 'magma',       # Matplotlib colormap for visualization. Default: 'viridis'
    "obj_export": True,        # Whether to export results as 3D OBJ file
    "output_directory": 'output/test',  # Directory for saving output files
    "output_file_name": 'instantaneous_solar_irradiance',  # Base filename for outputs (without extension)
    "alpha": 1.0,             # Transparency of visualization (0.0-1.0)
    "vmin": 0,               # Minimum value for colormap scaling in visualization
    # "vmax": 900,             # Maximum value for colormap scaling in visualization
}

# Compute global solar irradiance map (direct + diffuse radiation)
solar_grid = get_global_solar_irradiance_using_epw(
    voxcity,                             # VoxCity object containing voxel data and metadata
    calc_type='instantaneous',           # Calculate instantaneous irradiance at specified time
    direct_normal_irradiance_scaling=1.0, # Scaling factor for direct solar radiation (1.0 = no scaling)
    diffuse_irradiance_scaling=1.0,      # Scaling factor for diffuse solar radiation (1.0 = no scaling)
    **solar_kwargs                       # Pass all the parameters defined above
)

# Adjust parameters for cumulative calculation
solar_kwargs["start_time"] = "01-01 01:00:00" # Start time for cumulative calculation
solar_kwargs["end_time"] = "01-31 23:00:00" # End time for cumulative calculation
solar_kwargs["output_file_name"] = 'cumulative_solar_irradiance'  # Base filename for outputs (without extension)

# Calculate cumulative solar irradiance over the specified time period
cum_solar_grid = get_global_solar_irradiance_using_epw(
    voxcity,                             # VoxCity object containing voxel data and metadata
    calc_type='cumulative',              # Calculate cumulative irradiance over time period instead of instantaneous
    direct_normal_irradiance_scaling=1.0, # Scaling factor for direct solar radiation (1.0 = no scaling)
    diffuse_irradiance_scaling=1.0,      # Scaling factor for diffuse solar radiation (1.0 = no scaling)
    **solar_kwargs                       # Pass all the parameters defined above
)

Solar Irradiance Maps Rendered in Rhino

Example Results Saved as OBJ and Rendered in Rhino

👁️ Green View Index (GVI) & Sky View Index (SVI)

Compute Green View Index (GVI) and Sky View Index (SVI):

from voxcity.simulator.view import get_view_index

view_kwargs = {
    "view_point_height": 1.5,      # Height of observer viewpoint in meters
    "colormap": "viridis",         # Colormap for visualization
    "obj_export": True,            # Whether to export as OBJ file
    "output_directory": "output",  # Directory to save output files
    "output_file_name": "gvi"      # Base filename for outputs
}

# Compute Green View Index using mode='green'
gvi_grid = get_view_index(voxcity, mode='green', **view_kwargs)

# Adjust parameters for Sky View Index
view_kwargs["colormap"] = "BuPu_r"
view_kwargs["output_file_name"] = "svi"
view_kwargs["elevation_min_degrees"] = 0 # Start ray-tracing from the horizon

# Compute Sky View Index using mode='sky'
svi_grid = get_view_index(voxcity, mode='sky', **view_kwargs)

View Index Maps Rendered in Rhino

Example Results Saved as OBJ and Rendered in Rhino

🗼 Landmark visibility map

Landmark Visibility Map:

from voxcity.simulator.view import get_landmark_visibility_map

# Dictionary of parameters for landmark visibility analysis
landmark_kwargs = {
    "view_point_height": 1.5,                 # Height of observer viewpoint in meters
    "colormap": "cool",                       # Colormap for visualization
    "obj_export": True,                       # Whether to export as OBJ file
    "output_directory": "output",             # Directory to save output files
    "output_file_name": "landmark_visibility" # Base filename for outputs
}
landmark_vis_map, _ = get_landmark_visibility_map(voxcity, voxcity.extras.get('building_gdf'), **landmark_kwargs)

Landmark Visibility Map Rendered in Rhino

Example Result Saved as OBJ and Rendered in Rhino

🕸️ Network analysis (map values onto a street network)

Network Analysis:

from voxcity.geoprocessor.network import get_network_values

network_kwargs = {
    "network_type": "walk",        # Type of network to download from OSM (walk, drive, all, etc.)
    "colormap": "magma",          # Matplotlib colormap for visualization
    "vis_graph": True,            # Whether to display the network visualization
    "vmin": 0.0,                  # Minimum value for color scaling
    "vmax": 600000,               # Maximum value for color scaling
    "edge_width": 2,              # Width of network edges in visualization
    "alpha": 0.8,                 # Transparency of network edges
    "zoom": 16                    # Zoom level for basemap
}

G, edge_gdf = get_network_values(
    cum_solar_grid,               # Grid of cumulative solar irradiance values
    rectangle_vertices,           # Coordinates defining simulation domain boundary
    meshsize,                     # Size of each grid cell in meters
    value_name='Cumulative Global Solar Irradiance (W/m²·hour)',  # Label for values in visualization
    **network_kwargs              # Additional visualization and network parameters
)

Example of Graph Output

Cumulative Global Solar Irradiance (kW/m²·hour) on Road Network

VoxCity Standard Land Cover Classes (used in voxel grids)

Index Class Index Class
1 Bareland 8 Mangrove
2 Rangeland 9 Water
3 Shrub 10 Snow and ice
4 Agriculture land 11 Developed space
5 Tree 12 Road
6 Moss and lichen 13 Building
7 Wet land 14 No Data

References of Data Sources

VoxCity integrates many open datasets. Expand for full provenance (coverage, resolution, and acquisition).

📚 Full data source tables (buildings, canopy height, land cover, terrain)

Building

Dataset Spatial Coverage Source/Data Acquisition
OpenStreetMap Worldwide (24% completeness in city centers) Volunteered / updated continuously
Microsoft Building Footprints North America, Europe, Australia Prediction from satellite or aerial imagery / 2018-2019 for majority of the input imagery
Open Buildings 2.5D Temporal Dataset Africa, Latin America, and South and Southeast Asia Prediction from satellite imagery / 2016-2023
EUBUCCO v0.1 27 EU countries and Switzerland (378 regions and 40,829 cities) OpenStreetMap, government datasets / 2003-2021 (majority is after 2019)
UT-GLOBUS Worldwide (more than 1200 cities or locales) Prediction from building footprints, population, spaceborne nDSM / not provided
Overture Maps Worldwide OpenStreetMap, Esri Community Maps Program, Google Open Buildings, etc. / updated continuously

Tree Canopy Height

Dataset Coverage Resolution Source/Data Acquisition
High Resolution 1m Global Canopy Height Maps Worldwide 1 m Prediction from satellite imagery / 2009 and 2020 (80% are 2018-2020)
ETH Global Sentinel-2 10m Canopy Height (2020) Worldwide 10 m Prediction from satellite imagery / 2020

Land Cover

Dataset Spatial Coverage Resolution Source/Data Acquisition
ESA World Cover 10m 2021 V200 Worldwide 10 m Prediction from satellite imagery / 2021
ESRI 10m Annual Land Cover (2017-2023) Worldwide 10 m Prediction from satellite imagery / 2017-2023
Dynamic World V1 Worldwide 10 m Prediction from satellite imagery / updated continuously
OpenStreetMap Worldwide - (Vector) Volunteered / updated continuously
OpenEarthMap Japan Japan ~1 m Prediction from aerial imagery / 1974-2022 (mostly after 2018 in major cities)
UrbanWatch 22 major cities in the US 1 m Prediction from aerial imagery / 2014–2017

Terrain Elevation

Dataset Coverage Resolution Source/Data Acquisition
FABDEM Worldwide 30 m Correction of Copernicus DEM using canopy height and building footprints data / 2011-2015 (Copernicus DEM)
DeltaDTM Worldwide (Only for coastal areas below 10m + mean sea level) 30 m Copernicus DEM, spaceborne LiDAR / 2011-2015 (Copernicus DEM)
USGS 3DEP 1m DEM United States 1 m Aerial LiDAR / 2004-2024 (mostly after 2015)
England 1m Composite DTM England 1 m Aerial LiDAR / 2000-2022
Australian 5M DEM Australia 5 m Aerial LiDAR / 2001-2015
RGE Alti France 1 m Aerial LiDAR

Community & Contributing

VoxCity is open source and community-driven — contributions of all kinds are welcome.

  • 🐛 Report bugs or request features via the issue tracker.

  • 💬 Ask questions and share your work in Discussions.

  • 🤝 Contribute code — see CONTRIBUTING.rst. To get started:

    git clone https://github.com/kunifujiwara/VoxCity.git
    cd VoxCity
    pip install -r requirements_dev.txt
    pytest

Please also review our Code of Conduct.

Citation

Please cite the paper if you use voxcity in a scientific publication:

Fujiwara K, Tsurumi R, Kiyono T, Fan Z, Liang X, Lei B, Yap W, Ito K, Biljecki F., 2026. VoxCity: A Seamless Framework for Open Geospatial Data Integration, Grid-Based Semantic 3D City Model Generation, and Urban Environment Simulation. Computers, Environment and Urban Systems, 123, p.102366. https://doi.org/10.1016/j.compenvurbsys.2025.102366

@article{fujiwara2025voxcity,
  title={VoxCity: A Seamless Framework for Open Geospatial Data Integration, Grid-Based Semantic 3D City Model Generation, and Urban Environment Simulation},
  author={Fujiwara, Kunihiko and Tsurumi, Ryuta and Kiyono, Tomoki and Fan, Zicheng and Liang, Xiucheng and Lei, Binyu and Yap, Winston and Ito, Koichi and Biljecki, Filip},
  journal={Computers, Environment and Urban Systems},
  volume = {123},
  pages = {102366},
  year = {2026},
  doi = {10.1016/j.compenvurbsys.2025.102366}
}

Credit

This package was created with Cookiecutter and the audreyr/cookiecutter-pypackage project template.




Logo