Vanetza
 
Loading...
Searching...
No Matches
areas.hpp
1#ifndef AREAS_HPP_CVK1NIAI
2#define AREAS_HPP_CVK1NIAI
3
4#include <vanetza/units/angle.hpp>
5#include <vanetza/units/area.hpp>
6#include <vanetza/units/length.hpp>
7#include <boost/variant.hpp>
8
9namespace vanetza
10{
11namespace geonet
12{
13
14/**
15 * Cartesian position.
16 * As it is not strictly specified in any GeoNet standard document,
17 * I define it as point in an ENU coordinate system and its units as meters.
18 */
20{
21 CartesianPosition() : x(0.0 * units::si::meter), y(0.0 * units::si::meter) {}
22 CartesianPosition(units::Length x_, units::Length y_) : x(x_), y(y_) {}
23 units::Length x;
24 units::Length y;
25};
26
28
30{
32 latitude(0.0 * units::degree), longitude(0.0 * units::degree) {}
33 GeodeticPosition(units::GeoAngle lat, units::GeoAngle lon) :
34 latitude(lat), longitude(lon) {}
35 units::GeoAngle latitude;
36 units::GeoAngle longitude;
37};
38
39/**
40 * Get distance between two geodetic positions on WGS84 ellipsoid
41 * \param lhs left hand side
42 * \param rhs right hand side
43 * \return distance in meters (always positive) or NaN for invalid input
44 */
45units::Length distance(const GeodeticPosition& lhs, const GeodeticPosition& rhs);
46
47struct Circle
48{
49 Circle() : r(1.0 * units::si::meters) {}
50 units::Length r; // radius
51};
52
54{
55 Rectangle() : a(1.0 * units::si::meters), b(1.0 * units::si::meters) {}
56 units::Length a; // center to long side
57 units::Length b; // center to short side
58};
59
60struct Ellipse
61{
62 Ellipse() : a(1.0 * units::si::meters), b(1.0 * units::si::meters) {}
63 units::Length a; // long semi-axis
64 units::Length b; // short semi-axis
65};
66
67struct Area
68{
69 boost::variant<Rectangle, Ellipse, Circle> shape;
70 GeodeticPosition position;
71 units::Angle angle;
72};
73
74double geometric_function(const Circle&, const CartesianPosition&);
75double geometric_function(const Rectangle&, const CartesianPosition&);
76double geometric_function(const Ellipse&, const CartesianPosition&);
77double geometric_function(const decltype(Area::shape)&, const CartesianPosition&);
78
79/**
80 * Derive cartesian position ENU from geodetic WGS84 coordinates
81 * and a WGS84 reference point which becomes the cartesian origin.
82 * \param origin WGS84 reference point becoming origin
83 * \param position Calculate cartesian coordinates for this point
84 * \return Cartesian coordinates of position relative to origin
85 */
86CartesianPosition local_cartesian(
87 const GeodeticPosition& origin,
88 const GeodeticPosition& position);
89
90/**
91 * Canonicalize a point in a shape's coordinate system w.r.t. its azimuth angle
92 * \param point Point to canonicalize
93 * \param azimuth Azimuth angle of shape's long side
94 * \return canonical position (suitable for geometric_function)
95 */
96CartesianPosition canonicalize(const CartesianPosition& point, units::Angle azimuth);
97
98/**
99 * Check if positon is within or at border of area
100 * \param area with shape, dimensions, azimuth and center point position
101 * \param position Geodetic position to check against area
102 * \return true if position is inside or at border
103 */
104bool inside_or_at_border(const Area&, const GeodeticPosition&);
105
106/**
107 * Calculate area size in square km.
108 * \param area Area object
109 * \return area size
110 */
111units::Area area_size(const Area&);
112
113template<class SHAPE>
114bool inside_shape(const SHAPE& shape, const CartesianPosition& p)
115{
116 return geometric_function(shape, p) > 0.0;
117}
118
119template<class SHAPE>
120bool outside_shape(const SHAPE& shape, const CartesianPosition& p)
121{
122 return geometric_function(shape, p) < 0.0;
123}
124
125template<class SHAPE>
126bool at_shape_border(const SHAPE& shape, const CartesianPosition& p)
127{
128 return geometric_function(shape, p) == 0.0;
129}
130
131template<class SHAPE>
132bool at_center_point(const SHAPE& shape, const CartesianPosition& p)
133{
134 return geometric_function(shape, p) == 1.0;
135}
136
137} // namespace geonet
138} // namespace vanetza
139
140#endif /* AREAS_HPP_CVK1NIAI */
141