fix(B05·B06): 옮긴 관 측점의 숨은 계획선 꼭짓점 제거(192-1)
- 측점 있음 판정 폭 0.5m → 0.005m(측점 스냅 폭) — 0.1m 옮긴 관도 측점 없음으로 셈 - 비정규 측점 병합 때 사라진 측점의 base_pvi · 편집을 지움(0.006m 안 반올림은 옮김) · 계획선 다시 셈 · DB 등급 요약 갱신 - 시험 test_192_1(검증_랩탑메인 사본 재현) · missing_stations 판정 폭 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F3mdb91125mPoC6tpsQx4P
This commit is contained in:
@@ -28,7 +28,11 @@ from fastapi import APIRouter
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from B03_FileInput.B03_FileInput_Repository import get_project_storage_relative_path
|
||||
from B05_Profile.B05_Profile_Repository import get_latest_route, get_surface_crs_epsg
|
||||
from B05_Profile.B05_Profile_Repository import (
|
||||
get_latest_route,
|
||||
get_surface_crs_epsg,
|
||||
update_longitudinal_grade_summary,
|
||||
)
|
||||
from B05_Profile.B05_Profile_Router_Confirm import load_sampling_snapshot
|
||||
from common_util.common_util_storage import resolve_stored_project_path
|
||||
from config.config_db import run_with_connection
|
||||
@@ -37,14 +41,10 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
router = APIRouter(prefix="/api/projects", tags=["B06 Section"])
|
||||
|
||||
#: 「그 자리에 측점이 있다」고 볼 거리(m).
|
||||
#: ⚠⚠ **0.5m 다 — 0.05m 가 아니다**(2026-09-09 실측으로 뒤집힌 자리).
|
||||
#: 측점을 만들 때 **정수 미터가 같은 격자 측점이 있으면 그리로 스냅**한다
|
||||
#: (`B05_Profile_Engine_Sections_Core` 의 파일명 가드). 그래서 관 440.241 은 측점 440.0
|
||||
#: 위에 서고, 그 측점은 **구조물 이름표까지 달고 있다**(`structure`).
|
||||
#: 0.05m 로 보면 그런 자리를 「측점 없음」으로 잘못 세어 **있는 측점을 또 만들라고 한다.**
|
||||
#: 스냅 폭이 「정수 미터 반올림」이므로 최대 어긋남은 0.5m 다.
|
||||
STATION_MATCH_TOLERANCE_M = 0.5
|
||||
#: 「그 자리에 측점이 있다」고 볼 거리(m) — 측점 생성의 스냅 폭과 같음
|
||||
#: (`B05_Profile_Engine_Sections_Core` · 같은 횡단 이름이 되는 0.005m 안만 한 측점).
|
||||
#: 넓으면 조금 옮긴 관(769.28 → 769.38)을 「측점 있음」으로 세어 측점이 옛 자리에 남음(192-1).
|
||||
STATION_MATCH_TOLERANCE_M = 0.005
|
||||
|
||||
SNAPSHOT_MISSING = (
|
||||
"지표 샘플링 조건을 찾을 수 없어 측점을 만들 수 없음 — 1단계(지표 확정)를 마친 뒤"
|
||||
@@ -167,7 +167,7 @@ async def _regenerate_structure_stations(
|
||||
|
||||
stored_options, crs_epsg, longitudinal = await run_with_connection(_load)
|
||||
|
||||
def _regenerate() -> int:
|
||||
def _regenerate() -> tuple[int, dict[str, Any] | None]:
|
||||
polyline = _load_route_polyline(project_root, str(route["route_data_path"]))
|
||||
pipes = _load_pipe_points(project_root, polyline)
|
||||
extras = resolve_extra_stations(project_root, pipes)
|
||||
@@ -181,13 +181,22 @@ async def _regenerate_structure_stations(
|
||||
options=_section_options_from_stored(stored_options),
|
||||
crs=f"EPSG:{crs_epsg}" if crs_epsg is not None else None,
|
||||
)
|
||||
summary = None
|
||||
if stations and longitudinal:
|
||||
_merge_irregular_into_longitudinal(
|
||||
summary = _merge_irregular_into_longitudinal(
|
||||
project_root, str(longitudinal["longitudinal_file_path"]), stations
|
||||
)
|
||||
return len(stations)
|
||||
return len(stations), summary
|
||||
|
||||
return await asyncio.to_thread(_regenerate)
|
||||
made, summary = await asyncio.to_thread(_regenerate)
|
||||
if summary is not None:
|
||||
# 옮긴 관 자리의 계획선이 다시 셈됨 — DB 등급 요약도 같이(계획선 저장과 같은 길).
|
||||
await run_with_connection(
|
||||
lambda connection: update_longitudinal_grade_summary(
|
||||
connection, route_id=route["id"], grade_summary=summary
|
||||
)
|
||||
)
|
||||
return made
|
||||
|
||||
|
||||
async def ensure_structure_stations(project_id: UUID) -> int:
|
||||
|
||||
Reference in New Issue
Block a user