wrote a script to automate the export to unity
This commit is contained in:
77
export_heightmaps.py
Normal file
77
export_heightmaps.py
Normal file
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
import glob
|
||||
import math
|
||||
import os
|
||||
|
||||
from osgeo import gdal
|
||||
|
||||
RAW_DIR = "raw_dgm1"
|
||||
VRT_PATH = "work/dgm.vrt"
|
||||
OUT_DIR = "export_unity/height_png16"
|
||||
|
||||
TILE_SIZE_M = 1000 # real-world tile size in meters
|
||||
OUT_RES = 1025 # Unity Terrain-friendly resolution (2^n + 1)
|
||||
RESAMPLE = "bilinear"
|
||||
|
||||
os.makedirs("work", exist_ok=True)
|
||||
os.makedirs(OUT_DIR, exist_ok=True)
|
||||
|
||||
# Open VRT
|
||||
ds = gdal.Open(VRT_PATH)
|
||||
if ds is None:
|
||||
raise SystemExit(f"Could not open {VRT_PATH}. Did you run gdalbuildvrt?")
|
||||
|
||||
band = ds.GetRasterBand(1)
|
||||
|
||||
# Strategy B: compute global min/max for CURRENT downloaded AOI
|
||||
gmin, gmax = band.ComputeRasterMinMax(True)
|
||||
print(f"GLOBAL_MIN={gmin}, GLOBAL_MAX={gmax}")
|
||||
|
||||
# Export manifest for Unity placement later
|
||||
manifest_path = os.path.join("export_unity", "tile_index.csv")
|
||||
with open(manifest_path, "w", encoding="utf-8") as f:
|
||||
f.write("tile_id,xmin,ymin,xmax,ymax,global_min,global_max,out_res\n")
|
||||
|
||||
for tif in sorted(glob.glob(os.path.join(RAW_DIR, "*.tif"))):
|
||||
tds = gdal.Open(tif)
|
||||
if tds is None:
|
||||
print(f"Skipping unreadable: {tif}")
|
||||
continue
|
||||
|
||||
gt = tds.GetGeoTransform()
|
||||
ulx, xres, _, uly, _, yres = gt # yres typically negative in north-up rasters
|
||||
|
||||
# Snap tile bounds to the 1000 m grid to avoid drift/seams.
|
||||
# (This also neutralizes the 1001×1001 overlap nuance.)
|
||||
xmin = math.floor(ulx / TILE_SIZE_M) * TILE_SIZE_M
|
||||
ymax = math.ceil(uly / TILE_SIZE_M) * TILE_SIZE_M
|
||||
xmax = xmin + TILE_SIZE_M
|
||||
ymin = ymax - TILE_SIZE_M
|
||||
|
||||
base = os.path.splitext(os.path.basename(tif))[0]
|
||||
tile_id = base # keep stable naming = easy re-export + reimport
|
||||
|
||||
tmp_path = os.path.join("work", f"{tile_id}_tmp.tif")
|
||||
out_path = os.path.join(OUT_DIR, f"{tile_id}.png")
|
||||
|
||||
warp_opts = gdal.WarpOptions(
|
||||
outputBounds=(xmin, ymin, xmax, ymax),
|
||||
width=OUT_RES,
|
||||
height=OUT_RES,
|
||||
resampleAlg=RESAMPLE,
|
||||
dstNodata=-9999,
|
||||
)
|
||||
gdal.Warp(tmp_path, ds, options=warp_opts)
|
||||
|
||||
# Scale to UInt16 (0..65535) using Strategy-B global min/max
|
||||
trans_opts = gdal.TranslateOptions(
|
||||
outputType=gdal.GDT_UInt16,
|
||||
scaleParams=[(gmin, gmax, 0, 65535)],
|
||||
format="PNG",
|
||||
)
|
||||
gdal.Translate(out_path, tmp_path, options=trans_opts)
|
||||
|
||||
f.write(f"{tile_id},{xmin},{ymin},{xmax},{ymax},{gmin},{gmax},{OUT_RES}\n")
|
||||
print(f"Wrote {out_path}")
|
||||
|
||||
print(f"Manifest: {manifest_path}")
|
||||
11
export_unity/tile_index.csv
Normal file
11
export_unity/tile_index.csv
Normal file
@@ -0,0 +1,11 @@
|
||||
tile_id,xmin,ymin,xmax,ymax,global_min,global_max,out_res
|
||||
dgm1_32_328_5511,327000,5512000,328000,5513000,124.13099670410156,297.1679992675781,1025
|
||||
dgm1_32_328_5512,327000,5513000,328000,5514000,124.13099670410156,297.1679992675781,1025
|
||||
dgm1_32_328_5513,327000,5514000,328000,5515000,124.13099670410156,297.1679992675781,1025
|
||||
dgm1_32_328_5514,327000,5515000,328000,5516000,124.13099670410156,297.1679992675781,1025
|
||||
dgm1_32_328_5515,327000,5516000,328000,5517000,124.13099670410156,297.1679992675781,1025
|
||||
dgm1_32_329_5511,328000,5512000,329000,5513000,124.13099670410156,297.1679992675781,1025
|
||||
dgm1_32_329_5512,328000,5513000,329000,5514000,124.13099670410156,297.1679992675781,1025
|
||||
dgm1_32_329_5513,328000,5514000,329000,5515000,124.13099670410156,297.1679992675781,1025
|
||||
dgm1_32_329_5514,328000,5515000,329000,5516000,124.13099670410156,297.1679992675781,1025
|
||||
dgm1_32_329_5515,328000,5516000,329000,5517000,124.13099670410156,297.1679992675781,1025
|
||||
|
BIN
work/dgm1_32_328_5511_tmp.tif
Normal file
BIN
work/dgm1_32_328_5511_tmp.tif
Normal file
Binary file not shown.
BIN
work/dgm1_32_328_5512_tmp.tif
Normal file
BIN
work/dgm1_32_328_5512_tmp.tif
Normal file
Binary file not shown.
BIN
work/dgm1_32_328_5513_tmp.tif
Normal file
BIN
work/dgm1_32_328_5513_tmp.tif
Normal file
Binary file not shown.
BIN
work/dgm1_32_328_5514_tmp.tif
Normal file
BIN
work/dgm1_32_328_5514_tmp.tif
Normal file
Binary file not shown.
BIN
work/dgm1_32_328_5515_tmp.tif
Normal file
BIN
work/dgm1_32_328_5515_tmp.tif
Normal file
Binary file not shown.
BIN
work/dgm1_32_329_5511_tmp.tif
Normal file
BIN
work/dgm1_32_329_5511_tmp.tif
Normal file
Binary file not shown.
BIN
work/dgm1_32_329_5512_tmp.tif
Normal file
BIN
work/dgm1_32_329_5512_tmp.tif
Normal file
Binary file not shown.
BIN
work/dgm1_32_329_5513_tmp.tif
Normal file
BIN
work/dgm1_32_329_5513_tmp.tif
Normal file
Binary file not shown.
BIN
work/dgm1_32_329_5514_tmp.tif
Normal file
BIN
work/dgm1_32_329_5514_tmp.tif
Normal file
Binary file not shown.
BIN
work/dgm1_32_329_5515_tmp.tif
Normal file
BIN
work/dgm1_32_329_5515_tmp.tif
Normal file
Binary file not shown.
BIN
work/tile_tmp.tif
Normal file
BIN
work/tile_tmp.tif
Normal file
Binary file not shown.
Reference in New Issue
Block a user