MATSIM
GK4toWGS84.java
Go to the documentation of this file.
1 /* *********************************************************************** *
2  * project: org.matsim.*
3  * GK4toWGS84.java
4  * *
5  * *********************************************************************** *
6  * *
7  * copyright : (C) 2007 by the members listed in the COPYING, *
8  * LICENSE and WARRANTY file. *
9  * email : info at matsim dot org *
10  * *
11  * *********************************************************************** *
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * See also COPYING, LICENSE and WARRANTY file *
18  * *
19  * *********************************************************************** */
20 
21 package org.matsim.core.utils.geometry.transformations;
22 
23 import org.matsim.api.core.v01.Coord;
25 
35 public class GK4toWGS84 implements CoordinateTransformation {
36 
37  /*
38  * GK4 is a specially parameterized version of the Transverse Mercator coordinate system.
39  * Thus, the transformation from Transverse Mercator to WGS84 can be used to convert
40  * GK4 to WGS84.
41  *
42  * see http://www.epsg.org/guides/docs/G7-2.pdf, chapter on Transverse Mercator,
43  * for the conversion.
44  */
45 
46  // ellipsoid: bessel 1841
47  private static final double a = 6377397.155;
48  // private static final double f = 1/299.15281; // flattening of bessel 1841, not used here
49  private static final double e = 0.081696831;
50 
51  private static final double falseEasting = 4500110.0;
52  private static final double falseNorthing = 116.0;
53  private static final double k0 = 1.0;
54  // private static final double projectionLatitude = 0.0;
55  private static final double projectionLongitude = 12.0 * Math.PI / 180.0;
56 
57  private static final double e2 = e*e;
58  private static final double e_2 = e2 / (1 - e2);
59  private static final double e1 = (1 - Math.pow(1 - e2, 0.5)) / (1 + Math.pow(1 - e2, 0.5));
60  private static final double M0 = 0.0;
61  private static final double MU1_DIVISOR = a * (1 - e2*(1.0/4.0 - e2*(3.0/64.0) - e2*(5.0/256.0)));
62 
63  private static final double[] PHI1_DIVIDENS = {
64  (3 * e1 / 2 - 27 * Math.pow(e1, 3) / 32),
65  (21 * Math.pow(e1, 2) / 16 - 55 * Math.pow(e1, 4) / 32),
66  (151 * Math.pow(e1, 3) / 96),
67  (1097 * Math.pow(e1, 4) / 512)
68  };
69 
70  @Override
71  public Coord transform(final Coord coord) {
72 
73  double easting = coord.getX();
74  double northing = coord.getY();
75 
76  double M1 = M0 + (northing - falseNorthing) / k0;
77  double mu1 = M1 / MU1_DIVISOR;
78 
79  double phi1 = mu1
80  + PHI1_DIVIDENS[0] * Math.sin(2 * mu1)
81  + PHI1_DIVIDENS[1] * Math.sin(4 * mu1)
82  + PHI1_DIVIDENS[2] * Math.sin(6 * mu1)
83  + PHI1_DIVIDENS[3] * Math.sin(8 * mu1);
84 
85  double cosphi1 = Math.cos(phi1);
86  double sinphi1 = Math.sin(phi1);
87  double tanphi1 = Math.tan(phi1);
88 
89  double C1 = e_2 * cosphi1 * cosphi1;
90  double T1 = Math.pow(tanphi1, 2);
91  double rho1 = a * (1 - e2) / Math.pow((1 - e2 * sinphi1 * sinphi1), 1.5);
92  double nu1 = a / Math.pow((1 - e2 * sinphi1 * sinphi1), 0.5);
93  double D = (easting - falseEasting) / (nu1 * k0);
94 
95  double latitude = phi1
96  - (nu1 * tanphi1 / rho1) * (Math.pow(D, 2) / 2
97  - ( 5 + 3*T1 + 10 * C1 - 4*C1*C1 - 9 * e_2) * Math.pow(D, 4) / 24
98  + (61 + 90*T1 + 298 * C1 + 45*T1*T1 - 252 * e_2 - 3 * C1*C1) * Math.pow(D, 6) / 720);
99 
100  double longitude = projectionLongitude + (D
101  - (1 + 2 * T1 + C1) * Math.pow(D, 3) / 6
102  + (5 - 2 * C1 + 28 * T1 - 3 * C1*C1 + 8 * e_2 + 24 * T1*T1) * Math.pow(D, 5) / 120
103  ) / cosphi1;
104 
105  latitude = latitude * 180.0 / Math.PI;
106  longitude = longitude * 180.0 / Math.PI;
107 
108  double elevation;
109  try{
110  elevation = coord.getZ();
111  return new Coord(longitude, latitude, elevation);
112  } catch (Exception e){
113  return new Coord(longitude, latitude);
114  }
115  }
116 
117 }