gnom.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import adjust_lon from '../common/adjust_lon';
  2. import asinz from '../common/asinz';
  3. import {EPSLN} from '../constants/values';
  4. /*
  5. reference:
  6. Wolfram Mathworld "Gnomonic Projection"
  7. http://mathworld.wolfram.com/GnomonicProjection.html
  8. Accessed: 12th November 2009
  9. */
  10. export function init() {
  11. /* Place parameters in static storage for common use
  12. -------------------------------------------------*/
  13. this.sin_p14 = Math.sin(this.lat0);
  14. this.cos_p14 = Math.cos(this.lat0);
  15. // Approximation for projecting points to the horizon (infinity)
  16. this.infinity_dist = 1000 * this.a;
  17. this.rc = 1;
  18. }
  19. /* Gnomonic forward equations--mapping lat,long to x,y
  20. ---------------------------------------------------*/
  21. export function forward(p) {
  22. var sinphi, cosphi; /* sin and cos value */
  23. var dlon; /* delta longitude value */
  24. var coslon; /* cos of longitude */
  25. var ksp; /* scale factor */
  26. var g;
  27. var x, y;
  28. var lon = p.x;
  29. var lat = p.y;
  30. /* Forward equations
  31. -----------------*/
  32. dlon = adjust_lon(lon - this.long0);
  33. sinphi = Math.sin(lat);
  34. cosphi = Math.cos(lat);
  35. coslon = Math.cos(dlon);
  36. g = this.sin_p14 * sinphi + this.cos_p14 * cosphi * coslon;
  37. ksp = 1;
  38. if ((g > 0) || (Math.abs(g) <= EPSLN)) {
  39. x = this.x0 + this.a * ksp * cosphi * Math.sin(dlon) / g;
  40. y = this.y0 + this.a * ksp * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon) / g;
  41. }
  42. else {
  43. // Point is in the opposing hemisphere and is unprojectable
  44. // We still need to return a reasonable point, so we project
  45. // to infinity, on a bearing
  46. // equivalent to the northern hemisphere equivalent
  47. // This is a reasonable approximation for short shapes and lines that
  48. // straddle the horizon.
  49. x = this.x0 + this.infinity_dist * cosphi * Math.sin(dlon);
  50. y = this.y0 + this.infinity_dist * (this.cos_p14 * sinphi - this.sin_p14 * cosphi * coslon);
  51. }
  52. p.x = x;
  53. p.y = y;
  54. return p;
  55. }
  56. export function inverse(p) {
  57. var rh; /* Rho */
  58. var sinc, cosc;
  59. var c;
  60. var lon, lat;
  61. /* Inverse equations
  62. -----------------*/
  63. p.x = (p.x - this.x0) / this.a;
  64. p.y = (p.y - this.y0) / this.a;
  65. p.x /= this.k0;
  66. p.y /= this.k0;
  67. if ((rh = Math.sqrt(p.x * p.x + p.y * p.y))) {
  68. c = Math.atan2(rh, this.rc);
  69. sinc = Math.sin(c);
  70. cosc = Math.cos(c);
  71. lat = asinz(cosc * this.sin_p14 + (p.y * sinc * this.cos_p14) / rh);
  72. lon = Math.atan2(p.x * sinc, rh * this.cos_p14 * cosc - p.y * this.sin_p14 * sinc);
  73. lon = adjust_lon(this.long0 + lon);
  74. }
  75. else {
  76. lat = this.phic0;
  77. lon = 0;
  78. }
  79. p.x = lon;
  80. p.y = lat;
  81. return p;
  82. }
  83. export var names = ["gnom"];
  84. export default {
  85. init: init,
  86. forward: forward,
  87. inverse: inverse,
  88. names: names
  89. };