[Spring Boot] Haversine 공식을 이용한 원하는 범위의 마커 출력하기

2025. 10. 12. 21:06·Framework & Library/Spring Boot

대학생 주거 리뷰 플랫폼, 찐빵 서비스 운영 중 문제가 발생하였다.
원룸 리뷰를 작성할 때 건물 정보를 함께 입력하게 되는데, 원룸의 위치만으로 캠퍼스를 명확히 특정할 수 없는 경우가 많았다.

예를 들어

  • 건물이 두 개 이상의 캠퍼스 반경에 겹치는 경우
  • 특정 캠퍼스에서 조금 떨어져 있지만 사실상 생활권인 경우
  • 애초에 전혀 다른 곳에 사는 경우

초기 설계 단계에서 검색 필터에서 캠퍼스를 선택할 경우 캠퍼스 ID를 이용하여 검색하는 로직으로 구현했기에, 이런 애매한 상황은 마커 조회 및 검색 로직에서 걸림돌이 되었다.

그래서 캠퍼스 위치(위도·경도)를 기준으로 반경 1~2km 내의 모든 마커를 불러오는 방식으로 로직을 전환하기로 했다.

그래서 현재 위치(위도, 경도) 기반으로 반경에 속하는 마커들을 어떻게 하면 불러올 수 있을까 해서 발견한 것이 Haversine 공식이다.

Haversine 공식이란?

지구와 같은 구체의 두 지점 사이의 거리를 계산하기 위한 수학 공식이다.

image.png

)

image.png

잘 와닿지 않겠지만 대표적인 예를 보자.

image.png

위 두 사진을 보았을 때 신기하게 밑의 경로가 곡선이지만 더 짧은 것을 볼 수 있다.

왜냐하면 밑의 곡선 경로가 돌아가는 것처럼 보이지만, 사실 3차원의 공간에서의 거리를 2차원 평면에서 거리로 투영했기 때문에 곡선으로 보이지만 실제 지구 곡면 위에선 직선에 해당하는 경로이다.

그래서 Haversine 공식을 사용하면 곡면상의 최단 거리를 수학적으로 계산을 하기에 GPS, 네비게이션, 지도 서비스 등 여러 거리 계산에 활용된다.

계산 공식 및 코드

계산 공식은 다음과 같다

image.png

중심각이 위와 같을때 (d는 두 지점 사이의 거리, r은 지구의 반지름), $θ$의 하버사인은 다음과 같이 계산 가능하다.

image.png

)

image.png

)

image.png

위를 토대로 실제 거리 d는 다음과 같이 계산된다.

$$
d=2R⋅arcsin(hav(θ))
$$

즉, 두 점의 위도·경도를 이용해 중심각을 구한 뒤, 이를 지구 반지름에 곱하면 실제 거리를 구할 수 있다.

위도·경도 값은 반드시 라디안(radian) 단위로 변환 후 계산해야 한다.

보통 DB나 API로 받는 좌표는 도(degree) 단위이므로 변환 과정이 필수다.

/icons/fire_gray.svg

주의사항
위도·경도 값은 반드시 라디안(radian) 단위로 변환 후 계산해야 한다.

보통 DB나 API로 받는 좌표는 도(degree) 단위이므로 변환 과정이 필수다.

private static final double EARTH_RADIUS_METERS = 6371000; // 지구 반지름 (m 단위)

private double calculateDistanceMeters(double lat1, double lng1, double lat2, double lng2) {
                // 1. 위도·경도 차이를 라디안으로 변환
        double dLat = Math.toRadians(lat2 - lat1);
        double dLng = Math.toRadians(lng2 - lng1);

                // 2. Haversine 공식 적용
        double a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
                + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2))
                * Math.sin(dLng / 2) * Math.sin(dLng / 2);

        // 3. 중심각(θ) 계산
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));

                // 4. 거리 반환 (단위: m)
        return EARTH_RADIUS_METERS * c;
}
  1. 위도, 경도 차이를 Math.toRadians()를 이용하여 라디안으로 변환
  2. 두 점 사이의 구면 삼각형에 Haversine 함수 적용
  3. Math.atan2()로 중심각 구하기
  4. 지구 반지름에 곱해 실제 거리를 계산

마무리

Haversine 공식에서는 지구가 완전한 구형이라고 가정을 했지만 실제 지구는 적도 쪽이 좀 더 길쭉한 타원형이기 때문에 아주 정확하다곤 할 수 없다. 그래서 매우 정확한 거리를 알아야한다면 타원체인 것을 고려한 Vincenty 공식을 사용하는게 좋다. 하지만, 계산량이 좀 더 많아지고 살짝 더 복잡하다..

우리 서비스는 단순히 1~2km 반경의 마커들을 조회만 하면 되기에 계산량이 적고 좀 더 빠른 Haversine 공식을 채택하였지만 각 서비스에 맞춰서 원하는 공식을 적용하면 좋을 거 같다..!

참조

Haversine formula

[지리 정보] 지리적 좌표계, 위도/경도의 이해 및 Haversine 공식을 이용한 지도 좌표 거리 계산 Kotlin 함수 작성

'Framework & Library > Spring Boot' 카테고리의 다른 글

[Spring Boot] Spring Boot Actuator 살펴보기  (0) 2025.09.26
'Framework & Library/Spring Boot' 카테고리의 다른 글
  • [Spring Boot] Spring Boot Actuator 살펴보기
ryuwon
ryuwon
여러 개발 정보 끄적이고 있습니닷..
  • ryuwon
    이름 없는 블로그
    ryuwon
  • 글쓰기 관리
  • 전체
    오늘
    어제
    • 분류 전체보기 (34)
      • Series (0)
      • Programming (1)
        • Java (1)
        • C (0)
        • Swift (0)
      • Framework & Library (8)
        • Spring (6)
        • Spring Boot (2)
      • Data & ORM (0)
        • RDBMS (0)
        • NoSQL (0)
        • ORM (0)
      • Infra & DevOps (1)
        • Cloud (0)
        • DevOps (1)
        • Infra (0)
      • Knowledge (4)
        • 자료구조 (1)
        • 알고리즘 (3)
        • 운영체제 (2)
        • 네트워크 (1)
        • 아키텍쳐 및 디자인 패턴 (0)
        • 개발지식 (3)
      • Testing (0)
      • Security & System (0)
      • Project (5)
      • Writing (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    프로젝트
    OCI
    찐빵
    네트워크
    Spring Profile
    K3S
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.5
ryuwon
[Spring Boot] Haversine 공식을 이용한 원하는 범위의 마커 출력하기
상단으로

티스토리툴바