地面站终端 App
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

#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_