@@ -11,11 +11,11 @@ namespace carla {
1111namespace geom {
1212
1313 static double DegreesToRadians (double degrees) {
14- return degrees * Math::Pi<double >() / 180.0 ;
14+ return degrees * Math::Pi<double >() / 180.0 ;
1515 }
1616
1717 static double RadiansToDegrees (double radians) {
18- return radians * 180.0 / Math::Pi<double >();
18+ return radians * 180.0 / Math::Pi<double >();
1919 }
2020
2121 Location GeoProjection::GeoLocationToTransform (const GeoLocation& geolocation) const {
@@ -48,31 +48,31 @@ namespace geom {
4848 }
4949 }
5050
51- GeoLocation GeoProjection::TransformToGeoLocation (const Location& location ) const {
51+ GeoLocation GeoProjection::TransformToGeoLocation (const Location& location_lh ) const {
5252 switch (static_cast <ProjectionType>(params.index ())) {
5353 case ProjectionType::TransverseMercator: {
5454 auto & p = boost::variant2::get<TransverseMercatorParams>(params);
55- return TransformToGeoLocationTransverseMercator (location , p);
55+ return TransformToGeoLocationTransverseMercator (location_lh , p);
5656 }
5757
5858 case ProjectionType::UniversalTransverseMercator: {
5959 auto & p = boost::variant2::get<UniversalTransverseMercatorParams>(params);
60- return TransformToGeoLocationUniversalTransverseMercator (location , p);
60+ return TransformToGeoLocationUniversalTransverseMercator (location_lh , p);
6161 }
6262
6363 case ProjectionType::WebMercator: {
6464 auto & p = boost::variant2::get<WebMercatorParams>(params);
65- return TransformToGeoLocationWebMercator (location , p);
65+ return TransformToGeoLocationWebMercator (location_lh , p);
6666 }
6767
6868 case ProjectionType::LambertConformalConic:{
6969 auto & p = boost::variant2::get<LambertConformalConicParams>(params);
70- return TransformToGeoLocationLambertConformalConic (location , p);
70+ return TransformToGeoLocationLambertConformalConic (location_lh , p);
7171 }
7272
7373 default : {
7474 auto & p = boost::variant2::get<TransverseMercatorParams>(params);
75- return TransformToGeoLocationTransverseMercator (location , p);
75+ return TransformToGeoLocationTransverseMercator (location_lh , p);
7676 }
7777 }
7878 }
@@ -116,7 +116,7 @@ namespace geom {
116116 + (5.0 - T + 9.0 * C + 4.0 * C * C) * std::pow (A, 4 ) / 24.0
117117 + (61.0 - 58.0 * T + T * T + 600.0 * C - 330.0 * ep2) * std::pow (A, 6 ) / 720.0 ));
118118
119- return Location ( static_cast < float >(x), static_cast < float >(y), static_cast < float >( geolocation.altitude ) );
119+ return LocationRightHanded (x, y, geolocation.altitude );
120120 }
121121
122122 Location GeoProjection::GeoLocationToTransformUniversalTransverseMercator (
@@ -153,7 +153,7 @@ namespace geom {
153153 + (5.0 - T + 9.0 * C + 4.0 * C * C) * std::pow (A, 4 ) / 24.0
154154 + (61.0 - 58.0 * T + T * T + 600.0 * C - 330.0 * ep2) * std::pow (A, 6 ) / 720.0 ));
155155
156- return Location ( static_cast < float >(x), static_cast < float >(y), static_cast < float >( geolocation.altitude ) );
156+ return LocationRightHanded (x, y, geolocation.altitude );
157157 }
158158
159159 Location GeoProjection::GeoLocationToTransformWebMercator (
@@ -165,7 +165,7 @@ namespace geom {
165165 double x = p.ellps .a * lon;
166166 double y = p.ellps .a * std::log (std::tan (Math::Pi<double >() / 4.0 + lat / 2.0 ));
167167
168- return Location ( static_cast < float >(x), static_cast < float >(y), static_cast < float >( geolocation.altitude ) );
168+ return LocationRightHanded (x, y, geolocation.altitude );
169169 }
170170
171171 Location GeoProjection::GeoLocationToTransformLambertConformalConic (
@@ -203,11 +203,16 @@ namespace geom {
203203 double x = p.x_0 + rho * std::sin (theta);
204204 double y = p.y_0 + rho0 - rho * std::cos (theta);
205205
206- return Location ( static_cast < float >(x), static_cast < float >(y), static_cast < float >( geolocation.altitude ) );
206+ return LocationRightHanded (x, y, geolocation.altitude );
207207 }
208208
209209 GeoLocation GeoProjection::TransformToGeoLocationTransverseMercator (
210- const Location& location, const TransverseMercatorParams p) const {
210+ const Location& location_lh, const TransverseMercatorParams p) const {
211+
212+ LocationRightHanded location_rh (location_lh);
213+ if (p.offset .has_value ()) {
214+ location_rh = LocationRightHanded (p.offset ->ApplyTransformation (location_lh));
215+ }
211216
212217 // Using Snyder TM inverse (ellipsoidal) to 6th order
213218 double lat_0 = DegreesToRadians (p.lat_0 );
@@ -219,8 +224,8 @@ namespace geom {
219224 double e4 = e2 * e2 ;
220225 double e6 = e4 * e2 ;
221226
222- double x = (location .x - p.x_0 ) / p.k ;
223- double y = (location .y - p.y_0 ) / p.k ;
227+ double x = (location_rh .x - p.x_0 ) / p.k ;
228+ double y = (location_rh .y - p.y_0 ) / p.k ;
224229
225230 double M = a * ((1.0 - e2 / 4.0 - 3.0 * e4 / 64.0 - 5.0 * e6 / 256.0 ) * lat_0
226231 - (3.0 * e2 / 8.0 + 3.0 * e4 / 32.0 + 45.0 * e6 / 1024.0 ) * std::sin (2.0 * lat_0)
@@ -255,11 +260,16 @@ namespace geom {
255260
256261 lon = std::atan2 (std::sin (lon), std::cos (lon));
257262
258- return GeoLocation (RadiansToDegrees (lat), RadiansToDegrees (lon), location .z );
263+ return GeoLocation (RadiansToDegrees (lat), RadiansToDegrees (lon), location_rh .z );
259264 }
260265
261266 GeoLocation GeoProjection::TransformToGeoLocationUniversalTransverseMercator (
262- const Location& location_in, const UniversalTransverseMercatorParams p) const {
267+ const Location& location_lh, const UniversalTransverseMercatorParams p) const {
268+
269+ LocationRightHanded location_rh (location_lh);
270+ if (p.offset .has_value ()) {
271+ location_rh = LocationRightHanded (p.offset ->ApplyTransformation (location_lh));
272+ }
263273
264274 // Using Snyder TM inverse (ellipsoidal) to 6th order. Same formula as Transverse Mercator.
265275 double lon_0 = DegreesToRadians (6 * p.zone - 183 ); // central meridian
@@ -273,17 +283,8 @@ namespace geom {
273283 double e4 = e2 * e2 ;
274284 double e6 = e4 * e2 ;
275285
276- Location location;
277- if (p.offset .has_value ()) {
278- location = p.offset ->ApplyTransformation (location_in);
279- }
280- else {
281- location = location_in;
282- }
283-
284- // Negate the value of y because of the unreal left hand rule
285- double x = (location.x - x_0) / k;
286- double y = (location.y - y_0) / k;
286+ double x = (location_rh.x - x_0) / k;
287+ double y = (location_rh.y - y_0) / k;
287288
288289 double mu = y / (a * (1.0 - e2 / 4.0 - 3.0 * e4 / 64.0 - 5.0 * e6 / 256.0 ));
289290 double e1 = (1.0 - std::sqrt (1.0 - e2 )) / (1.0 + std::sqrt (1.0 - e2 ));
@@ -314,20 +315,30 @@ namespace geom {
314315
315316 lon = std::atan2 (std::sin (lon), std::cos (lon));
316317
317- return GeoLocation (RadiansToDegrees (lat), RadiansToDegrees (lon), location .z );;
318+ return GeoLocation (RadiansToDegrees (lat), RadiansToDegrees (lon), location_rh .z );;
318319 }
319320
320321 GeoLocation GeoProjection::TransformToGeoLocationWebMercator (
321- const Location& location , const WebMercatorParams p) const {
322+ const Location& location_lh , const WebMercatorParams p) const {
322323
323- double lon = location.x / p.ellps .a ;
324- double lat = 2 *std::atan (std::exp (location.y / p.ellps .a )) - Math::Pi<double >()/2 ;
324+ LocationRightHanded location_rh (location_lh);
325+ if (p.offset .has_value ()) {
326+ location_rh = LocationRightHanded (p.offset ->ApplyTransformation (location_lh));
327+ }
328+
329+ double lon = location_rh.x / p.ellps .a ;
330+ double lat = 2 *std::atan (std::exp (location_rh.y / p.ellps .a )) - Math::Pi<double >()/2 ;
325331
326- return GeoLocation (RadiansToDegrees (lat), RadiansToDegrees (lon), location .z );
332+ return GeoLocation (RadiansToDegrees (lat), RadiansToDegrees (lon), location_rh .z );
327333 }
328334
329335 GeoLocation GeoProjection::TransformToGeoLocationLambertConformalConic (
330- const Location& location, const LambertConformalConicParams p) const {
336+ const Location& location_lh, const LambertConformalConicParams p) const {
337+
338+ LocationRightHanded location_rh (location_lh);
339+ if (p.offset .has_value ()) {
340+ location_rh = LocationRightHanded (p.offset ->ApplyTransformation (location_lh));
341+ }
331342
332343 double lon_0 = DegreesToRadians (p.lon_0 );
333344 double lat_1 = DegreesToRadians (p.lat_1 );
@@ -352,8 +363,8 @@ namespace geom {
352363 double F = m1 / (n * std::pow (t1, n));
353364 double rho0 = a * F * std::pow (t0, n);
354365
355- double x = static_cast <double >(location .x ) - p.x_0 ;
356- double y = static_cast <double >(location .y ) - p.y_0 ;
366+ double x = static_cast <double >(location_rh .x ) - p.x_0 ;
367+ double y = static_cast <double >(location_rh .y ) - p.y_0 ;
357368
358369 double sgn = (n >= 0.0 ) ? 1.0 : -1.0 ;
359370 double Y = rho0 - y;
@@ -375,7 +386,7 @@ namespace geom {
375386 double lon = lon_0 + theta / n;
376387 lon = std::atan2 (std::sin (lon), std::cos (lon));
377388
378- return GeoLocation (RadiansToDegrees (lat), RadiansToDegrees (lon), location .z );
389+ return GeoLocation (RadiansToDegrees (lat), RadiansToDegrees (lon), location_rh .z );
379390 }
380391} // namespace geom
381392} // namespace carla
0 commit comments