sinu.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import adjust_lon from '../common/adjust_lon';
  2. import adjust_lat from '../common/adjust_lat';
  3. import pj_enfn from '../common/pj_enfn';
  4. var MAX_ITER = 20;
  5. import pj_mlfn from '../common/pj_mlfn';
  6. import pj_inv_mlfn from '../common/pj_inv_mlfn';
  7. import {EPSLN, HALF_PI} from '../constants/values';
  8. import asinz from '../common/asinz';
  9. export function init() {
  10. /* Place parameters in static storage for common use
  11. -------------------------------------------------*/
  12. if (!this.sphere) {
  13. this.en = pj_enfn(this.es);
  14. }
  15. else {
  16. this.n = 1;
  17. this.m = 0;
  18. this.es = 0;
  19. this.C_y = Math.sqrt((this.m + 1) / this.n);
  20. this.C_x = this.C_y / (this.m + 1);
  21. }
  22. }
  23. /* Sinusoidal forward equations--mapping lat,long to x,y
  24. -----------------------------------------------------*/
  25. export function forward(p) {
  26. var x, y;
  27. var lon = p.x;
  28. var lat = p.y;
  29. /* Forward equations
  30. -----------------*/
  31. lon = adjust_lon(lon - this.long0);
  32. if (this.sphere) {
  33. if (!this.m) {
  34. lat = this.n !== 1 ? Math.asin(this.n * Math.sin(lat)) : lat;
  35. }
  36. else {
  37. var k = this.n * Math.sin(lat);
  38. for (var i = MAX_ITER; i; --i) {
  39. var V = (this.m * lat + Math.sin(lat) - k) / (this.m + Math.cos(lat));
  40. lat -= V;
  41. if (Math.abs(V) < EPSLN) {
  42. break;
  43. }
  44. }
  45. }
  46. x = this.a * this.C_x * lon * (this.m + Math.cos(lat));
  47. y = this.a * this.C_y * lat;
  48. }
  49. else {
  50. var s = Math.sin(lat);
  51. var c = Math.cos(lat);
  52. y = this.a * pj_mlfn(lat, s, c, this.en);
  53. x = this.a * lon * c / Math.sqrt(1 - this.es * s * s);
  54. }
  55. p.x = x;
  56. p.y = y;
  57. return p;
  58. }
  59. export function inverse(p) {
  60. var lat, temp, lon, s;
  61. p.x -= this.x0;
  62. lon = p.x / this.a;
  63. p.y -= this.y0;
  64. lat = p.y / this.a;
  65. if (this.sphere) {
  66. lat /= this.C_y;
  67. lon = lon / (this.C_x * (this.m + Math.cos(lat)));
  68. if (this.m) {
  69. lat = asinz((this.m * lat + Math.sin(lat)) / this.n);
  70. }
  71. else if (this.n !== 1) {
  72. lat = asinz(Math.sin(lat) / this.n);
  73. }
  74. lon = adjust_lon(lon + this.long0);
  75. lat = adjust_lat(lat);
  76. }
  77. else {
  78. lat = pj_inv_mlfn(p.y / this.a, this.es, this.en);
  79. s = Math.abs(lat);
  80. if (s < HALF_PI) {
  81. s = Math.sin(lat);
  82. temp = this.long0 + p.x * Math.sqrt(1 - this.es * s * s) / (this.a * Math.cos(lat));
  83. //temp = this.long0 + p.x / (this.a * Math.cos(lat));
  84. lon = adjust_lon(temp);
  85. }
  86. else if ((s - EPSLN) < HALF_PI) {
  87. lon = this.long0;
  88. }
  89. }
  90. p.x = lon;
  91. p.y = lat;
  92. return p;
  93. }
  94. export var names = ["Sinusoidal", "sinu"];
  95. export default {
  96. init: init,
  97. forward: forward,
  98. inverse: inverse,
  99. names: names
  100. };