sfcgal/
lib.rs

1#![crate_name = "sfcgal"]
2#![doc(html_root_url = "https://mthh.github.io/sfcgal-rs/")]
3//! Rust bindings providing a high-level API to [`SFCGAL`](http://oslandia.github.io/SFCGAL/)
4//! library and conversion to / from other geometry crates from Rust ecosystem.
5//! Based on the [sfcgal-sys](https://github.com/mthh/sfcgal-sys) crate exposing low-level bindings.
6//!
7//! Allows notably reading from / writing to WKT as well as interoperability
8//! with [geojson](https://crates.io/crates/geojson) and [geo-types](https://crates.io/crates/geo) crates.
9//! It also offers an API
10//! to manipulate SFCGAL geometries from/to coordinates (represented as tuples
11//! of 2 or 3 positions).
12//!
13//! #### Example
14//! ```rust
15//! # extern crate anyhow;
16//! # fn fun() -> Result<(), anyhow::Error> {
17//! extern crate sfcgal;
18//! use sfcgal::{SFCGeometry, CoordSeq, ToGeoJSON, ToSFCGAL, Point2d, Point3d};
19//!
20//! // Create SFCGAL geometries from coordinates..
21//! let coords_linestring = vec![(-0.5, -0.5, 2.5), (0., 0., 4.0)];
22//! let coords_polygon = vec![
23//!     vec![(-1., -1., 3.0), (1., -1., 3.0), (1., 1., 3.0), (-1., 1., 3.0), (-1., -1., 3.0)], // Exterior ring
24//!     vec![(0.1, 0.1, 3.0), (0.1, 0.9, 3.0), (0.9, 0.9, 3.0), (0.9, 0.1, 3.0), (0.1, 0.1, 3.0)], // 1 interior ring
25//! ];
26//!
27//! // .. by using the CoordSeq enum variants to match the wanted SFCGAL geometry type:
28//! let line_3d = CoordSeq::Linestring(coords_linestring).to_sfcgal()?;
29//! let polygon_3d = CoordSeq::Polygon(coords_polygon).to_sfcgal()?;
30//!
31//! // ..
32//! assert!(line_3d.intersects_3d(&polygon_3d)?);
33//! let intersection = line_3d.intersection_3d(&polygon_3d)?;
34//!
35//! // Get the geojson representation of the geometry with 3-member coordinates :
36//! let geom = intersection.to_geojson::<Point3d>()?;
37//! // Or the wkt representation with a floating precision of 1 :
38//! let wkt = intersection.to_wkt_decim(1)?;
39//! # Ok(())
40//! # }
41//! # fn main() { fun().unwrap(); }
42//! ```
43#[macro_use]
44extern crate anyhow;
45
46#[macro_use]
47extern crate enum_primitive_derive;
48
49#[allow(unused_imports)]
50#[macro_use]
51extern crate approx;
52
53use sfcgal_sys::sfcgal_version;
54
55mod conversion;
56mod errors;
57mod geometry;
58mod utils;
59
60pub use conversion::CoordSeq;
61#[cfg(feature = "geo-types")]
62pub use conversion::TryInto;
63#[cfg(feature = "geojson")]
64pub use conversion::{FromGeoJSON, ToGeoJSON};
65pub use errors::Result;
66pub use geometry::{BufferType, GeomType, Orientation, SFCGeometry};
67
68/// Type alias for manipulating 2d coordinates, represented as (x, y).
69pub type Point2d = (f64, f64);
70
71/// Type alias for manipulating 3d coordinates, represented as (x, y, z).
72pub type Point3d = (f64, f64, f64);
73
74/// Convert object to a [`SFCGeometry`] (implemented on [`CoordSeq`] and [geo-types](https://docs.rs/geo-types/) geometries)
75///
76/// [`SFCGeometry`]: struct.SFCGeometry.html
77/// [`CoordSeq`]: enum.CoordSeq.html
78pub trait ToSFCGAL {
79    fn to_sfcgal(&self) -> Result<SFCGeometry>;
80}
81
82/// Convert object to a [`CoordSeq`] holding coordinates and information about
83/// geometry type.
84///
85/// [`CoordSeq`]: enum.CoordSeq.html
86pub trait ToCoordinates {
87    fn to_coordinates<T>(&self) -> Result<CoordSeq<T>>
88    where
89        T: conversion::CoordType + conversion::FromSFCGALGeom;
90}
91
92/// Display SFCGAL version information.
93pub fn version() -> String {
94    utils::_string(unsafe { sfcgal_version() })
95}
96
97#[cfg(test)]
98
99mod tests {
100
101    use super::version;
102
103    #[test]
104    fn display_version() {
105        assert!(version().starts_with("2."));
106    }
107}