source: josm/trunk/src/org/openstreetmap/josm/data/projection/proj/SwissObliqueMercator.java@ 5926

Last change on this file since 5926 was 5066, checked in by bastiK, 12 years ago

Proj parameter refactoring (see #7495)

  • Property svn:eol-style set to native
File size: 3.4 KB
Line 
1//License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.projection.proj;
3
4import static java.lang.Math.*;
5
6import static org.openstreetmap.josm.tools.I18n.tr;
7
8import org.openstreetmap.josm.data.projection.Ellipsoid;
9import org.openstreetmap.josm.data.projection.ProjectionConfigurationException;
10
11/**
12 * Projection for the SwissGrid CH1903 / L03, see http://de.wikipedia.org/wiki/Swiss_Grid.
13 *
14 * Calculations are based on formula from
15 * http://www.swisstopo.admin.ch/internet/swisstopo/en/home/topics/survey/sys/refsys/switzerland.parsysrelated1.37696.downloadList.12749.DownloadFile.tmp/ch1903wgs84en.pdf
16 *
17 * August 2010 update to this formula (rigorous formulas)
18 * http://www.swisstopo.admin.ch/internet/swisstopo/en/home/topics/survey/sys/refsys/switzerland.parsysrelated1.37696.downloadList.97912.DownloadFile.tmp/swissprojectionen.pdf
19 */
20public class SwissObliqueMercator implements Proj {
21
22 private Ellipsoid ellps;
23 private double kR;
24 private double alpha;
25 private double b0;
26 private double K;
27
28 private static final double EPSILON = 1e-11;
29
30 @Override
31 public void initialize(ProjParameters params) throws ProjectionConfigurationException {
32 if (params.lat_0 == null)
33 throw new ProjectionConfigurationException(tr("Parameter ''{0}'' required.", "lat_0"));
34 ellps = params.ellps;
35 initialize(params.lat_0);
36 }
37
38 private void initialize(double lat_0) {
39 double phi0 = toRadians(lat_0);
40 kR = sqrt(1 - ellps.e2) / (1 - (ellps.e2 * pow(sin(phi0), 2)));
41 alpha = sqrt(1 + (ellps.eb2 * pow(cos(phi0), 4)));
42 b0 = asin(sin(phi0) / alpha);
43 K = log(tan(PI / 4 + b0 / 2)) - alpha
44 * log(tan(PI / 4 + phi0 / 2)) + alpha * ellps.e / 2
45 * log((1 + ellps.e * sin(phi0)) / (1 - ellps.e * sin(phi0)));
46 }
47
48 @Override
49 public String getName() {
50 return tr("Swiss Oblique Mercator");
51 }
52
53 @Override
54 public String getProj4Id() {
55 return "somerc";
56 }
57
58 @Override
59 public double[] project(double phi, double lambda) {
60
61 double S = alpha * log(tan(PI / 4 + phi / 2)) - alpha * ellps.e / 2
62 * log((1 + ellps.e * sin(phi)) / (1 - ellps.e * sin(phi))) + K;
63 double b = 2 * (atan(exp(S)) - PI / 4);
64 double l = alpha * lambda;
65
66 double lb = atan2(sin(l), sin(b0) * tan(b) + cos(b0) * cos(l));
67 double bb = asin(cos(b0) * sin(b) - sin(b0) * cos(b) * cos(l));
68
69 double y = kR * lb;
70 double x = kR / 2 * log((1 + sin(bb)) / (1 - sin(bb)));
71
72 return new double[] { y, x };
73 }
74
75 @Override
76 public double[] invproject(double y, double x) {
77 double lb = y / kR;
78 double bb = 2 * (atan(exp(x / kR)) - PI / 4);
79
80 double b = asin(cos(b0) * sin(bb) + sin(b0) * cos(bb) * cos(lb));
81 double l = atan2(sin(lb), cos(b0) * cos(lb) - sin(b0) * tan(bb));
82
83 double lambda = l / alpha;
84 double phi = b;
85 double S = 0;
86
87 double prevPhi = -1000;
88 int iteration = 0;
89 // iteration to finds S and phi
90 while (abs(phi - prevPhi) > EPSILON) {
91 if (++iteration > 30)
92 throw new RuntimeException("Two many iterations");
93 prevPhi = phi;
94 S = 1 / alpha * (log(tan(PI / 4 + b / 2)) - K) + ellps.e
95 * log(tan(PI / 4 + asin(ellps.e * sin(phi)) / 2));
96 phi = 2 * atan(exp(S)) - PI / 2;
97 }
98 return new double[] { phi, lambda };
99 }
100
101}
Note: See TracBrowser for help on using the repository browser.