UNPKG

s2-tools

Version:

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

139 lines 4.78 kB
import { EPSLN } from '../constants'; import { ProjectionBase } from '.'; import { adjustLon, asinz } from '../common'; /** * # Gnomonic (gnom) * * For a sphere, the gnomonic projection is a projection from the center of * the sphere onto a plane tangent to the center point of the projection. * This projects great circles to straight lines. For an ellipsoid, it is * the limit of a doubly azimuthal projection, a projection where the * azimuths from 2 points are preserved, as the two points merge into the * center point. In this case, geodesics project to approximately straight * lines (these are exactly straight if the geodesic includes the center * point). For details, see Section 8 of :cite:`Karney2013`. * * **Classification**: Azimuthal * * **Available forms**: Forward and inverse, spherical and ellipsoidal * * **Defined area**: Within a quarter circumference of the center point * * **Alias**: gnom * * **Domain**: 2D * * **Input type**: Geodetic coordinates * * **Output type**: Projected coordinates * * ## Projection String * ``` * +proj=gnom +lat_0=90 +lon_0=-50 +R=6.4e6 * ``` * * ## Required Parameters * - None, all parameters are optional for this projection. * * ## Optional Parameters * - `+lon_0`: Longitude of origin (central meridian). * - `+lat_0`: Latitude of origin. * - `+x_0`: False easting. * - `+y_0`: False northing. * - `+ellps`: Ellipsoid. * - `+R`: Earth radius. * * Reference: * Wolfram Mathworld "Gnomonic Projection" * http://mathworld.wolfram.com/GnomonicProjection.html * Accessed: 12th November 2009 * * ![Gnomonic](https://github.com/Open-S2/s2-tools/blob/master/assets/proj4/projections/images/gnom.png?raw=true) */ export class Gnomonic extends ProjectionBase { name = 'GnomonicProjection'; static names = ['GnomonicProjection', 'Gnomonic Projection', 'gnom']; // Gnomonic specific variables rc; sinP14; cosP14; infinityDist; /** * Preps an Gnomonic projection * @param params - projection specific parameters */ constructor(params) { const { sin, cos } = Math; super(params); this.sinP14 = sin(this.lat0); this.cosP14 = cos(this.lat0); // Approximation for projecting points to the horizon (infinity) this.infinityDist = 1_000 * this.a; this.rc = 1; } /** * Gnomonic forward equations--mapping lon-lat to x-y * @param p - lon-lat WGS84 point */ forward(p) { const { abs, sin, cos } = Math; const { x: lon, y: lat } = p; let x, y; /* Forward equations -----------------*/ const dlon = adjustLon(lon - this.long0); /* delta longitude value */ const sinphi = sin(lat); const cosphi = cos(lat); const coslon = cos(dlon); /* cos of longitude */ const g = this.sinP14 * sinphi + this.cosP14 * cosphi * coslon; const ksp = 1; /* scale factor */ if (g > 0 || abs(g) <= EPSLN) { x = this.x0 + (this.a * ksp * cosphi * sin(dlon)) / g; y = this.y0 + (this.a * ksp * (this.cosP14 * sinphi - this.sinP14 * cosphi * coslon)) / g; } else { // Point is in the opposing hemisphere and is unprojectable // We still need to return a reasonable point, so we project // to infinity, on a bearing // equivalent to the northern hemisphere equivalent // This is a reasonable approximation for short shapes and lines that // straddle the horizon. x = this.x0 + this.infinityDist * cosphi * sin(dlon); y = this.y0 + this.infinityDist * (this.cosP14 * sinphi - this.sinP14 * cosphi * coslon); } p.x = x; p.y = y; } /** * Gnomonic inverse equations--mapping x-y to lon-lat * @param p - Gnomonic point */ inverse(p) { const { sin, cos, sqrt, atan2 } = Math; let sinc, cosc; let c; let lon, lat; /* Inverse equations -----------------*/ p.x = (p.x - this.x0) / this.a; p.y = (p.y - this.y0) / this.a; p.x /= this.k0; p.y /= this.k0; const rh = sqrt(p.x * p.x + p.y * p.y); /* Rho */ if (rh !== 0) { c = atan2(rh, this.rc); sinc = sin(c); cosc = cos(c); lat = asinz(cosc * this.sinP14 + (p.y * sinc * this.cosP14) / rh); lon = atan2(p.x * sinc, rh * this.cosP14 * cosc - p.y * this.sinP14 * sinc); lon = adjustLon(this.long0 + lon); } else { lat = this.phic0; lon = 0; } p.x = lon; p.y = lat; } } //# sourceMappingURL=gnom.js.map