Skip to content

Commit

Permalink
docs update & bump to 0.12 (#128)
Browse files Browse the repository at this point in the history
* docs update

* Update intro

* bump version and changelog
  • Loading branch information
kylebarron authored Nov 27, 2024
1 parent 94c32cd commit a8b8a1e
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 30 deletions.
7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changes

## 0.12.0 - 2024-11-26

* Writing WKT is now up to 50% faster by avoiding extra allocations and writing directly to an underlying buffer.
* Any `geo_traits` input is now supported when writing to WKT.
* Implements `geo_traits` on `Wkt` and all structs in `types`. This allows for easier interoperability when reading WKT data to other representations than `geo-types`.
* BREAKING: removed the `fmt::Display` impl on `wkt::Coord`.

## 0.11.1 - 2024-10-10

* Add an `infer_type` function to extract only the geometry type and dimension from a WKT string.
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "wkt"
description = "Rust read/write support for well-known text (WKT)"
version = "0.11.1"
version = "0.12.0"
license = "MIT OR Apache-2.0"
repository = "https://github.com/georust/wkt"
autobenches = true
Expand Down
45 changes: 32 additions & 13 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
//! geometry format.
//!
//! Conversions are available via the [`TryFromWkt`] and [`ToWkt`] traits, with implementations for
//! [`geo_types`] primitives enabled by default.
//! [`geo_types`] and [`geo_traits`] primitives enabled by default.
//!
//! For advanced usage, see the [`types`](crate::types) module for a list of internally used types.
//!
Expand Down Expand Up @@ -57,25 +57,44 @@
//!
//! Not using `geo-types` for your geometries? No problem!
//!
//! As of `wkt` version 0.12, this crate provides read and write integration with [`geo_traits`],
//! a collection of geometry access traits, to provide zero-copy integration with geometry
//! representations other than `geo-types`.
//!
//! This integration allows you to transparently read data from this crate's intermediate geometry
//! structure, and it allows you to write WKT strings directly from your geometry without any
//! intermediate representation.
//!
//! ### Reading
//!
//! You can use [`Wkt::from_str`] to parse a WKT string into this crate's intermediate geometry
//! structure. You can use that directly, or if have your own geometry types that you'd prefer to
//! use, utilize that [`Wkt`] struct to implement the [`ToWkt`] or [`TryFromWkt`] traits for your
//! own types.
//! structure. `Wkt` (and all structs defined in [types]) implement traits from [geo_traits]. You
//! can write functions in terms of those traits and you'll be able to work with the parsed WKT
//! without any further overhead.
//!
//! In doing so, you'll likely want to match on one of the WKT [`types`] (Point, Linestring, etc.)
//! stored in its `item` field
//! ```
//! use std::str::FromStr;
//! use wkt::Wkt;
//! use geo_traits::{GeometryTrait, GeometryType};
//!
//! fn is_line_string(geom: &impl GeometryTrait<T = f64>) {
//! assert!(matches!(geom.as_type(), GeometryType::LineString(_)))
//! }
//!
//! let wktls: Wkt<f64> = Wkt::from_str("LINESTRING(10 20, 20 30)").unwrap();
//! let ls = match wktls {
//! Wkt::LineString(line_string) => {
//! // you now have access to the `wkt::types::LineString`.
//! assert_eq!(line_string.0[0].x, 10.0);
//! }
//! _ => unreachable!(),
//! };
//! is_line_string(&wktls);
//! ```
//!
//! Working with the trait definition is preferable to working with `wkt::Wkt` directly, as the
//! geometry trait will work with many different geometry representations; not just the one from
//! this crate.
//!
//! ### Writing
//!
//! Consult the functions provided in [`to_wkt`]. Those functions will write any `geo_traits` object to WKT without any intermediate overhead.
//!
//! Implement [`geo_traits`] on your own geometry representation and those functions will work out
//! of the box on your data.
use std::default::Default;
use std::fmt;
use std::str::FromStr;
Expand Down
53 changes: 37 additions & 16 deletions src/to_wkt/geo_trait_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,20 @@ enum PhysicalCoordinateDimension {
Four,
}

impl From<geo_traits::Dimensions> for PhysicalCoordinateDimension {
fn from(value: geo_traits::Dimensions) -> Self {
impl TryFrom<geo_traits::Dimensions> for PhysicalCoordinateDimension {
type Error = Error;

fn try_from(value: geo_traits::Dimensions) -> Result<Self, Self::Error> {
match value.size() {
2 => Self::Two,
3 => Self::Three,
4 => Self::Four,
size => panic!("Unexpected dimension for coordinate: {}", size),
2 => Ok(Self::Two),
3 => Ok(Self::Three),
4 => Ok(Self::Four),
_ => Err(Error::UnknownDimension),
}
}
}

/// Write an object implementing [`PointTrait`] to a WKT string.
pub fn write_point<T: WktNum + fmt::Display>(
f: &mut impl Write,
g: &impl PointTrait<T = T>,
Expand All @@ -48,7 +51,7 @@ pub fn write_point<T: WktNum + fmt::Display>(
}
geo_traits::Dimensions::Unknown(_) => return Err(Error::UnknownDimension),
}?;
let size = PhysicalCoordinateDimension::from(dim);
let size = dim.try_into()?;
if let Some(coord) = g.coord() {
f.write_char('(')?;
write_coord(f, &coord, size)?;
Expand All @@ -59,6 +62,7 @@ pub fn write_point<T: WktNum + fmt::Display>(
}
}

/// Write an object implementing [`LineStringTrait`] to a WKT string.
pub fn write_linestring<T: WktNum + fmt::Display>(
f: &mut impl Write,
linestring: &impl LineStringTrait<T = T>,
Expand All @@ -78,14 +82,15 @@ pub fn write_linestring<T: WktNum + fmt::Display>(
}
geo_traits::Dimensions::Unknown(_) => return Err(Error::UnknownDimension),
}?;
let size = PhysicalCoordinateDimension::from(dim);
let size = dim.try_into()?;
if linestring.num_coords() == 0 {
Ok(f.write_str(" EMPTY")?)
} else {
write_coord_sequence(f, linestring.coords(), size)
}
}

/// Write an object implementing [`PolygonTrait`] to a WKT string.
pub fn write_polygon<T: WktNum + fmt::Display>(
f: &mut impl Write,
polygon: &impl PolygonTrait<T = T>,
Expand All @@ -103,7 +108,7 @@ pub fn write_polygon<T: WktNum + fmt::Display>(
}
geo_traits::Dimensions::Unknown(_) => return Err(Error::UnknownDimension),
}?;
let size = PhysicalCoordinateDimension::from(dim);
let size = dim.try_into()?;
if let Some(exterior) = polygon.exterior() {
if exterior.num_coords() != 0 {
f.write_str("(")?;
Expand All @@ -123,6 +128,7 @@ pub fn write_polygon<T: WktNum + fmt::Display>(
}
}

/// Write an object implementing [`MultiPointTrait`] to a WKT string.
pub fn write_multi_point<T: WktNum + fmt::Display>(
f: &mut impl Write,
multipoint: &impl MultiPointTrait<T = T>,
Expand All @@ -142,7 +148,7 @@ pub fn write_multi_point<T: WktNum + fmt::Display>(
}
geo_traits::Dimensions::Unknown(_) => return Err(Error::UnknownDimension),
}?;
let size = PhysicalCoordinateDimension::from(dim);
let size = dim.try_into()?;

let mut points = multipoint.points();

Expand All @@ -167,6 +173,7 @@ pub fn write_multi_point<T: WktNum + fmt::Display>(
Ok(())
}

/// Write an object implementing [`MultiLineStringTrait`] to a WKT string.
pub fn write_multi_linestring<T: WktNum + fmt::Display>(
f: &mut impl Write,
multilinestring: &impl MultiLineStringTrait<T = T>,
Expand All @@ -186,7 +193,7 @@ pub fn write_multi_linestring<T: WktNum + fmt::Display>(
}
geo_traits::Dimensions::Unknown(_) => return Err(Error::UnknownDimension),
}?;
let size = PhysicalCoordinateDimension::from(dim);
let size = dim.try_into()?;
let mut line_strings = multilinestring.line_strings();
if let Some(first_linestring) = line_strings.next() {
f.write_str("(")?;
Expand All @@ -205,6 +212,7 @@ pub fn write_multi_linestring<T: WktNum + fmt::Display>(
Ok(())
}

/// Write an object implementing [`MultiPolygonTrait`] to a WKT string.
pub fn write_multi_polygon<T: WktNum + fmt::Display>(
f: &mut impl Write,
multipolygon: &impl MultiPolygonTrait<T = T>,
Expand All @@ -224,7 +232,7 @@ pub fn write_multi_polygon<T: WktNum + fmt::Display>(
}
geo_traits::Dimensions::Unknown(_) => return Err(Error::UnknownDimension),
}?;
let size = PhysicalCoordinateDimension::from(dim);
let size = dim.try_into()?;

let mut polygons = multipolygon.polygons();

Expand Down Expand Up @@ -255,8 +263,7 @@ pub fn write_multi_polygon<T: WktNum + fmt::Display>(
Ok(())
}

/// Create geometry to WKT representation.
/// Write an object implementing [`GeometryTrait`] to a WKT string.
pub fn write_geometry<T: WktNum + fmt::Display>(
f: &mut impl Write,
geometry: &impl GeometryTrait<T = T>,
Expand All @@ -277,6 +284,7 @@ pub fn write_geometry<T: WktNum + fmt::Display>(
}
}

/// Write an object implementing [`GeometryCollectionTrait`] to a WKT string.
pub fn write_geometry_collection<T: WktNum + fmt::Display>(
f: &mut impl Write,
gc: &impl GeometryCollectionTrait<T = T>,
Expand Down Expand Up @@ -314,6 +322,13 @@ pub fn write_geometry_collection<T: WktNum + fmt::Display>(
Ok(())
}

/// Write an object implementing [`RectTrait`] to a WKT string.
///
/// The Rect will written as a Polygon with one exterior ring.
///
/// Note that only 2D `Rect`s are supported, because it's unclear how to map a higher-dimensional
/// Rect to a Polygon. For higher dimensional `Rect`, transform your data to a Polygon and use
/// [`write_polygon`].
pub fn write_rect<T: WktNum + fmt::Display>(
f: &mut impl Write,
rect: &impl RectTrait<T = T>,
Expand Down Expand Up @@ -366,6 +381,9 @@ pub fn write_rect<T: WktNum + fmt::Display>(
Ok(f.write_char(')')?)
}

/// Write an object implementing [`TriangleTrait`] to a WKT string.
///
/// The Triangle will written as a Polygon with one exterior ring.
pub fn write_triangle<T: WktNum + fmt::Display>(
f: &mut impl Write,
triangle: &impl TriangleTrait<T = T>,
Expand All @@ -383,7 +401,7 @@ pub fn write_triangle<T: WktNum + fmt::Display>(
}
geo_traits::Dimensions::Unknown(_) => return Err(Error::UnknownDimension),
}?;
let size = PhysicalCoordinateDimension::from(dim);
let size = dim.try_into()?;
f.write_str("(")?;

let coords_iter = triangle
Expand All @@ -395,6 +413,9 @@ pub fn write_triangle<T: WktNum + fmt::Display>(
Ok(f.write_char(')')?)
}

/// Write an object implementing [`LineTrait`] to a WKT string.
///
/// The Line will written as a LineString with two coordinates.
pub fn write_line<T: WktNum + fmt::Display>(
f: &mut impl Write,
line: &impl LineTrait<T = T>,
Expand All @@ -414,7 +435,7 @@ pub fn write_line<T: WktNum + fmt::Display>(
}
geo_traits::Dimensions::Unknown(_) => return Err(Error::UnknownDimension),
}?;
let size = PhysicalCoordinateDimension::from(dim);
let size = dim.try_into()?;
write_coord_sequence(f, line.coords().into_iter(), size)
}

Expand Down
2 changes: 2 additions & 0 deletions src/to_wkt/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Serialize geometries to WKT strings.
use crate::{Wkt, WktNum};

mod geo_trait_impl;
Expand Down

0 comments on commit a8b8a1e

Please sign in to comment.