CityDB v4 Solar is a distributed computing tool that calculates solar radiation and sky view factors for 3D city models. It analyzes building surfaces and terrain to determine direct/diffuse solar radiation (in kWh/m²) and sky view factor (SVF) values, which are essential for urban climate modeling, energy simulations, and environmental analysis.
The tool works on 3D city models represented according to the OGC CityGML 2.0 standard. It directly operates on the 3DCityDB V4, which is an Open Source 3D geodatabase solution containing the city model. Currently, the solar irradiation can only be computed for LOD2 building models with RoofSurface and WallSurface objects (and LOD2 MultiSurface geometries). However, many other city objects like the terrain, trees, other buildings in different LODs can be taken into account as shadow caster objects.
| New York City (Manhattan) | Tokyo Central Station Area | TU Munich Main Campus |
|---|---|---|
![]() |
. |
![]() |
| Online Demo | Online Demo | Online Demo |
CityDB v4 Solar performs the following calculations:
- Solar Radiation Analysis: Computes direct and diffuse solar irradiation for building walls and roofs, broken down by month and annually
- Sky View Factor (SVF) Calculation: Determines the portion of sky visible from each surface point, crucial for urban heat island studies or quality of living assessments.
- 3D Geometry Processing: Analyzes complex 3D city models to account for shadowing from buildings, vegetation, and terrain (even when the city is located in a mountain region)
- Calibration: Calibrates radiation calculations against NASA climate data using transmissivity parameters
- Multi-scale Analysis: Supports analysis at different scales from individual buildings to city-wide and even region-wide assessments.
- 3DCityDB v4.0 – v4.4 - A CityGML database storing 3D city models
- PostgreSQL with PostGIS plus SFCGAL extension - For spatial data handling (utilized by 3DCityDB V4)
- Java 11 or higher (OpenJDK recommended)
- PostgreSQL 10+ with PostGIS plus SFCGAL extension
- Gradle (for building from source)
- Multi-core CPU recommended (supports configurable thread pools)
- Sufficient RAM for processing large city models (depends on dataset size)
- PostgreSQL server with adequate storage for spatial index and results
citydb-v4-solar/
├── images/ # Project images and screenshots
├── sunpot-core/ # Main irradiation calculation engine
│ ├── src/main/java/
│ │ ├── main/ # Entry point and CLI
│ │ ├── config/ # Configuration classes
│ │ ├── geometry/ # 3D geometry processing
│ │ ├── intersection/ # Ray-surface intersection
│ │ ├── result/ # Result aggregation and output
│ │ ├── db/ # Database interaction
│ │ ├── calibration/ # Solar calibration
│ │ └── worker/ # Distributed processing
│ └── src/main/resources/
│ └── xml/ # Default configuration templates
├── sunpot-texture/ # Texture processing module
└── build.gradle # Gradle build configuration
sunpot-core [options] [config.xml]Database Connection:
-h <hostname>— PostgreSQL host (default: localhost)-p <port>— PostgreSQL port (default: 5432)-d <dbname>— Database name (default: citydb)-u <username>— Database user (default: postgres)-pw <password>— Database password (default: postgres)
Configuration & Execution:
<config.xml>— Path to SunPot configuration XML file (positional argument)-t <nodeType>— Node type:MASTER,WORKER(default:MASTER)
Test Mode:
-tr <n>— Perform a test run with n buildings per tile
Database Cleanup (mutually exclusive):
-R— Drop master and worker schemata and genAttribs, then quit-r— Drop master and worker schemata and genAttribs, then run SunPot-Rw— Drop worker schemata only and quit
CSV Output:
-o <path>— CSV output folder path (runs analysis and exports results; mutually exclusive with-r,-R,-Rw)-e <option>— CSV export option (requires-o):a= all resultsm= monthly aggregationy= yearly aggregationf= full table with GML IDs (default)
Information:
-v— Print version info and quit-help— Print CLI usage
# Run with default config
sunpot-core config.xml
# Run with custom database credentials
sunpot-core -h db.example.com -u admin -pw secret123 config.xml
# Export results to CSV
sunpot-core -o /output/results -e f config.xml
# Test run with 100 buildings per tile
sunpot-core -tr 100 config.xml
# Cleanup database and quit
sunpot-core -R config.xmlSunPot is configured via an XML file in the namespace https://github.com/tum-gis/citydb-v4-solar/. See default_config_full.xml for a complete example.
For a full reference of all configuration elements, their types, allowed values, and defaults, see Configuration.md.
<sunpot:DB-host>localhost</sunpot:DB-host>
<sunpot:DB-port>5432</sunpot:DB-port>
<sunpot:DB-dbname>citydb</sunpot:DB-dbname>
<sunpot:DB-username>postgres</sunpot:DB-username>
<sunpot:DB-password>postgres</sunpot:DB-password><sunpot:Location-SRID>31468</sunpot:Location-SRID> <!-- EPSG code -->
<sunpot:Location-LAT>48.15</sunpot:Location-LAT> <!-- Latitude -->
<sunpot:Location-LON>11.58</sunpot:Location-LON> <!-- Longitude --><sunpot:SUN-pointDistance>1.0E8</sunpot:SUN-pointDistance> <!-- Distance to sun in m -->
<sunpot:SUN-year>2021</sunpot:SUN-year> <!-- Analysis year -->
<sunpot:SUN-isLeapYear>false</sunpot:SUN-isLeapYear> <!-- Leap year -->
<sunpot:SUN-stepDays>1</sunpot:SUN-stepDays> <!-- Days between calculations -->
<sunpot:SUN-stepHours>1.0</sunpot:SUN-stepHours> <!-- Hours between calculations -->
<sunpot:SUN-timezone>2</sunpot:SUN-timezone> <!-- UTC offset --><sunpot:HEMISPHERE-pointDistance>1.0E8</sunpot:HEMISPHERE-pointDistance>
<sunpot:HEMISPHERE-stepAzimut>0.21</sunpot:HEMISPHERE-stepAzimut> <!-- Angular step (radians) -->
<sunpot:HEMISPHERE-stepZenit>0.157</sunpot:HEMISPHERE-stepZenit> <!-- Zenith step (radians) -->
<sunpot:HEMISPHERE-stepAngleOffset>0.05</sunpot:HEMISPHERE-stepAngleOffset><sunpot:POINTGRID-gridPointDistance>200</sunpot:POINTGRID-gridPointDistance> <!-- Spacing in cm -->
<sunpot:POINTGRID-gridPointOffset>0.1</sunpot:POINTGRID-gridPointOffset> <!-- Vertical offset of each point above its related surface in m --><sunpot:INDEX-Configs>
<sunpot:INDEX-Config>
<id>1</id>
<maxlevels>6</maxlevels>
<maxElements>200</maxElements>
</sunpot:INDEX-Config>
</sunpot:INDEX-Configs>
<sunpot:INDEX-Mappings>
<sunpot:INDEX-Mappings>
<entry>
<key>0</key>
<value>
<sunpot:ShadowingFeatureTypes>
<sunpot:ShadowingFeatureType>LoD2WallRoof</sunpot:ShadowingFeatureType>
<sunpot:ShadowingFeatureType>LoD1BldgSolid</sunpot:ShadowingFeatureType>
<sunpot:ShadowingFeatureType>TIN</sunpot:ShadowingFeatureType>
</sunpot:ShadowingFeatureTypes>
</value>
</entry>
</sunpot:INDEX-Mappings>
</sunpot:INDEX-Mappings><sunpot:CALIBRATION-initialTransmissivity>0.3</sunpot:CALIBRATION-initialTransmissivity>
<sunpot:CALIBRATION-tolerance>0.1</sunpot:CALIBRATION-tolerance>
<sunpot:CALIBRATION-dataSource>CSVNASA</sunpot:CALIBRATION-dataSource> <!-- Data source type -->
<sunpot:CALIBRATION-csvPath>/path/to/nasa/data.csv</sunpot:CALIBRATION-csvPath><sunpot:TILING-tileLength>100.0</sunpot:TILING-tileLength> <!-- Tile size in m -->
<sunpot:TILING-dgmLength>20000.0</sunpot:TILING-dgmLength> <!-- DGM tile size in m --><sunpot:CONFIG-readWalls>true</sunpot:CONFIG-readWalls> <!-- Process walls -->
<sunpot:CONFIG-readRoofs>true</sunpot:CONFIG-readRoofs> <!-- Process roofs -->
<sunpot:CONFIG-writeSurfaces>false</sunpot:CONFIG-writeSurfaces> <!-- Export surfaces -->
<sunpot:CONFIG-corePoolSize>4</sunpot:CONFIG-corePoolSize> <!-- Min threads -->
<sunpot:CONFIG-maxPoolSize>8</sunpot:CONFIG-maxPoolSize> <!-- Max threads -->
<sunpot:CONFIG-PoolSizeAdaptionStrategy>STEPWISE</sunpot:CONFIG-PoolSizeAdaptionStrategy>
<sunpot:CONFIG-queueSize>10</sunpot:CONFIG-queueSize> <!-- Task queue size --><sunpot:DEBUG-writeTriangles>false</sunpot:DEBUG-writeTriangles>
<sunpot:DEBUG-writeTriangleStats>false</sunpot:DEBUG-writeTriangleStats>
<sunpot:CONFIG-testrun>0</sunpot:CONFIG-testrun>
<sunpot:LOG-timeStampLog>false</sunpot:LOG-timeStampLog>
<sunpot:LOG-LogLevel>info</sunpot:LOG-LogLevel> <!-- debug, info, warn, error --><sunpot:INTERSECTION-ShadowingFeatures>
<sunpot:INTERSECTION-ShadowingFeature type="LoD2WallRoof"/>
<sunpot:INTERSECTION-ShadowingFeature type="LoD2BldgMultiSurface"/>
<sunpot:INTERSECTION-ShadowingFeature type="LoD2BuildingInstallation"/>
<sunpot:INTERSECTION-ShadowingFeature type="LoD2SolitaryVegetationObject"/>
<sunpot:INTERSECTION-ShadowingFeature type="LoD1BldgSolid"/>
<sunpot:INTERSECTION-ShadowingFeature type="TIN">
<sunpot:GMLIDs>
<sunpot:GMLID>terrain_id_1</sunpot:GMLID>
</sunpot:GMLIDs>
</sunpot:INTERSECTION-ShadowingFeature>
<sunpot:INTERSECTION-ShadowingFeature type="DGM">
<sunpot:GMLIDs>
<sunpot:GMLID>dgm_id</sunpot:GMLID>
</sunpot:GMLIDs>
</sunpot:INTERSECTION-ShadowingFeature>
</sunpot:INTERSECTION-ShadowingFeatures><sunpot:CALC-Features>
<sunpot:CALC-Feature>bldg_uuid_1</sunpot:CALC-Feature>
<sunpot:CALC-Feature>bldg_uuid_2</sunpot:CALC-Feature>
</sunpot:CALC-Features>SunPot stores results in the 3DCityDB database with the following result types:
- Direct Radiation (monthly & annual): kWh for each surface
- Diffuse Radiation (monthly & annual): kWh for each surface
- Global Radiation (monthly & annual): kWh for each surface
- Sky View Factor: [0.0 - 1.0]
Results can be exported to CSV using the -o CLI option.
- MASTER node: Prepares database schema, creates spatial indices, tiles the study area, manages work distribution
- WORKER nodes: Process individual tiles in parallel, perform ray-casting intersection calculations, aggregate results
- Distributed Processing: Multi-threaded task queue with configurable pool size for efficient CPU utilization
For a detailed explanation of the distributed processing workflow, including tile coordination, worker management, and failure handling, see Distributed-Processing.md.
For an explanation of how SunPot handles terrain data with dual-resolution TIN and DGM representations, see Handling-of-Terrain-Data.md.
sunpot-texture is a companion tool that generates visual textures from the solar radiation results produced by sunpot-core. It reads radiation values from the 3DCityDB database, classifies them into color ramps (using HSV color mapping), and writes the resulting textures back to 3DCityDB's appearance tables. This enables visualization of radiation values as colored building surfaces in 3D city model viewers (e.g., CityJSON viewers, 3DCityDB Web Viewer).
Use sunpot-texture after sunpot-core has finished processing and radiation results are stored in the database. It is useful for:
- Visualizing solar radiation distributions across building surfaces
- Creating monthly or yearly radiation maps for 3D viewers
- Generating color-coded textures for presentations or publications
- Connects to the 3DCityDB database
- Reads global radiation values (monthly or yearly) from sunpot-core's result tables
- Classifies radiation values into a color ramp (HSV 240° color scale)
- Generates texture coordinates for each building surface
- Writes textures and appearance data back to 3DCityDB's
appearancetables
sunpot-texture [options] [month1 month2 ...]Database Connection (required):
-h <hostname>— PostgreSQL host-p <port>— PostgreSQL port (default: 5432)-d <dbname>— Database name-u <username>— Database user (default: postgres)-pw <password>— Database password
Texture Generation (choose one):
-y— Generate yearly textures (aggregated over all months)-m— Generate monthly textures (requires month arguments)
Value Range (optional):
-lb <int>— Lower boundary of radiation value range (auto-detected from DB if omitted)-ub <int>— Upper boundary of radiation value range (auto-detected from DB if omitted)
Maintenance:
-t— Truncate all existing appearances before generating new textures-help— Print CLI usage
Arguments (for -m only):
<month1 month2 ...>— List of months as integers [1-12]
# Generate yearly texture
sunpot-texture -h localhost -d citydb -y
# Generate textures for January, June, and December
sunpot-texture -h localhost -d citydb -m 1 6 12
# Truncate existing textures first, then generate all 12 months
sunpot-texture -h localhost -d citydb -t -m 1 2 3 4 5 6 7 8 9 10 11 12
# Generate yearly texture with custom value range
sunpot-texture -h localhost -d citydb -y -lb 0 -ub 1500- JDK 11+
- Gradle 7.0+ (project uses Gradle 8.14.3 via wrapper)
cd citydb-v4-solar
./gradlew build./gradlew installDistThis produces runnable distributions in:
sunpot-core/build/install/sunpot-core/— Main radiation calculation enginesunpot-texture/build/install/sunpot-texture/— Texture generation tool
Each distribution contains a bin/ directory with the launcher scripts and a lib/ directory with all required JARs. Keep these directories together — the scripts reference lib/ via a relative path.
# Run sunpot-core
./sunpot-core/build/install/sunpot-core/bin/sunpot-core config.xml
# Run sunpot-texture
./sunpot-texture/build/install/sunpot-texture/bin/sunpot-texture -h localhost -d citydb -yAlternatively, cd into the bin/ directory and run the scripts directly, or add the bin/ path to your PATH environment variable.
A single Dockerfile is provided that packages both sunpot-core and sunpot-texture in one container. Build and run:
docker build -t citydb-v4-solar:latest .docker run citydb-v4-solar:latest sunpot-core -help
docker run citydb-v4-solar:latest sunpot-core -h db.example.com -u admin -pw secret123 config.xmldocker run citydb-v4-solar:latest sunpot-texture -help
docker run citydb-v4-solar:latest sunpot-texture -h localhost -d citydb -ydocker build -t citydb-v4-solar:latest . --build-arg CITYDB_V4_SOLAR_VERSION=v1.0.0Developers:
- Bruno Willenborg (former research associate at the Chair of Geoinformatics, TUM)
- Maximilian Sindram (former research associate at the Chair of Geoinformatics, TUM)
- Thomas H. Kolbe (thomas.kolbe@tum.de)
Affiliation: Chair of Geoinformatics, Technical University of Munich (TUM), Germany
If you are using the tool in your project or research, please provide a reference to the following paper:
- B. Willenborg, M. Sindram, T.H. Kolbe (2017): Applications of 3D City Models for a better understanding of the Built Environment. In: M. Behnisch, G. Meinel (eds): Trends in Spatial Analysis and Modelling, Geotechnologies and the Environment Series, Springer, Heidelberg. Click here to download a copy
CityDB v4 Solar is licensed under the Apache License, Version 2.0. See the LICENSE file at the project root for the full license text.
You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0
Copyright (c) Chair of Geoinformatics, Technical University of Munich (TUM) and contributors.
- 3DCityDB: https://www.3dcitydb.org/
- CityGML Standard: http://www.citygml.org/
- PostGIS: https://postgis.net/
The development and testing of the citydb-v4-solar tool was supported by a number of student theses and projects:
-
Wolfgang Zahn (2015). "Initial experiments on solar potential analysis for 3D city models." Master's Thesis, Technical University of Munich. https://mediatum.ub.tum.de/node?id=1276236
-
Leander Besinger (2019). "Investigation of the quality of the results of solar potential analyses when comparing against real measurements using pyranometers." Bachelor's Thesis, Technical University of Munich. https://mediatum.ub.tum.de/node?id=1551979
-
Philipp Sedlmeier (2020). "Extending the Calibration of the Transition Model for Calculating Solar Radiation Values." Student Project, Technical University of Munich. https://mediatum.ub.tum.de/node?id=1659518


