diff options
Diffstat (limited to 'server/src/geo/utm.cppm')
| -rw-r--r-- | server/src/geo/utm.cppm | 44 |
1 files changed, 27 insertions, 17 deletions
diff --git a/server/src/geo/utm.cppm b/server/src/geo/utm.cppm index c58ffb4..75bba6f 100644 --- a/server/src/geo/utm.cppm +++ b/server/src/geo/utm.cppm | |||
| @@ -110,6 +110,7 @@ using zonable_wgs84_linestring = | |||
| 110 | // and easting (so no Norway/Svalbard exceptions). | 110 | // and easting (so no Norway/Svalbard exceptions). |
| 111 | class zone | 111 | class zone |
| 112 | { | 112 | { |
| 113 | public: | ||
| 113 | // Note: calculations heavily depend on the values of the variants. | 114 | // Note: calculations heavily depend on the values of the variants. |
| 114 | enum class hemisphere : std::uint8_t | 115 | enum class hemisphere : std::uint8_t |
| 115 | { | 116 | { |
| @@ -117,23 +118,6 @@ class zone | |||
| 117 | southern = 1, | 118 | southern = 1, |
| 118 | }; | 119 | }; |
| 119 | 120 | ||
| 120 | // Negative if in the southern hemisphere | ||
| 121 | // Equal to (zone_no - 1) * 2 + hemisphere | ||
| 122 | // In range [0, 119] | ||
| 123 | std::uint8_t zone_; | ||
| 124 | |||
| 125 | static constexpr auto zone_no_valid(std::uint8_t zone_no) -> bool | ||
| 126 | { | ||
| 127 | return 0 < zone_no && zone_no <= 60; | ||
| 128 | } | ||
| 129 | |||
| 130 | static constexpr auto from(std::uint8_t zone_no, hemisphere h) -> std::uint8_t | ||
| 131 | { | ||
| 132 | if (!zone_no_valid(zone_no)) | ||
| 133 | throw std::invalid_argument{"invalid UTM zone number"}; | ||
| 134 | return (zone_no - 1) * 2 + static_cast<std::uint8_t>(h); | ||
| 135 | } | ||
| 136 | |||
| 137 | public: | 121 | public: |
| 138 | explicit constexpr zone(std::uint8_t zone_no, hemisphere h) | 122 | explicit constexpr zone(std::uint8_t zone_no, hemisphere h) |
| 139 | : zone_{from(zone_no, h)} | 123 | : zone_{from(zone_no, h)} |
| @@ -196,8 +180,34 @@ public: | |||
| 196 | { | 180 | { |
| 197 | return zone_ == rhs.zone_; | 181 | return zone_ == rhs.zone_; |
| 198 | } | 182 | } |
| 183 | |||
| 184 | private: | ||
| 185 | static constexpr auto zone_no_valid(std::uint8_t zone_no) -> bool | ||
| 186 | { | ||
| 187 | return 0 < zone_no && zone_no <= 60; | ||
| 188 | } | ||
| 189 | |||
| 190 | static constexpr auto from(std::uint8_t zone_no, enum hemisphere h) | ||
| 191 | -> std::uint8_t | ||
| 192 | { | ||
| 193 | if (!zone_no_valid(zone_no)) | ||
| 194 | throw std::invalid_argument{"invalid UTM zone number"}; | ||
| 195 | return (zone_no - 1) * 2 + static_cast<std::uint8_t>(h); | ||
| 196 | } | ||
| 197 | |||
| 198 | // Negative if in the southern hemisphere | ||
| 199 | // Equal to (zone_no - 1) * 2 + hemisphere | ||
| 200 | // In range [0, 119] | ||
| 201 | std::uint8_t zone_; | ||
| 199 | }; | 202 | }; |
| 200 | static_assert(zone::min().as_index() == 0); | 203 | static_assert(zone::min().as_index() == 0); |
| 201 | static_assert(zone::max().as_index() == 119); | 204 | static_assert(zone::max().as_index() == 119); |
| 202 | 205 | ||
| 206 | auto to_string(zone z) -> std::string | ||
| 207 | { | ||
| 208 | return std::format( | ||
| 209 | "{} {}", z.zone_no(), | ||
| 210 | z.hemisphere() == zone::hemisphere::northern ? "northern" : "southern"); | ||
| 211 | } | ||
| 212 | |||
| 203 | } // namespace routemon::geo::utm | 213 | } // namespace routemon::geo::utm |