stere.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import {EPSLN, HALF_PI} from '../constants/values';
  2. import sign from '../common/sign';
  3. import msfnz from '../common/msfnz';
  4. import tsfnz from '../common/tsfnz';
  5. import phi2z from '../common/phi2z';
  6. import adjust_lon from '../common/adjust_lon';
  7. export function ssfn_(phit, sinphi, eccen) {
  8. sinphi *= eccen;
  9. return (Math.tan(0.5 * (HALF_PI + phit)) * Math.pow((1 - sinphi) / (1 + sinphi), 0.5 * eccen));
  10. }
  11. export function init() {
  12. this.coslat0 = Math.cos(this.lat0);
  13. this.sinlat0 = Math.sin(this.lat0);
  14. if (this.sphere) {
  15. if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) {
  16. this.k0 = 0.5 * (1 + sign(this.lat0) * Math.sin(this.lat_ts));
  17. }
  18. }
  19. else {
  20. if (Math.abs(this.coslat0) <= EPSLN) {
  21. if (this.lat0 > 0) {
  22. //North pole
  23. //trace('stere:north pole');
  24. this.con = 1;
  25. }
  26. else {
  27. //South pole
  28. //trace('stere:south pole');
  29. this.con = -1;
  30. }
  31. }
  32. this.cons = Math.sqrt(Math.pow(1 + this.e, 1 + this.e) * Math.pow(1 - this.e, 1 - this.e));
  33. if (this.k0 === 1 && !isNaN(this.lat_ts) && Math.abs(this.coslat0) <= EPSLN) {
  34. 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));
  35. }
  36. this.ms1 = msfnz(this.e, this.sinlat0, this.coslat0);
  37. this.X0 = 2 * Math.atan(this.ssfn_(this.lat0, this.sinlat0, this.e)) - HALF_PI;
  38. this.cosX0 = Math.cos(this.X0);
  39. this.sinX0 = Math.sin(this.X0);
  40. }
  41. }
  42. // Stereographic forward equations--mapping lat,long to x,y
  43. export function forward(p) {
  44. var lon = p.x;
  45. var lat = p.y;
  46. var sinlat = Math.sin(lat);
  47. var coslat = Math.cos(lat);
  48. var A, X, sinX, cosX, ts, rh;
  49. var dlon = adjust_lon(lon - this.long0);
  50. if (Math.abs(Math.abs(lon - this.long0) - Math.PI) <= EPSLN && Math.abs(lat + this.lat0) <= EPSLN) {
  51. //case of the origine point
  52. //trace('stere:this is the origin point');
  53. p.x = NaN;
  54. p.y = NaN;
  55. return p;
  56. }
  57. if (this.sphere) {
  58. //trace('stere:sphere case');
  59. A = 2 * this.k0 / (1 + this.sinlat0 * sinlat + this.coslat0 * coslat * Math.cos(dlon));
  60. p.x = this.a * A * coslat * Math.sin(dlon) + this.x0;
  61. p.y = this.a * A * (this.coslat0 * sinlat - this.sinlat0 * coslat * Math.cos(dlon)) + this.y0;
  62. return p;
  63. }
  64. else {
  65. X = 2 * Math.atan(this.ssfn_(lat, sinlat, this.e)) - HALF_PI;
  66. cosX = Math.cos(X);
  67. sinX = Math.sin(X);
  68. if (Math.abs(this.coslat0) <= EPSLN) {
  69. ts = tsfnz(this.e, lat * this.con, this.con * sinlat);
  70. rh = 2 * this.a * this.k0 * ts / this.cons;
  71. p.x = this.x0 + rh * Math.sin(lon - this.long0);
  72. p.y = this.y0 - this.con * rh * Math.cos(lon - this.long0);
  73. //trace(p.toString());
  74. return p;
  75. }
  76. else if (Math.abs(this.sinlat0) < EPSLN) {
  77. //Eq
  78. //trace('stere:equateur');
  79. A = 2 * this.a * this.k0 / (1 + cosX * Math.cos(dlon));
  80. p.y = A * sinX;
  81. }
  82. else {
  83. //other case
  84. //trace('stere:normal case');
  85. A = 2 * this.a * this.k0 * this.ms1 / (this.cosX0 * (1 + this.sinX0 * sinX + this.cosX0 * cosX * Math.cos(dlon)));
  86. p.y = A * (this.cosX0 * sinX - this.sinX0 * cosX * Math.cos(dlon)) + this.y0;
  87. }
  88. p.x = A * cosX * Math.sin(dlon) + this.x0;
  89. }
  90. //trace(p.toString());
  91. return p;
  92. }
  93. //* Stereographic inverse equations--mapping x,y to lat/long
  94. export function inverse(p) {
  95. p.x -= this.x0;
  96. p.y -= this.y0;
  97. var lon, lat, ts, ce, Chi;
  98. var rh = Math.sqrt(p.x * p.x + p.y * p.y);
  99. if (this.sphere) {
  100. var c = 2 * Math.atan(rh / (2 * this.a * this.k0));
  101. lon = this.long0;
  102. lat = this.lat0;
  103. if (rh <= EPSLN) {
  104. p.x = lon;
  105. p.y = lat;
  106. return p;
  107. }
  108. lat = Math.asin(Math.cos(c) * this.sinlat0 + p.y * Math.sin(c) * this.coslat0 / rh);
  109. if (Math.abs(this.coslat0) < EPSLN) {
  110. if (this.lat0 > 0) {
  111. lon = adjust_lon(this.long0 + Math.atan2(p.x, - 1 * p.y));
  112. }
  113. else {
  114. lon = adjust_lon(this.long0 + Math.atan2(p.x, p.y));
  115. }
  116. }
  117. else {
  118. 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)));
  119. }
  120. p.x = lon;
  121. p.y = lat;
  122. return p;
  123. }
  124. else {
  125. if (Math.abs(this.coslat0) <= EPSLN) {
  126. if (rh <= EPSLN) {
  127. lat = this.lat0;
  128. lon = this.long0;
  129. p.x = lon;
  130. p.y = lat;
  131. //trace(p.toString());
  132. return p;
  133. }
  134. p.x *= this.con;
  135. p.y *= this.con;
  136. ts = rh * this.cons / (2 * this.a * this.k0);
  137. lat = this.con * phi2z(this.e, ts);
  138. lon = this.con * adjust_lon(this.con * this.long0 + Math.atan2(p.x, - 1 * p.y));
  139. }
  140. else {
  141. ce = 2 * Math.atan(rh * this.cosX0 / (2 * this.a * this.k0 * this.ms1));
  142. lon = this.long0;
  143. if (rh <= EPSLN) {
  144. Chi = this.X0;
  145. }
  146. else {
  147. Chi = Math.asin(Math.cos(ce) * this.sinX0 + p.y * Math.sin(ce) * this.cosX0 / rh);
  148. 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)));
  149. }
  150. lat = -1 * phi2z(this.e, Math.tan(0.5 * (HALF_PI + Chi)));
  151. }
  152. }
  153. p.x = lon;
  154. p.y = lat;
  155. //trace(p.toString());
  156. return p;
  157. }
  158. export var names = ["stere", "Stereographic_South_Pole", "Polar Stereographic (variant B)"];
  159. export default {
  160. init: init,
  161. forward: forward,
  162. inverse: inverse,
  163. names: names,
  164. ssfn_: ssfn_
  165. };