39
39
#include < geodesy/utm.h>
40
40
41
41
/* * @file
42
-
42
+
43
43
@brief Universal Transverse Mercator transforms.
44
44
45
45
Functions to convert WGS 84 (ellipsoidal) latitude and longitude
@@ -145,7 +145,7 @@ geographic_msgs::msg::GeoPoint toMsg(const UTMPoint &from)
145
145
mu = M/(a*(1 -eccSquared/4 -3 *eccSquared*eccSquared/64
146
146
-5 *eccSquared*eccSquared*eccSquared/256 ));
147
147
148
- phi1Rad = mu + ((3 *e1 /2 -27 *e1 *e1 *e1 /32 )*sin (2 *mu)
148
+ phi1Rad = mu + ((3 *e1 /2 -27 *e1 *e1 *e1 /32 )*sin (2 *mu)
149
149
+ (21 *e1 *e1 /16 -55 *e1 *e1 *e1 *e1 /32 )*sin (4 *mu)
150
150
+ (151 *e1 *e1 *e1 /96 )*sin (6 *mu));
151
151
@@ -183,7 +183,8 @@ geographic_msgs::msg::GeoPoint toMsg(const UTMPoint &from)
183
183
* @param from WGS 84 point message.
184
184
* @param to UTM point.
185
185
*/
186
- void fromMsg (const geographic_msgs::msg::GeoPoint &from, UTMPoint &to)
186
+ void fromMsg (const geographic_msgs::msg::GeoPoint &from, UTMPoint &to,
187
+ const bool & force_zone, const char & band, const uint8_t & zone)
187
188
{
188
189
double Lat = from.latitude ;
189
190
double Long = from.longitude ;
@@ -195,7 +196,7 @@ void fromMsg(const geographic_msgs::msg::GeoPoint &from, UTMPoint &to)
195
196
double LongOrigin;
196
197
double eccPrimeSquared;
197
198
double N, T, C, A, M;
198
-
199
+
199
200
// Make sure the longitude is between -180.00 .. 179.9
200
201
// (JOQ: this is broken for Long < -180, do a real normalize)
201
202
double LongTemp = (Long+180 )-int ((Long+180 )/360 )*360 -180 ;
@@ -204,25 +205,34 @@ void fromMsg(const geographic_msgs::msg::GeoPoint &from, UTMPoint &to)
204
205
double LongOriginRad;
205
206
206
207
to.altitude = from.altitude ;
207
- to.zone = int ((LongTemp + 180 )/6 ) + 1 ;
208
-
208
+ if (!force_zone)
209
+ to.zone = int ((LongTemp + 180 )/6 ) + 1 ;
210
+ else
211
+ to.zone = zone;
212
+
209
213
if ( Lat >= 56.0 && Lat < 64.0 && LongTemp >= 3.0 && LongTemp < 12.0 )
210
214
to.zone = 32 ;
211
215
212
216
// Special zones for Svalbard
213
- if ( Lat >= 72.0 && Lat < 84.0 )
217
+ if ( Lat >= 72.0 && Lat < 84.0 )
214
218
{
215
219
if ( LongTemp >= 0.0 && LongTemp < 9.0 ) to.zone = 31 ;
216
220
else if ( LongTemp >= 9.0 && LongTemp < 21.0 ) to.zone = 33 ;
217
221
else if ( LongTemp >= 21.0 && LongTemp < 33.0 ) to.zone = 35 ;
218
222
else if ( LongTemp >= 33.0 && LongTemp < 42.0 ) to.zone = 37 ;
219
223
}
220
224
// +3 puts origin in middle of zone
221
- LongOrigin = (to.zone - 1 )*6 - 180 + 3 ;
225
+ LongOrigin = (to.zone - 1 )*6 - 180 + 3 ;
222
226
LongOriginRad = angles::from_degrees (LongOrigin);
223
227
224
228
// compute the UTM band from the latitude
225
- to.band = UTMBand (Lat, LongTemp);
229
+ if (!force_zone)
230
+ to.band = UTMBand (Lat, LongTemp);
231
+ else
232
+ to.band = band;
233
+
234
+
235
+
226
236
#if 0
227
237
if (to.band == ' ')
228
238
throw std::range_error;
@@ -236,13 +246,13 @@ void fromMsg(const geographic_msgs::msg::GeoPoint &from, UTMPoint &to)
236
246
A = cos (LatRad)*(LongRad-LongOriginRad);
237
247
238
248
M = a*((1 - eccSquared/4 - 3 *eccSquared*eccSquared/64
239
- - 5 *eccSquared*eccSquared*eccSquared/256 ) * LatRad
249
+ - 5 *eccSquared*eccSquared*eccSquared/256 ) * LatRad
240
250
- (3 *eccSquared/8 + 3 *eccSquared*eccSquared/32
241
251
+ 45 *eccSquared*eccSquared*eccSquared/1024 )*sin (2 *LatRad)
242
252
+ (15 *eccSquared*eccSquared/256
243
- + 45 *eccSquared*eccSquared*eccSquared/1024 )*sin (4 *LatRad)
253
+ + 45 *eccSquared*eccSquared*eccSquared/1024 )*sin (4 *LatRad)
244
254
- (35 *eccSquared*eccSquared*eccSquared/3072 )*sin (6 *LatRad));
245
-
255
+
246
256
to.easting = (double )
247
257
(k0*N*(A+(1 -T+C)*A*A*A/6
248
258
+ (5 -18 *T+T*T+72 *C-58 *eccPrimeSquared)*A*A*A*A*A/120 )
@@ -277,7 +287,7 @@ bool isValid(const UTMPoint &pt)
277
287
278
288
return true ;
279
289
}
280
-
290
+
281
291
/* * Create UTM point from WGS 84 geodetic point. */
282
292
UTMPoint::UTMPoint (const geographic_msgs::msg::GeoPoint &pt)
283
293
{
@@ -291,9 +301,10 @@ UTMPoint::UTMPoint(const geographic_msgs::msg::GeoPoint &pt)
291
301
*
292
302
* @todo define the orientation transformation properly
293
303
*/
294
- void fromMsg (const geographic_msgs::msg::GeoPose &from, UTMPose &to)
304
+ void fromMsg (const geographic_msgs::msg::GeoPose &from, UTMPose &to,
305
+ const bool & force_zone, const char & band, const uint8_t & zone)
295
306
{
296
- fromMsg (from.position , to.position );
307
+ fromMsg (from.position , to.position , force_zone, band, zone );
297
308
to.orientation = from.orientation ;
298
309
}
299
310
0 commit comments