You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
146 lines
5.9 KiB
146 lines
5.9 KiB
#ifndef AIRMAP_GEOMETRY_H_ |
|
#define AIRMAP_GEOMETRY_H_ |
|
|
|
#include <airmap/optional.h> |
|
|
|
#include <vector> |
|
|
|
namespace airmap { |
|
|
|
/// Geometry bundles up different types of geometries. |
|
class Geometry { |
|
public: |
|
/// Type enumerates all known geometry types. |
|
enum class Type { |
|
invalid, ///< Marks an invalid geometry. |
|
point, ///< Geometry contains a Point. |
|
multi_point, ///< Geometry contains a MultiPoint. |
|
line_string, ///< Geometry contains a LineString. |
|
multi_line_string, ///< Geometry contains a MultiLineString. |
|
polygon, ///< Geometry contains a Polygon. |
|
multi_polygon, ///< Geometry contains a MultiPolygon. |
|
geometry_collection ///< Geometry is a GemetryCollection. |
|
}; |
|
|
|
/// Coordinate marks a point in 3-dimensional space. |
|
struct Coordinate { |
|
double latitude; /// The latitude component of this coordinate in [°]. |
|
double longitude; /// The longitude component of this coordinate in [°]. |
|
Optional<double> altitude; /// The altitude component of this coordinate in [m]. |
|
Optional<double> elevation; |
|
}; |
|
|
|
/// CoordinateVector is a collection of points in 3-dimensional space. |
|
template <Type tag> |
|
struct CoordinateVector { |
|
std::vector<Coordinate> coordinates; ///< The individual coordinates. |
|
}; |
|
|
|
using Point = Coordinate; |
|
using MultiPoint = CoordinateVector<Type::multi_point>; |
|
using LineString = CoordinateVector<Type::line_string>; |
|
using MultiLineString = std::vector<LineString>; |
|
/// Polygon follows the GeoJSON standard, citing from https://tools.ietf.org/html/rfc7946: |
|
/// * For type "Polygon", the "coordinates" member MUST be an array of |
|
/// linear ring coordinate arrays. |
|
/// * For Polygons with more than one of these rings, the first MUST be |
|
/// the exterior ring, and any others MUST be interior rings. The |
|
/// exterior ring bounds the surface, and the interior rings (if |
|
/// present) bound holes within the surface. |
|
struct Polygon { |
|
CoordinateVector<Type::polygon> outer_ring; |
|
std::vector<CoordinateVector<Type::polygon>> inner_rings; |
|
}; |
|
using MultiPolygon = std::vector<Polygon>; |
|
using GeometryCollection = std::vector<Geometry>; |
|
|
|
/// point returns a Geometry instance with Type::point at the given coordinate (lat, lon). |
|
static Geometry point(double lat, double lon); |
|
/// polygon returns a Geometry instance with Type::polygon with the given 'coordinates'. |
|
static Geometry polygon(const std::vector<Coordinate>& coordinates); |
|
|
|
/// Initializes a new instance with Type::invalid. |
|
Geometry(); |
|
/// Geometry initializes a new instance with the given Point. |
|
explicit Geometry(const Point& other); |
|
/// Geometry initializes a new instance with the given MultiPoint. |
|
explicit Geometry(const MultiPoint& other); |
|
/// Geometry initializes a new instance with the given LineString. |
|
explicit Geometry(const LineString& other); |
|
/// Geometry initializes a new instance with the given MultiLineString. |
|
explicit Geometry(const MultiLineString& other); |
|
/// Geometry initializes a new instance with the given Polyon. |
|
explicit Geometry(const Polygon& other); |
|
/// Geometry initializes a new instance with the given MultiPolygon. |
|
explicit Geometry(const MultiPolygon& other); |
|
/// Geometry initializes a new instance with the given GeometryCollection. |
|
explicit Geometry(const GeometryCollection& other); |
|
/// @cond |
|
Geometry(const Geometry& other); |
|
~Geometry(); |
|
Geometry& operator=(const Geometry& rhs); |
|
bool operator==(const Geometry& rhs) const; |
|
/// @endcond |
|
|
|
/// type returns the Type of the geometry. |
|
Type type() const; |
|
/// details_for_point returns an immutable instance to the contained Point instance. |
|
const Point& details_for_point() const; |
|
/// details_for_multi_point returns an immutable instance to the contained MultiPoint instance. |
|
const MultiPoint& details_for_multi_point() const; |
|
/// details_for_line_string returns an immutable instance to the contained LineString instance. |
|
const LineString& details_for_line_string() const; |
|
/// details_for_multi_line_string returns an immutable instance to the contained MultiLineString instance. |
|
const MultiLineString& details_for_multi_line_string() const; |
|
/// details_for_polygon returns an immutable instance to the contained Polygon instance. |
|
const Polygon& details_for_polygon() const; |
|
/// details_for_multi_polygon returns an immutable instance to the contained MultiPolygon instance. |
|
const MultiPolygon& details_for_multi_polygon() const; |
|
/// details_for_geometry_collection returns an immutable instance to the contained GeometryCollection instance. |
|
const GeometryCollection details_for_geometry_collection() const; |
|
|
|
private: |
|
struct Invalid {}; |
|
|
|
union Data { |
|
Data(); |
|
~Data(); |
|
|
|
Invalid invalid; |
|
Point point; |
|
MultiPoint multi_point; |
|
LineString line_string; |
|
MultiLineString multi_line_string; |
|
Polygon polygon; |
|
MultiPolygon multi_polygon; |
|
GeometryCollection geometry_collection; |
|
}; |
|
|
|
Geometry& reset(); |
|
void set_point(const Point& point); |
|
void set_multi_point(const MultiPoint& multi_point); |
|
void set_line_string(const LineString& line_string); |
|
void set_multi_line_string(const MultiLineString& multi_line_string); |
|
void set_polygon(const Polygon& polygon); |
|
void set_multi_polygon(const MultiPolygon& multi_polygon); |
|
void set_geometry_collection(const GeometryCollection& geometry_collection); |
|
Geometry& set_geometry(const Geometry& other); |
|
|
|
Type type_; |
|
Data data_; |
|
}; |
|
|
|
/// @cond |
|
bool operator==(const Geometry::Coordinate& lhs, const Geometry::Coordinate& rhs); |
|
|
|
bool operator==(const Geometry::Polygon& lhs, const Geometry::Polygon& rhs); |
|
|
|
template <Geometry::Type tag> |
|
bool operator==(const Geometry::CoordinateVector<tag>& lhs, const Geometry::CoordinateVector<tag>& rhs) { |
|
return lhs.coordinates == rhs.coordinates; |
|
} |
|
/// @endcond |
|
|
|
} // namespace airmap |
|
|
|
#endif // AIRMAP_GEOMETRY_H_
|
|
|