Skip to content
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

Implement geo_traits for geojson types. #245

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open

Conversation

frewsxcv
Copy link
Member

@frewsxcv frewsxcv commented Oct 25, 2024

  • 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.

@frewsxcv frewsxcv marked this pull request as draft October 25, 2024 04:31
@kylebarron
Copy link
Member

Still need to implement for Feature (and FeatureCollection?), but that should be easy.

I wouldn't necessarily expect the traits to be implemented on Feature and FeatureCollection. I think it's fine if they're only implemented on the geometry structs.

@frewsxcv frewsxcv marked this pull request as ready for review October 27, 2024 19:25
@@ -12,11 +12,14 @@ edition = "2018"

[features]
default = ["geo-types"]
geo-traits = ["dep:geo-traits", "dep:bytemuck"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you feel about making this a default dependency? I wouldn't imagine it would add too much to compilation time?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine by me! As long as we keep it optional

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure who's driving this PR at this point, but it seems like this is still outstanding.

src/geo_traits_impl/multi_point.rs Show resolved Hide resolved
match self {
crate::GeoJson::Feature(f) => f.as_type(),
crate::GeoJson::FeatureCollection(_fc) => {
unimplemented!("TODO")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO here needs to be completed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume a FeatureCollection, interpreted as a geometry-trait, would map to a GeometryCollection?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep exactly. FeatureCollection.as_type is already implemented to return a GeometryCollection. We just need to add that detail here in GeoJson::FeatureCollection.

match self {
crate::GeoJson::Feature(f) => f.as_type(),
crate::GeoJson::FeatureCollection(_fc) => {
unimplemented!("TODO")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume a FeatureCollection, interpreted as a geometry-trait, would map to a GeometryCollection?

src/geo_traits_impl/line_string.rs Outdated Show resolved Hide resolved
src/geo_traits_impl/geometry_collection.rs Outdated Show resolved Hide resolved
src/geo_traits_impl/multi_line_string.rs Outdated Show resolved Hide resolved
src/geo_traits_impl/geometry_collection.rs Outdated Show resolved Hide resolved
src/geo_traits_impl/geometry_collection.rs Show resolved Hide resolved
@kylebarron
Copy link
Member

I don't particularly like the overloading of unknown(0) here, because we're using the same enum variant to say both "we have a known number of dimensions but we don't know their semantic meaning" and "we don't know how many dimensions exist". I think it would be clearer to add a new enum variant to make both meanings clearer.

@frewsxcv
Copy link
Member Author

frewsxcv commented Nov 10, 2024

Sounds good to me. Conceptually, would that be much different than updating it to return Option<Dim>? I'm fine with any approach here. Just curious how you're thinking about it.

@kylebarron
Copy link
Member

Sounds good to me. Conceptually, would that be much different than updating it to return Option<Dim>? I'm fine with any approach here. Just curious how you're thinking about it.

That would be the same as Option<Dim>. I wish consumers didn't have to check if the dimension is None, but perhaps that's the only way to solve some producers like GeoJSON

@frewsxcv
Copy link
Member Author

frewsxcv commented Nov 11, 2024

I wish we could bundle the dimension and the non-empty geometry together. Something like Empty | (Dimension, Geometry) rather than (None, Empty) | (Some(Dimension), Geometry).

@kylebarron
Copy link
Member

I wish we could bundle the dimension and the non-empty geometry together.

I believe in Simple Features they're considered separate. E.g. in WKT you can have any of:

POINT EMPTY
POINT Z EMPTY
POINT M EMPTY
POINT ZM EMPTY

So you can't merge them into a single concept.

@frewsxcv
Copy link
Member Author

Ah darn 😞 . You're totally right

Cargo.toml Outdated

[dependencies]
serde = { version="~1.0", features = ["derive"] }
serde_json = "~1.0"
geo-types = { version = "0.7.13", features = ["serde"], optional = true }
geo-traits = { version = "0.1.0", optional = true }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@frewsxcv would you be able to update this pr to 0.2.0? Or otherwise I could make a new PR

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won't be able to get to this for the next few days. Feel free to open a new pull request or push directly to this one


#[derive(bytemuck::TransparentWrapper)]
#[repr(transparent)]
pub struct PointType(crate::Position);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if instead we should migrate all the geojson types from type aliases to actual types - the TransparentWrapper stuff seems expedient, but not flexible.

I don't think we necessarily need to address that in order to merge this PR - the current proposal is all within this new module, so I'm not overly concerned.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be in favor of creating full types. I don't have a preference on whether that should happen in this PR or not. That would obviate the need for using bytemuck here though

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Slightly in favor of merging with the current design and iterating with dedicated types after, but I don't feel strongly about that

@@ -12,11 +12,14 @@ edition = "2018"

[features]
default = ["geo-types"]
geo-traits = ["dep:geo-traits", "dep:bytemuck"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure who's driving this PR at this point, but it seems like this is still outstanding.


fn dim(&self) -> Dimensions {
match self.0.len() {
0 | 1 => panic!("Position must have at least 2 dimensions"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider: { "type": "Point", "coordinates": [] } right?

Granted, to be valid, a geojson MUST have at least two coordinates.

But this library is used to parse input that may be invalid, and I don't think we should be panic'ing in release builds for invalid input. I think this will surprise people in a bad way.

Instead, returning either Dimensions::Unknown(0) or Dimensions::Xy could be reasonable. Or dim could return an Option.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead, returning either Dimensions::Unknown(0) or Dimensions::Xy could be reasonable. Or dim could return an Option.

We talked about this above: #245 (comment), #245 (comment), #245 (comment).

And see also georust/geo#1263 (comment).

I'd personally choose a default of Dimensions::Xy. I don't think Dimensions::Unknown(0) should ever be used.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants