Files
GeoData/geodata_pipeline/config.py

107 lines
2.9 KiB
Python

from __future__ import annotations
import json
import os
from dataclasses import asdict, dataclass, field, replace
from typing import Any, Dict
DEFAULT_CONFIG_PATH = "geodata_config.json"
@dataclass
class RawConfig:
dgm1_dir: str = "raw/dgm1"
dop20_dir: str = "raw/dop20/jp2"
citygml_lod1_dir: str = "raw/citygml/lod1"
citygml_lod2_dir: str = "raw/citygml/lod2"
@dataclass
class ArchiveConfig:
dgm1_dir: str = "archive/dgm1"
dop20_dir: str = "archive/dop20"
citygml_lod1_dir: str = "archive/citygml/lod1"
citygml_lod2_dir: str = "archive/citygml/lod2"
@dataclass
class WorkConfig:
work_dir: str = "work"
heightmap_vrt: str = "work/dgm.vrt"
ortho_vrt: str = "work/dop.vrt"
@dataclass
class ExportConfig:
heightmap_dir: str = "export_unity/height_png16"
ortho_dir: str = "export_unity/ortho_jpg"
manifest_path: str = "export_unity/tile_index.csv"
@dataclass
class HeightmapConfig:
out_res: int = 1025
resample: str = "bilinear"
tile_size_m: int = 1000
@dataclass
class OrthoConfig:
out_res: int = 2048
jpeg_quality: int = 90
@dataclass
class Config:
raw: RawConfig = field(default_factory=RawConfig)
archives: ArchiveConfig = field(default_factory=ArchiveConfig)
work: WorkConfig = field(default_factory=WorkConfig)
export: ExportConfig = field(default_factory=ExportConfig)
heightmap: HeightmapConfig = field(default_factory=HeightmapConfig)
ortho: OrthoConfig = field(default_factory=OrthoConfig)
@classmethod
def default(cls) -> "Config":
return cls()
@classmethod
def load(cls, path: str = DEFAULT_CONFIG_PATH) -> "Config":
with open(path, "r", encoding="utf-8") as f:
data = json.load(f)
return cls.from_dict(data)
@classmethod
def from_dict(cls, data: Dict[str, Any]) -> "Config":
return cls(
raw=RawConfig(**data["raw"]),
archives=ArchiveConfig(**data["archives"]),
work=WorkConfig(**data["work"]),
export=ExportConfig(**data["export"]),
heightmap=HeightmapConfig(**data["heightmap"]),
ortho=OrthoConfig(**data["ortho"]),
)
def to_dict(self) -> Dict[str, Any]:
return asdict(self)
def save(self, path: str = DEFAULT_CONFIG_PATH) -> None:
with open(path, "w", encoding="utf-8") as f:
json.dump(self.to_dict(), f, indent=2)
def with_overrides(self, raw_dgm1_path: str | None = None, raw_dop20_path: str | None = None) -> "Config":
cfg = self
if raw_dgm1_path:
cfg = replace(cfg, raw=replace(cfg.raw, dgm1_dir=raw_dgm1_path))
if raw_dop20_path:
cfg = replace(cfg, raw=replace(cfg.raw, dop20_dir=raw_dop20_path))
return cfg
def ensure_default_config(path: str = DEFAULT_CONFIG_PATH) -> Config:
if not os.path.exists(path):
cfg = Config.default()
cfg.save(path)
return cfg
return Config.load(path)