- 새 `B05_Profile_Engine_RouteInitial_Follow.merged_follow` — 예정노선 폴리라인 → 큰 R(widen) → 꺾임만 곡선 → 같은 쪽 합치기(merge_same_side · 노선 횡단 토공 +10 % 멈춤) → 곡선 MC 일반측점 맞춤 · 잼 = 토공 최소와 같은 Guard(지형 · 계류 격자) · 같은 입력 기억 - 한 함수 — 체인 처음 · /route/plan · /route/replan(`initial_land` · 초기선 낡을 때만 지형 읽음) · /route/follow(`follow_land`) · 추천 「예상노선 추적」(follow_line · 묶음 격자 재사용) - 지형 못 읽으면 옛 길(순수 기하) · 기존 확정 노선 · 초기선 · 저장본은 안 바꿈(다음 체인 · 끌 때부터) - 화면 — 따라가기 뒤 지금 추천 = 예상노선 추적(「토공 최소」 꼬리표 남던 흠) · 걸음 사진에 실려 되돌리기 짝 - 엔진 합치기 잣대 셈(cross_total · cross_delta)은 새 파일 한 벌로 옮김(엔진 줄 줄어듦) - 시험: test_758_1 새 지킴 · test_383_1 은 체인 초기선도 같은 지형을 넘기게 고침(추천 추적 = 곡선 최적이라 순수 기하와 달라짐) · test_626_3 은 onFollow 새 꼴로 글 대조 고침 - 검증_sub1: 곡선 25 → 16 · 측점 16/16 · 예정노선과 최대 10.6 m · 끌 때 1.4~1.9 s Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
71 lines
3.1 KiB
Python
71 lines
3.1 KiB
Python
"""따라가기 곡선 최적의 지형 · 제약 읽기(758-1) — 체인 처음 · `/route/plan` · `/route/replan` ·
|
|
`/route/follow` 가 `followed_table` 에 넘김.
|
|
|
|
값 = 추천 엔진 기본 풀이와 같은 자리(`..._Router_RouteInitial.compute_initial`): 종단기울기 상한 =
|
|
법정(임도 종류 · 설계속도 · 지형 · 비포장) · 지형 = 설계 지형 비용면 · 계류 · 표준 횡단면 = 프로젝트
|
|
저장값 · 나머지는 엔진 기본값. 못 읽으면 None(옛 길 — 순수 기하 따라가기).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import asyncio
|
|
import logging
|
|
from pathlib import Path
|
|
from uuid import UUID
|
|
|
|
from B05_Profile.B05_Profile_Engine_RouteInitial_Follow import FollowLand
|
|
from common_util.common_util_route_geometry import (
|
|
expected_route_csv_path,
|
|
planned_route_initial_path,
|
|
)
|
|
from config.config_db import get_db_pool
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def follow_land(project_id: UUID, project_root: Path) -> FollowLand | None:
|
|
"""이 프로젝트의 따라가기 곡선 최적 입력 · 못 읽으면 None."""
|
|
from B05_Profile.B05_Profile_Engine_Grade import legal_grade_limit_pct
|
|
from B05_Profile.B05_Profile_Engine_RouteInitial import (
|
|
load_terrain_and_streams,
|
|
resolve_inputs,
|
|
)
|
|
from B05_Profile.B05_Profile_Router_Replan import _road_settings
|
|
from B05_Profile.B05_Profile_Router_RouteInitial import project_standard
|
|
from common_util.common_util_surface_confirmation import (
|
|
analysis_terrain_params,
|
|
get_surface_confirmation_params,
|
|
)
|
|
|
|
try:
|
|
grade_class, design_speed, terrain_type = await _road_settings(project_id)
|
|
max_grade = legal_grade_limit_pct(grade_class, terrain_type, False, design_speed) / 100.0
|
|
async with get_db_pool().acquire() as connection:
|
|
selection = await get_surface_confirmation_params(connection, str(project_id))
|
|
terrain, streams = await asyncio.to_thread(
|
|
load_terrain_and_streams, project_root, analysis_terrain_params(selection, None)
|
|
)
|
|
stream_offset, grade_smooth, goal_grade = resolve_inputs(max_grade, None, None, None)
|
|
return FollowLand(
|
|
terrain,
|
|
streams,
|
|
max_grade,
|
|
stream_offset,
|
|
grade_smooth,
|
|
goal_grade,
|
|
await project_standard(project_id),
|
|
)
|
|
except Exception: # noqa: BLE001 — 지형이 없어도 따라가기는 이어 감(순수 기하)
|
|
logger.warning("따라가기 곡선 최적 지형을 못 읽어 순수 기하로 따라갑니다: %s", project_id)
|
|
return None
|
|
|
|
|
|
async def initial_land(project_id: UUID, project_root: Path) -> FollowLand | None:
|
|
"""초기 폴리라인을 새로 세울 때만 지형을 읽음(`_ensure_planned_initial` 과 같은 낡음 판정)."""
|
|
target = planned_route_initial_path(project_root)
|
|
source = expected_route_csv_path(project_root)
|
|
if target.is_file():
|
|
if not source.is_file() or source.stat().st_mtime <= target.stat().st_mtime:
|
|
return None
|
|
return await follow_land(project_id, project_root)
|