#!/usr/bin/env python3
"""Map-viewer tools over a built world (see README.md): refine drawn regions, preview a region's sea floor, export
terrain for games. The server itself is serve.py."""
import argparse
import os
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
import worldgen_path # noqa: E402,F401 (mapgen on sys.path)
from mapgen import config as C # noqa: E402
from mapgen import pipeline as P # noqa: E402
def main(argv=None, root: Path | None = None) -> int:
ap = argparse.ArgumentParser(prog="mapview.py")
ap.add_argument("--world", help="the world's folder (its config/, out/, places/); default: the current folder")
ap.add_argument("--low-memory", action="store_true",
help="slower, lower memory peak; same results (or set WORLDGEN_LOW_MEMORY=1)")
sub = ap.add_subparsers(dest="cmd", required=True)
for name in ("refine", "seafloor-preview", "export"):
s = sub.add_parser(name)
s.add_argument("--res", type=int)
s.add_argument("--final", action="store_true")
if name == "seafloor-preview":
s.add_argument("--region", required=True, help="a region id from places/regions.json")
if name == "export":
s.add_argument("--lat", type=float, required=True)
s.add_argument("--lon", type=float, required=True)
s.add_argument("--size-km", type=float, default=40.0)
s.add_argument("--res-m", type=float, default=10.0)
s.add_argument("--pixels", type=int, help="samples per side (default: the smallest 2^n + 1 covering the size)")
s.add_argument("--name")
s.add_argument("--out", help="folder for exports (default <world>/exports)")
s.add_argument("--workers", type=int, default=max(0, min(6, (os.cpu_count() or 2) - 2)))
s.add_argument("--era", help="an era from config/eras.toml (default: [eras] default)")
a = ap.parse_args(argv)
if a.low_memory:
os.environ["WORLDGEN_LOW_MEMORY"] = "1"
root = Path(a.world).resolve() if a.world else (root or Path.cwd())
try:
cfg, _ = C.load(root)
res = a.res if a.res is not None else int(cfg["build"]["res_final" if a.final else "res_dev"])
if a.cmd == "seafloor-preview": # the refined sea floor of a region, per era
import seafloor
print(f"preview: {seafloor.preview_region(root, res, a.region)}")
return 0
if a.cmd == "refine": # regional refinement of places/regions.json
import refine
refine.build_areas(root, res, root / "places" / "regions.json")
return 0
import export
if a.res is None:
import serve
res = serve.pick_res(root, cfg) # the map the viewer shows
d = export.export(root, res, a.lat, a.lon, a.size_km, a.res_m, out_dir=Path(a.out) if a.out else None,
name=a.name, pixels=a.pixels, workers=a.workers, era=a.era,
progress=lambda k, n: print(f"\rexport: tile {k}/{n}", end="", flush=True))
print(f"\nexport: {d}")
return 0
except (C.ConfigError, P.StageError) as e:
print(f"error: {e}", file=sys.stderr)
return 2
if __name__ == "__main__":
sys.exit(main())