From abb37f25e2db075ec4d6667d57d2f7899b5caa23 Mon Sep 17 00:00:00 2001 From: "s0wlz (Matthias Puchstein)" Date: Mon, 15 Dec 2025 20:41:42 +0100 Subject: [PATCH] Add uv setup and document expected orthophoto warnings --- AGENTS.md | 34 ++++++++++++++++++++++++++++++++++ README.md | 15 +++++++++++---- pyproject.toml | 26 ++++++++++++++++++++++++++ uv.lock | 20 ++++++++++++++++++++ 4 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 AGENTS.md create mode 100644 pyproject.toml create mode 100644 uv.lock diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..30896e4 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,34 @@ +# Repository Guidelines + +## Project Structure & Module Organization +- `export_heightmaps.py` is the main pipeline: builds `work/dgm.vrt`, scales heights, and writes `export_unity/height_png16/*.png` plus `export_unity/tile_index.csv`. +- `export_ortho_tiles.py` exports orthophotos into `export_unity/ortho_jpg/` using the terrain manifest. +- Raw inputs (`raw_dgm1/`, `raw_dop/`, `raw_3dgeb_lod1/`, `raw_3dgeb_lod2/`) and `work/` intermediates are intentionally untracked; do not commit them. +- `export_unity/` is safe to sync to Unity projects; treat it as generated output. + +## Build, Test, and Development Commands +- Create a venv: `uv venv && source .venv/bin/activate`. Install deps: `uv sync` (generates `uv.lock`). +- If wheels fail, install system GDAL first (e.g., `brew install gdal` or `apt-get install gdal-bin libgdal-dev`), then rerun `uv sync`. +- Heightmap export (rebuilds VRT if absent): `uv run python export_heightmaps.py`. +- Orthophoto export: `uv run python export_ortho_tiles.py` (requires JP2s under `raw_dop/jp2/`). +- Refresh VRT manually if needed: `gdalbuildvrt work/dgm.vrt raw_dgm1/*.tif`. +- Inspect a result: `gdalinfo export_unity/height_png16/.png | head` to sanity-check bounds and scaling. + - Expected warning: `Computed -srcwin ... falls partially outside source raster extent` means 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 silence it. + +## Coding Style & Naming Conventions +- Python scripts use 4-space indentation, early-exit error handling, and `SystemExit` for fatal issues; follow PEP 8 where practical. +- Keep tile IDs stable (base filename without extension); avoid renaming inputs to reduce churn downstream. +- Prefer explicit constants for tunables (`OUT_RES`, `RESAMPLE`, `TILE_SIZE_M`) and log with clear context. + +## Testing Guidelines +- No automated tests yet; rely on manual validation: run exports on a small tile subset, open outputs in `gdalinfo` or GIS viewer, and confirm `tile_index.csv` aligns with Unity expectations. +- When changing scaling or resolution, compare before/after stats (min/max) and spot-check terrain in Unity. + +## Commit & Pull Request Guidelines +- Commit messages are short, imperative summaries (e.g., "Ignore generated orthophotos"). Group related changes per commit; commit `uv.lock` when dependency versions change. +- Before opening a PR: describe the change, list commands run, note data locations (not committed), and include any screenshots from Unity/GIS if visuals changed. +- Ensure raw datasets and large intermediates stay out of git; verify `.gitignore` still covers generated files after changes. + +## Security & Data Handling +- Keep raw geodata local; avoid publishing source tiles or credentials. Document download sources/scripts instead of committing data. +- Outputs may be large; prefer syncing `export_unity/` artifacts via project-specific channels rather than embedding in the repo. diff --git a/README.md b/README.md index e4c9d9a..0211c86 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,11 @@ This repository converts DGM1 elevation tiles into Unity-ready 16-bit PNG height - DGM1 source tiles placed in `raw_dgm1/` as `dgm1___.tif` (with matching `.tfw` files). - Raw inputs (`raw_dop/`, `raw_3dgeb_lod1/`, `raw_3dgeb_lod2/`) are **kept out of git**; keep them locally or document how to fetch/regenerate. +### Environment setup (uv) +- Create a project venv: `uv venv && source .venv/bin/activate`. +- Install dependencies from `pyproject.toml`: `uv sync` (generates `uv.lock`; warning-free with dependency-groups). +- If wheels fail to resolve, ensure system GDAL is present (e.g., `brew install gdal` or `apt-get install gdal-bin libgdal-dev`), then rerun `uv sync`. + ### Repository Layout - `raw_dgm1/` — input rasters (not versioned). - `raw_dop/` — raw orthophoto downloads (JP2/J2W/XML), ignored in git. @@ -21,15 +26,16 @@ This repository converts DGM1 elevation tiles into Unity-ready 16-bit PNG height - `AGENTS.md` — contributor guide. ### Quick Start -1. Export Unity heightmaps and manifest (builds `work/dgm.vrt` automatically if missing): +1. Activate the uv venv (`source .venv/bin/activate`) or prefix commands with `uv run`. +2. Export Unity heightmaps and manifest (builds `work/dgm.vrt` automatically if missing): ```bash - python3 export_heightmaps.py + uv run python export_heightmaps.py ``` 3. Import the PNGs into Unity Terrains using `tile_index.csv` for placement and consistent height scaling (0–65535). ### Key Commands - Refresh VRT: `gdalbuildvrt work/dgm.vrt raw_dgm1/*.tif` -- Run export pipeline: `python3 export_heightmaps.py` +- Run export pipeline: `uv run python export_heightmaps.py` - Inspect an output tile: `gdalinfo export_unity/height_png16/.png | head` ### Workflow Notes @@ -44,9 +50,10 @@ This repository converts DGM1 elevation tiles into Unity-ready 16-bit PNG height 1. Ensure DOP JP2s are present in `raw_dop/jp2/` (use `raw_dop/dlscript.sh` if needed). 2. From `GeoData/`, run: ```bash - python3 export_ortho_tiles.py + uv run python export_ortho_tiles.py ``` This builds `work/dop.vrt` if missing and writes `export_unity/ortho_jpg/.jpg` + `.jgw` aligned to `tile_index.csv`. + - If you see `Computed -srcwin ... falls partially outside source raster extent` warnings, 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. ### Buildings The building export pipeline is temporarily disabled while we choose a mesh conversion approach (GDAL lacks a native OBJ writer). CityGML LoD2 sources remain in `raw_3dgeb_lod2/` locally (ignored in git); consider CityGML→glTF/OBJ tools (e.g., citygml-tools + cityjson2gltf) for future integration. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..f5e9923 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,26 @@ +[project] +name = "geodata-heightmap-export" +version = "0.1.0" +description = "Heightmap and orthophoto exporters using GDAL for Unity terrains." +readme = "README.md" +requires-python = ">=3.9" +dependencies = [ + "gdal>=3.4", +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build.targets.wheel] +packages = [] +force-include = { "export_heightmaps.py" = "export_heightmaps.py", "export_ortho_tiles.py" = "export_ortho_tiles.py" } + +[tool.hatch.build.targets.sdist] +include = [ + "export_heightmaps.py", + "export_ortho_tiles.py", + "README.md", + "AGENTS.md", + "pyproject.toml", +] diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..860ce54 --- /dev/null +++ b/uv.lock @@ -0,0 +1,20 @@ +version = 1 +revision = 3 +requires-python = ">=3.9" + +[[package]] +name = "gdal" +version = "3.12.0.post1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/95/fc/9d187c4d280122b497c2d4c25a1c3b1ba50e5e1836924e49323685999c43/gdal-3.12.0.post1.tar.gz", hash = "sha256:d2b68361c7cf2ef7caa8cbb8549a315080301564e3f025d1842df71a4e406236", size = 902365, upload-time = "2025-11-07T23:40:07.734Z" } + +[[package]] +name = "geodata-heightmap-export" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "gdal" }, +] + +[package.metadata] +requires-dist = [{ name = "gdal", specifier = ">=3.4" }]