proj.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /**
  2. * Contains methods for transforming point on sphere to
  3. * Cartesian coordinates using various projections.
  4. * @class
  5. */
  6. jvm.Proj = {
  7. degRad: 180 / Math.PI,
  8. radDeg: Math.PI / 180,
  9. radius: 6381372,
  10. sgn: function(n){
  11. if (n > 0) {
  12. return 1;
  13. } else if (n < 0) {
  14. return -1;
  15. } else {
  16. return n;
  17. }
  18. },
  19. /**
  20. * Converts point on sphere to the Cartesian coordinates using Miller projection
  21. * @param {Number} lat Latitude in degrees
  22. * @param {Number} lng Longitude in degrees
  23. * @param {Number} c Central meridian in degrees
  24. */
  25. mill: function(lat, lng, c){
  26. return {
  27. x: this.radius * (lng - c) * this.radDeg,
  28. y: - this.radius * Math.log(Math.tan((45 + 0.4 * lat) * this.radDeg)) / 0.8
  29. };
  30. },
  31. /**
  32. * Inverse function of mill()
  33. * Converts Cartesian coordinates to point on sphere using Miller projection
  34. * @param {Number} x X of point in Cartesian system as integer
  35. * @param {Number} y Y of point in Cartesian system as integer
  36. * @param {Number} c Central meridian in degrees
  37. */
  38. mill_inv: function(x, y, c){
  39. return {
  40. lat: (2.5 * Math.atan(Math.exp(0.8 * y / this.radius)) - 5 * Math.PI / 8) * this.degRad,
  41. lng: (c * this.radDeg + x / this.radius) * this.degRad
  42. };
  43. },
  44. /**
  45. * Converts point on sphere to the Cartesian coordinates using Mercator projection
  46. * @param {Number} lat Latitude in degrees
  47. * @param {Number} lng Longitude in degrees
  48. * @param {Number} c Central meridian in degrees
  49. */
  50. merc: function(lat, lng, c){
  51. return {
  52. x: this.radius * (lng - c) * this.radDeg,
  53. y: - this.radius * Math.log(Math.tan(Math.PI / 4 + lat * Math.PI / 360))
  54. };
  55. },
  56. /**
  57. * Inverse function of merc()
  58. * Converts Cartesian coordinates to point on sphere using Mercator projection
  59. * @param {Number} x X of point in Cartesian system as integer
  60. * @param {Number} y Y of point in Cartesian system as integer
  61. * @param {Number} c Central meridian in degrees
  62. */
  63. merc_inv: function(x, y, c){
  64. return {
  65. lat: (2 * Math.atan(Math.exp(y / this.radius)) - Math.PI / 2) * this.degRad,
  66. lng: (c * this.radDeg + x / this.radius) * this.degRad
  67. };
  68. },
  69. /**
  70. * Converts point on sphere to the Cartesian coordinates using Albers Equal-Area Conic
  71. * projection
  72. * @see <a href="http://mathworld.wolfram.com/AlbersEqual-AreaConicProjection.html">Albers Equal-Area Conic projection</a>
  73. * @param {Number} lat Latitude in degrees
  74. * @param {Number} lng Longitude in degrees
  75. * @param {Number} c Central meridian in degrees
  76. */
  77. aea: function(lat, lng, c){
  78. var fi0 = 0,
  79. lambda0 = c * this.radDeg,
  80. fi1 = 29.5 * this.radDeg,
  81. fi2 = 45.5 * this.radDeg,
  82. fi = lat * this.radDeg,
  83. lambda = lng * this.radDeg,
  84. n = (Math.sin(fi1)+Math.sin(fi2)) / 2,
  85. C = Math.cos(fi1)*Math.cos(fi1)+2*n*Math.sin(fi1),
  86. theta = n*(lambda-lambda0),
  87. ro = Math.sqrt(C-2*n*Math.sin(fi))/n,
  88. ro0 = Math.sqrt(C-2*n*Math.sin(fi0))/n;
  89. return {
  90. x: ro * Math.sin(theta) * this.radius,
  91. y: - (ro0 - ro * Math.cos(theta)) * this.radius
  92. };
  93. },
  94. /**
  95. * Converts Cartesian coordinates to the point on sphere using Albers Equal-Area Conic
  96. * projection
  97. * @see <a href="http://mathworld.wolfram.com/AlbersEqual-AreaConicProjection.html">Albers Equal-Area Conic projection</a>
  98. * @param {Number} x X of point in Cartesian system as integer
  99. * @param {Number} y Y of point in Cartesian system as integer
  100. * @param {Number} c Central meridian in degrees
  101. */
  102. aea_inv: function(xCoord, yCoord, c){
  103. var x = xCoord / this.radius,
  104. y = yCoord / this.radius,
  105. fi0 = 0,
  106. lambda0 = c * this.radDeg,
  107. fi1 = 29.5 * this.radDeg,
  108. fi2 = 45.5 * this.radDeg,
  109. n = (Math.sin(fi1)+Math.sin(fi2)) / 2,
  110. C = Math.cos(fi1)*Math.cos(fi1)+2*n*Math.sin(fi1),
  111. ro0 = Math.sqrt(C-2*n*Math.sin(fi0))/n,
  112. ro = Math.sqrt(x*x+(ro0-y)*(ro0-y)),
  113. theta = Math.atan( x / (ro0 - y) );
  114. return {
  115. lat: (Math.asin((C - ro * ro * n * n) / (2 * n))) * this.degRad,
  116. lng: (lambda0 + theta / n) * this.degRad
  117. };
  118. },
  119. /**
  120. * Converts point on sphere to the Cartesian coordinates using Lambert conformal
  121. * conic projection
  122. * @see <a href="http://mathworld.wolfram.com/LambertConformalConicProjection.html">Lambert Conformal Conic Projection</a>
  123. * @param {Number} lat Latitude in degrees
  124. * @param {Number} lng Longitude in degrees
  125. * @param {Number} c Central meridian in degrees
  126. */
  127. lcc: function(lat, lng, c){
  128. var fi0 = 0,
  129. lambda0 = c * this.radDeg,
  130. lambda = lng * this.radDeg,
  131. fi1 = 33 * this.radDeg,
  132. fi2 = 45 * this.radDeg,
  133. fi = lat * this.radDeg,
  134. n = Math.log( Math.cos(fi1) * (1 / Math.cos(fi2)) ) / Math.log( Math.tan( Math.PI / 4 + fi2 / 2) * (1 / Math.tan( Math.PI / 4 + fi1 / 2) ) ),
  135. F = ( Math.cos(fi1) * Math.pow( Math.tan( Math.PI / 4 + fi1 / 2 ), n ) ) / n,
  136. ro = F * Math.pow( 1 / Math.tan( Math.PI / 4 + fi / 2 ), n ),
  137. ro0 = F * Math.pow( 1 / Math.tan( Math.PI / 4 + fi0 / 2 ), n );
  138. return {
  139. x: ro * Math.sin( n * (lambda - lambda0) ) * this.radius,
  140. y: - (ro0 - ro * Math.cos( n * (lambda - lambda0) ) ) * this.radius
  141. };
  142. },
  143. /**
  144. * Converts Cartesian coordinates to the point on sphere using Lambert conformal conic
  145. * projection
  146. * @see <a href="http://mathworld.wolfram.com/LambertConformalConicProjection.html">Lambert Conformal Conic Projection</a>
  147. * @param {Number} x X of point in Cartesian system as integer
  148. * @param {Number} y Y of point in Cartesian system as integer
  149. * @param {Number} c Central meridian in degrees
  150. */
  151. lcc_inv: function(xCoord, yCoord, c){
  152. var x = xCoord / this.radius,
  153. y = yCoord / this.radius,
  154. fi0 = 0,
  155. lambda0 = c * this.radDeg,
  156. fi1 = 33 * this.radDeg,
  157. fi2 = 45 * this.radDeg,
  158. n = Math.log( Math.cos(fi1) * (1 / Math.cos(fi2)) ) / Math.log( Math.tan( Math.PI / 4 + fi2 / 2) * (1 / Math.tan( Math.PI / 4 + fi1 / 2) ) ),
  159. F = ( Math.cos(fi1) * Math.pow( Math.tan( Math.PI / 4 + fi1 / 2 ), n ) ) / n,
  160. ro0 = F * Math.pow( 1 / Math.tan( Math.PI / 4 + fi0 / 2 ), n ),
  161. ro = this.sgn(n) * Math.sqrt(x*x+(ro0-y)*(ro0-y)),
  162. theta = Math.atan( x / (ro0 - y) );
  163. return {
  164. lat: (2 * Math.atan(Math.pow(F/ro, 1/n)) - Math.PI / 2) * this.degRad,
  165. lng: (lambda0 + theta / n) * this.degRad
  166. };
  167. }
  168. };