|
@@ -0,0 +1,89 @@
|
|
|
+/*
|
|
|
+ * Author:
|
|
|
+ * Sven Czarnian <devel@svcz.de>
|
|
|
+ * Brief:
|
|
|
+ * Implements the coordinate to abstract global coordinates
|
|
|
+ * Copyright:
|
|
|
+ * 2020-2021 Sven Czarnian
|
|
|
+ * License:
|
|
|
+ * GNU General Public License v3 (GPLv3)
|
|
|
+ */
|
|
|
+
|
|
|
+#include <algorithm>
|
|
|
+
|
|
|
+#include <GeographicLib/Geodesic.hpp>
|
|
|
+#include <gsl/gsl>
|
|
|
+
|
|
|
+#include <aman/helper/Math.h>
|
|
|
+#include <aman/helper/String.h>
|
|
|
+#include <aman/types/GeoCoordinate.h>
|
|
|
+
|
|
|
+using namespace aman;
|
|
|
+
|
|
|
+static constexpr float MinutesToHours = 60.0f;
|
|
|
+static constexpr float SecondsToHours = 3600.0f;
|
|
|
+static constexpr float MillisecondsToHours = 3600000.0f;
|
|
|
+static constexpr float MaxAngle = 360.0f;
|
|
|
+
|
|
|
+GeoCoordinate::GeoCoordinate() noexcept :
|
|
|
+ m_longitude(0.0f),
|
|
|
+ m_latitude(0.0f) { }
|
|
|
+
|
|
|
+GeoCoordinate::GeoCoordinate(const Angle& longitude, const Angle& latitude) noexcept :
|
|
|
+ m_longitude(longitude),
|
|
|
+ m_latitude(latitude) { }
|
|
|
+
|
|
|
+bool GeoCoordinate::operator==(const GeoCoordinate& other) const {
|
|
|
+ return this->m_longitude == other.m_longitude && this->m_latitude == other.m_latitude;
|
|
|
+}
|
|
|
+
|
|
|
+bool GeoCoordinate::operator!=(const GeoCoordinate& other) const {
|
|
|
+ return false == this->operator==(other);
|
|
|
+}
|
|
|
+
|
|
|
+const Angle& GeoCoordinate::longitude() const noexcept {
|
|
|
+ return this->m_longitude;
|
|
|
+}
|
|
|
+
|
|
|
+Angle& GeoCoordinate::longitude() noexcept {
|
|
|
+ return this->m_longitude;
|
|
|
+}
|
|
|
+
|
|
|
+const Angle& GeoCoordinate::latitude() const noexcept {
|
|
|
+ return this->m_latitude;
|
|
|
+}
|
|
|
+
|
|
|
+Angle& GeoCoordinate::latitude() noexcept {
|
|
|
+ return this->m_latitude;
|
|
|
+}
|
|
|
+
|
|
|
+GeoCoordinate GeoCoordinate::projection(const Angle& heading, const Length& distance) const {
|
|
|
+ float lat = 0.0f, lon = 0.0f;
|
|
|
+ GeographicLib::Geodesic::WGS84().Direct(this->latitude().convert(degree), this->longitude().convert(degree),
|
|
|
+ heading.convert(degree), distance.convert(metre), lat, lon);
|
|
|
+ return GeoCoordinate(lon * degree, lat * degree);
|
|
|
+}
|
|
|
+
|
|
|
+Length GeoCoordinate::distanceTo(const GeoCoordinate& other) const {
|
|
|
+ float distance = 0.0f;
|
|
|
+ GeographicLib::Geodesic::WGS84().Inverse(this->latitude().convert(degree), this->longitude().convert(degree),
|
|
|
+ other.latitude().convert(degree), other.longitude().convert(degree),
|
|
|
+ distance);
|
|
|
+ return distance * metre;
|
|
|
+}
|
|
|
+
|
|
|
+Angle GeoCoordinate::bearingTo(const GeoCoordinate& other) const {
|
|
|
+ float azimuth0 = 0.0f, azimuth1 = 0.0f;
|
|
|
+ GeographicLib::Geodesic::WGS84().Inverse(this->latitude().convert(degree), this->longitude().convert(degree),
|
|
|
+ other.latitude().convert(degree), other.longitude().convert(degree),
|
|
|
+ azimuth0, azimuth1);
|
|
|
+
|
|
|
+ std::ignore = azimuth1;
|
|
|
+
|
|
|
+ while (0.0f > azimuth0)
|
|
|
+ azimuth0 += MaxAngle;
|
|
|
+ while (MaxAngle < azimuth0)
|
|
|
+ azimuth0 += MaxAngle;
|
|
|
+
|
|
|
+ return azimuth0 * degree;
|
|
|
+}
|