1 package org.opentrafficsim.core.gis;
2
3 import java.awt.geom.Point2D;
4 import java.awt.geom.Rectangle2D;
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 public final class TransformWgs84DutchRdNew
20 {
21
22
23 private static final double WGS84_WEST_LIMIT = 3.2;
24
25
26 private static final double WGS84_EAST_LIMIT = 7.3;
27
28
29 private static final double WGS84_SOUTH_LIMIT = 50.6;
30
31
32 private static final double WGS84_NORTH_LIMIT = 53.7;
33
34
35 private static final double RD_MINIMUM_X = 11000;
36
37
38 private static final double RD_MAXIMUM_X = 280000;
39
40
41 private static final double RD_MINIMUM_Y = 300000;
42
43
44 private static final double RD_MAXIMUM_Y = 630000;
45
46
47 private TransformWgs84DutchRdNew()
48 {
49
50 }
51
52
53
54
55
56
57
58 private static Point2D.Double ellipseWgs84ToRd(final double wgs84East, final double wgs84North)
59 {
60 if (wgs84North > WGS84_NORTH_LIMIT || wgs84North < WGS84_SOUTH_LIMIT || wgs84East < WGS84_WEST_LIMIT
61 || (wgs84East > WGS84_EAST_LIMIT))
62 {
63 throw new IllegalArgumentException("ellipswgs842rd input out of range (" + wgs84East + ", " + wgs84North + ")");
64 }
65
66 @SuppressWarnings("checkstyle:nowhitespacebefore")
67
68 final double[][] r =
69 {
70 { 155000.00, 190094.945, -0.008, -32.391, 0.0 , },
71 { -0.705, -11832.228, 0.0 , 0.608, 0.0 , },
72 { 0.0 , -114.221, 0.0 , 0.148, 0.0 , },
73 { 0.0 , -2.340, 0.0 , 0.0 , 0.0 , },
74 { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , }
75 };
76 @SuppressWarnings("checkstyle:nowhitespacebefore")
77 final double[][] s =
78 {
79 { 463000.00 , 0.433, 3638.893, 0.0 , 0.092, },
80 { 309056.544, -0.032, -157.984, 0.0 , -0.054, },
81 { 73.077, 0.0 , -6.439, 0.0 , 0.0 , },
82 { 59.788, 0.0 , 0.0 , 0.0 , 0.0 , },
83 { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , }
84 };
85
86 double resultX = 0;
87 double resultY = 0;
88 double powNorth = 1;
89 double dNorth = 0.36 * (wgs84North - 52.15517440);
90 double dEast = 0.36 * (wgs84East - 5.38720621);
91
92 for (int p = 0; p < 5; p++)
93 {
94 double powEast = 1;
95 for (int q = 0; q < 5; q++)
96 {
97 resultX += r[p][q] * powEast * powNorth;
98 resultY += s[p][q] * powEast * powNorth;
99 powEast *= dEast;
100 }
101 powNorth *= dNorth;
102 }
103 return new Point2D.Double(resultX, resultY);
104 }
105
106
107
108
109
110
111
112
113 private static Point2D rdToEllipseWgs84(final double rdX, final double rdY) throws IllegalArgumentException
114 {
115 if (rdX < RD_MINIMUM_X || rdX > RD_MAXIMUM_X || rdY < RD_MINIMUM_Y || rdY > RD_MAXIMUM_Y)
116 {
117 throw new IllegalArgumentException(
118 "Location (" + rdX + "," + rdY + ") is not within the range " + "of the Dutch RD system");
119 }
120 final double dX = (rdX - 155000) / 100000;
121 final double dY = (rdY - 463000) / 100000;
122
123
124 @SuppressWarnings("checkstyle:nowhitespacebefore")
125 final double[][] k =
126 {
127 { 3600 * 52.15517440, 3235.65389, -0.24750, -0.06550, 0.0 , },
128 { -0.00738 , -0.00012, 0.0 , 0.0 , 0.0 , },
129 { -32.58297 , -0.84978, -0.01709, -0.00039, 0.0 , },
130 { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , },
131 { 0.00530 , 0.00033, 0.0 , 0.0 , 0.0 , },
132 { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , }
133 };
134 @SuppressWarnings("checkstyle:nowhitespacebefore")
135 final double[][] l = {
136 { 3600 * 5.38720621, 0.01199, 0.00022, 0.0 , 0.0 , },
137 { 5260.52916 , 105.94684, 2.45656, 0.05594, 0.00128, },
138 { -0.00022 , 0.0 , 0.0 , 0.0 , 0.0 , },
139 { -0.81885 , -0.05607, -0.00256, 0.0 , 0.0 , },
140 { 0.0 , 0.0 , 0.0 , 0.0 , 0.0 , },
141 { 0.00026 , 0.0 , 0.0 , 0.0 , 0.0 , }
142 };
143
144 double resultNorth = 0;
145 double resultEast = 0;
146 double powX = 1;
147 for (int p = 0; p < 6; p++)
148 {
149 double powY = 1;
150 for (int q = 0; q < 5; q++)
151 {
152 resultNorth += k[p][q] * powX * powY / 3600;
153 resultEast += l[p][q] * powX * powY / 3600;
154 powY *= dY;
155 }
156 powX *= dX;
157 }
158 return new Point2D.Double(resultEast, resultNorth);
159 }
160
161
162
163
164
165
166
167 public static Point2D toWgs84(final Point2D local) throws IllegalArgumentException
168 {
169 return toWgs84(local.getX(), local.getY());
170 }
171
172
173
174
175
176
177
178
179 public static Point2D toWgs84(final double localX, final double localY) throws IllegalArgumentException
180 {
181 return rdToEllipseWgs84(localX, localY);
182 }
183
184
185
186
187
188
189
190 public static Point2D fromWgs84(final Point2D wgs84) throws IllegalArgumentException
191 {
192 return fromWgs84(wgs84.getX(), wgs84.getY());
193 }
194
195
196
197
198
199
200
201
202 public static Point2D fromWgs84(final double wgs84East, final double wgs84North) throws IllegalArgumentException
203 {
204 return ellipseWgs84ToRd(wgs84East, wgs84North);
205 }
206
207
208
209
210
211
212
213
214
215 public static Rectangle2D fromWgs84Bounds()
216 {
217 return new Rectangle2D.Double(WGS84_WEST_LIMIT, WGS84_SOUTH_LIMIT, WGS84_EAST_LIMIT - WGS84_WEST_LIMIT,
218 WGS84_NORTH_LIMIT - WGS84_SOUTH_LIMIT);
219 }
220
221
222
223
224
225
226
227
228
229 public static Rectangle2D toWgs84Bounds()
230 {
231 return new Rectangle2D.Double(RD_MINIMUM_X, RD_MINIMUM_Y, RD_MAXIMUM_X - RD_MINIMUM_X, RD_MAXIMUM_Y - RD_MINIMUM_Y);
232 }
233
234 }