마커 펼치기로 포장 지도 UX 개선하기 : Map Projection

6 hours ago 3

마커 펼치기로 포장 지도 UX 개선하기 : Map Projection

안녕하세요. 요기요 모바일팀 Android 개발자 김윤한입니다.

요기요의 포장 지도 화면에서 동일한 위경도에 여러 가게가 존재할 때 유저의 탐색 가독성이 떨어지는 문제가 있었습니다.

이 글에서는 Map Projection 기반의 마커 펼치기 구현 과정과 탐색 가독성을 유지하기 위해 했던 고민들을 소개 해 드리겠습니다.

왜 이 개선이 필요했는가

같은 건물이나 상가에 여러 가게가 입점한 경우 지도에서는 마커가 겹쳐 보입니다. 기존에는 핀 리스트로 이를 보완했지만 사용자가 지도에서 직관적으로 가게를 탐색하기 어려웠고 지도를 보며 선택하는 흐름이 끊기는 문제가 있었습니다.

개선 전 동일한 위치의 겹쳐진 가게들

마커가 겹치면 지도 위에서 개별 가게를 선택할 수 없어 사용자가 지도 화면을 이탈하는 경우가 많았습니다. 이번 개선의 목표는 동일 위치의 가게를 지도 위에서 분리해 보여주어 사용자가 탐색 흐름을 유지한 채로 원하는 가게를 선택할 수 있게 만드는 것입니다.

탐색 경험을 개선하는 변화

사용자의 탐색 경험을 개선하기 위해 적용한 변화는 크게 두 가지입니다.

  • 지도 이동 시 자동 재검색
  • 겹쳐진 마커를 펼치기

기존에는 지도 이동 후 재검색 버튼이 노출되고 사용자가 버튼을 눌러야 결과가 갱신되는 흐름이었습니다. 개선 후에는 지도 이동 시 자동 재검색을 통해 결과가 자연스럽게 갱신되도록 했습니다. 사용자가 별도의 버튼을 눌러 상태를 갱신하지 않아도 되기 때문에 지도를 움직이며 탐색하는 흐름이 끊기지 않게 되었습니다.

지도 이동을 통한 자동 재검색

기존에는 동일 위치 가게가 겹치면 핀 리스트를 통해 탐색해야 했습니다. 핀 리스트의 경우 지도 화면에서 탐색 가독성이 떨어졌습니다. 이를 해결하기 위해 지도 확대 시 같은 위치 가게들을 지도 위에서 펼쳐져 개별 선택이 가능하도록 개선하였습니다. 결과적으로 포장 화면에서의 탐색과 선택이 자연스러워 질 수 있었습니다.

그렇다면 UX 개선의 핵심인 “마커 펼치기” 계산을 어디에서 수행할까요?

클라이언트 마커 펼치기: Projection과 Zoom Level

마커 펼치기는 사용자의 현재 지도 상태(Projection, Zoom Level, 화면 좌표계)에 직접 영향을 받습니다. 따라서 서버에서 좌표를 계산해 내려주면 사용자가 보는 “현재 화면 기준”으로 일관된 결과를 보장하기 어렵습니다. 또한 지도 이동 시 자동 재검색이 동작하는 환경에서 서버 계산/전송을 늘리는 방식이 비용과 지연 측면에서 불리할 수 있습니다.

반면 클라이언트에서는 Map Projection을 활용해 실시간 계산이 가능했고 펼치기 개수/조건을 제한하면 성능도 안정적으로 관리할 수 있다고 판단했습니다. 이 결론을 바탕으로 겹친 마커를 어떤 형태로 펼칠 것인가를 결정했습니다.

균등 분할과 최소 면적: 원형 배치

동일한 위경도를 가진 가게들을 펼쳐서 보여주는 것에 대한 다양한 논의가 있었고 원형으로 펼치는 의견을 제안했습니다. 원형 배치는 “균등 분할”이라는 단순한 원리를 가집니다.

val radius = distance * factor // 반경
val angle = 2 * Math.PI * index / maxIndex // 각도
val dx = radius * Math.cos(angle)
val dy = radius * Math.sin(angle)
  • 마커 N개일 때 각도 간격 = 360° / N
  • 반경(radius)과 각도(angle)로 dx, dy를 만들고
  • 기준점에서 dx, dy만큼 이동한 좌표로 마커를 배치합니다.
개수 별 원형으로 펼쳐진 마커

3개의 마커라면 120°, 4개라면 90°, 5개라면 72° 간격을 두고 원형으로 배치됩니다.

다만 여기서 한 가지 문제가 있습니다. 위경도 좌표계에 dx·dy를 그대로 더하면 지도 상 거리/형태가 일정하지 않습니다.

위도에 따라 경도 1도의 실제 거리가 달라지기 때문입니다. 위경도에 dx·dy를 단순히 더하면 화면에서는 원형이 찌그러지거나 간격이 달라 보일 수 있습니다. 왜곡을 해결하기 위해서는 Map Projection이 필요합니다.

Map Projection

지구는 평면이 아닌 곡면이기 때문에 이를 평면으로 펼치는 과정에서 왜곡이 발생합니다. 곡면 좌표를 평면 좌표로 옮기는 과정에서는 발생한 왜곡을 해결하기 위해 Map Projection 활용하였습니다.

