Skip to main content

geometry_io_wkt/
lib.rs

1//! OGC Well-Known Text (WKT) reader and writer.
2//!
3//! Mirrors `boost/geometry/io/wkt/{read,write,wkt}.hpp`. The parser
4//! emits a [`geometry_model::DynGeometry`] because WKT is heterogeneous
5//! by construction (a `GEOMETRYCOLLECTION` mixes kinds); the writer
6//! accepts concrete model geometries with [`to_wkt`] and user-defined
7//! polygons implementing the geometry traits with [`to_wkt_polygon`].
8//!
9//! Reference: OGC Simple Feature Access Part 1 (SFA-1) §7 for the WKT
10//! grammar.
11//!
12//! ## Serialize a user-defined polygon
13//!
14//! Application types can implement the lightweight [`geometry_trait`] traits
15//! directly; they do not need to be converted to a `geometry_model` polygon.
16//!
17//! ```
18//! use geometry_cs::Cartesian;
19//! use geometry_io_wkt::to_wkt_polygon;
20//! use geometry_tag::{PointTag, PolygonTag, RingTag};
21//! use geometry_trait::{Geometry, Point, Polygon, Ring};
22//!
23//! struct Coordinate(f64, f64);
24//!
25//! impl Geometry for Coordinate {
26//!     type Kind = PointTag;
27//!     type Point = Self;
28//! }
29//!
30//! impl Point for Coordinate {
31//!     type Scalar = f64;
32//!     type Cs = Cartesian;
33//!     const DIM: usize = 2;
34//!
35//!     fn get<const D: usize>(&self) -> f64 {
36//!         match D {
37//!             0 => self.0,
38//!             1 => self.1,
39//!             _ => unreachable!("a Coordinate has two dimensions"),
40//!         }
41//!     }
42//! }
43//!
44//! struct Boundary(Vec<Coordinate>);
45//!
46//! impl Geometry for Boundary {
47//!     type Kind = RingTag;
48//!     type Point = Coordinate;
49//! }
50//!
51//! impl Ring for Boundary {
52//!     fn points(&self) -> impl ExactSizeIterator<Item = &Coordinate> + Clone {
53//!         self.0.iter()
54//!     }
55//! }
56//!
57//! struct Parcel {
58//!     exterior: Boundary,
59//!     holes: Vec<Boundary>,
60//! }
61//!
62//! impl Geometry for Parcel {
63//!     type Kind = PolygonTag;
64//!     type Point = Coordinate;
65//! }
66//!
67//! impl Polygon for Parcel {
68//!     type Ring = Boundary;
69//!
70//!     fn exterior(&self) -> &Boundary {
71//!         &self.exterior
72//!     }
73//!
74//!     fn interiors(&self) -> impl ExactSizeIterator<Item = &Boundary> {
75//!         self.holes.iter()
76//!     }
77//! }
78//!
79//! let parcel = Parcel {
80//!     exterior: Boundary(vec![
81//!         Coordinate(0.0, 0.0),
82//!         Coordinate(0.0, 2.0),
83//!         Coordinate(2.0, 2.0),
84//!         Coordinate(2.0, 0.0),
85//!         Coordinate(0.0, 0.0),
86//!     ]),
87//!     holes: vec![],
88//! };
89//!
90//! assert_eq!(
91//!     to_wkt_polygon(&parcel),
92//!     "POLYGON((0 0,0 2,2 2,2 0,0 0))"
93//! );
94//! ```
95
96#![cfg_attr(not(feature = "std"), no_std)]
97#![forbid(unsafe_code)]
98
99extern crate alloc;
100
101mod lexer;
102mod parse;
103mod write;
104
105pub use lexer::{Token, WktError};
106// feature-group: I/O — Well-Known Text
107// feature-desc: Parse and write the OGC WKT format
108pub use parse::{
109    from_wkt, parse_linestring, parse_multi_linestring, parse_multi_point, parse_multi_polygon,
110    parse_point, parse_polygon,
111};
112// feature-group: I/O — Well-Known Text
113pub use write::{WriteWkt, to_wkt, to_wkt_polygon, write_wkt};