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