Rust read/write support for well-known text (WKT)

Overview

wkt

Rust read/write support for well-known text (WKT).

Crate API Documentation

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Comments
  • Store a single geometry inside Wkt

    Store a single geometry inside Wkt

    • [x] I agree to follow the project's code of conduct.
    • [x] I added an entry to CHANGES.md if knowledge of this change could be valuable to users.

    r? @urschrei

    opened by lnicola 11
  • Try/From<Wkt> traits for Geometry

    Try/From traits for Geometry

    This is a couple separate but related things...

    The main new functionality is that you can call Geometry::from(wkt)

    Along the way, I replaced the Try/Into impls with Try/From. We should prefer TryFrom where possible since it is sometimes nicer to use and also gives you the TryInto impl for free.

    Correspondingly, I deprecated methods like try_into_geometry in favor of geometry.try_into which I think is more discoverable.

    One thing I was curious about - I think conventionally conversions are done via move, so the caller is responsible for any cloning, but previously all our conversions were done via references and our impls were creating new points for everything. That seemed a little strange to me, so I implemented all the new ones with the move semantics that I'm used to. I did leave the existing functionality (but rephrased them as From) so as not to break the API.

    A couple potentially controversial things I'll call out inline...

    opened by michaelkirk 8
  • Use generic type for precision in conversion

    Use generic type for precision in conversion

    Attempt to close #33. I based this off of the conversion implementation in geojson and only used generic types for converting to geo_types objects

    Initially I tried to update the From trait implementation, but I used Into instead because updating From gave me the following error:

    type parameter `T` must be used as the type parameter for some local type
    

    If I missed something that would make From work instead I can make that change. Let me know if I should change that or anything else here, thanks!

    opened by pjsier 8
  • Fix some clippy warnings

    Fix some clippy warnings

    • [x] I agree to follow the project's code of conduct.
    • [ ] I added an entry to CHANGES.md if knowledge of this change could be valuable to users.
    • [x] I ran cargo fmt

    opened by lnicola 5
  • Use SPDX license expression

    Use SPDX license expression

    • [x] I agree to follow the project's code of conduct.
    • [x] I added an entry to CHANGES.md if knowledge of this change could be valuable to users.
    • [x] I ran cargo fmt

    Uses a SPDX license expression as recommended by Cargo.

    This enables e.g. parsing via the CycloneDX Rust Cargo Plugin.

    opened by gerritsangel 5
  • Easier serialization of wkt with ToWkt::wkt_string/write_wkt

    Easier serialization of wkt with ToWkt::wkt_string/write_wkt

    • [x] I agree to follow the project's code of conduct.
    • [x] I added an entry to CHANGES.md if knowledge of this change could be valuable to users.
    • [x] I ran cargo fmt

    Fixes #55 - adds an easier API to serialize a geo-type.

    ~~Depends on #86, so merge that first.~~ Merged!

    ~~partially conflicts with #88, because I'm relying on the ToWkt trait.~~ superseded!

    opened by michaelkirk 5
  • WIP: Impl/from geo types

    WIP: Impl/from geo types

    • [x] I agree to follow the project's code of conduct.
    • [x] I added an entry to CHANGES.md if knowledge of this change could be valuable to users.
    • [x] I ran cargo fmt

    addresses #73 and #48.

    This adds impls of From for every type and the Geometry enum in geo_types. It makes it unnecessary to bring to scope the ToWkt trait which gets deleted because it was not being used actually. Of course this is a breaking change.

    Additionally I added some docs on the most relevant cases for this crate: parsing a wkt and getting a geometry and having a geometry and getting its WKT string. This is what actually motivates most of the PRs I've been doing, I just wanted to do that .-.

    Some opinions

    What if Wkt was instead a trait itself, implemented for every type in geo_types that provided a single method: wkt(&self) -> String?

    being georust an environment for building geo applications it makes sense that things are integrated to work well within the environment, and maybe providing some LineString etc. traits which, if implemented on foreign types would give automatically a Wkt impl that allows to get its WKT string. And perhaps a WktGeometry enum with inner types refering to those in the geo_types crate just for the purposes of having something to parse a string into. Although it probably makes more sense to just have FromStr impls for the geo_types themselves...

    Just an idea, I think it would simplify a lot how work with this crate happens.

    This actually requires #86 for the docs to pass the tests

    opened by categulario 5
  • impl Display for Wkt

    impl Display for Wkt

    • [x] I agree to follow the project's code of conduct.
    • [x] I added an entry to CHANGES.md if knowledge of this change could be valuable to users.

    to address #83 and make it easier to go from Wkt to string representation. Includes test

    opened by categulario 5
  • specific errors and `try_into` for inner geo-types

    specific errors and `try_into` for inner geo-types

    • [x] I agree to follow the project's code of conduct.
    • [x] I added an entry to CHANGES.md if knowledge of this change could be valuable to users.

    DRAFT: depends on https://github.com/georust/geo/pull/614 being released first.

    Add TryFrom for converting directly to geo_types::Geometry enum members.

    let ls: geo_types::LineString = geo_types::LineString::try_from(wkt).unwrap();
    

    Previously it was:

    let geom: geo_types::Geometry = geo_types::Geometry::from(wkt).unwrap();
    let ls: geo_types::LineString = geo_types::LineString::try_from(geom).unwrap();
    

    This introduced two new error cases, so I've also introduced thiserror which solves #49

    FIXES https://github.com/georust/wkt/issues/49

    opened by michaelkirk 5
  • Better way to serialize to wkt?

    Better way to serialize to wkt?

    I was trying to write a geo-type as WKT to file, and this is what I came up with:

        let points = include!("../src/algorithm/test_fixtures/louisiana.rs");
        let geo_linestring: geo::LineString<f32> = points.into();
        use wkt::ToWkt;
        let wkt: wkt::Wkt<_> = geo::Geometry::from(geo_linestring).to_wkt();
        let wkt_linestring = wkt.items.first().unwrap();
        let serialized = format!("{}", wkt_linestring);
        println!("{}", &serialized);
    

    Is there already better way?

    I was hoping for something like:

        let points = include!("../src/algorithm/test_fixtures/louisiana.rs");
        let geo_linestring: geo::LineString<f32> = points.into();
        use wkt::ToWkt;
        let wkt: wkt::Wkt<_> = geo::Geometry::from(geo_linestring).to_wkt();
    -   let wkt_linestring = wkt.items.first().unwrap();
    -   let serialized = format!("{}", wkt_linestring);
    +   let serialized = wkt.to_string()
        println!("{}", &serialized);
    

    Or like serde_jsons::to_writer

        let points = include!("../src/algorithm/test_fixtures/louisiana.rs");
        let geo_linestring: geo::LineString<f32> = points.into();
        use wkt::ToWkt;
        let wkt: wkt::Wkt<_> = geo::Geometry::from(geo_linestring).to_wkt();
    -   let wkt_linestring = wkt.items.first().unwrap();
    -   let serialized = format!("{}", wkt_linestring);
    +   let file = File::create("/tmp/foo").unwrap();
    +   let mut writer = BufWriter::new(file);
    +   wkt::to_writer(&mut writer, wkt);
        println!("{}", &serialized);
    

    Any thoughts?

    opened by michaelkirk 5
  • TryFromWkt for integer geometries

    TryFromWkt for integer geometries

    • [x] I agree to follow the project's code of conduct.
    • [x] I added an entry to CHANGES.md if knowledge of this change could be valuable to users.
    • [x] I ran cargo fmt

    Fixes https://github.com/georust/wkt/issues/102

    ~~This is based on #101, which @rmanoka already approved (thanks!), but I'm going to wait just a bit longer to merge it in case someone else wanted to take a look at it.~~ update: #101 has been merged, and this is ready for review!

    opened by michaelkirk 4
  • release 0.11.0

    release 0.11.0

    I'd like to get the next release out.

    If possible, I'd like to include https://github.com/georust/wkt/pull/103 since it's the logical compliment to the already merged but unreleased https://github.com/georust/wkt/pull/101

    Can someone take a look?

    And anything else we should wait for?

    opened by michaelkirk 2
  • Output `TRIANGLE` type?

    Output `TRIANGLE` type?

    I'm not sure if we should support this, but I wanted to at least gather some facts for documentation.

    postgis supports it:

    SELECT ST_AsText('TRIANGLE((0 0,0 1,1 1,0 0 ))');
              st_astext          
    -----------------------------
     TRIANGLE((0 0,0 1,1 1,0 0))
    (1 row)
    

    JTS does not support it

    reader.read("TRIANGLE((0 0,0 1,1 1,0 0 ))");
    > org.locationtech.jts.io.ParseException: Unknown geometry type: TRIANGLE (line 1)
    

    Nor does GEOS

         message: `ParseException: Unknown type: 'TRIANGLE'`
    
    opened by michaelkirk 1
  • Avoid intermediate `Wkt` allocation for `ToWkt::wkt_string` for geo-types

    Avoid intermediate `Wkt` allocation for `ToWkt::wkt_string` for geo-types

    Currently geo-types uses the default implementation of wkt_string

    fn wkt_string(&self) -> String {
        self
            .to_wkt() // <-- this allocates a Wkt struct
            .to_string()
    }
    

    Instead we could write an individual implementation for each geometry type that doesn't rely on first converting to a Wkt struct. e.g.

    impl ToWkt for geo_types::Point {
        ...
        fn wkt_string(&self) -> String {
            format!("POINT({} {})", self.x, self.y)
        } 
    }
    

    There might be better and worse ways to do this WRT code re-use of the existing serialization methods on Wkt.

    help wanted 
    opened by michaelkirk 0
  • Use new TZM geo-types instead the custom WKT ones

    Use new TZM geo-types instead the custom WKT ones

    Once (if) the new geo-types with 3dM support is merged, I think wkt can migrate to use them directly, instead of having its own duplicate set of types. This should improve performance (no extra transformation), and simplify code - one set of types for everything.

    // current WKT type
    pub struct Coord<T: WktFloat> {
        pub x: T,
        pub y: T,
        pub z: Option<T>,
        pub m: Option<T>,
    }
    
    // corresponding geo type
    pub struct Coordinate<T: CoordNum, Z: ZCoord, M: Measure> {
        pub x: T,
        pub y: T,
        pub z: Z,
        pub m: M,
    }
    

    The 3dM types require proper generics (either concrete float type or a NoValue empty struct). We could represent it with a new Wkt enum instead of the existing pub struct Wkt<T> { pub item: Geometry<T> }. NoValue might need to be updated to support all CoordNum requirements.

    // Usage:
    match Wkt::from_str("LINESTRING (10 -20, -0 -0.5)").unwrap() {
      Wkt(g) => ..., // 2D value
      WktM(g) => ..., // 2D+M value
      Wkt3D(g) => ..., // 3D value
      Wkt3DM(g) => ..., // 3D+M value
      WktEmpty(g) => ..., // Empty value, e.g. "POINT EMPTY"
    }
    
    // Note that all T, Z, and M types of the 3dM geo-types in WKT are used as the same `T` generic type, except for the empty type
    pub enum Wkt {
        Wkt(Geometry<T>),
        WktM(GeometryM<T>),
        Wkt3D(Geometry3D<T>),
        Wkt3DM(Geometry3DM<T>),
        WktEmpty(Geometry<NoValue>),
    }
    
    opened by nyurik 11
  • wkt adapted for 3d/m change in geo

    wkt adapted for 3d/m change in geo

    This PR updates WKT to the pending https://github.com/georust/geo/pull/742

    Note that merging this PR might make the main branch unpublishable because it requires patched crates

    opened by nyurik 1
  • Reduce usage of `let GeoType(a) = b`

    Reduce usage of `let GeoType(a) = b`

    Constructs such as

    let &geo_types::LineString(ref g_points) = g_line;
    w_lines.push(g_points_to_w_linestring(g_points));
    

    cannot be easily ported if we introduce 3D/M coordinates. This PR changes them to the direct tuple access. Eventually we may want to create dedicated tuple member accessors instead.

    w_lines.push(g_points_to_w_linestring(&g_line.0));
    
    • [x] I agree to follow the project's code of conduct. ~- [ ] I added an entry to CHANGES.md if knowledge of this change could be valuable to users.~

    opened by nyurik 0
