moll.js 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. import adjust_lon from '../common/adjust_lon';
  2. export function init() {}
  3. import {EPSLN} from '../constants/values';
  4. /* Mollweide forward equations--mapping lat,long to x,y
  5. ----------------------------------------------------*/
  6. export function forward(p) {
  7. /* Forward equations
  8. -----------------*/
  9. var lon = p.x;
  10. var lat = p.y;
  11. var delta_lon = adjust_lon(lon - this.long0);
  12. var theta = lat;
  13. var con = Math.PI * Math.sin(lat);
  14. /* Iterate using the Newton-Raphson method to find theta
  15. -----------------------------------------------------*/
  16. while (true) {
  17. var delta_theta = -(theta + Math.sin(theta) - con) / (1 + Math.cos(theta));
  18. theta += delta_theta;
  19. if (Math.abs(delta_theta) < EPSLN) {
  20. break;
  21. }
  22. }
  23. theta /= 2;
  24. /* If the latitude is 90 deg, force the x coordinate to be "0 + false easting"
  25. this is done here because of precision problems with "cos(theta)"
  26. --------------------------------------------------------------------------*/
  27. if (Math.PI / 2 - Math.abs(lat) < EPSLN) {
  28. delta_lon = 0;
  29. }
  30. var x = 0.900316316158 * this.a * delta_lon * Math.cos(theta) + this.x0;
  31. var y = 1.4142135623731 * this.a * Math.sin(theta) + this.y0;
  32. p.x = x;
  33. p.y = y;
  34. return p;
  35. }
  36. export function inverse(p) {
  37. var theta;
  38. var arg;
  39. /* Inverse equations
  40. -----------------*/
  41. p.x -= this.x0;
  42. p.y -= this.y0;
  43. arg = p.y / (1.4142135623731 * this.a);
  44. /* Because of division by zero problems, 'arg' can not be 1. Therefore
  45. a number very close to one is used instead.
  46. -------------------------------------------------------------------*/
  47. if (Math.abs(arg) > 0.999999999999) {
  48. arg = 0.999999999999;
  49. }
  50. theta = Math.asin(arg);
  51. var lon = adjust_lon(this.long0 + (p.x / (0.900316316158 * this.a * Math.cos(theta))));
  52. if (lon < (-Math.PI)) {
  53. lon = -Math.PI;
  54. }
  55. if (lon > Math.PI) {
  56. lon = Math.PI;
  57. }
  58. arg = (2 * theta + Math.sin(2 * theta)) / Math.PI;
  59. if (Math.abs(arg) > 1) {
  60. arg = 1;
  61. }
  62. var lat = Math.asin(arg);
  63. p.x = lon;
  64. p.y = lat;
  65. return p;
  66. }
  67. export var names = ["Mollweide", "moll"];
  68. export default {
  69. init: init,
  70. forward: forward,
  71. inverse: inverse,
  72. names: names
  73. };