-
Notifications
You must be signed in to change notification settings - Fork 198
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
Introduce trait for accessing geometries #67
Comments
Sorry, didn't see this until today. I'll need a day or two to think this through but I think this is a good idea. I'm not sure how this might work for something like |
My current experiments look like this: pub trait PointType {
fn x(&self) -> f64;
fn y(&self) -> f64;
//...
}
pub trait LineStringType<'a> {
fn points(self) -> PointRefIter<'a>;
}
pub trait MultiLineStringType<'a> {
fn lines(self) -> LineStringRefIter<'a>;
} I got the point iterator working, but not yet the line iterator. let sumx = linestring.points().fold(0., |sum, p| sum + p.x()); |
I played around with this idea today: https://is.gd/tqkzBp I think this is a good idea. If you have any feedback for my link above, let me know. Commented out section was something I tried, but I couldn't get the typechecker to behave. Will have to do some more thinking. |
I made some progress implementing the following traits: pub trait Point {
fn x(&self) -> f64;
fn y(&self) -> f64;
//...
}
/// Iterator for points of a line
pub struct Points<'a, T: 'a + Point>
{
pub iter: Iter<'a, T>
}
pub trait LineString<'a> {
type PointType: Point;
fn points(&'a self) -> Points<'a, Self::PointType>;
}
/// Iterator for lines of multi-lines
pub struct LineStrings<'a, T: 'a + LineString<'a>>
{
pub iter: Iter<'a, T>
}
pub trait MultiLineString<'a> {
type LineStringType: LineString<'a>;
fn lines(self) -> LineStrings<'a, Self::LineStringType>;
} Full code is here |
Nicer traits which don't depend on pub trait Point {
fn x(&self) -> f64;
fn y(&self) -> f64;
//...
}
/// Iterator for points of line or multi-point geometry
pub trait Points<'a> {
type ItemType: 'a + Point;
type Iter: Iterator<Item=&'a Self::ItemType>;
fn points(&'a self) -> Self::Iter;
}
pub trait LineString<'a>: Points<'a> {
}
/// Iterator for lines of multi-lines
pub trait Lines<'a> {
type ItemType: 'a + LineString<'a>;
type Iter: Iterator<Item=&'a Self::ItemType>;
fn lines(&'a self) -> Self::Iter;
}
pub trait MultiLineString<'a>: Lines<'a> {
} Full code on playground |
@pka I really appreciate the effort you're putting into this! ✨ In my opinion, I do think this is the right path for rust-geo; supplying a set of traits like these matches Rust's principle of "abstraction without overhead". Even though I am interested in helping out with this, I'm writing just to inform that I probably won't be able to make assist in any progress with this specific issue over the next couple weeks (busy week with work and preparing a workshop for a conference). Just thought I'd mention instead of just leaving you hanging. |
I've ended up with the following traits: pub trait Point {
fn x(&self) -> f64;
fn y(&self) -> f64;
fn opt_z(&self) -> Option<f64> {
None
}
fn opt_m(&self) -> Option<f64> {
None
}
}
pub trait LineString<'a> {
type ItemType: 'a + Point;
type Iter: Iterator<Item=&'a Self::ItemType>;
fn points(&'a self) -> Self::Iter;
}
pub trait Polygon<'a> {
type ItemType: 'a + LineString<'a>;
type Iter: Iterator<Item=&'a Self::ItemType>;
fn rings(&'a self) -> Self::Iter;
}
pub trait MultiPoint<'a> {
type ItemType: 'a + Point;
type Iter: Iterator<Item=&'a Self::ItemType>;
fn points(&'a self) -> Self::Iter;
}
pub trait MultiLineString<'a> {
type ItemType: 'a + LineString<'a>;
type Iter: Iterator<Item=&'a Self::ItemType>;
fn lines(&'a self) -> Self::Iter;
}
pub trait MultiPolygon<'a> {
type ItemType: 'a + Polygon<'a>;
type Iter: Iterator<Item=&'a Self::ItemType>;
fn polygons(&'a self) -> Self::Iter;
} They are implemented in rust-postgis allowing to store any geometry type implementing these traits. |
I really like the idea of having traits for accessing geometries :) |
Hi @jdroenner
|
Hi @pka
This still allows to have XYZM Points in rust-postgis e.g. |
Looks nice for points, but I don't see how you could access Z values of 3D line points and I'm afraid that I had to write separate WKB conversion routines for each point type. |
I guess you are right. If we treat Point2D and Point3D as different types than some things have to be handled separate. Accessing the z values of 3D line points shouldn't be a problem. If you have something like this:
A line could be created like this: |
I'm with you, that these traits are implementable for 3D point types. But wouldn't we need additional line traits like pub trait LineString3D<'a> {
type ItemType: 'a + Point3D;
type Iter: Iterator<Item=&'a Self::ItemType>;
fn points(&'a self) -> Self::Iter;
} for accessing Z values? |
We can use the associated type
|
My main concern with offering Taking a step back and looking at the bigger picture here, I'm still convinced this is the right way to go with this crate. Similar to rust-num, which offers abstract numeric My last hesitation here is UX related. If we transition this entire crate to be |
To me I feel like the structs would be offered by surrounding format libraries (wkt, gdal, geojson, etc.). Yet, there may be a lot of overlap there. I agree for now, a common struct is not absolutely necessary. Great work @pka |
Maybe we can create a "basic-geometries" crate at some point which a format library can use if it doesn't need a special implementation... Just to be clear: i really like the traits @pka created :) Also what do you (all) think about a |
@jdroenner your proposed solution using an associated Concrete structures in rust-geo: A next step would be to define geo factory traits. A rust-geo method like intersection would use these traits to generate the output geometry. Without factory traits, rust-geo needs concrete structures to produce results. XYZM handling in rust-geo: In a trait based rust-geo I would at least expect that geographic operations keep my ZM values whenever possible. |
Maybe we could start out by having concrete structures in rust-geo, and once RFC 1522 stabilizes, we can do something like: // Note: this struct is not `pub`
struct CentroidPoint<T: Float> {
x: T,
y: T,
}
pub trait Centroid<T: Float> {
fn centroid(&self) -> Option<impl Point<T>>;
}
impl<T> Centroid<T> for Polygon<T>
where T: Float
{
fn centroid(&self) -> Option<impl Point<T>> {
// do some maths and then return CentroidPoint
CentroidPoint { x: 10., y: 10. }
}
} |
Hey all. I'm interested in moving forward with this. @pka Do you have a local git branch with your changes you could open a PR with? I'd be interested in getting it ready for merging. If not, not a big deal, I'll make a branch and open a PR. |
I'm also still interested in this. One open point is the design of factory traits. What are the minimal requirements for such a trait?
|
WIP PR: #85 |
Nice to see you PR. My implementation is in rust-postgis |
Any new on this ? The PR have been closed but we are still interesting for using geo with postgis and vectortile (based on postgis types) ? If you need some help I can try to help you 👨💻 |
67: Minimal support for JTS extensions r=michaelkirk a=rmanoka Refer discussion in georust#50 + support LINEARRING by parsing it as a LINESTRING + test LINEARRING parsing - [x] I agree to follow the project's [code of conduct](https://github.com/georust/geo/blob/master/CODE_OF_CONDUCT.md). - [x] I added an entry to `CHANGES.md` if knowledge of this change could be valuable to users. --- Co-authored-by: Rajsekar Manokaran <[email protected]>
1011: Initial geo-traits implementation r=frewsxcv a=kylebarron - [x] I agree to follow the project's [code of conduct](https://github.com/georust/geo/blob/main/CODE_OF_CONDUCT.md). - [ ] I added an entry to `CHANGES.md` if knowledge of this change could be valuable to users. --- As discussed on the discord, in #838, and originally in #67, this is an initial bare-bones implementation of geometry access traits for discussion. As `@frewsxcv` suggested, for now this is a separate crate in the workspace to let us iterate on some ideas. ### Future work #### Minimize cloning in the geo-types implementation I got lost in lifetime errors so to get things to compile I added cloning to the geo-types implementations. I.e. for `MultiPoint` each point is cloned when accessed. Co-authored-by: Kyle Barron <[email protected]>
Hello from four years in the future. There is an active branch being worked on with trait implementations for geometries #1011 |
This is done!! https://crates.io/crates/geo-traits/ |
In the course of refactoring rust-postgis to use rust-geo geometries, I'm looking at needed conversions between different georust geometries. One goal would be to store a rust-gdal geometry with rust-postgis as efficient as possible.
One possible solution would be using iterators returning a Point trait instead of accessing the structs directly. If rust-gdal would implement this trait, storing a geometry with rust-postgis could be done without any conversion. And if the geo algorithms would use this trait, they could be applied directly on geometries implementing this trait. It should also solve the ownership problem in #21.
A simplified trait could be
When this trait is implemented for
geo::Point
andgeo::LineString
implementsIntoIterator
withItem=&PointType
, you can iterate likeThe text was updated successfully, but these errors were encountered: