17#include <mp-units/systems/si.h>
18#include <mp-units/ostream.h>
23using std::numbers::pi;
39template <Gr
idCoordinate C1, Gr
idCoordinate C2>
auto operator==(
const C1 &c1,
const C2 &c2)
41 return std::tie(c1.col, c1.row) == std::tie(c2.col, c2.row);
45template <Gr
idCoordinate C1, Gr
idCoordinate C2>
auto operator<=>(
const C1 &c1,
const C2 &c2)
47 return std::tie(c1.col, c1.row) <=> std::tie(c2.col, c2.row);
51template <Gr
idCoordinate C> std::ostream &
operator<<(std::ostream &stream,
const C &c)
53 stream <<
"(Column: " << c.col <<
", Row: " << c.row <<
")";
63 using value_type = int;
76static_assert(GridCoordinate<rowcol>);
84 using value_type = int;
97static_assert(GridCoordinate<colrow>);
108template <Coordinate C1, Coordinate C2>
auto operator==(
const C1 &c1,
const C2 &c2)
110 return std::tie(c1.lat, c1.lon) == std::tie(c2.lat, c2.lon);
114template <Coordinate C1, Coordinate C2>
auto operator<=>(
const C1 &c1,
const C2 &c2)
116 return std::tie(c1.lat, c1.lon) <=> std::tie(c2.lat, c2.lon);
120template <Coordinate C> std::ostream &
operator<<(std::ostream &stream,
const C &c)
122 stream <<
"(Lat: " << c.lat <<
", Lon: " << c.lon <<
")";
130void check(
double lat,
double lon)
132 if ((lat > 90.) || (lat < -90.) || (lon < -180.) || (lon > 180.))
133 throw std::invalid_argument(
"invalid coordinates");
137constexpr double deg2rad(
double deg)
noexcept
139 return (deg * pi / 180.0);
143constexpr double rad2deg(
double rad)
noexcept
145 return (rad * 180.0 / pi);
155constexpr double distanceEarth(
double lat1d,
double lon1d,
double lat2d,
double lon2d)
158 const double earthRadiusKm = 6371.0;
160 const double lat1r = deg2rad(lat1d);
161 const double lon1r = deg2rad(lon1d);
162 const double lat2r = deg2rad(lat2d);
163 const double lon2r = deg2rad(lon2d);
165 const double u = sin((lat2r - lat1r) / 2);
166 const double v = sin((lon2r - lon1r) / 2);
168 const double d = 2.0 * earthRadiusKm * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
181 using decimal_degree = double;
190 constexpr explicit latlon(decimal_degree latitude, decimal_degree longitude) noexcept
191 :
lat(latitude),
lon(longitude)
203 template <
class T>
constexpr
206 const double d = details::distanceEarth(this->lat, this->lon, other.lat, other.lon);
208 return d * 1000.0 * mp_units::si::metre;
212static_assert(Coordinate<latlon>);
220 using decimal_degree = double;
229 constexpr explicit lonlat(decimal_degree longitude, decimal_degree latitude) noexcept
230 :
lon(longitude),
lat(latitude)
246 const double d = details::distanceEarth(this->lat, this->lon, other.lat, other.lon);
248 return d * 1000.0 * mp_units::si::metre;
252static_assert(Coordinate<lonlat>);
Requires a type to define a lat and a lon member.
Definition coordinates.hpp:101
Requires a type to define a row and a col member.
Definition coordinates.hpp:32
Geospatial data formatting and processing.
Definition geography.hpp:17
auto operator<=>(const C1 &c1, const C2 &c2)
GridCoordinates are three-way comparable.
Definition coordinates.hpp:45
std::ostream & operator<<(std::ostream &stream, const C &c)
GridCoordinates are streamable.
Definition coordinates.hpp:51
auto operator==(const C1 &c1, const C2 &c2)
GridCoordinates are equality comparable.
Definition coordinates.hpp:39
Grid coordinates.
Definition coordinates.hpp:82
constexpr colrow(value_type column, value_type row) noexcept
Constructor.
Definition coordinates.hpp:93
value_type col
Column descriptor.
Definition coordinates.hpp:87
value_type row
Row descriptor.
Definition coordinates.hpp:90
Geographic coordinates.
Definition coordinates.hpp:179
decimal_degree lat
Latitude.
Definition coordinates.hpp:184
constexpr mp_units::quantity< mp_units::si::metre > great_circle_distance_to(const T &other) const noexcept
Compute great-circle distance between two points on the Earth.
Definition coordinates.hpp:204
constexpr latlon(decimal_degree latitude, decimal_degree longitude) noexcept
Constructor.
Definition coordinates.hpp:190
decimal_degree lon
Longitude.
Definition coordinates.hpp:187
Geographic coordinates.
Definition coordinates.hpp:218
constexpr lonlat(decimal_degree longitude, decimal_degree latitude) noexcept
Constructor.
Definition coordinates.hpp:229
decimal_degree lon
Longitude.
Definition coordinates.hpp:223
decimal_degree lat
Latitude.
Definition coordinates.hpp:226
constexpr mp_units::quantity< mp_units::si::metre > great_circle_distance_to(const T &other) const noexcept
Compute great-circle distance between two points on the Earth.
Definition coordinates.hpp:244
Grid coordinates.
Definition coordinates.hpp:61
constexpr rowcol(value_type row, value_type column) noexcept
Constructor.
Definition coordinates.hpp:72
value_type col
Column descriptor.
Definition coordinates.hpp:69
value_type row
Row descriptor.
Definition coordinates.hpp:66