/** * Geographic primitives used by map layers and predictions. * * LngLat convention matches MapLibre (longitude first) for on-map work; * LatLng is preserved for API payloads and legacy Leaflet-era code paths. */ export interface LatLng { lat: number; lng: number; alt?: number; } export type LatLngTuple = [lat: number, lng: number] | [lat: number, lng: number, alt: number]; export type LatLngExpression = LatLng | LatLngTuple; export type LngLatTuple = [lng: number, lat: number]; export function toLngLat(p: LatLngExpression): LngLatTuple { if (Array.isArray(p)) return [p[1], p[0]]; return [p.lng, p.lat]; } export function toLatLng(p: LatLngExpression): LatLng { if (Array.isArray(p)) return { lat: p[0], lng: p[1], alt: p[2] }; return p; } export function normalizeLng(lng: number): number { // API occasionally returns longitudes in the 0..360 range. return lng > 180 ? lng - 360 : lng; }