var adjust_lon = require('../common/adjust_lon'); var adjust_lat = require('../common/adjust_lat'); var pj_enfn = require('../common/pj_enfn'); var MAX_ITER = 20; var pj_mlfn = require('../common/pj_mlfn'); var pj_inv_mlfn = require('../common/pj_inv_mlfn'); var HALF_PI = Math.PI/2; var EPSLN = 1.0e-10; var asinz = require('../common/asinz'); exports.init = function() { /* Place parameters in static storage for common use -------------------------------------------------*/ if (!this.sphere) { this.en = pj_enfn(this.es); } else { this.n = 1; this.m = 0; this.es = 0; this.C_y = Math.sqrt((this.m + 1) / this.n); this.C_x = this.C_y / (this.m + 1); } }; /* Sinusoidal forward equations--mapping lat,long to x,y -----------------------------------------------------*/ exports.forward = function(p) { var x, y; var lon = p.x; var lat = p.y; /* Forward equations -----------------*/ lon = adjust_lon(lon - this.long0); if (this.sphere) { if (!this.m) { lat = this.n !== 1 ? Math.asin(this.n * Math.sin(lat)) : lat; } else { var k = this.n * Math.sin(lat); for (var i = MAX_ITER; i; --i) { var V = (this.m * lat + Math.sin(lat) - k) / (this.m + Math.cos(lat)); lat -= V; if (Math.abs(V) < EPSLN) { break; } } } x = this.a * this.C_x * lon * (this.m + Math.cos(lat)); y = this.a * this.C_y * lat; } else { var s = Math.sin(lat); var c = Math.cos(lat); y = this.a * pj_mlfn(lat, s, c, this.en); x = this.a * lon * c / Math.sqrt(1 - this.es * s * s); } p.x = x; p.y = y; return p; }; exports.inverse = function(p) { var 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.C_y; lon = lon / (this.C_x * (this.m + Math.cos(lat))); if (this.m) { lat = asinz((this.m * lat + Math.sin(lat)) / this.n); } else if (this.n !== 1) { lat = asinz(Math.sin(lat) / this.n); } lon = adjust_lon(lon + this.long0); lat = adjust_lat(lat); } else { lat = pj_inv_mlfn(p.y / this.a, this.es, this.en); s = Math.abs(lat); if (s < HALF_PI) { s = Math.sin(lat); temp = this.long0 + p.x * Math.sqrt(1 - this.es * s * s) / (this.a * Math.cos(lat)); //temp = this.long0 + p.x / (this.a * Math.cos(lat)); lon = adjust_lon(temp); } else if ((s - EPSLN) < HALF_PI) { lon = this.long0; } } p.x = lon; p.y = lat; return p; }; exports.names = ["Sinusoidal", "sinu"];