fix(B04): 등고선 보간을 등간격으로 — 얇은 래스터·앵커 제거·최소 다듬기

사용자 지적(1m 보간선이 등간격 아님)의 원인 세 가지를 잡았다.
- 등고 라인 래스터가 all_touched=True라 2px 두께였다. 그 폭만큼 정확히 5m
  배수 표고인 평탄 띠가 생겨(격자의 7.6%) 사이 1m 선 간격이 찌그러졌다.
  서피스 전용 얇은 래스터화(all_touched=False)로 바꾸고, 봉우리 폐합 링이
  사라지지 않도록 길이 필터도 뺐다.
- 계곡 앵커를 1m로 양자화해 제약에 섞은 탓에 제약 표고가 29단→121단이 되어
  계곡 주변만 1m 간격이 됐다. 앵커를 뺐다 — V자 등고선이 계곡 하강을 이미
  담고 있어 거리 보간만으로 충분하다.
- 등고선 고정 완화를 수렴시키면 harmonic 해가 되어 마루가 눌린다. z=r은
  biharmonic이라서다 — ANUDEM/Topo to Raster가 라플라스가 아니라 thin plate
  spline을 쓰는 이유(Hutchinson 1988/89, 조사 결과). 다듬기를 omega=1·5회로
  줄였다. 합성 원뿔 검증: 거리보간 오차 0.121m·간격 CV 2.18 → 5회 0.118m·1.43,
  20회 이상 CV 50↑ 악화. 원뿔 회귀 테스트를 남겼다.

실측(c1bb453f): 평탄 셀 0.00%, 5m 구간 표고 분포 8.4~10.3%(균등),
생성 6.3s, 노선 |Δz| 2.64m.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-30 15:51:08 +09:00
co-authored by Claude Opus 5
parent 31e3eb4ecf
commit 15ce46d54d
2 changed files with 112 additions and 97 deletions
+4 -6
View File
@@ -188,12 +188,10 @@ SURFACE_CONTOUR_GRID_RESOLUTION_M = float(os.getenv("SURFACE_CONTOUR_GRID_RESOLU
SHEET_SURFACE_MARGIN_M = float(os.getenv("SHEET_SURFACE_MARGIN_M", "300.0"))
# 도엽등고선 DTM 격자 한 변(m). LAS DTM·등고선 캐시와 같은 1m(사용자 확정값).
SHEET_SURFACE_GRID_M = float(os.getenv("SHEET_SURFACE_GRID_M", "1.0"))
# 중간 보간선(인접 등고선 쌍의 등거리선) 탐색 최대 거리(m). 등고선 간격이 이보다 넓은
# 완경사면은 보간선을 넣지 않는다. 5m 주곡선 기준 경사 2.5%까지 커버.
SHEET_SURFACE_MIDLINE_MAX_M = float(os.getenv("SHEET_SURFACE_MIDLINE_MAX_M", "200.0"))
# 가상 등고라인 반복 이분 횟수. 2회 = 5m 주곡선 → 2.5m → 1.25m 가상 등고 생성
# (2026-08-30 사용자 지시 — 2D 사이 등고선을 먼저 만들고 3D화).
SHEET_SURFACE_MIDLINE_ROUNDS = int(os.getenv("SHEET_SURFACE_MIDLINE_ROUNDS", "2"))
# 등고선 고정 다듬기 반복 횟수. 거리 보간이 능선·계곡 중심축에 남기는 각진 자국만
# 지우는 용도라 **적을수록 좋다** — 수렴시키면 harmonic 해가 되어 마루가 눌린다
# (합성 원뿔 검증: 5회가 최적, 20회 이상 악화). 0이면 다듬지 않는다.
SHEET_SURFACE_RELAX_ITERATIONS = int(os.getenv("SHEET_SURFACE_RELAX_ITERATIONS", "5"))
# 일반 사용자 WF1 자동 확정 기본값
SURFACE_CONFIRM_DEFAULT_FILTER = os.getenv("SURFACE_CONFIRM_DEFAULT_FILTER", "csf")