Owner
GeoRust
A collection of geospatial tools and libraries written in Rust
GeoRust
Rust read/write support for GPS Exchange Format (GPX)

gpx gpx is a library for reading and writing GPX (GPS Exchange Format) files. It uses the primitives provided by geo-types to allow for storage of GPS

GeoRust 63 Dec 5, 2022
Rust read/write support for GPS Exchange Format (GPX)

gpx gpx is a library for reading and writing GPX (GPS Exchange Format) files. It uses the primitives provided by geo-types to allow for storage of GPS

GeoRust 63 Dec 5, 2022
Read GDAL compatible file formats into polars / geopolars

Read GDAL-compatible geospatial data into Polars and GeoPolars. Supports reading the following geospatial formats into a Polars Dataframe: GeoJSON Sha

Patrick Hayes 5 Nov 27, 2022
Rust crate for performing coordinate transforms

Synopsis A Rust crate use for performing coordinate transformations. The crate relies on nalgebra vectors to perform the coordinate transformations. C

Dave 25 Aug 20, 2022
An fast, offline reverse geocoder (>1,000 HTTP requests per second) in Rust.

Rust Reverse Geocoder A fast reverse geocoder in Rust. Inspired by Python reverse-geocoder. Links Crate 2.0.0 Docs 1.0.1 Docs Description rrgeo takes

