96 lines
3.4 KiB
Python
96 lines
3.4 KiB
Python
from __future__ import annotations
|
|
|
|
import argparse
|
|
import shutil
|
|
import sys
|
|
from pathlib import Path
|
|
import numpy as np
|
|
|
|
ROOT_DIR = Path(__file__).resolve().parents[1]
|
|
if str(ROOT_DIR) not in sys.path:
|
|
sys.path.insert(0, str(ROOT_DIR))
|
|
|
|
from config import TERRAIN_MODEL_CONFIG
|
|
from utils.terrain_model_converter import build_all_terrain_models
|
|
|
|
|
|
def parse_args() -> argparse.Namespace:
|
|
parser = argparse.ArgumentParser(
|
|
description="TIN과 DTM 지표면 모델만 빠르게 재생성 및 스무딩을 테스트합니다.",
|
|
)
|
|
parser.add_argument("--project-id", default="upload_sample", help="instance 하위 프로젝트 ID")
|
|
return parser.parse_args()
|
|
|
|
|
|
def clean_terrain_outputs(project_dir: Path) -> None:
|
|
project_dir = project_dir.resolve()
|
|
terrain_dir = (project_dir / "terrain_models").resolve()
|
|
if terrain_dir.parent != project_dir:
|
|
raise RuntimeError(f"삭제 대상이 프로젝트 폴더 밖입니다: {terrain_dir}")
|
|
if terrain_dir.exists():
|
|
# dtm과 tin 관련 파일만 선별 삭제
|
|
for f in terrain_dir.glob("*"):
|
|
if "tin" in f.name or "dtm" in f.name or f.name == "manifest.json":
|
|
if f.is_file():
|
|
f.unlink()
|
|
elif f.is_dir():
|
|
shutil.rmtree(f)
|
|
print(f"[정리] {terrain_dir} 내 tin/dtm 관련 파일 정리 완료")
|
|
|
|
|
|
def main() -> int:
|
|
args = parse_args()
|
|
project_dir = ROOT_DIR / "instance" / args.project_id
|
|
structured_path = project_dir / "structured.npz"
|
|
if not structured_path.exists():
|
|
raise FileNotFoundError(
|
|
f"{structured_path}가 없습니다. run_filters_and_terrain_models.py를 먼저 실행하세요."
|
|
)
|
|
|
|
masks: dict[str, np.ndarray] = {}
|
|
for source_filter in TERRAIN_MODEL_CONFIG["source_filters"]:
|
|
mask_path = project_dir / f"mask_{source_filter}.npy"
|
|
if not mask_path.exists():
|
|
raise FileNotFoundError(
|
|
f"{mask_path}가 없습니다. run_filters_and_terrain_models.py를 먼저 실행하세요."
|
|
)
|
|
masks[source_filter] = np.load(mask_path, mmap_mode="r")
|
|
|
|
print(f"[입력] 프로젝트={args.project_id}")
|
|
print(f"[입력] 구조화={structured_path}")
|
|
|
|
# 캐시 스킵 방지를 위해 기존 파일 삭제 부분 주석 처리
|
|
# clean_terrain_outputs(project_dir)
|
|
|
|
# TIN과 DTM 방식만 실행하도록 임시 오버라이드
|
|
fast_config = TERRAIN_MODEL_CONFIG.copy()
|
|
fast_config["precompute"] = ("tin", "dtm")
|
|
|
|
print("[모델] TIN 및 DTM 조합(스무딩 포함) 계산 시작")
|
|
with np.load(structured_path) as data:
|
|
manifest = build_all_terrain_models(
|
|
data,
|
|
masks,
|
|
project_dir / "terrain_models",
|
|
fast_config,
|
|
force=False, # force=False로 변경하여 이미 만들어진 파일은 연산을 스킵하게 함
|
|
)
|
|
|
|
print(
|
|
f"[완료] 상태={manifest['status']} | 실패={manifest['failure_count']} | "
|
|
f"{manifest['duration_seconds']:.2f}초"
|
|
)
|
|
print(f"[결과] {project_dir / 'terrain_models'}")
|
|
return 0 if manifest["failure_count"] == 0 else 1
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
raise SystemExit(main())
|
|
except KeyboardInterrupt:
|
|
print("\n[중단] 사용자가 실행을 중단했습니다.")
|
|
raise SystemExit(130)
|
|
except Exception as exc:
|
|
print(f"\n[오류] {exc}", file=sys.stderr)
|
|
raise SystemExit(1)
|