-
Notifications
You must be signed in to change notification settings - Fork 200
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add geo-traits crate #1157
Merged
Merged
Add geo-traits crate #1157
Changes from all commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
e337d8a
Add geo-traits crate
kylebarron 7f68df2
Update doc
kylebarron 34ed5be
Update geo-traits/Cargo.toml
kylebarron d57995e
Merge branch 'main' into kyle/geo-traits-crate
kylebarron 7308df3
Merge branch 'kyle/geo-traits-crate' of github.com:kylebarron/geo int…
kylebarron ee04201
Update docker images
kylebarron ad48ee1
Remove CoordTrait and add multiple dimensions
kylebarron 4261836
Module docs
kylebarron 449b39f
rename
kylebarron f54fffc
Add logical Dimension
kylebarron db08c55
partialeq and hash
kylebarron 7ecdb7e
return impl Iterator
kylebarron 03f6615
rename to min/max
kylebarron 31435e8
Merge branch 'main' into kyle/geo-traits-crate
kylebarron 1d30066
Specialized implementations of GeometryTrait
kylebarron ab0bf7b
clearer GeometryTrait naming
kylebarron 33c1ef9
Rename ItemType
kylebarron 6363ad8
Unimplemented versions
kylebarron 9421e05
Add LineTrait and TriangleTrait and improve trait docs
kylebarron 9552705
Fix geo-types empty Polygon
kylebarron 3725844
Merge branch 'main' into kyle/geo-traits-crate
kylebarron 7a2effd
Make iterators private
kylebarron 8dcbe50
Rename Dimension -> Dimensions
kylebarron 6889cae
No default x() and y()
kylebarron de7ca8a
More descriptive point panics
kylebarron 0fb5ab8
Change to DoubleEndedIterator + ExactSizeIterator
kylebarron 58117ce
change dimensions case
kylebarron 6b697dd
Update geo-traits/src/point.rs
kylebarron 2eb3b03
reorder unchecked
kylebarron 1f68cc3
`PointTrait::is_empty`
kylebarron b1364ef
Merge branch 'main' into kyle/geo-traits-crate
kylebarron d49873b
Add sentence to is_empty
kylebarron 7c0e90f
fix doc link
kylebarron 09de278
Use array
kylebarron 8418780
Update geo-traits/src/line.rs
kylebarron 4a9b3cc
typo
kylebarron ba9bf98
Merge branch 'main' into kyle/geo-traits-crate
kylebarron 4764343
Restore CoordTrait, PointTrait yields Option<CoordTrait>
kylebarron 2b77691
Merge branch 'main' into kyle/geo-traits-crate
kylebarron 711dfac
Update geo-traits/src/coord.rs
kylebarron File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
[package] | ||
name = "geo-traits" | ||
version = "0.1.0" | ||
license = "MIT OR Apache-2.0" | ||
repository = "https://github.com/georust/geo" | ||
documentation = "https://docs.rs/geo-traits/" | ||
readme = "../README.md" | ||
keywords = ["gis", "geo", "geography", "geospatial"] | ||
description = "Geospatial traits" | ||
rust-version = "1.65" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
geo-types = "0.7" | ||
|
||
[dev-dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
use std::marker::PhantomData; | ||
|
||
use geo_types::{Coord, CoordNum}; | ||
|
||
use crate::Dimensions; | ||
|
||
/// A trait for accessing data from a generic Coord. | ||
/// | ||
/// Refer to [geo_types::Coord] for information about semantics and validity. | ||
pub trait CoordTrait { | ||
/// The coordinate type of this geometry | ||
type T: CoordNum; | ||
|
||
/// Dimensions of the coordinate tuple | ||
fn dim(&self) -> Dimensions; | ||
|
||
/// Access the n'th (0-based) element of the CoordinateTuple. | ||
/// Returns `None` if `n >= DIMENSION`. | ||
/// See also [`nth_unchecked()`](Self::nth_unchecked). | ||
fn nth(&self, n: usize) -> Option<Self::T> { | ||
if n < self.dim().size() { | ||
Some(self.nth_unchecked(n)) | ||
} else { | ||
None | ||
} | ||
} | ||
|
||
/// x component of this coord. | ||
fn x(&self) -> Self::T; | ||
|
||
/// y component of this coord. | ||
fn y(&self) -> Self::T; | ||
|
||
/// Returns a tuple that contains the x/horizontal & y/vertical component of the coord. | ||
fn x_y(&self) -> (Self::T, Self::T) { | ||
(self.x(), self.y()) | ||
} | ||
|
||
/// Access the n'th (0-based) element of the CoordinateTuple. | ||
/// May panic if n >= DIMENSION. | ||
/// See also [`nth()`](Self::nth). | ||
fn nth_unchecked(&self, n: usize) -> Self::T; | ||
} | ||
|
||
impl<T: CoordNum> CoordTrait for Coord<T> { | ||
type T = T; | ||
|
||
fn nth_unchecked(&self, n: usize) -> Self::T { | ||
match n { | ||
0 => self.x(), | ||
1 => self.y(), | ||
_ => panic!("Coord only supports 2 dimensions"), | ||
} | ||
} | ||
|
||
fn dim(&self) -> Dimensions { | ||
Dimensions::Xy | ||
} | ||
|
||
fn x(&self) -> Self::T { | ||
self.x | ||
} | ||
|
||
fn y(&self) -> Self::T { | ||
self.y | ||
} | ||
} | ||
|
||
impl<T: CoordNum> CoordTrait for &Coord<T> { | ||
type T = T; | ||
|
||
fn nth_unchecked(&self, n: usize) -> Self::T { | ||
match n { | ||
0 => self.x(), | ||
1 => self.y(), | ||
_ => panic!("Coord only supports 2 dimensions"), | ||
} | ||
} | ||
|
||
fn dim(&self) -> Dimensions { | ||
Dimensions::Xy | ||
} | ||
|
||
fn x(&self) -> Self::T { | ||
self.x | ||
} | ||
|
||
fn y(&self) -> Self::T { | ||
self.y | ||
} | ||
} | ||
|
||
impl<T: CoordNum> CoordTrait for (T, T) { | ||
type T = T; | ||
|
||
fn nth_unchecked(&self, n: usize) -> Self::T { | ||
match n { | ||
0 => self.x(), | ||
1 => self.y(), | ||
_ => panic!("(T, T) only supports 2 dimensions"), | ||
} | ||
} | ||
|
||
fn dim(&self) -> Dimensions { | ||
Dimensions::Xy | ||
} | ||
|
||
fn x(&self) -> Self::T { | ||
self.0 | ||
} | ||
|
||
fn y(&self) -> Self::T { | ||
self.1 | ||
} | ||
} | ||
|
||
/// An empty struct that implements [CoordTrait]. | ||
/// | ||
/// This can be used as the `CoordType` of the `GeometryTrait` by implementations that don't have a | ||
/// Coord concept | ||
pub struct UnimplementedCoord<T: CoordNum>(PhantomData<T>); | ||
|
||
impl<T: CoordNum> CoordTrait for UnimplementedCoord<T> { | ||
type T = T; | ||
|
||
fn dim(&self) -> Dimensions { | ||
unimplemented!() | ||
} | ||
|
||
fn nth_unchecked(&self, _n: usize) -> Self::T { | ||
unimplemented!() | ||
} | ||
|
||
fn x(&self) -> Self::T { | ||
unimplemented!() | ||
} | ||
|
||
fn y(&self) -> Self::T { | ||
unimplemented!() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/// The logical dimension of the geometry. | ||
/// | ||
/// | ||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
pub enum Dimensions { | ||
/// A two-dimensional geometry with X and Y values | ||
Xy, | ||
|
||
/// A three-dimensional geometry with X, Y, and Z values | ||
Xyz, | ||
|
||
/// A three-dimensional geometry with X, Y, and M values | ||
Xym, | ||
|
||
/// A four-dimensional geometry with X, Y, Z, and M values | ||
Xyzm, | ||
|
||
/// A geometry with unknown logical type. The contained `usize` value represents the number of | ||
/// physical dimensions. | ||
Unknown(usize), | ||
} | ||
|
||
impl Dimensions { | ||
/// The physical number of dimensions in this geometry. | ||
pub fn size(&self) -> usize { | ||
match self { | ||
Self::Xy => 2, | ||
Self::Xyz | Self::Xym => 3, | ||
Self::Xyzm => 4, | ||
Self::Unknown(val) => *val, | ||
} | ||
} | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I first read this, I thought this would behave similarly to
Vec#get_unchecked
which is anunsafe
method which does not do a bounds check, hence it being marked asunsafe
. In fact, it looks like all functions named*_unchecked
Rust's standard library are marked asunsafe
, which to me implies they skip the bounds check.My first though was, what if we had a naming convention like this:
But that may psychologically push people to use the panic'ing version.
I don't know what the right answer is, just wanted to call out that I was surprised when implementing
CoordTrait
thatnth_unchecked
was not marked withunsafe
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another option 🤷🏻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But we also definitely don't need to have an
unsafe
method, in fact probably better to leave it out for this initial implementationThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's nice. 👏
We could also just leave out the
panic
flavor.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although I didn't find it in the stdlib, apparently there's quite a bit of precedent for
_or_panic
in 3rd party crateshttps://github.com/search?q=or_panic+language%3ARust&type=code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Open to suggestions here. I suppose it's worthwhile having a variant that is actually unsafe (e.g. doesn't even do the bounds check), for situations where you know you're in bounds (like the iterator)