voxcity.generator¶

VoxCity generator subpackage.

This package organizes the voxel city generation pipeline into focused modules while preserving the original public API under voxcity.generator.

Orientation contract: - All 2D grids use uv_m/SOUTH_UP orientation (axis 0 = u/north, row 0 = southern origin edge; axis 1 = v/east). - 3D indexing follows (row, col, z) = (north→south, west→east, ground→up).

Submodules¶

Attributes¶

Classes¶

Functions¶

get_voxcity(rectangle_vertices, meshsize[, ...])

Generate a VoxCity model with automatic or custom data source selection.

get_voxcity_CityGML(rectangle_vertices, ...[, ...])

auto_select_data_sources(rectangle_vertices)

Automatically choose data sources for buildings, land cover, canopy height, and DEM

get_land_cover_grid(rectangle_vertices, meshsize, ...)

get_building_height_grid(rectangle_vertices, meshsize, ...)

get_canopy_height_grid(rectangle_vertices, meshsize, ...)

get_dem_grid(rectangle_vertices, meshsize, source, ...)

save_voxcity(output_path, city)

Save a VoxCity instance to disk.

load_voxcity(input_path, *[, trusted])

Load a VoxCity instance from a file.

save_h5(output_path, city)

Save a VoxCity model to an HDF5 file (no simulation results).

load_h5(input_path)

Load a VoxCity model from an HDF5 file.

save_results_h5(output_path, city[, ground_results, ...])

Save a VoxCity model and simulation results to an HDF5 file.

load_results_h5(input_path)

Load a VoxCity model and simulation results from an HDF5 file.

update_voxcity(→ voxcity.models.VoxCity)

Update a VoxCity object with new grid data and regenerate the VoxelGrid.

regenerate_voxels(→ voxcity.models.VoxCity)

Regenerate only the VoxelGrid from existing component grids.

Package Contents¶

voxcity.generator.get_voxcity(rectangle_vertices, meshsize, building_source=None, land_cover_source=None, canopy_height_source=None, dem_source=None, building_complementary_source=None, building_gdf=None, terrain_gdf=None, **kwargs)¶

Generate a VoxCity model with automatic or custom data source selection.

This function supports both auto mode and custom mode: - Auto mode: When sources are not specified (None), they are automatically selected based on location - Custom mode: When sources are explicitly specified, they are used as-is - Hybrid mode: Specify some sources and auto-select others

Parameters:
  • rectangle_vertices – List of (lon, lat) tuples defining the area of interest

  • meshsize – Grid resolution in meters (required)

  • building_source – Building base source (default: auto-selected based on location)

  • land_cover_source – Land cover source (default: auto-selected based on location)

  • canopy_height_source – Canopy height source (default: auto-selected based on location)

  • dem_source – Digital elevation model source (default: auto-selected based on location)

  • building_complementary_source – Building complementary source (default: auto-selected based on location)

  • building_gdf – Optional pre-loaded building GeoDataFrame

  • terrain_gdf – Optional pre-loaded terrain GeoDataFrame

  • **kwargs – Additional options for building, land cover, canopy, DEM, visualization, and I/O. Performance options include: - parallel_download: bool, if True downloads run concurrently (default: False) I/O options include: - output_dir: Directory for intermediate/downloaded data (default: “output”) - save_path: Full file path to save the VoxCity object (overrides output_dir default) - save_voxcity_data / save_voxctiy_data: bool flag to enable saving (default: True)

Returns:

VoxCity object containing the generated 3D city model

voxcity.generator.get_voxcity_CityGML(rectangle_vertices, land_cover_source, canopy_height_source, meshsize, url_citygml=None, citygml_path=None, **kwargs)¶
voxcity.generator.auto_select_data_sources(rectangle_vertices)¶

Automatically choose data sources for buildings, land cover, canopy height, and DEM based on the target area’s location.

Rules (heuristic, partially inferred from latest availability): - Buildings (base): ‘OpenStreetMap’. - Buildings (complementary):

  • USA, Europe, Australia -> ‘Microsoft Building Footprints’

  • England -> ‘England 1m DSM - DTM’ (height from DSM-DTM)

  • Netherlands -> ‘Netherlands 0.5m DSM - DTM’ (height from DSM-DTM)

  • Africa, South Asia, SE Asia, Latin America & Caribbean -> ‘Open Building 2.5D Temporal’

  • Otherwise -> ‘None’

  • Land cover: USA -> ‘Urbanwatch’; Japan -> ‘OpenEarthMapJapan’; otherwise ‘OpenStreetMap’. (If OSM is insufficient, consider ‘ESA WorldCover’ manually.)

  • Canopy height: ‘High Resolution 1m Global Canopy Height Maps’.

  • DEM: High-resolution where available (USA, England, Australia, France, Netherlands), else ‘FABDEM’.

