UNPKG

s2-tools

Version:

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

161 lines 4.52 kB
import { ProjectionBase } from '.'; import { EPSLN, HALF_PI } from '../constants'; import { adjustLat, adjustLon, asinz, pjEnfn, pjInvMlfn, pjMlfn } from '../common'; /** * # Sinusoidal (Sanson-Flamsteed) * * **Classification**: Pseudocylindrical * * **Available forms**: Forward and inverse, spherical and ellipsoidal * * **Defined area**: Global * * **Alias**: sinu * * **Domain**: 2D * * **Input type**: Geodetic coordinates * * **Output type**: Projected coordinates * * ## Projection String * ``` * +proj=sinu * ``` * * ## Parameters * * All parameters are optional. * * - `+lon_0=<value>`: Central meridian. * - `+R=<value>`: Radius of the sphere or semi-major axis of the ellipsoid. * - `+x_0=<value>`: False easting. * - `+y_0=<value>`: False northing. * * ## Mathematical Definition * * MacBryde and Thomas developed generalized formulas for several of the * pseudocylindricals with sinusoidal meridians. The formulas describing the Sinusoidal * projection are: * * Forward projection: * ``` * x = C * λ * (m + cos(θ)) / (m + 1) * y = C * θ * ``` * * Inverse projection: * ``` * λ = x * (m + 1) / (C * (m + cos(y / C))) * θ = y / C * ``` * * Where: * ``` * C = sqrt((m + 1) / n) * ``` * * ## Further Reading * - [Wikipedia](https://en.wikipedia.org/wiki/Sinusoidal_projection) * * ![Sinusoidal (Sanson-Flamsteed)](https://github.com/Open-S2/s2-tools/blob/master/assets/proj4/projections/images/sinu.png?raw=true) */ export class Sinusoidal extends ProjectionBase { name = 'Sinusoidal'; static names = ['Sinusoidal', 'sinu']; /** * Preps an Sinusoidal projection * @param params - projection specific parameters */ constructor(params) { super(params); if (!this.sphere) { this.en = pjEnfn(this.es); } else { this.n = 1; this.m = 0; this.es = 0; this.Cy = Math.sqrt((this.m + 1) / this.n); this.Cx = this.Cy / (this.m + 1); } } /** * Sinusoidal forward equations--mapping lon-lat to x-y * @param p - lon-lat WGS84 point */ forward(p) { const { abs, sin, cos, sqrt, asin } = Math; let x, y; let lon = p.x; let lat = p.y; /* Forward equations -----------------*/ lon = adjustLon(lon - this.long0); if (this.sphere) { if (this.m !== 0) { lat = this.n !== 1 ? asin(this.n * sin(lat)) : lat; } else { const k = this.n * sin(lat); for (let i = 20; i !== 0; --i) { const V = (this.m * lat + sin(lat) - k) / (this.m + cos(lat)); lat -= V; if (abs(V) < EPSLN) { break; } } } x = this.a * this.Cx * lon * (this.m + cos(lat)); y = this.a * this.Cy * lat; } else { const s = sin(lat); const c = cos(lat); y = this.a * pjMlfn(lat, s, c, this.en); x = (this.a * lon * c) / sqrt(1 - this.es * s * s); } p.x = x; p.y = y; } /** * Sinusoidal inverse equations--mapping x-y to lon-lat * @param p - Sinusoidal point */ inverse(p) { const { abs, sin, cos, sqrt } = Math; let lat, temp, lon, s; p.x -= this.x0; lon = p.x / this.a; p.y -= this.y0; lat = p.y / this.a; if (this.sphere) { lat /= this.Cy; lon = lon / (this.Cx * (this.m + cos(lat))); if (this.m !== 0) { lat = asinz((this.m * lat + sin(lat)) / this.n); } else if (this.n !== 1) { lat = asinz(sin(lat) / this.n); } lon = adjustLon(lon + this.long0); lat = adjustLat(lat); } else { lat = pjInvMlfn(p.y / this.a, this.es, this.en); s = abs(lat); if (s < HALF_PI) { s = sin(lat); temp = this.long0 + (p.x * sqrt(1 - this.es * s * s)) / (this.a * cos(lat)); //temp = this.long0 + p.x / (this.a * cos(lat)); lon = adjustLon(temp); } else if (s - EPSLN < HALF_PI) { lon = this.long0; } } p.x = lon; p.y = lat; } } //# sourceMappingURL=sinu.js.map