123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- import {EPSLN, HALF_PI} from '../constants/values';
- import sign from '../common/sign';
- import msfnz from '../common/msfnz';
- import tsfnz from '../common/tsfnz';
- import phi2z from '../common/phi2z';
- import adjust_lon from '../common/adjust_lon';
- export function ssfn_(phit, sinphi, eccen) {
- sinphi *= eccen;
- return (Math.tan(0.5 * (HALF_PI + phit)) * Math.pow((1 - sinphi) / (1 + sinphi), 0.5 * eccen));
- }
- export function init() {
- this.coslat0 = Math.cos(this.lat0);
- this.sinlat0 = Math.sin(this.lat0);
- if (this.sphere) {
- if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) {
- this.k0 = 0.5 * (1 + sign(this.lat0) * Math.sin(this.lat_ts));
- }
- }
- else {
- if (Math.abs(this.coslat0) <= EPSLN) {
- if (this.lat0 > 0) {
- //North pole
- //trace('stere:north pole');
- this.con = 1;
- }
- else {
- //South pole
- //trace('stere:south pole');
- this.con = -1;
- }
- }
- this.cons = Math.sqrt(Math.pow(1 + this.e, 1 + this.e) * Math.pow(1 - this.e, 1 - this.e));
- if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) {
- this.k0 = 0.5 * this.cons * msfnz(this.e, Math.sin(this.lat_ts), Math.cos(this.lat_ts)) / tsfnz(this.e, this.con * this.lat_ts, this.con * Math.sin(this.lat_ts));
- }
- this.ms1 = msfnz(this.e, this.sinlat0, this.coslat0);
- this.X0 = 2 * Math.atan(this.ssfn_(this.lat0, this.sinlat0, this.e)) - HALF_PI;
- this.cosX0 = Math.cos(this.X0);
- this.sinX0 = Math.sin(this.X0);
- }
- }
- // Stereographic forward equations--mapping lat,long to x,y
- export function forward(p) {
- var lon = p.x;
- var lat = p.y;
- var sinlat = Math.sin(lat);
- var coslat = Math.cos(lat);
- var A, X, sinX, cosX, ts, rh;
- var dlon = adjust_lon(lon - this.long0);
- if (Math.abs(Math.abs(lon - this.long0) - Math.PI) <= EPSLN && Math.abs(lat + this.lat0) <= EPSLN) {
- //case of the origine point
- //trace('stere:this is the origin point');
- p.x = NaN;
- p.y = NaN;
- return p;
- }
- if (this.sphere) {
- //trace('stere:sphere case');
- A = 2 * this.k0 / (1 + this.sinlat0 * sinlat + this.coslat0 * coslat * Math.cos(dlon));
- p.x = this.a * A * coslat * Math.sin(dlon) + this.x0;
- p.y = this.a * A * (this.coslat0 * sinlat - this.sinlat0 * coslat * Math.cos(dlon)) + this.y0;
- return p;
- }
- else {
- X = 2 * Math.atan(this.ssfn_(lat, sinlat, this.e)) - HALF_PI;
- cosX = Math.cos(X);
- sinX = Math.sin(X);
- if (Math.abs(this.coslat0) <= EPSLN) {
- ts = tsfnz(this.e, lat * this.con, this.con * sinlat);
- rh = 2 * this.a * this.k0 * ts / this.cons;
- p.x = this.x0 + rh * Math.sin(lon - this.long0);
- p.y = this.y0 - this.con * rh * Math.cos(lon - this.long0);
- //trace(p.toString());
- return p;
- }
- else if (Math.abs(this.sinlat0) < EPSLN) {
- //Eq
- //trace('stere:equateur');
- A = 2 * this.a * this.k0 / (1 + cosX * Math.cos(dlon));
- p.y = A * sinX;
- }
- else {
- //other case
- //trace('stere:normal case');
- A = 2 * this.a * this.k0 * this.ms1 / (this.cosX0 * (1 + this.sinX0 * sinX + this.cosX0 * cosX * Math.cos(dlon)));
- p.y = A * (this.cosX0 * sinX - this.sinX0 * cosX * Math.cos(dlon)) + this.y0;
- }
- p.x = A * cosX * Math.sin(dlon) + this.x0;
- }
- //trace(p.toString());
- return p;
- }
- //* Stereographic inverse equations--mapping x,y to lat/long
- export function inverse(p) {
- p.x -= this.x0;
- p.y -= this.y0;
- var lon, lat, ts, ce, Chi;
- var rh = Math.sqrt(p.x * p.x + p.y * p.y);
- if (this.sphere) {
- var c = 2 * Math.atan(rh / (2 * this.a * this.k0));
- lon = this.long0;
- lat = this.lat0;
- if (rh <= EPSLN) {
- p.x = lon;
- p.y = lat;
- return p;
- }
- lat = Math.asin(Math.cos(c) * this.sinlat0 + p.y * Math.sin(c) * this.coslat0 / rh);
- if (Math.abs(this.coslat0) < EPSLN) {
- if (this.lat0 > 0) {
- lon = adjust_lon(this.long0 + Math.atan2(p.x, - 1 * p.y));
- }
- else {
- lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y));
- }
- }
- else {
- lon = adjust_lon(this.long0 + Math.atan2(p.x * Math.sin(c), rh * this.coslat0 * Math.cos(c) - p.y * this.sinlat0 * Math.sin(c)));
- }
- p.x = lon;
- p.y = lat;
- return p;
- }
- else {
- if (Math.abs(this.coslat0) <= EPSLN) {
- if (rh <= EPSLN) {
- lat = this.lat0;
- lon = this.long0;
- p.x = lon;
- p.y = lat;
- //trace(p.toString());
- return p;
- }
- p.x *= this.con;
- p.y *= this.con;
- ts = rh * this.cons / (2 * this.a * this.k0);
- lat = this.con * phi2z(this.e, ts);
- lon = this.con * adjust_lon(this.con * this.long0 + Math.atan2(p.x, - 1 * p.y));
- }
- else {
- ce = 2 * Math.atan(rh * this.cosX0 / (2 * this.a * this.k0 * this.ms1));
- lon = this.long0;
- if (rh <= EPSLN) {
- Chi = this.X0;
- }
- else {
- Chi = Math.asin(Math.cos(ce) * this.sinX0 + p.y * Math.sin(ce) * this.cosX0 / rh);
- lon = adjust_lon(this.long0 + Math.atan2(p.x * Math.sin(ce), rh * this.cosX0 * Math.cos(ce) - p.y * this.sinX0 * Math.sin(ce)));
- }
- lat = -1 * phi2z(this.e, Math.tan(0.5 * (HALF_PI + Chi)));
- }
- }
- p.x = lon;
- p.y = lat;
- //trace(p.toString());
- return p;
- }
- export var names = ["stere", "Stereographic_South_Pole", "Polar Stereographic (variant B)"];
- export default {
- init: init,
- forward: forward,
- inverse: inverse,
- names: names,
- ssfn_: ssfn_
- };
|