ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
gps.cc
Go to the documentation of this file.
1 // Copyright (c) 2018, ETH Zurich and UNC Chapel Hill.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 //
14 // * Neither the name of ETH Zurich and UNC Chapel Hill nor the names of
15 // its contributors may be used to endorse or promote products derived
16 // from this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 // POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Author: Johannes L. Schoenberger (jsch-at-demuc-dot-de)
31 
32 #include "base/gps.h"
33 
34 #include "util/math.h"
35 
36 namespace colmap {
37 
38 GPSTransform::GPSTransform(const int ellipsoid) {
39  switch (ellipsoid) {
40  case GRS80:
41  case WGS84:
42  a_ = 6378137.0;
43  // Using flattening factor and semi-minor axis calculation from Bing maps.
44  // New calculations are marginally more accurate than the original values.
45  f_ = 1.0 / 298.257222101;
46  b_ = (1.0 - f_) * a_;
47  break;
48  default:
49  a_ = std::numeric_limits<double>::quiet_NaN();
50  b_ = std::numeric_limits<double>::quiet_NaN();
51  f_ = std::numeric_limits<double>::quiet_NaN();
52  throw std::invalid_argument("Ellipsoid not defined");
53  }
54  e2_ = f_ * (2.0 - f_);
55 }
56 
57 std::vector<Eigen::Vector3d> GPSTransform::EllToXYZ(
58  const std::vector<Eigen::Vector3d>& ell) const {
59  std::vector<Eigen::Vector3d> xyz(ell.size());
60 
61  for (size_t i = 0; i < ell.size(); ++i) {
62  const double lat = DegToRad(ell[i](0));
63  const double lon = DegToRad(ell[i](1));
64  const double alt = ell[i](2);
65 
66  const double sin_lat = sin(lat);
67  const double sin_lon = sin(lon);
68  const double cos_lat = cos(lat);
69  const double cos_lon = cos(lon);
70 
71  // Normalized radius
72  const double N = a_ / sqrt(1 - e2_ * sin_lat * sin_lat);
73 
74  xyz[i](0) = (N + alt) * cos_lat * cos_lon;
75  xyz[i](1) = (N + alt) * cos_lat * sin_lon;
76  xyz[i](2) = (N * (1 - e2_) + alt) * sin_lat;
77  }
78 
79  return xyz;
80 }
81 
82 std::vector<Eigen::Vector3d> GPSTransform::XYZToEll(
83  const std::vector<Eigen::Vector3d>& xyz) const {
84  std::vector<Eigen::Vector3d> ell(xyz.size());
85 
86  for (size_t i = 0; i < ell.size(); ++i) {
87  const double x = xyz[i](0);
88  const double y = xyz[i](1);
89  const double z = xyz[i](2);
90 
91  const double radius_xy = sqrt(x * x + y * y);
92  const double kEps = 1e-12;
93 
94  // Latitude
95  double lat = atan2(z, radius_xy);
96  double alt;
97 
98  for (size_t j = 0; j < 100; ++j) {
99  const double sin_lat0 = sin(lat);
100  const double N = a_ / sqrt(1 - e2_ * sin_lat0 * sin_lat0);
101  alt = radius_xy / cos(lat) - N;
102  const double prev_lat = lat;
103  lat = atan((z / radius_xy) * 1 / (1 - e2_ * N / (N + alt)));
104 
105  if (std::abs(prev_lat - lat) < kEps) {
106  break;
107  }
108  }
109 
110  ell[i](0) = RadToDeg(lat);
111 
112  // Longitude
113  ell[i](1) = RadToDeg(atan2(y, x));
114  // Alt
115  ell[i](2) = alt;
116  }
117 
118  return ell;
119 }
120 
121 } // namespace colmap
GPSTransform(const int ellipsoid=GRS80)
Definition: gps.cc:38
std::vector< Eigen::Vector3d > EllToXYZ(const std::vector< Eigen::Vector3d > &ell) const
Definition: gps.cc:57
std::vector< Eigen::Vector3d > XYZToEll(const std::vector< Eigen::Vector3d > &xyz) const
Definition: gps.cc:82
const double * e
normal_z y
normal_z x
normal_z z
float RadToDeg(const float rad)
Definition: math.h:180
float DegToRad(const float deg)
Definition: math.h:171