UNPKG

s2-tools

Version:

A collection of geospatial tools primarily designed for WGS84, Web Mercator, and S2.

87 lines 3.05 kB
import { degToRad, radToDeg } from '../geometry'; /** * # Orthodrome * * ## Description * Represents an orthodrome, which is the shortest path between two points on a sphere. * [Learn more here](http://www.movable-type.co.uk/scripts/latlong.html) * * ## Usage * ```ts * import { Orthodrome } from 's2-tools' * * // starting at lon-lat (-60, -40) and ending at (20, 10) * const orthodrome = new Orthodrome(-60, -40, 20, 10); * // { x: -39.13793657428956, y: -33.72852197561652 } * const intermediatePoint = orthodrome.intermediatePoint(0.2); * // Distance in KM: 1.5514126949321814 * const distance = orthodrome.distanceTo(); */ export class Orthodrome { /** start longitude */ lon1; /** start latitude */ lat1; /** end longitude */ lon2; /** end latitude */ lat2; /** distance property */ a; /** distance property */ dist; /** * @param startLon - start longitude * @param startLat - start latitude * @param endLon - end longitude * @param endLat - end latitude */ constructor(startLon, startLat, endLon, endLat) { const { sin, cos, atan2, sqrt } = Math; const lon1 = (this.lon1 = degToRad(startLon)); const lat1 = (this.lat1 = degToRad(startLat)); const lon2 = (this.lon2 = degToRad(endLon)); const lat2 = (this.lat2 = degToRad(endLat)); const dLat = lat2 - lat1; const dLon = lon2 - lon1; const a = (this.a = sin(dLat / 2) * sin(dLat / 2) + cos(lat1) * cos(lat2) * sin(dLon / 2) * sin(dLon / 2)); this.dist = 2 * atan2(sqrt(a), sqrt(1 - a)); } /** * input t 0->1. Find a point along the orthodrome. * @param t - distance along the orthodrome to find * @returns [lon, lat] */ intermediatePoint(t) { const { lon1, lon2, lat1, lat2, dist } = this; const { sin, cos, atan2, sqrt } = Math; // check corner cases first if (t === 0) return { x: radToDeg(lon1), y: radToDeg(lat1) }; else if (t === 1) return { x: radToDeg(lon2), y: radToDeg(lat2) }; // check if points are equal else if (lon1 === lon2 && lat1 === lat2) return { x: radToDeg(lon1), y: radToDeg(lat1) }; const A = sin((1 - t) * dist) / sin(dist); const B = sin(t * dist) / sin(dist); const x = A * cos(lat1) * cos(lon1) + B * cos(lat2) * cos(lon2); const y = A * cos(lat1) * sin(lon1) + B * cos(lat2) * sin(lon2); const z = A * sin(lat1) + B * sin(lat2); const lat = atan2(z, sqrt(x * x + y * y)); const lon = atan2(y, x); return { x: radToDeg(lon), y: radToDeg(lat) }; } /** * Finds the distance between the two points in kilometers * projected normalized (0->1) * @returns - total distance between the two points */ distanceTo() { const { a } = this; const { atan2, sqrt } = Math; return 2 * atan2(sqrt(a), sqrt(1 - a)); } } //# sourceMappingURL=orthodrome.js.map