perf(배수유역): 347-1 흐름 방향 · 도엽 좌표 저장 — 격자 원점 좌표 정수 m · 노선이 범위 안이면 읽기만
- 격자 원점 = 좌표 정수 m(GRID_ORIGIN_XY · 옛 「도로 시작점」 지시를 바꿈 · 사용자 확정) - 흐름 방향 저장본 drainage/descent_<입력 지문>_<범위>.npz — 입력 지문 = 도엽 등고선 지문 + 남긴 등고 단 + 셀 + 계산 규칙 · 덮으면 읽어 잘라 씀 · 최근 2벌 - 도엽(하천 · 등고선) 사업지 좌표 저장본 drainage/00_sheet_metric.pkl — 원본 자국 · 좌표계가 같으면 재투영 안 함 - 검증_sub3 실측: 저장본 읽기 = 지은 것과 칸마다 같음(적색 · 해석 영역 · 화살표 · 귀속 차이 0) · 108 → 10.8 s(붐빔 · 340 기준 약 6 s) · 원점 바뀜으로 적색 460,035 → 459,792칸(−0.05 %) · 관 자리 같음 - 시험 test_347_1_descent_store · 실측 bench 저장본 갈래 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XWh5wNNycMkbwMpACz1rte
This commit is contained in:
@@ -8,9 +8,11 @@
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
import math
|
||||
import pickle
|
||||
import time
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
@@ -149,6 +151,42 @@ def _map_coordinates(coordinates: Any, transformer: Transformer) -> Any:
|
||||
return [item for item in mapped if item is not None]
|
||||
|
||||
|
||||
# 도엽을 사업지 좌표로 바꾼 저장본(347-1) — 원본 파일 자국 · 좌표계가 같으면 읽기만.
|
||||
SHEET_METRIC_FILENAME = "00_sheet_metric.pkl"
|
||||
|
||||
|
||||
def _metric_sheets(
|
||||
directory: Path, cache_dir: Path, source_crs: str, transformer: Transformer
|
||||
) -> tuple[list[dict[str, Any]], list[dict[str, Any]], str]:
|
||||
"""(하천, 등고선, 도엽 등고선 지문). 피처 4,200개 재투영(3.8 s)을 한 번만 한다."""
|
||||
marks = []
|
||||
for name in (STREAM_FILE, CONTOUR_FILE):
|
||||
try:
|
||||
info = (directory / name).stat()
|
||||
marks.append(f"{name}:{info.st_mtime_ns}:{info.st_size}")
|
||||
except OSError:
|
||||
marks.append(f"{name}:-")
|
||||
text = "|".join([*marks, str(source_crs)])
|
||||
key = hashlib.sha1(text.encode(), usedforsecurity=False).hexdigest()[:16]
|
||||
path = cache_dir / SHEET_METRIC_FILENAME
|
||||
try:
|
||||
with path.open("rb") as file:
|
||||
saved = pickle.load(file)
|
||||
if saved.get("key") == key:
|
||||
return saved["streams"], saved["contours"], key
|
||||
except (OSError, pickle.PickleError, EOFError, AttributeError, KeyError, TypeError):
|
||||
pass
|
||||
streams = _reproject_features(_load_features(directory, STREAM_FILE), transformer)
|
||||
contours = _reproject_features(_load_features(directory, CONTOUR_FILE), transformer)
|
||||
try:
|
||||
cache_dir.mkdir(parents=True, exist_ok=True)
|
||||
with path.open("wb") as file:
|
||||
pickle.dump({"key": key, "streams": streams, "contours": contours}, file)
|
||||
except OSError:
|
||||
logger.warning("배수유역: 도엽 좌표 저장본을 남기지 못했습니다 (%s).", path)
|
||||
return streams, contours, key
|
||||
|
||||
|
||||
def _candidate_payload(
|
||||
candidate: StructureCandidate,
|
||||
to_lonlat: Any,
|
||||
@@ -204,10 +242,8 @@ async def _prepare(project_id: UUID) -> dict[str, Any] | JSONResponse:
|
||||
to_lonlat_transformer = Transformer.from_crs(source_crs, "EPSG:4326", always_xy=True)
|
||||
to_metric_transformer = Transformer.from_crs("EPSG:4326", source_crs, always_xy=True)
|
||||
|
||||
directory = _sheet_dir(stored_path)
|
||||
streams = _reproject_features(_load_features(directory, STREAM_FILE), to_metric_transformer)
|
||||
contour_features = _reproject_features(
|
||||
_load_features(directory, CONTOUR_FILE), to_metric_transformer
|
||||
streams, contour_features, contour_key = _metric_sheets(
|
||||
_sheet_dir(stored_path), drainage_dir(stored_path), source_crs, to_metric_transformer
|
||||
)
|
||||
return {
|
||||
"route_source": route_file.name,
|
||||
@@ -215,6 +251,7 @@ async def _prepare(project_id: UUID) -> dict[str, Any] | JSONResponse:
|
||||
"route_line": planned.line,
|
||||
"streams": streams,
|
||||
"contours": contour_features,
|
||||
"contour_key": contour_key,
|
||||
"stored_path": stored_path,
|
||||
"to_lonlat": lambda x, y: to_lonlat_transformer.transform(x, y),
|
||||
}
|
||||
@@ -403,6 +440,8 @@ async def get_primary_region(
|
||||
prepared["vertices"],
|
||||
prepared["contours"],
|
||||
prepared["streams"],
|
||||
# 흐름 방향 저장본(347-1) — 노선이 저장 범위 안이면 읽기만
|
||||
(drainage_dir(prepared["stored_path"]), prepared["contour_key"]),
|
||||
)
|
||||
if preview is None:
|
||||
return JSONResponse(
|
||||
|
||||
Reference in New Issue
Block a user