Returns a dict with keys: building_source, building_complementary_source, land_cover_source, canopy_height_source, dem_source.

voxcity.generator.get_land_cover_grid(rectangle_vertices, meshsize, source, output_dir, print_class_info=True, **kwargs)¶
voxcity.generator.get_building_height_grid(rectangle_vertices, meshsize, source, output_dir, building_gdf=None, **kwargs)¶
voxcity.generator.get_canopy_height_grid(rectangle_vertices, meshsize, source, output_dir, **kwargs)¶
voxcity.generator.get_dem_grid(rectangle_vertices, meshsize, source, output_dir, **kwargs)¶
voxcity.generator.GROUND_CODE = -1¶
voxcity.generator.TREE_CODE = -2¶
voxcity.generator.BUILDING_CODE = -3¶
voxcity.generator.save_voxcity(output_path, city)¶

Save a VoxCity instance to disk.

The format is chosen automatically based on the file extension:

  • .h5 / .hdf5 → safe HDF5 format (recommended).

  • Anything else (e.g. .pkl) → legacy pickle format.

Parameters:
  • output_path (str or Path) – Destination file path.

  • city (VoxCity) – The model to save.

voxcity.generator.load_voxcity(input_path, *, trusted: bool = False)¶

Load a VoxCity instance from a file.

The format is detected automatically based on the file extension:

  • .h5 / .hdf5 → safe HDF5 format (no warning).

  • Anything else (e.g. .pkl) → legacy pickle format.

Warning

Pickle files can execute arbitrary code on load. Only load files you created yourself or received from a trusted source. Pass trusted=True to suppress this warning.

Parameters:
  • input_path (str or Path) – Path to the file.

  • trusted (bool, default False) – (Pickle only) Set to True to acknowledge the security implications of loading a pickle file and suppress the warning.

Return type:

VoxCity

voxcity.generator.save_h5(output_path, city)¶

Save a VoxCity model to an HDF5 file (no simulation results).

This is the recommended alternative to save_voxcity() (pickle-based) because HDF5 files cannot execute arbitrary code on load.

Parameters:
  • output_path (str or Path) – Destination file path (e.g. "model.h5").

  • city (VoxCity) – The VoxCity model instance.

See also

load_h5

Load a VoxCity model from an HDF5 file.

save_results_h5

Save a VoxCity model together with simulation results.

voxcity.generator.load_h5(input_path)¶

Load a VoxCity model from an HDF5 file.

This is the safe counterpart to load_voxcity() (pickle-based). Works with files written by either save_h5() or save_results_h5() — simulation result groups are simply ignored.

Parameters:

input_path (str or Path) – Path to the HDF5 file.

Returns:

The reconstructed VoxCity model.

Return type:

VoxCity

See also

save_h5

Save a VoxCity model to an HDF5 file.

load_results_h5

Load a VoxCity model together with simulation results.

voxcity.generator.save_results_h5(output_path, city, ground_results=None, building_results=None, simulation_results=None)¶

Save a VoxCity model and simulation results to an HDF5 file.

Parameters:
  • output_path (str) – Destination file path (e.g. "results.h5").

  • city (VoxCity) – The VoxCity model instance.

  • ground_results (dict, optional) –

    Ground-level simulation results. Keys whose values are numpy.ndarray are stored as HDF5 datasets (with gzip compression); all other JSON-serializable values are stored as group attributes.

    Typical keys produced by the GPU solar integration module:

    {
        'sunlight_hours':    np.ndarray (ny, nx),
        'cumulative_global': np.ndarray (ny, nx),
        'svf':               np.ndarray (ny, nx),
        'potential_sunlight_hours': float,
        'mode':              str,
        ...
    }
    

    If the input numpy array carries a .metadata dict (e.g. ArrayWithMetadata), those metadata entries are also persisted as sub-attributes.

  • building_results (dict, optional) –

    Building-surface simulation results. The dict must contain a 'mesh' key whose value is a Trimesh object. Per-face data arrays are taken either from the 'metadata' sub-dict or directly from the Trimesh’s .metadata attribute.

    Typical keys produced by the GPU solar integration module:

    {
        'mesh': trimesh.Trimesh,
        'metadata': {
            'irradiance_direct':  np.ndarray (n_faces,),
            'irradiance_diffuse': np.ndarray (n_faces,),
            'sunlight_hours':     np.ndarray (n_faces,),
            'potential_sunlight_hours': float,
            ...
        },
    }
    

    If 'metadata' is not provided explicitly, the function falls back to mesh.metadata.

  • simulation_results (dict, optional) –

    Multiple named simulation results grouped by simulation type. The recommended structure is:

    {
        'ground': {
            'solar_cumulative': {'cumulative_global': array, ...},
            'sunlight_hours_dsh': {'sunlight_hours': array, ...},
        },
        'building_surface': {
            'solar_cumulative': trimesh_obj,
            'sky_view_factor': {'mesh': trimesh_obj, 'metadata': {...}},
        },
    }
    

    Supported simulation types are 'ground' and 'building_surface'. The legacy ground_results and building_results arguments remain supported for saving one unnamed/default result of each type.

