"""따라가기 곡선 최적의 지형 · 제약 읽기(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)