지구 위의 계산(Spherical)
거리・방위・면적・보간 같은 지리 계산을, 3개 플랫폼에서 같은 이름・같은 결과로 제공합니다. 지도 SDK마다의 유틸리티에 기대지 않기 때문에, 프로바이더를 교체해도 수치가 달라지지 않습니다. SDK 내부의 탭 판정이나 대권 코스 렌더링도, 모두 이 계산을 쓰고 있습니다.
01 · 기본의 계산
자주 쓰는 함수는 Spherical에 모여 있습니다. 거리는 미터, 방위는 진북을 0으로 한 도, 면적은 제곱미터로 반환됩니다. 인수는 좌표 그 자체이고, 투영이나 줌에는 의존하지 않습니다.
val meters = Spherical.computeDistanceBetween(from, to)
val heading = Spherical.computeHeading(from, to)
// 원의 외곽 마커를 8방향에 놓는다
val ring = (0 until 8).map { i ->
Spherical.computeOffset(center, 3_000.0, i * 45.0)
}
val routeMeters = Spherical.computeLength(routePoints)
val areaSqMeters = Spherical.computeArea(polygonPoints)let meters = Spherical.computeDistanceBetween(from: from, to: to)
let heading = Spherical.computeHeading(from: from, to: to)
let ring = (0..<8).map { i in
Spherical.computeOffset(origin: center, distance: 3_000.0, heading: Double(i) * 45.0)
}
let routeMeters = Spherical.computeLength(routePoints)import { computeDistanceBetween, computeOffset, computeLength } from '@mapconductor/js-sdk-core';
const meters = computeDistanceBetween(from, to);
// 중심에서 3km, 45도 간격의 링
const ring = Array.from({ length: 8 }, (_, i) =>
computeOffset({ origin: center, distance: 3000, heading: i * 45 }));
const routeMeters = computeLength(routePoints);02 · 구체 모델과 타원체 모델
지리 계산에는 2가지 정밀도 수준을 마련하고 있습니다. 지구를 완전한 구로 다루는 구체 모델과, WGS84 타원체로 다루는 측지선 모델입니다. 용도에 따라 나눠 씁니다.
상수는 양쪽 모두 WGS84에 기반합니다(적도 반경 6,378,137 m, 편평률 1/298.257223563). 3개 플랫폼에서 같은 상수・같은 식을 쓰기 때문에, 같은 입력이라면 같은 값이 반환됩니다.
구체 모델(충분히 빠르고, 충분히 정확)
반정시(haversine)에 의한 거리, 구면삼각법에 의한 방위・보간입니다. 수백km 정도까지라면 오차는 실용상 무시할 수 있고, 계산 비용이 작은 것이 장점입니다.
타원체 모델(측지선)
WGS84 타원체 위의 측지선(Vincenty 계열의 반복 해)으로 계산합니다. Spherical과 같은 메서드 구성이므로, 구체라면 Spherical, WGS84라면 WGS84Geodesic처럼 호출을 바꾸지 않고 교체할 수 있습니다. 면적은 타원체(authalic)로 구합니다.
수렴하지 않을 때는 구체로 폴백
타원체의 반복 해는, 거의 대척점에 있는 2점 등에서 수렴하지 않는 경우가 있습니다. 그 경우에는 구체 모델의 결과로 자동으로 전환하기 때문에, 0이나 NaN이 반환되는 일은 없습니다. 호출하는 쪽에서 예외 처리를 쓸 필요는 없습니다.
03 · 화면과의 다리 놓기
지도 위의 「손가락 하나 분」이나 「16px의 여백」 같은 화면 기준의 양을, 지리적인 거리로 환산하는 함수군입니다. 줌과 위도에 따른 환산이 들어 있기 때문에, 배율이나 장소가 바뀌어도 체감이 변하지 않습니다.
그림 · 탭 판정에 쓰이는 흐름
설정값의 「손가락의 크기」(논리 단위)를 화면 픽셀로 변환합니다.
calculateMetersPerPixel로, 현재의 줌과 위도에서의 허용 거리(미터)로 환산합니다.
그 허용 거리를 써서, 선이나 도형과의 거리를 지리 좌표인 채로 판정합니다.
이 흐름 덕분에, 줌을 바꿔도 선의 누르기 쉬운 정도가 변하지 않고, 어느 프로바이더에서도 같은 판정이 됩니다.
04 · 선과 형태를 위한 계산
폴리라인이나 폴리곤의 렌더링・판정을, 어느 프로바이더에서도 같은 결과로 만들기 위한 함수군입니다. SDK 내부에서 쓰고 있는 것과 같은 것이 공개되어 있습니다.
createInterpolatePoints와 pointOnLineOrNull은, WGS84Geodesic과 Planar 양쪽에 같은 이름으로 마련되어 있습니다. 호출하는 쪽은 네임스페이스를 교체하기만 하면, 측지선 모델과 직선 모델을 전환할 수 있습니다.
같은 입력이라면 같은 결과
Kotlin・Swift・TypeScript의 구현은 같은 식으로 쓰여 있고, 같은 상수를 씁니다. 플랫폼 간에 표시되는 거리나 면적이 어긋나는 일은 없습니다.
앱에서도 쓸 수 있다
코어의 계산 함수는 내부 전용이 아니라 공개 API입니다. 경로 거리의 표시, 반지름의 계산, 독자적인 히트 판정 등, 앱 쪽의 로직에 그대로 쓸 수 있습니다. 이 페이지에 든 함수는 모두 3개 플랫폼에 갖춰져 있습니다.