지역 정보(맛집·관광지·축제)는 행정구역 코드(local_contents.region_code) 단위로 캐시돼 "그 시군구에 있는 것"을 줬다. 양양군 업장 옆 5km 속초 관광지는 빠지고 같은 군 반대편 30km 맛집이 붙는 구조라, 캔버스의 지역 정보 섹션은 늘 "준비 중"이었다. 업장 좌표로 TourAPI 를 직접 물어 업장 단위(place_contents)에 담고, 캔버스는 스크린샷으로 받은 형식(도보 시간 필터 + 카드 캐러셀)으로 통일했다.
25 lines
1.3 KiB
Python
25 lines
1.3 KiB
Python
"""좌표 거리 — 공용 한 벌.
|
|
|
|
★ 같은 하버사인 공식이 tour_lookup(500m 동일업소 판정)·itinerary(일정 반경)·tour_api(축제 20km 필터)
|
|
세 곳에 각각 복사돼 있었다(2026-09-08 정리). 지구 반지름·단위가 파일마다 달라지면 같은 두 점의
|
|
거리가 모듈마다 다르게 나온다 — 거리로 무엇을 넣고 뺄지 정하는 코드가 셋이라 한 벌이어야 한다.
|
|
|
|
국내 범위라 하버사인(구면 근사)이면 충분하다. 오차는 수 m 수준으로, 우리가 쓰는 판정
|
|
(500m 이내·5~20km 반경)에서 결과를 바꾸지 않는다.
|
|
"""
|
|
import math
|
|
|
|
EARTH_RADIUS_M = 6_371_000.0
|
|
|
|
|
|
def haversine_m(lat1: float, lng1: float, lat2: float, lng2: float) -> float:
|
|
"""두 좌표(위도, 경도) 사이의 거리(m). ★ 인자 순서는 (위도, 경도) — mapx/mapy 는 (경도, 위도)라 뒤집어 넣는다."""
|
|
p1, p2 = math.radians(lat1), math.radians(lat2)
|
|
dp, dl = math.radians(lat2 - lat1), math.radians(lng2 - lng1)
|
|
a = math.sin(dp / 2) ** 2 + math.cos(p1) * math.cos(p2) * math.sin(dl / 2) ** 2
|
|
return 2 * EARTH_RADIUS_M * math.asin(math.sqrt(a))
|
|
|
|
|
|
def haversine_km(lat1: float, lng1: float, lat2: float, lng2: float) -> float:
|
|
return haversine_m(lat1, lng1, lat2, lng2) / 1000.0
|