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.
147 lines
5.9 KiB
147 lines
5.9 KiB
7 years ago
|
#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_
|