Peano
SphereProjection.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../Constants.h"
4 
5 #include <cmath>
6 #include <utility>
7 
8 namespace projection {
9  namespace albers_equal_area {
10  namespace sphere {
11  namespace constants = ::applications::exahype2::swe;
12 
23  inline auto forward(const auto lon, const auto lat) {
24  constexpr auto lon0 = constants::aeaLon0;
25  constexpr auto lat0 = constants::aeaLat0;
26  constexpr auto stdParallel1 = constants::aeaStdParallel1;
27  constexpr auto stdParallel2 = constants::aeaStdParallel2;
28  constexpr auto R = constants::aeaEarthRadius;
29 
30  constexpr auto toRad = M_PI / 180.0;
31 
32  constexpr auto stdParallel1Rad = stdParallel1 * toRad;
33  constexpr auto stdParallel2Rad = stdParallel2 * toRad;
34  constexpr auto lat0Rad = lat0 * toRad;
35  constexpr auto lon0Rad = lon0 * toRad;
36 
37  const auto lonRad = lon * toRad;
38  const auto latRad = lat * toRad;
39 
40  static const auto n = (std::sin(stdParallel1Rad) + std::sin(stdParallel2Rad)) / 2;
41  static const auto C = (std::cos(stdParallel1Rad) * std::cos(stdParallel1Rad))
42  + (2 * n * std::sin(stdParallel1Rad));
43  static const auto p0 = R * std::sqrt(C - (2 * n * std::sin(lat0Rad))) / n;
44 
45  const auto p = R * std::sqrt(C - (2 * n * std::sin(latRad))) / n;
46  const auto theta = n * (lonRad - lon0Rad);
47 
48  const auto x = p * std::sin(theta);
49  const auto y = p0 - (p * std::cos(theta));
50 
51  return std::pair{x, y};
52  };
53 
64  inline auto inverse(const auto x, const auto y) {
65  constexpr auto lon0 = constants::aeaLon0;
66  constexpr auto lat0 = constants::aeaLat0;
67  constexpr auto stdParallel1 = constants::aeaStdParallel1;
68  constexpr auto stdParallel2 = constants::aeaStdParallel2;
69  constexpr auto R = constants::aeaEarthRadius;
70 
71  constexpr auto toRad = M_PI / 180.0;
72 
73  constexpr auto stdParallel1Rad = stdParallel1 * toRad;
74  constexpr auto stdParallel2Rad = stdParallel2 * toRad;
75  constexpr auto lat0Rad = lat0 * toRad;
76  constexpr auto lon0Rad = lon0 * toRad;
77 
78  static const auto n = (std::sin(stdParallel1Rad) + std::sin(stdParallel2Rad)) / 2;
79  static const auto C = (std::cos(stdParallel1Rad) * std::cos(stdParallel1Rad))
80  + (2 * n * std::sin(stdParallel1Rad));
81  static const auto p0 = R * std::sqrt(C - (2 * n * std::sin(lat0Rad))) / n;
82 
83  const auto p = std::sqrt((x * x) + ((p0 - y) * (p0 - y)));
84  const auto theta = std::atan2(x, p0 - y);
85 
86  const auto lat = std::asin((C - ((p * n / R) * (p * n / R))) / (2 * n));
87  const auto lon = lon0Rad + (theta / n);
88 
89  return std::pair{lon / toRad, lat / toRad};
90  };
91  } // namespace sphere
92  } // namespace albers_equal_area
93 } // namespace projection
auto forward(const auto lon, const auto lat)
Projects geographic coordinates (longitude, latitude) onto a planar surface using the Albers Equal-Ar...
auto inverse(const auto x, const auto y)
Inverts the spherical Albers Equal-Area Conic projection and returns the geographic coordinates (long...