Skip to content

Commit ab6e851

Browse files
committed
Use GeographicLib for UTMtoLL conversions
1 parent 11e821a commit ab6e851

File tree

1 file changed

+10
-64
lines changed

1 file changed

+10
-64
lines changed

include/robot_localization/navsat_conversions.h

Lines changed: 10 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -175,86 +175,32 @@ static inline void LLtoUTM(const double Lat, const double Long,
175175
}
176176

177177
/**
178-
* Converts UTM coords to lat/long. Equations from USGS Bulletin 1532
178+
* Converts UTM coords to lat/long.
179179
*
180180
* East Longitudes are positive, West longitudes are negative.
181181
* North latitudes are positive, South latitudes are negative
182182
* Lat and Long are in fractional degrees.
183-
* Meridian convergence is computed as for Spherical Transverse Mercator,
184-
* which gives quite good approximation.
185-
*
186-
* @param[out] gamma meridian convergence at point (degrees).
187183
*
188-
* Written by Chuck Gantz- [email protected]
184+
* @param[out] gamma meridian convergence at point (degrees).
189185
*/
190186
static inline void UTMtoLL(const double UTMNorthing, const double UTMEasting,
191187
const std::string &UTMZone, double& Lat, double& Long, double &gamma)
192188
{
193-
double k0 = UTM_K0;
194-
double a = WGS84_A;
195-
double eccSquared = UTM_E2;
196-
double eccPrimeSquared;
197-
double e1 = (1-sqrt(1-eccSquared))/(1+sqrt(1-eccSquared));
198-
double N1, T1, C1, R1, D, M;
199-
double LongOrigin;
200-
double mu, phi1Rad;
201-
double x, y;
202-
int ZoneNumber;
203-
char* ZoneLetter;
204-
205-
x = UTMEasting - 500000.0; // remove 500,000 meter offset for longitude
206-
y = UTMNorthing;
207-
208-
ZoneNumber = strtoul(UTMZone.c_str(), &ZoneLetter, 10);
209-
if ((*ZoneLetter - 'N') < 0)
210-
{
211-
// remove 10,000,000 meter offset used for southern hemisphere
212-
y -= 10000000.0;
213-
}
214-
215-
// +3 puts origin in middle of zone
216-
LongOrigin = (ZoneNumber - 1)*6 - 180 + 3;
217-
eccPrimeSquared = (eccSquared)/(1-eccSquared);
218-
219-
M = y / k0;
220-
mu = M/(a*(1-eccSquared/4-3*eccSquared*eccSquared/64
221-
-5*eccSquared*eccSquared*eccSquared/256));
222-
223-
phi1Rad = mu + ((3*e1/2-27*e1*e1*e1/32)*sin(2*mu)
224-
+ (21*e1*e1/16-55*e1*e1*e1*e1/32)*sin(4*mu)
225-
+ (151*e1*e1*e1/96)*sin(6*mu));
226-
227-
N1 = a/sqrt(1-eccSquared*sin(phi1Rad)*sin(phi1Rad));
228-
T1 = tan(phi1Rad)*tan(phi1Rad);
229-
C1 = eccPrimeSquared*cos(phi1Rad)*cos(phi1Rad);
230-
R1 = a*(1-eccSquared)/pow(1-eccSquared*sin(phi1Rad)*sin(phi1Rad), 1.5);
231-
D = x/(N1*k0);
232-
233-
Lat = phi1Rad - ((N1*tan(phi1Rad)/R1)
234-
*(D*D/2
235-
-(5+3*T1+10*C1-4*C1*C1-9*eccPrimeSquared)*D*D*D*D/24
236-
+(61+90*T1+298*C1+45*T1*T1-252*eccPrimeSquared
237-
-3*C1*C1)*D*D*D*D*D*D/720));
238-
239-
Lat = Lat * DEGREES_PER_RADIAN;
240-
241-
Long = ((D-(1+2*T1+C1)*D*D*D/6
242-
+(5-2*C1+28*T1-3*C1*C1+8*eccPrimeSquared+24*T1*T1)
243-
*D*D*D*D*D/120)
244-
/ cos(phi1Rad));
245-
Long = LongOrigin + Long * DEGREES_PER_RADIAN;
246-
247-
gamma = atan(tanh(x/(k0*a))*tan(y/(k0*a))) * DEGREES_PER_RADIAN;
189+
int zone;
190+
bool northp;
191+
double x_unused;
192+
double y_unused;
193+
int prec_unused;
194+
GeographicLib::MGRS::Reverse(UTMZone, zone, northp, x_unused, y_unused, prec_unused, true);
195+
GeographicLib::UTMUPS::Reverse(zone, northp, UTMEasting, UTMNorthing, Lat, Long);
248196
}
249197

250198
/**
251-
* Converts UTM coords to lat/long. Equations from USGS Bulletin 1532
199+
* Converts UTM coords to lat/long.
252200
*
253201
* East Longitudes are positive, West longitudes are negative.
254202
* North latitudes are positive, South latitudes are negative
255203
* Lat and Long are in fractional degrees.
256-
*
257-
* Written by Chuck Gantz- [email protected]
258204
*/
259205
static inline void UTMtoLL(const double UTMNorthing, const double UTMEasting,
260206
const std::string &UTMZone, double& Lat, double& Long)

0 commit comments

Comments
 (0)