tmerc.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. var e0fn = require('../common/e0fn');
  2. var e1fn = require('../common/e1fn');
  3. var e2fn = require('../common/e2fn');
  4. var e3fn = require('../common/e3fn');
  5. var mlfn = require('../common/mlfn');
  6. var adjust_lon = require('../common/adjust_lon');
  7. var HALF_PI = Math.PI/2;
  8. var EPSLN = 1.0e-10;
  9. var sign = require('../common/sign');
  10. var asinz = require('../common/asinz');
  11. exports.init = function() {
  12. this.e0 = e0fn(this.es);
  13. this.e1 = e1fn(this.es);
  14. this.e2 = e2fn(this.es);
  15. this.e3 = e3fn(this.es);
  16. this.ml0 = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, this.lat0);
  17. };
  18. /**
  19. Transverse Mercator Forward - long/lat to x/y
  20. long/lat in radians
  21. */
  22. exports.forward = function(p) {
  23. var lon = p.x;
  24. var lat = p.y;
  25. var delta_lon = adjust_lon(lon - this.long0);
  26. var con;
  27. var x, y;
  28. var sin_phi = Math.sin(lat);
  29. var cos_phi = Math.cos(lat);
  30. if (this.sphere) {
  31. var b = cos_phi * Math.sin(delta_lon);
  32. if ((Math.abs(Math.abs(b) - 1)) < 0.0000000001) {
  33. return (93);
  34. }
  35. else {
  36. x = 0.5 * this.a * this.k0 * Math.log((1 + b) / (1 - b));
  37. con = Math.acos(cos_phi * Math.cos(delta_lon) / Math.sqrt(1 - b * b));
  38. if (lat < 0) {
  39. con = -con;
  40. }
  41. y = this.a * this.k0 * (con - this.lat0);
  42. }
  43. }
  44. else {
  45. var al = cos_phi * delta_lon;
  46. var als = Math.pow(al, 2);
  47. var c = this.ep2 * Math.pow(cos_phi, 2);
  48. var tq = Math.tan(lat);
  49. var t = Math.pow(tq, 2);
  50. con = 1 - this.es * Math.pow(sin_phi, 2);
  51. var n = this.a / Math.sqrt(con);
  52. var ml = this.a * mlfn(this.e0, this.e1, this.e2, this.e3, lat);
  53. x = this.k0 * n * al * (1 + als / 6 * (1 - t + c + als / 20 * (5 - 18 * t + Math.pow(t, 2) + 72 * c - 58 * this.ep2))) + this.x0;
  54. y = this.k0 * (ml - this.ml0 + n * tq * (als * (0.5 + als / 24 * (5 - t + 9 * c + 4 * Math.pow(c, 2) + als / 30 * (61 - 58 * t + Math.pow(t, 2) + 600 * c - 330 * this.ep2))))) + this.y0;
  55. }
  56. p.x = x;
  57. p.y = y;
  58. return p;
  59. };
  60. /**
  61. Transverse Mercator Inverse - x/y to long/lat
  62. */
  63. exports.inverse = function(p) {
  64. var con, phi;
  65. var delta_phi;
  66. var i;
  67. var max_iter = 6;
  68. var lat, lon;
  69. if (this.sphere) {
  70. var f = Math.exp(p.x / (this.a * this.k0));
  71. var g = 0.5 * (f - 1 / f);
  72. var temp = this.lat0 + p.y / (this.a * this.k0);
  73. var h = Math.cos(temp);
  74. con = Math.sqrt((1 - h * h) / (1 + g * g));
  75. lat = asinz(con);
  76. if (temp < 0) {
  77. lat = -lat;
  78. }
  79. if ((g === 0) && (h === 0)) {
  80. lon = this.long0;
  81. }
  82. else {
  83. lon = adjust_lon(Math.atan2(g, h) + this.long0);
  84. }
  85. }
  86. else { // ellipsoidal form
  87. var x = p.x - this.x0;
  88. var y = p.y - this.y0;
  89. con = (this.ml0 + y / this.k0) / this.a;
  90. phi = con;
  91. for (i = 0; true; i++) {
  92. delta_phi = ((con + this.e1 * Math.sin(2 * phi) - this.e2 * Math.sin(4 * phi) + this.e3 * Math.sin(6 * phi)) / this.e0) - phi;
  93. phi += delta_phi;
  94. if (Math.abs(delta_phi) <= EPSLN) {
  95. break;
  96. }
  97. if (i >= max_iter) {
  98. return (95);
  99. }
  100. } // for()
  101. if (Math.abs(phi) < HALF_PI) {
  102. var sin_phi = Math.sin(phi);
  103. var cos_phi = Math.cos(phi);
  104. var tan_phi = Math.tan(phi);
  105. var c = this.ep2 * Math.pow(cos_phi, 2);
  106. var cs = Math.pow(c, 2);
  107. var t = Math.pow(tan_phi, 2);
  108. var ts = Math.pow(t, 2);
  109. con = 1 - this.es * Math.pow(sin_phi, 2);
  110. var n = this.a / Math.sqrt(con);
  111. var r = n * (1 - this.es) / con;
  112. var d = x / (n * this.k0);
  113. var ds = Math.pow(d, 2);
  114. lat = phi - (n * tan_phi * ds / r) * (0.5 - ds / 24 * (5 + 3 * t + 10 * c - 4 * cs - 9 * this.ep2 - ds / 30 * (61 + 90 * t + 298 * c + 45 * ts - 252 * this.ep2 - 3 * cs)));
  115. lon = adjust_lon(this.long0 + (d * (1 - ds / 6 * (1 + 2 * t + c - ds / 20 * (5 - 2 * c + 28 * t - 3 * cs + 8 * this.ep2 + 24 * ts))) / cos_phi));
  116. }
  117. else {
  118. lat = HALF_PI * sign(y);
  119. lon = this.long0;
  120. }
  121. }
  122. p.x = lon;
  123. p.y = lat;
  124. return p;
  125. };
  126. exports.names = ["Transverse_Mercator", "Transverse Mercator", "tmerc"];