feat(B04): 배경 지도 여유폭을 미터가 아닌 주변 셀 겹수로 지정

사용자 요청 방향(2026-08-01): 해상도(zoom 18)는 그대로 두고, 계획노선과 기준 좌표를
덮는 타일 바깥으로 주변 셀을 더 확보한다.

- SURFACE_MAP_MARGIN_M(300m) 제거, SURFACE_MAP_MARGIN_TILES(3겹) 신설.
  기존 하드코딩 1겹 -> 설정값. zoom 18에서 1겹 약 122m(위도 37deg).
- download_extent는 덮어야 할 범위(라이다 U 계획노선)만 돌려주고 여유는 타일 쪽에서 준다.
- 표본 실측: 덮을 범위 372x401m -> 10x11 타일 = 1220x1341m,
  계획노선 사방 여유 474~588m (이전 731x853m).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-01 12:11:39 +09:00
co-authored by Claude Opus 5
parent 5073916739
commit d3b443e077
3 changed files with 19 additions and 16 deletions
@@ -11,8 +11,6 @@ import logging
from pathlib import Path
from typing import Any
from config.config_system import SURFACE_MAP_MARGIN_M
logger = logging.getLogger(__name__)
_ROUTE_CSV_GLOB = "B03_FileInput/input/csv/*.csv"
@@ -49,9 +47,11 @@ def download_extent(
project_root: Path,
las_bounds: dict[str, list[float]],
target_epsg: str,
margin_m: float = SURFACE_MAP_MARGIN_M,
) -> dict[str, list[float]]:
"""배경 지도를 내려받을 범위. 라이다 범위 계획노선을 합친 뒤 여유폭만큼 넓힌다.
"""배경 지도가 반드시 덮어야 할 범위 = 라이다 범위 계획노선 범위.
여유폭은 여기서 미터로 더하지 않는다. 내려받기 쪽에서 이 범위를 덮는 타일을 정한 뒤
바깥으로 `SURFACE_MAP_MARGIN_TILES` 겹만큼 주변 셀을 더 받는다(2026-08-01 사용자 지시).
las_bounds/반환값 모두 {"x": [최소, 최대], "y": [...], "z": [...]} 꼴(라이다 좌표계).
"""
@@ -75,8 +75,8 @@ def download_extent(
y_min, y_max = min(y_min, y), max(y_max, y)
return {
"x": [x_min - margin_m, x_max + margin_m],
"y": [y_min - margin_m, y_max + margin_m],
"x": [x_min, x_max],
"y": [y_min, y_max],
"z": list(las_bounds.get("z", [0.0, 0.0])),
}
@@ -19,8 +19,10 @@ try:
VWORLD_API_KEY = getattr(
config_system, "VWORLD_API_KEY", "3DBD7306-7DBD-38BB-B292-267C5ED7AC6B"
)
SURFACE_MAP_MARGIN_TILES = getattr(config_system, "SURFACE_MAP_MARGIN_TILES", 3)
except ImportError:
VWORLD_API_KEY = "3DBD7306-7DBD-38BB-B292-267C5ED7AC6B"
SURFACE_MAP_MARGIN_TILES = 3
def get_epsg_from_prj(prj_content: str) -> str:
@@ -103,11 +105,12 @@ def download_vworld_satellite_map(
x1, y1 = latlon_to_tile(lat_max, lon_min, zoom)
x2, y2 = latlon_to_tile(lat_min, lon_max, zoom)
# 타일 경계 마진 패딩
x_start = min(x1, x2) - 1
x_end = max(x1, x2) + 1
y_start = min(y1, y2) - 1
y_end = max(y1, y2) + 1
# 범위를 덮는 타일 바깥으로 주변 셀을 더 받는다(해상도는 그대로, 셀만 확장).
margin = SURFACE_MAP_MARGIN_TILES
x_start = min(x1, x2) - margin
x_end = max(x1, x2) + margin
y_start = min(y1, y2) - margin
y_end = max(y1, y2) + margin
tile_w = x_end - x_start + 1
tile_h = y_end - y_start + 1
+5 -5
View File
@@ -516,11 +516,11 @@ STORAGE_BASE_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "sto
MAP_SHEETS_DIRNAME = "map_sheets"
MAP_SHEETS_INDEX_FILENAME = "map_sheets_index.json"
# 배경 지도(위성·하이브리드·백지도) 내려받을 범위의 여유폭.
# 라이다 범위와 계획노선을 합친 뒤 이만큼 넓혀서 받는다 — 계획노선이 라이다 범위를 벗어나도
# 배경이 잘리지 않게 한다. 브이월드 위성사진은 더 높은 해상도를 주지 않으므로 도엽만큼
# 넓게 받을 필요는 없다(2026-08-01 사용자 지시).
SURFACE_MAP_MARGIN_M = 300.0
# 배경 지도(위성·하이브리드·백지도) 내려받을 때 덧붙일 주변 셀(타일) 겹 수.
# 계획노선과 기준 좌표(라이다 범위)를 덮는 타일을 먼저 정하고, 그 바깥으로 이만큼 받는다.
# 해상도(zoom)는 그대로 두고 주변 셀만 늘린다 — 브이월드가 더 높은 해상도를 주지 않는다
# (2026-08-01 사용자 지시). zoom 18에서 셀 1겹 ≈ 122m(위도 37° 기준), 3겹 ≈ 366m.
SURFACE_MAP_MARGIN_TILES = 3
# 브이월드 지도서비스 도엽 자동 다운로드 — 세션 만료 시 id/pw로 자동 재로그인 (.env)
VWORLD_LOGIN_ID = os.getenv("VWORLD_LOGIN_ID", "")