좌 : 위경도 기반 펼쳐진 마커/ 우 : Map Projection 기반 펼쳐진 마커

위경도 좌표계를 그대로 사용하면 왜곡이 발생해 타원 형태로 불균등하게 펼쳐집니다. 반면 Map Projection을 적용하면 원형으로 균등하게 펼쳐집니다.

Map Projection3차원 지구 좌표(위경도)를 2차원 지도 화면 좌표(x, y)로 변환하는 메커니즘입니다. Map Projection을 활용하여 위경도 좌표를 지도 화면 좌표로 변환하는 계산을 진행했습니다.

Map Projection 적용은 아래 3단계로 정리됩니다.

  1. 기준 위경도 → 지도 화면 좌표로 변환
  2. 지도 화면 좌표에서 dx, dy만큼 이동
  3. 이동한 지도 화면 좌표 → 위경도로 변환
val radius = distance * factor // 반경
val angle = 2 * Math.PI * index / maxIndex // 각도
val dx = radius * Math.cos(angle)
val dy = radius * Math.sin(angle)

val base = projection.toScreenLocation(baseLatLng) // 위경도 -> 좌표 변환
val offset = PointF(base.x + dx, base.y + dy) // 좌표 이동
val result = projection.fromScreenLocation(offset) // 좌표 -> 위경도 변환

핵심은 위경도가 아닌 사용자가 보는 지도 화면 좌표계에서 계산한다는 점입니다. 지도 화면의 좌표계는 왜곡이 없는 평면이기 때문에 삼각함수로 계산한 dx, dy를 그대로 적용하여 원형으로 마커를 펼칠 수 있었습니다.

마커 펼치기 최적화: 개수 제한과 면적 줄이기

원형 배치는 균등하지만 동일한 위경도를 가지는 가게 수가 늘수록 펼침 면적이 커져 주변 가게/도로 정보를 가리거나 다른 그룹과 겹칠 수 있습니다. 그래서 서비스에서는 ‘항상 최대한 펼친다’가 아니라 선택성과 가독성을 우선하는 운영 정책을 함께 적용했습니다.

  • 최대 8개까지만 펼침
  • 4개당 1 depth, 최대 2 depth
원형 2 depth 를 통해 정사각형 모양으로 펼쳐진 마커

요기요에 입점한 가게들 중 9개 이상으로 같은 위경도를 가진 가게들의 케이스는 1% 미만이었습니다. 이 경우를 예외 케이스로 두고 나머지 99%에 집중하였습니다. 같은 위경도에서 최대 8개까지만 펼쳐 화면 점유 면적을 줄이기 위해 논의를 진행하였습니다. 이때 가장 효율적인 배치를 적용하기 위해 2depth로 원형 두 개를 겹쳐 정사각형 모양으로 펼치게 되었습니다.

UX 개선 확장 : 펼침 강도와 반경 스케일링

마커 펼치기를 항상 동일한 강도로 적용하지는 않았습니다. Zoom Level이 낮은 상태에서 많은 마커를 펼치면 화면이 급격히 복잡해지기 때문에, 확대 수준에 따라 펼침 강도를 단계적으로 올렸습니다.

Zoom Level에 따라 펼쳐지는 마커

Zoom Level이 낮을 때는 최소 개수만 펼쳐 화면 복잡도를 낮추고 사용자가 확대할수록 더 많은 가게를 펼쳐 상세 선택이 가능하도록 했습니다. 별도의 안내 없이도 확대할수록 더 자세히 탐색할 수 있다는 것은 사용자의 동작과 자연스럽게 연결되었습니다.

이 때 Zoom Level이 변경되는 동안 마커가 펼치는 반경이 고정값이면 체감 거리가 급격히 달라집니다. 그래서 Zoom Level을 반영하여 반경을 스케일링했습니다.

val zoomDiffFactor = 2.0.pow(currentZoomLevel - standardZoomLevel)
val radiusPx = standardRadiusPx * zoomDiffFactor

이 방식은 Zoom Level 달라져도 반경이 보정돼 동일한 거리로 마커를 펼칠 수 있게 됩니다. 마커가 무분별하게 펼쳐지는 현상을 줄여 탐색의 가독성을 일정하게 유지해줍니다.

마치며

이 글에서는 포장 화면 지도에서 동일 위경도 가게들로 인해 발생하던 탐색 가독성의 저하 문제를 Map Projection 기반 마커 펼치기와 정책으로 해결한 과정을 공유했습니다.

마커 펼치기를 통해 동일 위경도 가게들이 지도 위에서 분리되어 표시되면서 탐색과 선택이 자연스러워졌고 포장 화면의 핵심 지표(CVR, GMV)도 긍정적으로 개선되었습니다.

앞으로도 사용자 행동 흐름을 기준으로 문제를 정의하고 최적화하는 개선을 이어가겠습니다. 읽어주셔서 감사합니다.


마커 펼치기로 포장 지도 UX 개선하기 : Map Projection was originally published in YOGIYO Tech Blog - 요기요 기술블로그 on Medium, where people are continuing the conversation by highlighting and responding to this story.

Read Entire Article