define the geographic library
This commit is contained in:
91
include/aman/types/GeoCoordinate.h
Normal file
91
include/aman/types/GeoCoordinate.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* @brief Defines a geo-referenced coordinate
|
||||
* @file types/GeoCoordinate.h
|
||||
* @author Sven Czarnian <devel@svcz.de>
|
||||
* @copyright Copyright 2020-2021 Sven Czarnian
|
||||
* @license This project is published under the GNU General Public License v3 (GPLv3)
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <aman/types/Quantity.hpp>
|
||||
|
||||
namespace aman {
|
||||
/**
|
||||
* @brief Describes a geo-reference coordinate with longitude and latitude
|
||||
* @ingroup types
|
||||
*/
|
||||
class GeoCoordinate {
|
||||
private:
|
||||
Angle m_longitude;
|
||||
Angle m_latitude;
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief Creates a coordinate with zero-values
|
||||
*/
|
||||
GeoCoordinate() noexcept;
|
||||
/**
|
||||
* @brief Creates a coordinate with initial values
|
||||
* @param[in] longitude The initial longitudinal value
|
||||
* @param[in] latitude The initial latitudinal value
|
||||
*/
|
||||
GeoCoordinate(const Angle& longitude, const Angle& latitude) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Checks if two positions are equal
|
||||
* @param[in] other The other coordinate instance
|
||||
* @return True if this instance is equal to the other instance, else false
|
||||
*/
|
||||
bool operator==(const GeoCoordinate& other) const;
|
||||
/**
|
||||
* @brief Checks if two positions are not equal
|
||||
* @param[in] other The other coordinate instance
|
||||
* @return True if this instance is not equal to the other instance, else false
|
||||
*/
|
||||
bool operator!=(const GeoCoordinate& other) const;
|
||||
|
||||
/**
|
||||
* @brief Returns the longitudinal component
|
||||
* @return The constant reference to the longitudinal component
|
||||
*/
|
||||
const Angle& longitude() const noexcept;
|
||||
/**
|
||||
* @brief Returns the longitudinal component
|
||||
* @return The reference to the longitudinal component
|
||||
*/
|
||||
Angle& longitude() noexcept;
|
||||
/**
|
||||
* @brief Returns the latitudinal component
|
||||
* @return The constant reference to the latitudinal component
|
||||
*/
|
||||
const Angle& latitude() const noexcept;
|
||||
/**
|
||||
* @brief Returns the latitudinal component
|
||||
* @return The reference to the latitudinal component
|
||||
*/
|
||||
Angle& latitude() noexcept;
|
||||
/**
|
||||
* @brief Calculates the coordinate from this coordinate and based on a heading and a distance
|
||||
* The function uses the haversine-formular and calculates the coordinate based on the great circle distance
|
||||
* @param[in] heading The heading from this coordinate to the next one
|
||||
* @param[in] distance The distance from this coordinate to the next one
|
||||
* @return The resulting coordinate which is based on the heading and the distance
|
||||
*/
|
||||
GeoCoordinate projection(const Angle& heading, const Length& distance) const;
|
||||
/**
|
||||
* @brief Calculates the great circle distance between this coordinate and the other
|
||||
* @param[in] other The other coordinate
|
||||
* @return The great circle distance between this coordinate and the other
|
||||
*/
|
||||
Length distanceTo(const GeoCoordinate& other) const;
|
||||
/**
|
||||
* @brief Calculates the bearing between this coordinate and the other
|
||||
* @param[in] other The other coordinate
|
||||
* @return The bearing between this coordinate and the other
|
||||
*/
|
||||
Angle bearingTo(const GeoCoordinate& other) const;
|
||||
};
|
||||
}
|
||||
89
src/types/GeoCoordinate.cpp
Normal file
89
src/types/GeoCoordinate.cpp
Normal file
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user