3aed6333bcee4494718f7bcd53dd6d1715a109a4
GeoData Toolkit
This repository converts DGM1 elevation tiles into Unity-ready 16-bit PNG heightmaps and a placement manifest. It relies on GDAL for mosaicking, resampling, and scaling to UInt16 ranges Unity expects.
Prerequisites
uvinstalled. Use Python 3.10–3.12 for now (triangle2fromcjio[export]has no CPython 3.13 wheels).- Optional: Java 17+ if you want to experiment with the bundled
citygml-toolsutilities (not needed for heightmaps/orthophotos).
Environment setup (uv)
- Install deps (creates
.venvif missing):uv sync. You can skip manual activation by prefixing commands withuv run ...; if you prefer activation, runuv venv && source .venv/bin/activate. uv run <cmd>executes with the project environment (e.g.,uv run python geodata_to_unity.py --setup). Use--directoryto target another path if needed;--offlinedisables network fetches.- If wheels fail to resolve, ensure system GDAL is present (e.g.,
brew install gdalorapt-get install gdal-bin libgdal-dev), then rerunuv sync. - Create the default directory tree and config:
uv run python geodata_to_unity.py --setup(orbash scripts/setup_dirs.shfor directories only).
Repository Layout
raw/— working inputs (not versioned):raw/dgm1/,raw/dop20/jp2/,raw/citygml/lod1/,raw/citygml/lod2/.archive/— offline storage for untouched downloads (e.g., zipped DOP/CityGML tiles, dop20 filelist).work/— intermediates such asdgm.vrtand_tmp.tiffiles; safe to delete/regenerate.export_unity/height_png16/— final 16-bit PNG heightmaps for Unity import.export_unity/tile_index.csv— manifest mapping tile IDs to world bounds and global min/max used for scaling; built during heightmap export and required by orthophotos.export_unity/ortho_jpg/— cropped orthophoto tiles aligned to the terrain grid (JPEG + worldfiles).geodata_to_unity.py— main CLI (usesgeodata_pipeline/library modules).scripts/— helpers to create the directory tree and fetch DOP20 inputs.geodata_config.json— generated config (seegeodata_config.example.jsonfor defaults).AGENTS.md— contributor guide.
Quick Start
- Activate the uv venv (
source .venv/bin/activate) or prefix commands withuv run. - Initialize config + directories:
uv run python geodata_to_unity.py --setup. - Export assets (builds VRTs automatically if missing):
uv run python geodata_to_unity.py --export all # heightmaps only: uv run python geodata_to_unity.py --export heightmap # textures only: uv run python geodata_to_unity.py --export textures # buildings: uv run python geodata_to_unity.py --export buildings # trees (CSV+GLB): uv run python geodata_to_unity.py --export trees - Import the PNGs into Unity Terrains using
tile_index.csvfor placement and consistent height scaling (0–65535).
How the export works
- Heightmaps: the pipeline builds
work/dgm.vrtfrom allraw/dgm1/*.tif, computes a global min/max once, and warps each tile footprint toheightmap.out_reswithsrcNodata=-9999anddstNodataset to the global min. PNGs are scaled to[0, 65535]with worldfiles and listed inexport_unity/tile_index.csv. - Orthophotos:
work/dop.vrtis built fromraw/dop20/jp2/*.jp2; the manifest drives the cropping bounds. JPEG tiles are written toexport_unity/ortho_jpg/with matching.jgwworldfiles. If the manifest is missing, the orthophoto export aborts—run the heightmap export first or use--export all. - Archives:
--build-from-archiveexpands every*.zipunderarchive/*into the matchingraw/*directories and copiesarchive/dop20/filelist.txtnext toraw/dop20/for the downloader. - Cleanup: temporary
_tmp.tifand GDAL aux XML files underwork/andraw/dgm1/are removed at the end of the heightmap export; avoid storing non-GDAL metadata in those folders.
Key Commands
- Refresh VRT:
gdalbuildvrt work/dgm.vrt raw/dgm1/*.tif - Run export pipeline:
uv run python geodata_to_unity.py --export all - Inspect an output tile:
gdalinfo export_unity/height_png16/<tile>.png | head - Override config paths: use
--config <path>,--raw-dgm1-path <dir>,--raw-dop20-path <dir>. - Build raws from archives:
uv run python geodata_to_unity.py --build-from-archive --export all(unzipsarchive/*; dop20 filelist stays inarchive/dop20/for the downloader). - Rebuild VRTs after moving data: add
--force-vrt.
Workflow Notes
- The pipeline computes a global min/max from the VRT to scale all tiles consistently; adjust
heightmap.out_resorheightmap.resampleingeodata_config.jsonif your AOI or target resolution changes. _tmp.tiffiles inwork/are transient; you can deletework/to force a clean rebuild.- Keep file names stable to avoid churn in Unity scenes; re-exports overwrite in place.
- Large raw datasets are intentionally excluded from version control—document download sources or scripts instead of committing data.
- Additional inputs: download helper lives in
scripts/dlscript_dop20.shand pulls JP2/J2W/XML orthophotos listed inarchive/dop20/filelist.txt(one URL per line);archive/can hold zipped 3D building tiles for future use. - Handoff to Unity: copy/sync
export_unity/height_png16/andexport_unity/tile_index.csvintoDTrierFlood/Assets/GeoData/before running the Unity-side importer. Keepheightmap.out_resaligned with the importer’s expected resolution (currently 1025).
Orthophotos (textures)
- Ensure DOP assets are present in
raw/dop20/jp2/,raw/dop20/j2w/, andraw/dop20/meta/; usescripts/dlscript_dop20.shto fetch JP2/J2W/XML entries listed inarchive/dop20/filelist.txt(one URL per line). - From
GeoData/, run:This buildsuv run python geodata_to_unity.py --export textureswork/dop.vrtif missing and writesexport_unity/ortho_jpg/<tile>.jpg+.jgwaligned totile_index.csv.- If you see
Computed -srcwin ... falls partially outside source raster extentwarnings, the DOP coverage is slightly smaller than the tile footprint; edge pixels will be filled with NoData/zeros. Add adjacent JP2s or shrink the requested window if you need to avoid the warning. - The download script relies on a Linux/OpenSSL toolchain with system CA bundle at
/etc/ssl/certs/ca-certificates.crt; it builds a trust chain by fetching the geobasis intermediate. macOS/Windows users should either provide a combined CA viaCURL_CA_BUNDLEor download with a browser/wget and place files manually. - Place companion
.j2wand.xmlfiles underraw/dop20/j2w/andraw/dop20/meta/if available; they are not required for the VRT but help provenance.
- If you see
Buildings (automated exporter)
- Run:
uv run python geodata_to_unity.py --export buildings - What it does per tile:
- Converts LoD2 CityGML → CityJSON (citygml-tools), triangulates with cjio, rebases to tile-local XY using
tile_index.csv. - Merges all buildings into one GLB (1 mesh with roof/wall primitives), decimates to the configured triangle budget.
- Roofs: planar UVs from tile-local XY, embedded per-tile DOP20 orthophoto as base color (unlit by default).
- Walls: vertex colors sampled from the ortho as a fallback (neutral otherwise).
- Coordinates: glTF-friendly (x=east, y=height, z=-north) so glTFast instantiates one GameObject with two submeshes.
- Converts LoD2 CityGML → CityJSON (citygml-tools), triangulates with cjio, rebases to tile-local XY using
- Requirements: LoD2 GMLs under
raw/citygml/lod2/, per-tile orthos inexport_unity/ortho_jpg/, tools on PATH (tools/citygml-tools-2.4.0/citygml-tools,cjioor override viaCJIOenv). - Open items: richer wall coloring from BDOM/LPO facades, better simplification, footprint-aware ground snapping beyond the current clamp-to-ground.
Troubleshooting
- Empty raw directories cause VRT creation to fail fast (
No sources available to build VRT); populate inputs or adjust--raw-*overrides. - If you moved raw data or deleted
work/, add--force-vrtto rebuild VRTs before exporting. - Orthophoto export warnings like
Computed -srcwin ... falls partially outside source raster extentindicate coverage gaps; add neighboring JP2s or accept the NoData edge fill. - If GDAL Python bindings are missing, install system GDAL first and re-run
uv syncsoosgeoimports succeed.
Description
Languages
Python
61.4%
C#
29.9%
Shell
6.8%
Batchfile
1.9%