fix(754-1): B04 등고선 · 격자 외곽 = 지금 지표면 외곽 — 어느 표현을 지어도 낡은 dtm 같이 다시 지음 · 등고선 캐시 판단에 dtm · 굳힌 격자 때

- 지표면 짓기 차례에 dtm 을 늘 맨 앞 — manifest 항목 없음 · 지문 다름이면 같이 다시 지음(화면 [서피스 생성] = 표현 하나만 짓던 길)
- 등고선 캐시 낡음 = 모델 · 같은 필터 dtm · implicit 굳힌 격자 중 하나라도 더 새것(짓기 차례 · 등고선 API 한 함수)
- 등고선 추출이 모델 · dtm 파일을 닫음 — 실패 때 열린 채 남아 Windows 에서 다시 짓기(교체)가 막히던 흠
- ptd 처럼 dtm 없던 필터도 dtm · 굳힌 격자가 생겨 ptd · implicit 확정 길 B05 · B06 열림
- 새 시험 test_754_1_contour_outline.py

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-02 23:13:13 +09:00
co-authored by Claude Opus 5.5
parent d87c7b14fd
commit 3f4fd188e8
4 changed files with 150 additions and 15 deletions
@@ -16,6 +16,7 @@ import numpy as np
from B04_PreProcess.B04_PreProcess_Engine_Contour import (
CONTOUR_EXTRACTOR_VERSION,
contour_cache_is_stale,
extract_contours,
)
from B04_PreProcess.B04_PreProcess_Engine_ModelBuild import BUILDERS
@@ -191,11 +192,9 @@ def _build_all_terrain_models(
output_dir.mkdir(parents=True, exist_ok=True)
manifest_path = output_dir / "manifest.json"
filters = tuple(key for key in config["source_filters"] if key in ground_masks)
methods_list = [key for key in config["precompute"] if key in BUILDERS]
if "dtm" in methods_list:
methods_list.remove("dtm")
methods_list.insert(0, "dtm")
methods = tuple(methods_list)
# dtm 은 늘 맨 앞 — 같은 필터 외곽 · implicit 굳힌 격자 · 등고선 자르기의 바탕이라
# 어느 표현을 지어도 낡았으면(manifest 항목 없음 · 지문 다름) 같이 다시 지음(754-1).
methods = ("dtm", *(key for key in config["precompute"] if key in BUILDERS and key != "dtm"))
# 무거운 implicit 은 기본 필터(첫 필터)에만 — 분류 LAS 의 csf 까지 두 번 짓지 않음(요구 558).
later_methods = tuple(method for method in methods if method != "implicit")
signature = config_signature(config)
@@ -244,12 +243,14 @@ def _build_all_terrain_models(
if not force and _cache_is_valid(output_dir, stem, method, entry, config):
interval = float(config.get("contour_interval_meters", 1.0))
contour_path = output_dir / f"contour_{filter_key}_{method}_{interval}m.json"
needs_contours = not contour_path.exists()
needs_contours = contour_cache_is_stale(contour_path, output_dir / f"{stem}.npz")
if method in config.get("smoothing_methods", ("dtm", "tin")):
smooth_contour_path = (
output_dir / f"contour_{filter_key}_{method}_smooth_{interval}m.json"
)
needs_contours = needs_contours or not smooth_contour_path.exists()
needs_contours = needs_contours or contour_cache_is_stale(
smooth_contour_path, output_dir / f"{stem}_smooth.npz"
)
if needs_contours:
_cache_contours_safely(
output_dir,