OTB  9.0.0
Orfeo Toolbox
otbGeocentricTransform.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbGeocentricTransform_hxx
22 #define otbGeocentricTransform_hxx
23 
24 #include "otbGeocentricTransform.h"
25 #include "otbMath.h"
26 
27 namespace otb
28 {
29 
30 template <TransformDirection TDirectionOfMapping, class TScalarType>
33 {
34  // Geographic to geocentric
35  if (DirectionOfMapping == TransformDirection::FORWARD)
36  {
37  return Projection::WorldToEcef(point);
38  }
39  // Geocentric to geographic
40  else
41  {
42  return Projection::EcefToWorld(point);
43  }
44 }
45 
46 namespace Projection
47 {
48 
49 template <class TScalarType, class TEllipsoid>
50 itk::Point<TScalarType, 3> WorldToEcef(const itk::Point<TScalarType, 3> & worldPoint)
51 {
52  itk::Point<TScalarType, 3> ecefPoint;
53 
54  const auto lon = worldPoint[0]* CONST_PI_180;
55  const auto lat = worldPoint[1]* CONST_PI_180;
56  const auto height = worldPoint[2];
57 
58  auto sin_latitude = std::sin(lat);
59  auto cos_latitude = std::cos(lat);
60  auto N = TEllipsoid::a / sqrt( 1.0 - TEllipsoid::es * sin_latitude * sin_latitude);
61 
62  ecefPoint[0] = (N + height) * cos_latitude * cos(lon);
63  ecefPoint[1] = (N + height) * cos_latitude * sin(lon);
64  ecefPoint[2] = (N * (1 - TEllipsoid::es) + height) * sin_latitude;
65 
66  return ecefPoint;
67 }
68 
69 template <class TScalarType, class TEllipsoid>
70 itk::Point<TScalarType, 3> EcefToWorld(const itk::Point<TScalarType, 3> & ecefPoint)
71 {
72  itk::Point<TScalarType, 3> worldPoint;
73 
74  const auto x = ecefPoint[0];
75  const auto y = ecefPoint[1];
76  const auto z = ecefPoint[2];
77 
78  const TScalarType tol = 1e-15;
79  const TScalarType d2 = x*x + y*y;
80  const TScalarType d = sqrt(d2);
81  const int MAX_ITER = 10;
82 
83  constexpr TScalarType a2 = TEllipsoid::a * TEllipsoid::a;
84  constexpr TScalarType b2 = TEllipsoid::b * TEllipsoid::b;
85  const TScalarType pa2 = d2 * a2;
86  const TScalarType qb2 = z * z * b2;
87  constexpr TScalarType ae2 = a2 * TEllipsoid::es;
88  constexpr TScalarType ae4 = ae2 * ae2;
89 
90  const TScalarType c3 = -( ae4/2 + pa2 + qb2 ); // s^2
91  const TScalarType c4 = ae2*( pa2 - qb2 ); // s^1
92  const TScalarType c5 = ae4/4 * ( ae4/4 - pa2 - qb2 ); // s^0
93 
94  TScalarType s0 = 0.5 * (a2 + b2) * std::sqrt(d/TEllipsoid::a * d/TEllipsoid::a + z/TEllipsoid::b * z/TEllipsoid::b);
95 
96  for (int iterIdx = 0; iterIdx < MAX_ITER; ++iterIdx)
97  {
98  const TScalarType pol = c5 + s0 * ( c4 + s0 * ( c3 + s0 * s0 ) );
99  const TScalarType der = c4 + s0 * ( 2 * c3 + 4 * s0 * s0 );
100 
101  const TScalarType ds = - pol / der;
102  s0 += ds;
103 
104  if (std::abs(ds) < tol * s0)
105  {
106  constexpr TScalarType half = 0.5;
107  constexpr TScalarType one = 1.0;
108 
109  const auto t = s0 - half * (a2 + b2);
110  const auto x_ell = d / (one + t/a2);
111  const auto y_ell = z / (one + t/b2);
112 
113  auto const xea2 = x_ell / a2;
114  auto const yeb2 = y_ell / b2;
115 
116  auto height = (d - x_ell) * xea2 + (z - y_ell) * yeb2;
117  height /= std::sqrt(xea2 * xea2 + yeb2 * yeb2);
118 
119  //lat
120  worldPoint[1] = std::atan2(yeb2, xea2) * CONST_180_PI;
121 
122  //lon
123  worldPoint[0] = std::atan2(y, x) * CONST_180_PI;
124  worldPoint[2] = height;
125  }
126  }
127  return worldPoint;
128 }
129 
130 } // namespace Projection
131 
132 
133 
134 
135 } // namespace otb
136 #endif
otb::GeocentricTransform::TransformPoint
OutputPointType TransformPoint(const InputPointType &point) const override
Definition: otbGeocentricTransform.hxx:32
otbMath.h
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::GeocentricTransform::OutputPointType
itk::Point< ScalarType, 3 > OutputPointType
Definition: otbGeocentricTransform.h:50
otb::CONST_PI_180
constexpr double CONST_PI_180
Definition: otbMath.h:56
otb::Projection::EcefToWorld
itk::Point< TScalarType, 3 > EcefToWorld(const itk::Point< TScalarType, 3 > &ecefPoint)
Definition: otbGeocentricTransform.hxx:70
otbGeocentricTransform.h
otb::TransformDirection::FORWARD
@ FORWARD
otb::GeocentricTransform< otb::TransformDirection::INVERSE, double >::InputPointType
itk::Point< ScalarType, 3 > InputPointType
Definition: otbGeocentricTransform.h:49
otb::CONST_180_PI
constexpr double CONST_180_PI
Definition: otbMath.h:57
otb::Projection::WorldToEcef
itk::Point< TScalarType, 3 > WorldToEcef(const itk::Point< TScalarType, 3 > &worldPoint)
Definition: otbGeocentricTransform.hxx:50