feat(배수유역): 347-2 「지금 노선으로 셈」 서버 길 · 347-3 관 자리 후보 · [확정] 다시 셈

- POST drainage/live — 몸통 = 차례 번호 + 노선 초안(RouteDraft · 노선 [확인]과 같은 폴리라인 규칙) + 관 목록 · 서버 단독 · 작업본(00_watershed_response · 격자 배열 · 관 지점)에 안 씀 · 세부 유역까지 메모리 격자로 한 요청
- 프로젝트별 마지막 차례 · 1차 영역 뒤 · 확장 회차마다 · 세부 유역 앞에서 바뀌었으면 그만둠(superseded · AnalysisStopped)
- build_detail 에 메모리 routing · 상류선 · 관 자리 후보 suggest_pipe_positions(간격 보충 규칙 · 흐름 세기 + 오목 · 기존 관에서 먼 곳 · 정수 m) · 응답 pipe_candidates
- PUT pipe-points ?recompute=true([확정]) = 낡았으면 배수유역부터 다시 셈 · [저장]은 낡음 달고 관만
- 시험 test_347_2_drainage_live(늦은 차례 그만둠 둘 · 엔진 회차 그만둠 · 메모리 격자 · 후보 · 확정 다시 셈) · 검증_sub3 실측 저장 노선 16.9 s · 초안 노선 11.5 s

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWh5wNNycMkbwMpACz1rte
This commit is contained in:
2026-10-16 11:38:17 +09:00
co-authored by Claude Opus 5.5
parent c0ad3edc80
commit d5d6415966
7 changed files with 399 additions and 5 deletions
@@ -21,6 +21,7 @@ from __future__ import annotations
import logging
import time
from collections.abc import Callable
from dataclasses import dataclass
from pathlib import Path
from typing import Any
@@ -58,6 +59,10 @@ logger = logging.getLogger(__name__)
DESCENT_SPARE_M = 400.0
class AnalysisStopped(Exception):
"""새 차례가 와서 계산을 그만둠(「지금 노선으로 셈」 · 347-2) — 단계 사이에서만 확인."""
@dataclass
class GridAnalysis:
"""한 회차 분석 결과 — 격자·해석 영역·방향·색까지 한 묶음."""
@@ -142,6 +147,7 @@ def expand_by_red_boundary(
band_m: float = DRAINAGE_RED_EXPAND_BAND_M,
max_rounds: int = DRAINAGE_RED_EXPAND_MAX_ROUNDS,
descent_store: tuple[Path, str] | None = None,
should_stop: Callable[[], bool] | None = None,
) -> RedExpansion | None:
"""최외곽 적색 셀 주변으로 넓히며, 새로 추가한 셀에 적색이 없을 때까지 반복한다."""
_expand_started = time.perf_counter()
@@ -194,6 +200,8 @@ def expand_by_red_boundary(
rounds = 0
closed = False
for attempt in range(max_rounds):
if should_stop is not None and should_stop():
raise AnalysisStopped
_round_started = time.perf_counter()
current = analysis.spec
reaches = analysis.flow.reaches_road.reshape(current.n_rows, current.n_cols)