somerc.js 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. references:
  3. Formules et constantes pour le Calcul pour la
  4. projection cylindrique conforme à axe oblique et pour la transformation entre
  5. des systèmes de référence.
  6. http://www.swisstopo.admin.ch/internet/swisstopo/fr/home/topics/survey/sys/refsys/switzerland.parsysrelated1.31216.downloadList.77004.DownloadFile.tmp/swissprojectionfr.pdf
  7. */
  8. export function init() {
  9. var phy0 = this.lat0;
  10. this.lambda0 = this.long0;
  11. var sinPhy0 = Math.sin(phy0);
  12. var semiMajorAxis = this.a;
  13. var invF = this.rf;
  14. var flattening = 1 / invF;
  15. var e2 = 2 * flattening - Math.pow(flattening, 2);
  16. var e = this.e = Math.sqrt(e2);
  17. this.R = this.k0 * semiMajorAxis * Math.sqrt(1 - e2) / (1 - e2 * Math.pow(sinPhy0, 2));
  18. this.alpha = Math.sqrt(1 + e2 / (1 - e2) * Math.pow(Math.cos(phy0), 4));
  19. this.b0 = Math.asin(sinPhy0 / this.alpha);
  20. var k1 = Math.log(Math.tan(Math.PI / 4 + this.b0 / 2));
  21. var k2 = Math.log(Math.tan(Math.PI / 4 + phy0 / 2));
  22. var k3 = Math.log((1 + e * sinPhy0) / (1 - e * sinPhy0));
  23. this.K = k1 - this.alpha * k2 + this.alpha * e / 2 * k3;
  24. }
  25. export function forward(p) {
  26. var Sa1 = Math.log(Math.tan(Math.PI / 4 - p.y / 2));
  27. var Sa2 = this.e / 2 * Math.log((1 + this.e * Math.sin(p.y)) / (1 - this.e * Math.sin(p.y)));
  28. var S = -this.alpha * (Sa1 + Sa2) + this.K;
  29. // spheric latitude
  30. var b = 2 * (Math.atan(Math.exp(S)) - Math.PI / 4);
  31. // spheric longitude
  32. var I = this.alpha * (p.x - this.lambda0);
  33. // psoeudo equatorial rotation
  34. var rotI = Math.atan(Math.sin(I) / (Math.sin(this.b0) * Math.tan(b) + Math.cos(this.b0) * Math.cos(I)));
  35. var rotB = Math.asin(Math.cos(this.b0) * Math.sin(b) - Math.sin(this.b0) * Math.cos(b) * Math.cos(I));
  36. p.y = this.R / 2 * Math.log((1 + Math.sin(rotB)) / (1 - Math.sin(rotB))) + this.y0;
  37. p.x = this.R * rotI + this.x0;
  38. return p;
  39. }
  40. export function inverse(p) {
  41. var Y = p.x - this.x0;
  42. var X = p.y - this.y0;
  43. var rotI = Y / this.R;
  44. var rotB = 2 * (Math.atan(Math.exp(X / this.R)) - Math.PI / 4);
  45. var b = Math.asin(Math.cos(this.b0) * Math.sin(rotB) + Math.sin(this.b0) * Math.cos(rotB) * Math.cos(rotI));
  46. var I = Math.atan(Math.sin(rotI) / (Math.cos(this.b0) * Math.cos(rotI) - Math.sin(this.b0) * Math.tan(rotB)));
  47. var lambda = this.lambda0 + I / this.alpha;
  48. var S = 0;
  49. var phy = b;
  50. var prevPhy = -1000;
  51. var iteration = 0;
  52. while (Math.abs(phy - prevPhy) > 0.0000001) {
  53. if (++iteration > 20) {
  54. //...reportError("omercFwdInfinity");
  55. return;
  56. }
  57. //S = Math.log(Math.tan(Math.PI / 4 + phy / 2));
  58. S = 1 / this.alpha * (Math.log(Math.tan(Math.PI / 4 + b / 2)) - this.K) + this.e * Math.log(Math.tan(Math.PI / 4 + Math.asin(this.e * Math.sin(phy)) / 2));
  59. prevPhy = phy;
  60. phy = 2 * Math.atan(Math.exp(S)) - Math.PI / 2;
  61. }
  62. p.x = lambda;
  63. p.y = phy;
  64. return p;
  65. }
  66. export var names = ["somerc"];
  67. export default {
  68. init: init,
  69. forward: forward,
  70. inverse: inverse,
  71. names: names
  72. };