fix(배수 공용): 369 전체 자동 — 새 자리 0.5 m 안 지금 관 = 같은 관(그 자리 · 속성 · id 이어받음)
- 노선 따라감으로 0.14 m 어긋난 세월교가 새 관(관경 기본값)으로 바뀌던 흠 · 화면 SAME_PIPE_M 과 같은 값 - 검증_sub5 실측(지금 노선 메모리 격자) — 관 11 · 이어받음 5(세월교 352 m 포함) · 최대 간격 99 m Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VmC34fsxxbweEG3RUjs3Mn
This commit is contained in:
@@ -26,7 +26,7 @@ from __future__ import annotations
|
||||
|
||||
import json
|
||||
import logging
|
||||
from dataclasses import dataclass, field
|
||||
from dataclasses import dataclass, field, replace
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
@@ -66,6 +66,10 @@ _SCORE_WEIGHT_STRENGTH = 0.7
|
||||
_SCORE_WEIGHT_SAG = 0.3
|
||||
# 성토부(내리막)는 물이 노선 밖으로 빠지므로 관 위치로 덜 선호한다.
|
||||
_SCORE_FILL_PENALTY = 0.5
|
||||
# [자동 제안] 전체 자동(369) — 새 자리에서 이만큼(m) 안의 지금 관 = 같은 관(그 자리 그대로 ·
|
||||
# 속성 이어받음). 화면 `SAME_PIPE_M`(제안 · 같은 유역)과 같은 값 — 노선 따라감으로 cm 어긋난
|
||||
# 세월교도 같은 관.
|
||||
SAME_PIPE_M = 0.5
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -201,6 +205,19 @@ def build_detail(
|
||||
# 자동 관 자리 = 정수 m · 일반 측점 1 m 안이면 그 측점(234-1) — 확정본(위)은 단추로만
|
||||
placed = place_pipes(vertices, base, routing.strength_curve, fill=auto is not None)
|
||||
pipes = snap_candidates(placed, vertices)
|
||||
if confirmed_chainages:
|
||||
kept = pipes_from_chainages(vertices, confirmed_chainages)
|
||||
pipes = [
|
||||
replace(
|
||||
min(
|
||||
(k for k in kept if abs(k.chainage_m - pipe.chainage_m) <= SAME_PIPE_M),
|
||||
key=lambda k: abs(k.chainage_m - pipe.chainage_m),
|
||||
default=pipe,
|
||||
),
|
||||
reason=pipe.reason,
|
||||
)
|
||||
for pipe in pipes
|
||||
]
|
||||
candidates = suggest_pipe_positions(vertices, pipes, routing.strength_curve)
|
||||
|
||||
detail = DrainageDetail(
|
||||
|
||||
@@ -56,7 +56,7 @@ def test_all_은_세류선_더하기_100m_보충_지금_목록_무시(tmp_path):
|
||||
reasons = [p.reason for p in detail.pipes]
|
||||
places = [p.chainage_m for p in detail.pipes]
|
||||
assert reasons.count("stream") == 1 and reasons.count("spacing") == 2
|
||||
assert 150.0 in places and 10.0 not in places
|
||||
assert 150.02 in places and 10.0 not in places # 세류선 150 m 0.5 m 안의 지금 관 = 그 자리
|
||||
gaps = np.diff([0.0, *places, 300.0])
|
||||
assert gaps.max() <= 100.0 and not detail.pipe_candidates
|
||||
|
||||
@@ -78,7 +78,7 @@ def _build(tmp_path, monkeypatch, points, auto):
|
||||
|
||||
def test_all_같은_자리_관은_속성_id_유지_새_관은_기본값(tmp_path, monkeypatch):
|
||||
kept = PipePoint(
|
||||
chainage_m=150.03,
|
||||
chainage_m=150.3, # 세류선 150 m 에서 0.3 m — 노선 따라감으로 어긋난 같은 관
|
||||
source="user",
|
||||
facility="ford_bridge",
|
||||
options={"ford_width_m": 4.0},
|
||||
@@ -88,6 +88,7 @@ def test_all_같은_자리_관은_속성_id_유지_새_관은_기본값(tmp_path
|
||||
_, carried = _build(tmp_path, monkeypatch, [gone, kept], "all")
|
||||
ford = [p for p in carried if p.id == "keep"]
|
||||
assert len(ford) == 1 and ford[0].facility == "ford_bridge" and ford[0].source == "user"
|
||||
assert ford[0].chainage_m == 150.3 # 그 자리 그대로
|
||||
assert all(p.id != "gone" for p in carried)
|
||||
fresh = [p for p in carried if p.id != "keep"]
|
||||
assert len(fresh) == 2 and all(p.source == "spacing" for p in fresh)
|
||||
|
||||
Reference in New Issue
Block a user