Notes

  • Requires the h5py package (pip install h5py).

  • The file is self-contained – no pickle dependency at load time.

  • Datasets use compression='gzip' by default for compact files.

voxcity.generator.load_results_h5(input_path)¶

Load a VoxCity model and simulation results from an HDF5 file.

Parameters:

input_path (str) – Path to the HDF5 file created by save_results_h5().

Returns:

A dictionary with the following keys:

'voxcity'

The reconstructed VoxCity instance.

'ground' (if present)

dict mapping dataset names to numpy arrays, plus scalar metadata entries.

'building' (if present)

dict with 'mesh_vertices', 'mesh_faces', 'mesh_face_normals' (numpy arrays) and per-face data arrays / scalar metadata.

'simulations' (if present)

nested dict of named simulation results grouped by simulation type, e.g. data['simulations']['ground']['solar_cumulative'] or data['simulations']['building_surface']['sky_view_factor']. Legacy top-level 'ground' and 'building' groups are also exposed as 'default' entries in this nested structure.

'meta'

dict with 'crs', 'meshsize', 'bounds'.

Return type:

dict

Notes

The returned 'voxcity' object is a fully reconstructed VoxCity dataclass – it can be passed directly to any simulator or visualizer function.

voxcity.generator.update_voxcity(city: voxcity.models.VoxCity, *, buildings: voxcity.models.BuildingGrid | None = None, building_heights: numpy.ndarray | None = None, building_min_heights: numpy.ndarray | None = None, building_ids: numpy.ndarray | None = None, land_cover: voxcity.models.LandCoverGrid | numpy.ndarray | None = None, dem: voxcity.models.DemGrid | numpy.ndarray | None = None, tree_canopy: voxcity.models.CanopyGrid | numpy.ndarray | None = None, canopy_top: numpy.ndarray | None = None, canopy_bottom: numpy.ndarray | None = None, building_gdf=None, tree_gdf=None, tree_gdf_mode: str = 'replace', land_cover_source: str | None = None, trunk_height_ratio: float | None = None, voxel_dtype=None, max_voxel_ram_mb: float | None = None, inplace: bool = False) voxcity.models.VoxCity¶

Update a VoxCity object with new grid data and regenerate the VoxelGrid.

This function allows partial updates - only the grids you provide will be updated, while the rest will be taken from the existing VoxCity object. The VoxelGrid is always regenerated from the (updated) component grids.

