Files
GeoData/geodata_pipeline/citygml_utils.py

72 lines
2.0 KiB
Python

from __future__ import annotations
import glob
import os
from typing import Iterable
from .config import Config
def _tile_suffix(tile_id: str) -> str:
parts = tile_id.split("_")
return "_".join(parts[-3:]) if len(parts) >= 3 else tile_id
def _parse_tile_xy(tile_id: str) -> tuple[int, int] | None:
parts = tile_id.split("_")
coords = [p for p in parts if p.isdigit() and len(p) >= 3]
if len(coords) >= 2:
return int(coords[-2]), int(coords[-1])
return None
def _unique(paths: Iterable[str]) -> list[str]:
seen: set[str] = set()
ordered: list[str] = []
for path in paths:
if path in seen:
continue
seen.add(path)
ordered.append(path)
return ordered
def candidate_citygml_lod2_paths(tile_id: str, cfg: Config) -> list[str]:
candidates: list[str] = []
suffix = _tile_suffix(tile_id)
candidates.append(os.path.join(cfg.raw.citygml_lod2_dir, f"LoD2_{suffix}.gml"))
xy = _parse_tile_xy(tile_id)
if xy:
x, y = xy
candidates.append(os.path.join(cfg.raw.citygml_lod2_dir, f"LoD2_32_{x}_{y}_2_RP.gml"))
x2 = x - (x % 2)
y2 = y - (y % 2)
candidates.append(os.path.join(cfg.raw.citygml_lod2_dir, f"LoD2_32_{x2}_{y2}_2_RP.gml"))
return _unique(candidates)
def find_citygml_lod2(tile_id: str, cfg: Config) -> str | None:
candidates = candidate_citygml_lod2_paths(tile_id, cfg)
for path in candidates:
if os.path.exists(path):
return path
suffix = _tile_suffix(tile_id)
patterns: list[str] = [
os.path.join(cfg.raw.citygml_lod2_dir, f"*{tile_id}*.gml"),
os.path.join(cfg.raw.citygml_lod2_dir, f"*{suffix}*.gml"),
]
xy = _parse_tile_xy(tile_id)
if xy:
x, y = xy
patterns.insert(0, os.path.join(cfg.raw.citygml_lod2_dir, f"LoD2_32_{x}_{y}_*.gml"))
for pattern in patterns:
matches = sorted(glob.glob(pattern))
if matches:
return matches[0]
return None