Grant Miner 91 Dec 29, 2022
Geospatial primitives and algorithms for Rust

geo Geospatial Primitives, Algorithms, and Utilities The geo crate provides geospatial primitive types such as Point, LineString, and Polygon, and pro

GeoRust 989 Dec 29, 2022
Rust bindings for GDAL

gdal [] GDAL bindings for Rust. So far, you can: open a raster dataset for reading/writing get size and number of bands get/set projection and geo-tra

GeoRust 211 Jan 4, 2023
Rust bindings for the latest stable release of PROJ

PROJ Coordinate transformation via bindings to the PROJ v7.2.1 API. Two coordinate transformation operations are currently provided: projection (and i

GeoRust 96 Dec 21, 2022
Geohash for Rust

Rust-Geohash Rust-Geohash is a Rust library for Geohash algorithm. Ported from node-geohash module. Documentation Docs Check the API doc at docs.rs Li

GeoRust 74 Sep 8, 2022
Google Encoded Polyline encoding & decoding in Rust.

polyline Google Encoded Polyline encoding & decoding in Rust. A Note on Coordinate Order This crate uses Coordinate and LineString types from the geo-

GeoRust 14 Dec 11, 2022
Geocoding library for Rust.

geocoding Rust utilities to enrich addresses, cities, countries, and landmarks with geographic coordinates through third-party geocoding web services.

GeoRust 55 Dec 12, 2022
Geospatial primitives and algorithms for Rust

geo Geospatial Primitives, Algorithms, and Utilities The geo crate provides geospatial primitive types such as Point, LineString, and Polygon, and pro

GeoRust 990 Jan 1, 2023
Rust bindings for GEOS

geos Rust bindings for GEOS C API. The supported geos version is >= 3.5 Disclaimer GEOS can be a tad strict on the validity on the input geometry and

GeoRust 75 Dec 11, 2022
Rust bindings for the latest stable release of PROJ

PROJ Coordinate transformation via bindings to the PROJ v7.2.1 API. Two coordinate transformation operations are currently provided: projection (and i

GeoRust 96 Dec 21, 2022
Spatial Data Structures for Rust

spade Documentation Using spade Examples Project state Performance License Spade (SPAtial DatastructurEs, obviously!) implements a few nifty data stru

Stefan Altmayer 195 Dec 21, 2022
Rust implementation of the Martinez-Rueda Polygon Clipping Algorithm

Boolean operations on geo shapes This is an implementation of the Martinez-Rueda Polygon Clipping Algorithm in rust to integrate smoothly into the alr

21re 70 Nov 28, 2022
Fast 2D Delaunay triangulation in Rust. A port of Delaunator.

delaunator-rs A very fast static 2D Delaunay triangulation library for Rust. A port of Delaunator. Documentation Example use delaunator::{Point, trian

Vladimir Agafonkin 123 Dec 20, 2022
port of MapBox's earcut triangulation code to Rust language

Earcutr This is a port of the MapBox company's Earcut computer code, which triangulates polygons. Please see https://github.com/mapbox/earcut for more

don bright 41 Dec 26, 2022
Rust bindings for GDAL

gdal [] GDAL bindings for Rust. So far, you can: open a raster dataset for reading/writing get size and number of bands get/set projection and geo-tra

GeoRust 208 Dec 27, 2022