summaryrefslogtreecommitdiffstats
path: root/server/src/geo/utm.cppm
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/geo/utm.cppm')
-rw-r--r--server/src/geo/utm.cppm44
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).
111class zone 111class zone
112{ 112{
113public:
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
137public: 121public:
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
184private:
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};
200static_assert(zone::min().as_index() == 0); 203static_assert(zone::min().as_index() == 0);
201static_assert(zone::max().as_index() == 119); 204static_assert(zone::max().as_index() == 119);
202 205
206auto 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