[76] | 1 | /******************************************************************************* |
---|
| 2 | NAME SWISS OBLIQUE MERCATOR |
---|
| 3 | |
---|
| 4 | PURPOSE: Swiss projection. |
---|
| 5 | WARNING: X and Y are inverted (weird) in the swiss coordinate system. Not |
---|
| 6 | here, since we want X to be horizontal and Y vertical. |
---|
| 7 | |
---|
| 8 | ALGORITHM REFERENCES |
---|
| 9 | 1. "Formules et constantes pour le Calcul pour la |
---|
| 10 | projection cylindrique conforme à axe oblique et pour la transformation entre |
---|
| 11 | des systÚmes de référence". |
---|
| 12 | http://www.swisstopo.admin.ch/internet/swisstopo/fr/home/topics/survey/sys/refsys/switzerland.parsysrelated1.31216.downloadList.77004.DownloadFile.tmp/swissprojectionfr.pdf |
---|
| 13 | |
---|
| 14 | *******************************************************************************/ |
---|
| 15 | |
---|
| 16 | Proj4js.Proj.somerc = { |
---|
| 17 | |
---|
| 18 | init: function() { |
---|
| 19 | var phy0 = this.lat0; |
---|
| 20 | this.lambda0 = this.long0; |
---|
| 21 | var sinPhy0 = Math.sin(phy0); |
---|
| 22 | var semiMajorAxis = this.a; |
---|
| 23 | var invF = this.rf; |
---|
| 24 | var flattening = 1 / invF; |
---|
| 25 | var e2 = 2 * flattening - Math.pow(flattening, 2); |
---|
| 26 | var e = this.e = Math.sqrt(e2); |
---|
| 27 | this.R = this.k0 * semiMajorAxis * Math.sqrt(1 - e2) / (1 - e2 * Math.pow(sinPhy0, 2.0)); |
---|
| 28 | this.alpha = Math.sqrt(1 + e2 / (1 - e2) * Math.pow(Math.cos(phy0), 4.0)); |
---|
| 29 | this.b0 = Math.asin(sinPhy0 / this.alpha); |
---|
| 30 | this.K = Math.log(Math.tan(Math.PI / 4.0 + this.b0 / 2.0)) |
---|
| 31 | - this.alpha |
---|
| 32 | * Math.log(Math.tan(Math.PI / 4.0 + phy0 / 2.0)) |
---|
| 33 | + this.alpha |
---|
| 34 | * e / 2 |
---|
| 35 | * Math.log((1 + e * sinPhy0) |
---|
| 36 | / (1 - e * sinPhy0)); |
---|
| 37 | }, |
---|
| 38 | |
---|
| 39 | |
---|
| 40 | forward: function(p) { |
---|
| 41 | var Sa1 = Math.log(Math.tan(Math.PI / 4.0 - p.y / 2.0)); |
---|
| 42 | var Sa2 = this.e / 2.0 |
---|
| 43 | * Math.log((1 + this.e * Math.sin(p.y)) |
---|
| 44 | / (1 - this.e * Math.sin(p.y))); |
---|
| 45 | var S = -this.alpha * (Sa1 + Sa2) + this.K; |
---|
| 46 | |
---|
| 47 | // spheric latitude |
---|
| 48 | var b = 2.0 * (Math.atan(Math.exp(S)) - Math.PI / 4.0); |
---|
| 49 | |
---|
| 50 | // spheric longitude |
---|
| 51 | var I = this.alpha * (p.x - this.lambda0); |
---|
| 52 | |
---|
| 53 | // psoeudo equatorial rotation |
---|
| 54 | var rotI = Math.atan(Math.sin(I) |
---|
| 55 | / (Math.sin(this.b0) * Math.tan(b) + |
---|
| 56 | Math.cos(this.b0) * Math.cos(I))); |
---|
| 57 | |
---|
| 58 | var rotB = Math.asin(Math.cos(this.b0) * Math.sin(b) - |
---|
| 59 | Math.sin(this.b0) * Math.cos(b) * Math.cos(I)); |
---|
| 60 | |
---|
| 61 | p.y = this.R / 2.0 |
---|
| 62 | * Math.log((1 + Math.sin(rotB)) / (1 - Math.sin(rotB))) |
---|
| 63 | + this.y0; |
---|
| 64 | p.x = this.R * rotI + this.x0; |
---|
| 65 | return p; |
---|
| 66 | }, |
---|
| 67 | |
---|
| 68 | inverse: function(p) { |
---|
| 69 | var Y = p.x - this.x0; |
---|
| 70 | var X = p.y - this.y0; |
---|
| 71 | |
---|
| 72 | var rotI = Y / this.R; |
---|
| 73 | var rotB = 2 * (Math.atan(Math.exp(X / this.R)) - Math.PI / 4.0); |
---|
| 74 | |
---|
| 75 | var b = Math.asin(Math.cos(this.b0) * Math.sin(rotB) |
---|
| 76 | + Math.sin(this.b0) * Math.cos(rotB) * Math.cos(rotI)); |
---|
| 77 | var I = Math.atan(Math.sin(rotI) |
---|
| 78 | / (Math.cos(this.b0) * Math.cos(rotI) - Math.sin(this.b0) |
---|
| 79 | * Math.tan(rotB))); |
---|
| 80 | |
---|
| 81 | var lambda = this.lambda0 + I / this.alpha; |
---|
| 82 | |
---|
| 83 | var S = 0.0; |
---|
| 84 | var phy = b; |
---|
| 85 | var prevPhy = -1000.0; |
---|
| 86 | var iteration = 0; |
---|
| 87 | while (Math.abs(phy - prevPhy) > 0.0000001) |
---|
| 88 | { |
---|
| 89 | if (++iteration > 20) |
---|
| 90 | { |
---|
| 91 | Proj4js.reportError("omercFwdInfinity"); |
---|
| 92 | return; |
---|
| 93 | } |
---|
| 94 | //S = Math.log(Math.tan(Math.PI / 4.0 + phy / 2.0)); |
---|
| 95 | S = 1.0 |
---|
| 96 | / this.alpha |
---|
| 97 | * (Math.log(Math.tan(Math.PI / 4.0 + b / 2.0)) - this.K) |
---|
| 98 | + this.e |
---|
| 99 | * Math.log(Math.tan(Math.PI / 4.0 |
---|
| 100 | + Math.asin(this.e * Math.sin(phy)) |
---|
| 101 | / 2.0)); |
---|
| 102 | prevPhy = phy; |
---|
| 103 | phy = 2.0 * Math.atan(Math.exp(S)) - Math.PI / 2.0; |
---|
| 104 | } |
---|
| 105 | |
---|
| 106 | p.x = lambda; |
---|
| 107 | p.y = phy; |
---|
| 108 | return p; |
---|
| 109 | } |
---|
| 110 | }; |
---|