| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 | 
var mode = {  N_POLE: 0,  S_POLE: 1,  EQUIT: 2,  OBLIQ: 3};import { D2R, HALF_PI, EPSLN } from "../constants/values";import hypot from "../common/hypot";var params = {  h:     { def: 100000, num: true },           // default is Karman line, no default in PROJ.7  azi:   { def: 0, num: true, degrees: true }, // default is North  tilt:  { def: 0, num: true, degrees: true }, // default is Nadir  long0: { def: 0, num: true },                // default is Greenwich, conversion to rad is automatic  lat0:  { def: 0, num: true }                 // default is Equator, conversion to rad is automatic};export function init() {  Object.keys(params).forEach(function (p) {    if (typeof this[p] === "undefined") {      this[p] = params[p].def;    } else if (params[p].num && isNaN(this[p])) {      throw new Error("Invalid parameter value, must be numeric " + p + " = " + this[p]);    } else if (params[p].num) {      this[p] = parseFloat(this[p]);    }    if (params[p].degrees) {      this[p] = this[p] * D2R;    }  }.bind(this));  if (Math.abs((Math.abs(this.lat0) - HALF_PI)) < EPSLN) {    this.mode = this.lat0 < 0 ? mode.S_POLE : mode.N_POLE;  } else if (Math.abs(this.lat0) < EPSLN) {    this.mode = mode.EQUIT;  } else {    this.mode = mode.OBLIQ;    this.sinph0 = Math.sin(this.lat0);    this.cosph0 = Math.cos(this.lat0);  }  this.pn1 = this.h / this.a;  // Normalize relative to the Earth's radius  if (this.pn1 <= 0 || this.pn1 > 1e10) {    throw new Error("Invalid height");  }    this.p = 1 + this.pn1;  this.rp = 1 / this.p;  this.h1 = 1 / this.pn1;  this.pfact = (this.p + 1) * this.h1;  this.es = 0;  var omega = this.tilt;  var gamma = this.azi;  this.cg = Math.cos(gamma);  this.sg = Math.sin(gamma);  this.cw = Math.cos(omega);  this.sw = Math.sin(omega);}export function forward(p) {  p.x -= this.long0;  var sinphi = Math.sin(p.y);  var cosphi = Math.cos(p.y);  var coslam = Math.cos(p.x);  var x, y;  switch (this.mode) {    case mode.OBLIQ:      y = this.sinph0 * sinphi + this.cosph0 * cosphi * coslam;      break;    case mode.EQUIT:      y = cosphi * coslam;      break;    case mode.S_POLE:      y = -sinphi;      break;    case mode.N_POLE:      y = sinphi;      break;  }  y = this.pn1 / (this.p - y);  x = y * cosphi * Math.sin(p.x);  switch (this.mode) {    case mode.OBLIQ:      y *= this.cosph0 * sinphi - this.sinph0 * cosphi * coslam;      break;    case mode.EQUIT:      y *= sinphi;      break;    case mode.N_POLE:      y *= -(cosphi * coslam);      break;    case mode.S_POLE:      y *= cosphi * coslam;      break;  }  // Tilt   var yt, ba;  yt = y * this.cg + x * this.sg;  ba = 1 / (yt * this.sw * this.h1 + this.cw);  x = (x * this.cg - y * this.sg) * this.cw * ba;  y = yt * ba;  p.x = x * this.a;  p.y = y * this.a;  return p;}export function inverse(p) {  p.x /= this.a;  p.y /= this.a;  var r = { x: p.x, y: p.y };  // Un-Tilt  var bm, bq, yt;  yt = 1 / (this.pn1 - p.y * this.sw);  bm = this.pn1 * p.x * yt;  bq = this.pn1 * p.y * this.cw * yt;  p.x = bm * this.cg + bq * this.sg;  p.y = bq * this.cg - bm * this.sg;  var rh = hypot(p.x, p.y);  if (Math.abs(rh) < EPSLN) {    r.x = 0;    r.y = p.y;  } else {    var cosz, sinz;    sinz = 1 - rh * rh * this.pfact;    sinz = (this.p - Math.sqrt(sinz)) / (this.pn1 / rh + rh / this.pn1);    cosz = Math.sqrt(1 - sinz * sinz);    switch (this.mode) {      case mode.OBLIQ:        r.y = Math.asin(cosz * this.sinph0 + p.y * sinz * this.cosph0 / rh);        p.y = (cosz - this.sinph0 * Math.sin(r.y)) * rh;        p.x *= sinz * this.cosph0;        break;      case mode.EQUIT:        r.y = Math.asin(p.y * sinz / rh);        p.y = cosz * rh;        p.x *= sinz;        break;      case mode.N_POLE:        r.y = Math.asin(cosz);        p.y = -p.y;        break;      case mode.S_POLE:        r.y = -Math.asin(cosz);        break;    }    r.x = Math.atan2(p.x, p.y);  }  p.x = r.x + this.long0;  p.y = r.y;  return p;}export var names = ["Tilted_Perspective", "tpers"];export default {  init: init,  forward: forward,  inverse: inverse,  names: names};
 |