galileo_types/
lib.rs

1//! This crate contains a set of geometric primitives and operations on them used in GIS systems. It includes
2//! geometries themselves, projections and coordinate systems.
3//!
4//! The approach taken by this crate is trait-first approach. All business logic and operations are defined in traits
5//! and some simple default implementations are provided for convenience. The traits are designed to be simple to
6//! implement.
7//!
8//! # Projected vs geographic coordinates
9//!
10//! GIS systems work with geometries in two representations:
11//! * geographic coordinates are defined by *latitude* and *longitude*
12//! * projected coordinates are defined in cartesian *X* and *Y* on a flat surface of the Earth
13//!
14//! Most GIS systems do not distinguish these coordinates and just consider *latitude* to be *Y* and *longitude* to be
15//! *X*. This brings a lot of confusion, starting with mixing of order of coordinates, as in geography latitude usually
16//! goes first, but in geometry nobody puts *Y* before *X*, and ending with euclidean operations being applied to
17//! angular coordinates.
18//!
19//! Because of that, `galileo-types` crate makes strong distinction between geographic and cartesian coordinates. Basic
20//! trait for coordinates in any space is a point:
21//! * [`GeoPoint`](geo::GeoPoint) is defined in [`geo`] module, and represents a point in geographic coordinate system
22//! * [`CartesianPoint2d`](cartesian::CartesianPoint2d) is defined in [`cartesian`] module, and represents a point in cartesian coordinate system
23//!   on a flat surface of the Earth (or another stellar body)
24//!
25//! Geometry traits are generic over point type they are constructed with.
26//!
27//! Unfortunately, most of existing systems do not have this distinction and so a same point type might require
28//! implementation of both these traits. This creates a problem though for sometime it's difficult to know which trait's
29//! methods are to be used in a given moment. To help elevate this problem, [`Disambig`] struct can be used.
30//!
31//! # Z, H, M, T coordinates
32//!
33//! GIS systems often work with 3rd and even 4th coordinates, but the meaning of those coordinates can differ between
34//! coordinate systems:
35//! * `Z` is usually an *up* coordinate in projected cartesian coordinate system with same units as *X* and *Y*
36//! * `H` means height above surface or above datum
37//! * `M` is an arbitrary *measure* coordinate
38//! * `T` is a time coordinate
39//!
40//! Not distinguishing between those usages also brings confusion. For example, what would *distance* between two
41//! points defined in *XYH* space mean? It might be euclidean distance on the flat surface, or 3d distance in
42//! projection units, or 3d distance in *H* units (e.g. meters or feet).
43//!
44//! Because of this reason, points in every of those spaces are represented by different traits and provide
45//! different set of methods with their own meaning.
46//!
47//! At this point, one such trait is defined:
48//! * [`CartesianPoint3d`](cartesian::CartesianPoint3d) - a point in *XYZ* coordinate system, where *Z* is defined in projection units.
49//!
50//! # Converting between coordinate systems
51//!
52//! Converting between different types of coordinates is done using [`Projections`](geo::Projection).
53//!
54//! # Geometry types
55//!
56//! A subset of OGC geometry types are supported at the moment:
57//! * [`GeoPoint`](geo::GeoPoint), [`CartesianPoint2d`](cartesian::CartesianPoint2d), [`CartesianPoint3d`](cartesian::CartesianPoint2d)
58//!   (correspond to OGC *Point* geometry)
59//! * [`MultiPoint`]
60//! * [`Contour`] (corresponds to OGC *LineString* geometry with slight difference, check the trait's documentation)
61//! * [`MultiContour`] (corresponds to OGC *MultiLineString* geometry)
62//! * [`Polygon`]
63//! * [`MultiPolygon`]
64//!
65//! # Implementing `Geometry` trait
66//!
67//! The most generic trait is [`Geometry`], which provides operations that can be done on any type of geometry.
68//! Implementing this trait manually might be tedious for every geometry type, although for most use cases the
69//! default implementation provided by this crate would be sufficient. Unfortunately, Rust type system doesn't allow
70//! to provide blanket implementations of a trait for a set of other traits (because of possible conflicting implementations),
71//! and at the same time let the user override default implementation with more specific one (because of
72//! trait specialization problem).
73//!
74//! There is a way around those limitations though. You can use [`GeometryType`](geometry_type::GeometryType) trait to make your type, implementing
75//! any of the specific geometry traits, also implement [`Geometry`] trait automatically.
76//!
77//! # Implementation for foreign types
78//!
79//! `galileo-types` provides geometry traits implementation for these crates:
80//! * `geo-types` - enabled by `geo-types` feature
81//! * `geojson` - enabled by `geojson` feature
82
83pub mod cartesian;
84pub mod contour;
85mod disambig;
86pub mod error;
87pub mod geo;
88pub mod geometry;
89pub mod geometry_type;
90pub mod impls;
91mod multi_contour;
92mod multi_point;
93mod multi_polygon;
94mod polygon;
95mod segment;
96
97#[cfg(feature = "geo-types")]
98mod geo_types;
99
100#[cfg(feature = "geojson")]
101mod geojson;
102
103pub use contour::{ClosedContour, Contour};
104pub use disambig::{Disambig, Disambiguate};
105pub use geometry::{CartesianGeometry2d, Geometry};
106pub use multi_contour::MultiContour;
107pub use multi_point::MultiPoint;
108pub use multi_polygon::MultiPolygon;
109pub use polygon::Polygon;
110pub use segment::Segment;