sinu.js 2.5 KB

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