Parameters:
  • city (VoxCity) – The existing VoxCity object to update.

  • buildings (BuildingGrid, optional) – Complete replacement for the building grid. If provided, takes precedence over individual building_heights/building_min_heights/building_ids.

  • building_heights (np.ndarray, optional) – 2D array of building heights. If buildings is not provided, this updates only the heights while keeping existing min_heights and ids.

  • building_min_heights (np.ndarray, optional) – 2D object-dtype array of lists containing [min_height, max_height] pairs for each building segment per cell.

  • building_ids (np.ndarray, optional) – 2D array of building IDs per cell.

  • land_cover (LandCoverGrid or np.ndarray, optional) – New land cover data. Can be a LandCoverGrid or a raw numpy array.

  • dem (DemGrid or np.ndarray, optional) – New DEM/elevation data. Can be a DemGrid or a raw numpy array.

  • tree_canopy (CanopyGrid or np.ndarray, optional) – New tree canopy data. Can be a CanopyGrid (with top/bottom) or a raw numpy array (interpreted as canopy top heights).

  • canopy_top (np.ndarray, optional) – 2D array of tree canopy top heights. Takes precedence over tree_canopy for top heights if both are provided.

  • canopy_bottom (np.ndarray, optional) – 2D array of tree canopy bottom heights (crown base).

  • building_gdf (GeoDataFrame, optional) – Updated building GeoDataFrame. If provided without building grids (building_heights, building_min_heights, building_ids), the function will automatically generate the building grids from the GeoDataFrame using create_building_height_grid_from_gdf_polygon. The GeoDataFrame is also stored in city.extras[‘building_gdf’].

  • tree_gdf (GeoDataFrame, optional) – Updated tree GeoDataFrame. If provided without tree canopy data (tree_canopy, canopy_top, canopy_bottom), the function will automatically generate the canopy grids from the GeoDataFrame using create_canopy_grids_from_tree_gdf. The GeoDataFrame must contain ‘top_height’, ‘bottom_height’, ‘crown_diameter’, and ‘geometry’ columns. The GeoDataFrame is stored in city.extras[‘tree_gdf’].

  • tree_gdf_mode (str, default "replace") –

    How to combine tree_gdf with existing canopy data. Options: - “replace”: Replace the existing canopy grids with new ones from tree_gdf. - “add”: Merge the tree_gdf grids with existing (or provided) canopy grids

    by taking the maximum height at each cell (preserves existing trees). When canopy_top/canopy_bottom are also provided, the tree_gdf grids are merged on top of those arrays instead of the existing city canopy.

  • land_cover_source (str, optional) – The land cover source name for proper voxelization. If not provided, attempts to use the source from city.extras or defaults to ‘OpenStreetMap’.

  • trunk_height_ratio (float, optional) – Ratio of trunk height to total tree height for canopy bottom calculation. Default is approximately 0.588 (11.76/19.98).

  • voxel_dtype (dtype, optional) – NumPy dtype for the voxel grid. Defaults to np.int8.

  • max_voxel_ram_mb (float, optional) – Maximum RAM in MB for voxel grid allocation. Raises MemoryError if exceeded.

  • inplace (bool, default False) – If True, modifies the input city object directly and returns it. If False, creates and returns a new VoxCity object.

Returns:

The updated VoxCity object with regenerated VoxelGrid.

Return type:

VoxCity

Examples

Update building heights and regenerate voxels:

>>> import numpy as np
>>> new_heights = city.buildings.heights.copy()
>>> new_heights[10:20, 10:20] = 50.0  # Increase height in a region
>>> updated = update_voxcity(city, building_heights=new_heights)

Update with a complete new BuildingGrid:

>>> from voxcity.models import BuildingGrid
>>> new_buildings = BuildingGrid(heights=..., min_heights=..., ids=..., meta=city.buildings.meta)
>>> updated = update_voxcity(city, buildings=new_buildings)

Update land cover and DEM together:

>>> updated = update_voxcity(city, land_cover=new_lc_array, dem=new_dem_array)

Update buildings from GeoDataFrame (automatic grid generation):

>>> updated = update_voxcity(city, building_gdf=updated_building_gdf)

Update trees from GeoDataFrame (replace existing canopy):

>>> updated = update_voxcity(city, tree_gdf=updated_tree_gdf)

Add trees from GeoDataFrame to existing canopy:

>>> updated = update_voxcity(city, tree_gdf=new_tree_gdf, tree_gdf_mode="add")
voxcity.generator.regenerate_voxels(city: voxcity.models.VoxCity, *, land_cover_source: str | None = None, trunk_height_ratio: float | None = None, voxel_dtype=None, max_voxel_ram_mb: float | None = None, inplace: bool = False) voxcity.models.VoxCity¶

Regenerate only the VoxelGrid from existing component grids.

This is a convenience function for when you’ve modified the grids in-place and need to regenerate the voxels without passing all parameters.

Parameters:
  • city (VoxCity) – The VoxCity object whose voxels should be regenerated.

  • land_cover_source (str, optional) – Land cover source for voxelization. Defaults to source from extras.

  • trunk_height_ratio (float, optional) – Trunk height ratio for tree canopy calculation.

  • voxel_dtype (dtype, optional) – NumPy dtype for voxel grid.

  • max_voxel_ram_mb (float, optional) – Maximum RAM in MB for voxel allocation.

  • inplace (bool, default False) – If True, modifies city directly; otherwise returns a new object.

Returns:

The VoxCity object with regenerated VoxelGrid.

Return type:

VoxCity

Examples

>>> # Modify building heights in place
>>> city.buildings.heights[50:60, 50:60] = 100.0
>>> # Regenerate voxels to reflect the change
>>> city = regenerate_voxels(city, inplace=True)