diff --git a/geo-types/src/lib.rs b/geo-types/src/lib.rs index ac90c64f2..c105b3ef1 100644 --- a/geo-types/src/lib.rs +++ b/geo-types/src/lib.rs @@ -1,3 +1,11 @@ +#![doc(html_logo_url = "https://raw.githubusercontent.com/georust/meta/master/logo/logo.png")] +//! The `geo-types` library provides geospatial primitive types and traits to the [`GeoRust`](https://github.com/georust) +//! crate ecosystem. +//! +//! In most cases, you will only need to use this crate if you're a crate author and want compatibility +//! with other `GeoRust` crates. Otherwise, the [`geo`](https://crates.io/crates/geo) crate re-exports these types and +//! provides geospatial algorithms, while the [`geojson`](https://crates.io/crates/geojson) crate allows serialising +//! and de-serialising `geo-types` primitives to GeoJSON. extern crate num_traits; #[cfg(feature = "serde")] diff --git a/geo-types/src/line_string.rs b/geo-types/src/line_string.rs index bd76369e8..26df82783 100644 --- a/geo-types/src/line_string.rs +++ b/geo-types/src/line_string.rs @@ -66,12 +66,28 @@ use std::ops::{Index, IndexMut}; /// } /// ``` /// +/// You can also iterate over the coordinates in the `LineString` as `Point`s: +/// +/// ``` +/// use geo_types::{LineString, Coordinate}; +/// +/// let line_string = LineString(vec![ +/// Coordinate { x: 0., y: 0. }, +/// Coordinate { x: 10., y: 0. }, +/// ]); +/// +/// for point in line_string.points_iter() { +/// println!("Point x = {}, y = {}", point.x(), point.y()); +/// } +/// ``` + #[derive(PartialEq, Clone, Debug, Hash)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct LineString(pub Vec>) where T: CoordinateType; +/// A `Point` iterator returned by the `points_iter` method pub struct PointsIter<'a, T: CoordinateType + 'a>(::std::slice::Iter<'a, Coordinate>); impl<'a, T: CoordinateType> Iterator for PointsIter<'a, T> { @@ -89,15 +105,17 @@ impl<'a, T: CoordinateType> DoubleEndedIterator for PointsIter<'a, T> { } impl LineString { + /// Return an iterator yielding the coordinates of a `LineString` as `Point`s pub fn points_iter(&self) -> PointsIter { PointsIter(self.0.iter()) } + /// Return the coordinates of a `LineString` as a `Vec` of `Point`s pub fn into_points(self) -> Vec> { self.0.into_iter().map(Point).collect() } - /// Return an `Line` iterator that yields one `Line` for each line segment + /// Return an iterator yielding one `Line` for each line segment /// in the `LineString`. /// /// # Examples @@ -126,6 +144,7 @@ impl LineString { }) } + /// An iterator which yields the coordinates of a `LineString` as `Triangle`s pub fn triangles<'a>(&'a self) -> impl ExactSizeIterator + Iterator> + 'a { self.0.windows(3).map(|w| { // slice::windows(N) is guaranteed to yield a slice with exactly N elements @@ -166,14 +185,14 @@ impl LineString { } } -/// Turn a `Vec` of `Point`-ish objects into a `LineString`. +/// Turn a `Vec` of `Point`-like objects into a `LineString`. impl>> From> for LineString { fn from(v: Vec) -> Self { LineString(v.into_iter().map(|c| c.into()).collect()) } } -/// Turn a `Point`-ish iterator into a `LineString`. +/// Turn an iterator of `Point`-like objects into a `LineString`. impl>> FromIterator for LineString { fn from_iter>(iter: I) -> Self { LineString(iter.into_iter().map(|c| c.into()).collect()) diff --git a/geo-types/src/point.rs b/geo-types/src/point.rs index 46c9adede..cfa02201b 100644 --- a/geo-types/src/point.rs +++ b/geo-types/src/point.rs @@ -6,7 +6,8 @@ use std::ops::Sub; /// A single point in 2D space. /// -/// Points can be created using the `new(x, y)` constructor, or from a `Coordinate` or pair of points. +/// Points can be created using the `new(x, y)` constructor, the `point!` macro, a `Coordinate`, or from +/// two-element tuples or arrays – see the `From` impl section for a complete list. /// /// # Examples /// @@ -34,6 +35,12 @@ impl From<(T, T)> for Point { } } +impl From<[T; 2]> for Point { + fn from(coords: [T; 2]) -> Point { + Point::new(coords[0], coords[1]) + } +} + impl Point where T: CoordinateType, @@ -379,9 +386,3 @@ where } } } - -impl From<[T; 2]> for Point { - fn from(coords: [T; 2]) -> Point { - Point::new(coords[0], coords[1]) - } -} diff --git a/geo/src/algorithm/chamberlain_duquette_area.rs b/geo/src/algorithm/chamberlain_duquette_area.rs index 9443f765c..4870adf63 100644 --- a/geo/src/algorithm/chamberlain_duquette_area.rs +++ b/geo/src/algorithm/chamberlain_duquette_area.rs @@ -1,7 +1,7 @@ use crate::{CoordinateType, LineString, Polygon, EQUATORIAL_EARTH_RADIUS}; use num_traits::Float; -/// Signed approximate geodesic area of a geometry. +/// Calculate the signed approximate geodesic area of a `Geometry`. /// /// # Units /// diff --git a/geo/src/algorithm/closest_point.rs b/geo/src/algorithm/closest_point.rs index bce474041..20a3f64ca 100644 --- a/geo/src/algorithm/closest_point.rs +++ b/geo/src/algorithm/closest_point.rs @@ -3,15 +3,15 @@ use crate::{Closest, Line, LineString, MultiLineString, MultiPoint, MultiPolygon use num_traits::Float; use std::iter; -/// Find the closest point between two objects, where the other object is -/// assumed to be a `Point` by default. +/// Find the closest `Point` between a given geometry and an input `Point`. +/// The closest point may intersect the geometry, be a single +/// point, or be indeterminate, as indicated by the value of the returned enum. /// /// # Examples /// -/// Here's a simple example where we've got a horizontal line which goes -/// through `(-50, 0) -> (50, 0)` and want to find the closest point to -/// `(0, 100)`. If you draw it out on paper the point on the line which is -/// closest to `(0, 100)` will be the origin. +/// We have a horizontal line which goes through `(-50, 0) -> (50, 0)`, +/// and want to find the closest point to the point `(0, 100)`. +/// Drawn on paper, the point on the line which is closest to `(0, 100)` is the origin (0, 0). /// /// ```rust /// # use geo::algorithm::closest_point::ClosestPoint; diff --git a/geo/src/algorithm/from_postgis.rs b/geo/src/algorithm/from_postgis.rs index a4c6762f0..c81add1f1 100644 --- a/geo/src/algorithm/from_postgis.rs +++ b/geo/src/algorithm/from_postgis.rs @@ -5,6 +5,7 @@ use crate::{ use postgis; use postgis::ewkb::{GeometryCollectionT, GeometryT}; +#[cfg_attr(docsrs, doc(cfg(feature = "postgis")))] /// Creates geometry from a PostGIS type. /// /// Note that PostGIS databases can store data under any spatial diff --git a/geo/src/algorithm/mod.rs b/geo/src/algorithm/mod.rs index 1d600d0b8..a21402a21 100644 --- a/geo/src/algorithm/mod.rs +++ b/geo/src/algorithm/mod.rs @@ -6,15 +6,15 @@ pub mod bearing; pub mod bounding_rect; /// Calculate the centroid of a `Geometry`. pub mod centroid; -/// Signed approximate geodesic area of a geometry. +/// Calculate the signed approximate geodesic area of a `Geometry`. pub mod chamberlain_duquette_area; -/// Calculate the minimum distance between two `Geometries`. +/// Calculate the closest `Point` between a `Geometry` and an input `Point`. pub mod closest_point; /// Determine whether `Geometry` `A` is completely enclosed by `Geometry` `B`. pub mod contains; /// Calculate the convex hull of a `Geometry`. pub mod convexhull; -/// Calculate the Euclidean distance between two `Geometries`. +/// Calculate the minimum Euclidean distance between two `Geometries`. pub mod euclidean_distance; /// Calculate the length of a planar line between two `Geometries`. pub mod euclidean_length; @@ -25,7 +25,10 @@ pub mod frechet_distance; /// Produces a `Geometry` from PostGIS. #[cfg(feature = "postgis-integration")] pub mod from_postgis; -/// Calculate a new Point given a distance and a bearing. +/// Convert a `Geometry` into a PostGIS. +#[cfg(feature = "postgis-integration")] +pub mod to_postgis; +/// Calculate a destination `Point`, given a distance and a bearing. pub mod haversine_destination; /// Calculate the Haversine distance between two `Geometries`. pub mod haversine_distance; @@ -41,7 +44,7 @@ pub mod map_coords; pub mod orient; /// Helper functions for the "fast path" variant of the Polygon-Polygon Euclidean distance method. pub(crate) mod polygon_distance_fast_path; -/// Coordinate projections and transformations using [PROJ](http://proj4.org) v5.0.x. +/// Coordinate projections and transformations using the current stable version of [PROJ](http://proj.org). #[cfg(feature = "use-proj")] pub mod proj; /// Rotate a `Geometry` around either its centroid or a `Point` by an angle given in degrees. @@ -50,9 +53,6 @@ pub mod rotate; pub mod simplify; /// Simplify `Geometries` using the Visvalingam-Whyatt algorithm. Includes a topology-preserving variant. pub mod simplifyvw; -/// Convert `Geometries` into PostGIS types. -#[cfg(feature = "postgis-integration")] -pub mod to_postgis; /// Translate a `Geometry` along the given offsets. pub mod translate; /// Calculate the Vincenty distance between two `Point`s. diff --git a/geo/src/lib.rs b/geo/src/lib.rs index d83e305d0..da553d733 100644 --- a/geo/src/lib.rs +++ b/geo/src/lib.rs @@ -1,3 +1,42 @@ +#![doc(html_logo_url = "https://raw.githubusercontent.com/georust/meta/master/logo/logo.png")] +//! The `geo` crate provides geospatial primitive types such as `Coordinate`, `Point`, `LineString`, and `Polygon` as +//! well as their `Multi–` equivalents, and provides algorithms and operations such as: +//! - Area and centroid calculation +//! - Simplification and convex hull operations +//! - Distance measurement +//! - Intersection checks +//! - Transformation to and from PostGIS types +//! - Affine transforms such as rotation and translation. +//! +//! The primitive types also provide the basis for other functionality in the `Geo` ecosystem, including: +//! - Serialization to and from [GeoJSON](https://docs.rs/geojson) and [WKT](https://docs.rs/wkt) +//! - [Coordinate transformation and projection](https://docs.rs/proj) +//! - [Geocoding](https://docs.rs/geocoding) +//! - [Working with GPS data](https://docs.rs/gpx) +//! +//! …allowing these crates to interoperate; GeoJSON can readily be read from a file, deserialised, transformed +//! to a local datum, modified, transformed back to `WGS84`, and serialised back to GeoJSON. +//! +//! Operations available for primitive types can be found in the `algorithm` module, along with +//! comprehensive usage examples. +//! +//! While `Geo` is primarily intended to operate on **planar** geometries, some other useful algorithms are +//! provided: Haversine, Frechet, and Vincenty distances, as well as Chamberlain-Duquette area. +//! +//! ## Optional Features (these can be activated in your `cargo.toml`) +//! The following optional features are available: +//! - `from-postgis`: convert `Geometry` types to and from [`PostGIS`](https://docs.rs/postgis) types. +//! - `use-proj`: enable coordinate conversion and transformation of `Point` geometries using the [`proj`](https://docs.rs/proj) crate +//! - `use-serde`: enable serialisation of geometries using `serde`. +//! +//! ## GeoJSON +//! If you wish to read or write `GeoJSON`, use the [`geojson`](https://docs.rs/geojson) crate, with the `geo-types` feature activated. +//! This provides fallible conversions **to** `geo-types` primitives such as `Point` and `Polygon` from `geojson` `Value` +//! structs using the standard [`TryFrom`](https://doc.rust-lang.org/stable/std/convert/trait.TryFrom.html) +//! and [`TryInto`](https://doc.rust-lang.org/stable/std/convert/trait.TryInto.html) traits, +//! and conversion **from** `geo-types` primitives to `geojson` +//! `Value` structs using the [`From`](https://doc.rust-lang.org/stable/std/convert/trait.TryFrom.html) trait. + extern crate geo_types; extern crate num_traits; #[cfg(feature = "use-serde")]