feat(D 예정노선): 영역 루틴 — 받기 끝 지형면 · 받은 범위 먼저 → 겹 다시(차례 번호) · 도엽 겹 서버 자름 · 위치 칸 제목 서클 하나 · 10 km 밖 알림 (PLAN 604 · 요구 475 · 476-2)
- 받기 끝 = 지형면 · 받은 범위 다 읽은 뒤 겹 판정(동시 읽기 = 옛 범위 판정 뿌리) · 되돌리기 · 다시하기도 영역 확인 - 겹 load(have) — 받은 범위 지문 · 위성 틀 바뀜 = 차례 +1 · 자료 · 받는 중 비움 · 켠 겹 모두 다시 · 옛 차례 답은 자료 · GL 에 안 씀 - 등고 · 세류 = 예정노선 겹 길(layers/sheet) · 도엽 겹 모두 서버가 받은 범위로 자른 사본(화면 상자 · 보관함 지문 걷음) - 서클 = 위치 칸 제목 오른쪽 하나 · 들어간 일 수(지형 받기 · 지형면 · 겹 · 임도망 올리기) · 부품 상자 원에 제목 줄 꼴(inline) 덧 · 지도 귀퉁이 서클 걷음 - 기준점 10 km 밖 점 = 위치 칸 알림 한 줄 - 시험 553_4 서클 줄 = 새 자리로 고침 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -290,12 +290,51 @@ async def _layer_root(project_id: UUID) -> tuple[Path, int, terrain.Box]:
|
||||
return root, epsg, box
|
||||
|
||||
|
||||
SHEET_CLIP_KIND = "plan_sheet"
|
||||
SHEET_CLIP_VERSION = 1
|
||||
|
||||
|
||||
def _clip_to_box(root: Path, source: Path, box: terrain.Box, epsg: int) -> Path:
|
||||
"""받은 범위(경위도 외접 상자)로 자른 사본(475) — 열쇠 = 사본 지문 + 범위 · 실패 = 통째."""
|
||||
from B04_PreProcess.B04_PreProcess_Engine_SheetClip import clip_collection
|
||||
from common_util.common_util_derived_store import (
|
||||
derived_dir,
|
||||
derived_key,
|
||||
file_stamp,
|
||||
prune_derived,
|
||||
)
|
||||
|
||||
try:
|
||||
bounds = layers._lonlat_bounds(box, epsg)
|
||||
rect = (bounds["min_lon"], bounds["min_lat"], bounds["max_lon"], bounds["max_lat"])
|
||||
key = derived_key(
|
||||
SHEET_CLIP_VERSION, source.name, file_stamp(source), [round(v, 1) for v in box]
|
||||
)
|
||||
target = derived_dir(root, SHEET_CLIP_KIND) / f"{key}.json"
|
||||
if target.is_file():
|
||||
return target
|
||||
collection = json.loads(source.read_text(encoding="utf-8"))
|
||||
text = json.dumps(
|
||||
clip_collection(collection, rect), ensure_ascii=False, separators=(",", ":")
|
||||
)
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
temporary = target.with_suffix(f".{uuid4().hex}.tmp")
|
||||
temporary.write_text(text, encoding="utf-8")
|
||||
temporary.replace(target)
|
||||
prune_derived(root, SHEET_CLIP_KIND, keep=2 * len(layers.SHEET_LAYERS))
|
||||
return target
|
||||
except Exception as error: # 자르기 실패가 화면을 막으면 안 됨
|
||||
logger.warning("도엽 겹 받은 범위 자름 실패 (%s): %s", source.name, error)
|
||||
return source
|
||||
|
||||
|
||||
@router.get("/{project_id}/plan/layers/sheet", response_model=None)
|
||||
async def plan_layer_sheet(project_id: UUID, key: str, request: Request) -> Response:
|
||||
"""도엽 겹 GeoJSON(하천중심선 · 도로중심선 …) — 없으면 지난 병합 도엽에서 풀어 냄."""
|
||||
"""도엽 겹 GeoJSON(등고선 · 하천중심선 · 도로중심선 …) — 없으면 지난 병합 도엽에서 풀어 냄 ·
|
||||
받은 범위로 자름(475 · 범위가 늘면 새 사본)."""
|
||||
from B04_PreProcess.B04_PreProcess_Router_GIS import _display_copy
|
||||
|
||||
root, _, _ = await _layer_root(project_id)
|
||||
root, epsg, box = await _layer_root(project_id)
|
||||
try:
|
||||
path = await asyncio.to_thread(layers.ensure_sheet_layer, root, key)
|
||||
except KeyError as error:
|
||||
@@ -303,7 +342,8 @@ async def plan_layer_sheet(project_id: UUID, key: str, request: Request) -> Resp
|
||||
except FileNotFoundError as error:
|
||||
raise HTTPException(status_code=404, detail=str(error)) from error
|
||||
display = await asyncio.to_thread(_display_copy, path)
|
||||
return cached_file_response(request, display, "application/geo+json")
|
||||
clipped = await asyncio.to_thread(_clip_to_box, root, display, box, epsg)
|
||||
return cached_file_response(request, clipped, "application/geo+json")
|
||||
|
||||
|
||||
@router.get("/{project_id}/plan/layers/cadastral", response_model=None)
|
||||
|
||||
Reference in New Issue
Block a user