☀️ VoxCity Solar Irradiance Analysis¶
Calculate instantaneous and cumulative solar irradiance using EPW (EnergyPlus Weather) data and 3D ray-tracing through your voxel city model.
What This Notebook Covers¶
Analysis Type |
Description |
|---|---|
Instantaneous |
Solar irradiance at a specific date/time |
Cumulative |
Total solar irradiance over a time period |
Key Features¶
Automatic EPW weather file download based on location
Direct Normal Irradiance (DNI) and Diffuse Horizontal Irradiance (DHI) modeling
Shadow casting through 3D voxel geometry
Tree canopy transmissivity
Export colored OBJ meshes for visualization
Prerequisites¶
pip install voxcity
# Installation (uncomment if running in a fresh environment)
# %pip install voxcity
# %pip install contextily osmnx geopandas matplotlib timezonefinder
import ee
from voxcity.geoprocessor.draw import draw_rectangle_map_cityname, center_location_map_cityname
from voxcity.generator import get_voxcity
from voxcity.simulator.solar import get_global_solar_irradiance_using_epw
# Authenticate & initialize Earth Engine (only needed if you plan to download data via GEE in your pipeline)
# ee.Authenticate()
# ee.Initialize(project='your-project-id')
cityname = "Tokyo, Japan"
meshsize = 5
# Option A: Draw rectangle interactively around a city
# m, rectangle_vertices = draw_rectangle_map_cityname(cityname, zoom=15)
# m # display the map, draw a rectangle, then capture rectangle_vertices
# Option B: Click to set center with fixed width/height (meters)
# m, rectangle_vertices = center_location_map_cityname(cityname, east_west_length=500, north_south_length=500, zoom=15)
# m
# Option C: Provide rectangle vertices directly (lon, lat) if known
rectangle_vertices = [
(139.760, 35.680), # SW
(139.760, 35.690), # NW
(139.770, 35.690), # NE
(139.770, 35.680) # SE
]
building_source = 'OpenStreetMap'
land_cover_source = 'OpenStreetMap'
canopy_height_source = 'High Resolution 1m Global Canopy Height Maps'
dem_source = 'DeltaDTM'
kwargs = {
"output_dir": "output/solar_demo",
# Optional DEM smoothing when reading GeoTIFF sources internally
"dem_interpolation": True,
}
city = get_voxcity(
rectangle_vertices,
meshsize=meshsize,
building_source=building_source,
land_cover_source=land_cover_source,
canopy_height_source=canopy_height_source,
dem_source=dem_source,
**kwargs
)
# Access grids from the VoxCity object
voxcity_grid = city.voxels.classes
dem_grid = city.dem.elevation
print(voxcity_grid.shape, dem_grid.shape)
⚡ Instantaneous Solar Irradiance¶
Calculate global solar irradiance at a specific date and time.
Key Parameters¶
Parameter |
Description |
|---|---|
|
Date and time in format “MM-DD HH:MM:SS” |
|
Auto-download nearest weather file |
|
Tree extinction coefficient |
|
Leaf Area Density |
|
Scale factor for DNI |
|
Scale factor for DHI |
solar_kwargs = {
"download_nearest_epw": True,
"rectangle_vertices": rectangle_vertices,
# Or set a local EPW directly:
# "epw_file_path": "./output/your_city.epw",
"calc_time": "01-01 12:00:00",
"view_point_height": 1.5,
"tree_k": 0.6,
"tree_lad": 1.0,
"colormap": "magma",
"obj_export": True,
"output_directory": "output/solar_demo",
"output_file_name": "instantaneous_solar_irradiance",
"alpha": 1.0,
"vmin": 0,
# "vmax": 900,
}
solar_grid = get_global_solar_irradiance_using_epw(
city,
calc_type='instantaneous',
direct_normal_irradiance_scaling=1.0,
diffuse_irradiance_scaling=1.0,
**solar_kwargs
)
solar_grid.shape
📊 Cumulative Solar Irradiance¶
Calculate total solar irradiance over a time period (e.g., daily, monthly, seasonal).
Key Parameters¶
Parameter |
Description |
|---|---|
|
Start of accumulation period (MM-DD HH:MM:SS) |
|
End of accumulation period (MM-DD HH:MM:SS) |
|
Time step for integration |
|
Restrict calculation to certain hours (e.g., 8AM-6PM) |
Note: Cumulative calculations can be computationally intensive for large areas/long time periods.
cum_kwargs = solar_kwargs.copy()
# Define the time window for accumulation
cum_kwargs["start_time"] = "01-01 05:00:00"
cum_kwargs["end_time"] = "01-31 20:00:00"
# Optionally restrict hours each day (e.g., 8AM–4PM)
cum_kwargs["start_hour"] = 8
cum_kwargs["end_hour"] = 16
# Performance controls (internal numba threads)
cum_kwargs["numba_num_threads"] = 4
cum_kwargs["progress_report"] = True
cum_kwargs["output_file_name"] = "cumulative_solar_irradiance"
cum_solar_grid = get_global_solar_irradiance_using_epw(
city,
calc_type='cumulative',
direct_normal_irradiance_scaling=1.0,
diffuse_irradiance_scaling=1.0,
**cum_kwargs
)
cum_solar_grid.shape
Tips¶
If EPW download fails due to SSL, consider
allow_insecure_ssl=Trueorallow_http_fallback=Truein kwargs.To avoid repeated downloads, set
download_nearest_epw=Falseand provideepw_file_path.Adjust
tree_kandtree_ladto tune vegetation transmittance.