반자오선(Antimeridian) 통과 시 경로 방향이 바뀌는 문제

1. 문제 개요

Mapbox 기반 지도에서 LineString 경로가 반자오선(경도 ±180°) 을 통과할 때, 경로가 의도한 방향과 반대로 지구 반대편으로 크게 꺾여 렌더링되는 현상이 발생합니다.
예를 들어 한국(127°E)에서 미국 서부(-122°W)로 이동하는 경우 태평양을 가로질러 동경으로 이동해야 하지만 대서양 방향으로 서경으로 경로가 렌더링되게 됩니다. (첨부 이미지 참고)
반자오선(Antimeridian)
반자오선은 지구를 반으로 가르는 자오선(경선)으로, 일반적으로 180도 자오선을 의미하며, 본초 자오선(0도, prime antimeridian)과 마주보며 지구를 동반구와 서반구로 나누고, 국제 날짜변경선의 기준이 되는 선입니다.
2. 증상
좌표와 좌표 사이가 반자오선을 통과하게 되는 경우 경로의 방향이 반전
3. 원인
3.1 경도의 수학적 표현
경도(longitude)는 다음과 같은 순환 좌표계입니다.
-180° ~ +180°
따라서 +181°은 -1°을 의미하며 170° → -170° 는 동경20° 이동을 의미합니다.
하지만 지도 라이브러리에서는 이를 순환적으로 해석하지 않고 선형적으로 해석합니다.
동일한 상황을 선형적으로 해석할 경우 170° → -170°는 -340°의 이동이 됩니다.
하지만 지도 라이브러는 내부적으로 연속적인 선형적 선으로 해석합니다.
이 차이로 인해 다음과 같은 상황이 발생합니다.
- +179° → -179° 을 -358° 이동으로 해석
3.2 반자오선(antimeridian)에 대한 지도 라이브러리 해석
이러한 반자오선(antimeridian)에 대한 처리는 지도 라이브러리에서 처리되지 않습니다.
4. 해결
해결의 접근 방향은 경도를 연속적인 수치로 표현하는 것입니다.
이 접근에는 크게 두 가지 접근방식을 고민해 볼 수 있습니다.
- 반자오선은 경계로 multi-line을 생성한다.
- 경도를 unwrap한다.
4.1 경도를 unwrap
반자오선을 통과하는 구간에서 경도를 의도적으로 보정하는 방식입니다.
-180° ~ +180° 의 순환적 표현 대신 선형적 표현으로 보정하여 연속적 경로를 유도합니다.
쉽게 말해 180°에서 반지오선을 통과해 -170°으로 이동한 경우 360°를 더해서 190°로 표현하는 것입니다.
이 방식을 unwrap이라 표현하는 것은 원형을 순환하는 것을 wrap으로 표현했을 때, 반대로 선형적으로 표현하는 것을 감긴 것을 푼다는 관점이라 이해할 수 있습니다.
이 접근 방식의 장점은 연속적 표현을 쉽게 할 수 있다는 장점이 있습니다. 특히 연속적 애니메이션을 구현할 때 편리한 방법입니다. 단점을 생각하자면 비표준 방식이라는 점입니다. 따라서 상황에 따라 다시 [-180, 180] 범위로 normalize가 필요할 수 있습니다.
4.2 본자오선 기준 LineString 분할
반자오선을 통과하는 지점에서 경로를 분할하여 두 개의 linestring을 만드는 방법입니다.
[170° → 180°] + [-180° → -170°]
이렇게 되면 경도를 표준에 맞게 유지할 수 있어 정석적 접근 방식이라 할 수 있습니다.
실제로 mapbox에서 항공,해운의 경로를 표현하는 방식으로 linestring 분할 방식을 권장하고 있습니다.
다만 정적 경로를 연결하는 것이 아닌 연속적 애니메이션을 표현할 때는 로직의 복잡도가 높아지니다.
When representing a LineString that crosses the antimeridian, interoperability is improved by modifying their geometry. Any geometry that crosses the antimeridian SHOULD be represented by cutting it in two such that neither part's representation crosses the antimeridian.
For example, a line extending from 45 degrees N, 170 degrees E across the antimeridian to 45 degrees N, 170 degrees W should be cut in two and represented as a MultiLineString.
출처: https://docs.mapbox.com/android/java/api/libjava-geojson/7.7.0/com/mapbox/geojson/LineString.html?utm_source=chatgpt.com
5. 결론
최종적으로 경도 unwrap방식을 채택하여 선형적 경로를 표현하여 문제를 해결했습니다.
구현이 간단하고 애니메이션 구현에서 연속적인 라인으로 로직을 단순화할 수 있는 이점이 크다는 판단이었습니다.