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 Forward and Reverse traits, add initial provider #4

Merged
merged 15 commits into from Apr 10, 2018

Conversation

urschrei
Copy link
Member

@urschrei urschrei commented Apr 9, 2018

This is an implementation of forward and reverse geocoding traits, and
the provision of these traits for the OpenCage geocoding service.

The traits are deliberately split, and are deliberately minimal; any
geocoding provider should be able to return an address, and accept an
address, returning one or more Points. In order to avoid possible incompatibilities, I've re-used the Coordinate and Point structs from Geo. I'm happy to import them, but I'm aware that

a) this will blow up compile times for this crate
b) it will make interaction between the two crates less flexible.

The initial implementation makes this trait available for the OpenCage
provider, and also makes its full API responses available so that
more flexible methods can be added (that isn't WIP, but they'll land
at some point in the near future)

@urschrei urschrei mentioned this pull request Apr 9, 2018
3 tasks
@urschrei urschrei requested a review from frewsxcv April 9, 2018 17:43
@groteworld
Copy link
Member

Thanks for this initial push, i'll be reviewing here over the next view minutes!

@groteworld
Copy link
Member

A great start to this library! The only thing that I think we should really fix now before this is released is instead of creating our own structs for geospatial features (Coordinates and Points), this project should definitely utilize rust-geo for these. All my other changes are small style/maintainability things that can be changed in days to come. But I feel this issue will set the external expectation of how one should interact with this library.

Other than that, thank you for your contribution on this, it sadly was constantly in my backlog of TODO.

@urschrei
Copy link
Member Author

urschrei commented Apr 9, 2018

OK, we've switched over to Geo for primitives. One thing that occurred to me is that we need to be careful with handling coordinate order; Geo's Point defines x, y (or lon, lat) order, and even if it didn't, it would be disastrous if reverse-coded data from two different providers were mixed if the output order were different. Thus, all documentation makes the lon, lat order requirement clear, and notes that even though individual providers' docs may show lat, lon coordinates, Geocoding always requires lon, lat input, and returns lon, lat Point data.

@urschrei urschrei removed the request for review from frewsxcv April 10, 2018 12:14
@urschrei
Copy link
Member Author

OK, I'm happy with this for now, so just gonna wait on review.

  • The OpenCage instance now has a method to retrieve the remaining API quota – it's using an Arc<Mutex<Option<_>>> under the hood for interior mutability, so it's thread-safe. There's obviously a little overhead associated with this, but I'm not too worried about it.
  • The OpenCage instance calls will return early with an Error if they encounter 4xx or 5xx responses.

Copy link
Member

@groteworld groteworld left a comment

Choose a reason for hiding this comment

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

Just a few comments, not all need to be fixed before merge approval, but just trying to think through usage.

/// Create a new OpenCage geocoding instance
pub fn new(api_key: String) -> Self {
let mut headers = header::Headers::new();
headers.set(header::UserAgent::new(UA_STRING));
Copy link
Member

Choose a reason for hiding this comment

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

So if a developer would want to change their User-Agent string they would need to make their opencage object mutable and then go through its client instance? Is there a better way about this?

Copy link
Member Author

Choose a reason for hiding this comment

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

The OpenCage developer guidelines ask for a unique UA string, so they can track library usage, so this was a deliberate decision. I could add a getter / setter with the same interior mutability technique as remaining so that a mut OpenCage instance isn't necessary, but I'd also have to replace the Client instance in the same way, since its settings are retained across calls. The same applies to endpoint – its replacement or alteration requires a new Client. What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

Sounds fine for now, thanks for the explanation.

Opencage {
api_key,
client,
endpoint: "https://api.opencagedata.com/geocode/v1/json".to_string(),
Copy link
Member

Choose a reason for hiding this comment

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

Similar with endpoint here, say the user is using a opencage ci/test api

src/opencage.rs Outdated
// it's OK to index into this vec, because reverse-geocoding only returns a single result
let address = &res.results[0];
let headers = resp.headers().get::<XRatelimitRemaining>().unwrap();
// *self.remaining.lock().unwrap(Some(**headers));
Copy link
Member

Choose a reason for hiding this comment

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

Is this an artifact from development or is this comment purposeful still

urschrei and others added 15 commits April 10, 2018 14:58
This is an implementation of forward and reverse geocoding traits, and
the provision of these traits for the OpenCage geocoding service.

The traits are deliberately split, and are deliberately minimal; any
geocoding provider should be able to return an address, and accept an
address, returning one or more points.

The initial implementation makes this trait available for the OpenCage
provider, and also makes its full API responses available so that
more flexible methods can be added (that isn't WIP, but they'll land
at some point in the near future)
This method uses a `Cell` and interior mutability to check a custom
header (`X-RateLimit-Remaining`) from an OpenCage API response,
updating a private field of the OpenCage instance. The value can be
retrieved using the remaining_calls() method.
It's a valid API key, so something will have to be done about that at
some point.
@groteworld
Copy link
Member

bors r+

bors bot added a commit that referenced this pull request Apr 10, 2018
4: Implement Forward and Reverse traits, add initial provider r=groteworld a=urschrei

This is an implementation of forward and reverse geocoding traits, and
the provision of these traits for the OpenCage geocoding service.

The traits are deliberately split, and are deliberately minimal; any
geocoding provider should be able to return an address, and accept an
address, returning one or more Points. In order to avoid possible incompatibilities, I've re-used the `Coordinate` and `Point` structs from `Geo`. I'm happy to import them, but I'm aware that

a) this will blow up compile times for this crate
b) it will make interaction between the two crates less flexible.

The initial implementation makes this trait available for the OpenCage
provider, and also makes its full API responses available so that
more flexible methods can be added (that isn't WIP, but they'll land
at some point in the near future)

Co-authored-by: Stephan Hügel <stephan.hugel.12@ucl.ac.uk>
Co-authored-by: Stephan Hügel <urschrei@gmail.com>
@groteworld
Copy link
Member

Well... bors crashed. So that's fun. I will need to investigate...

@bors
Copy link
Contributor

bors bot commented Apr 10, 2018

Build succeeded

@bors bors bot merged commit dd9debc into georust:master Apr 10, 2018
@groteworld
Copy link
Member

or nevermind? Yay?

@urschrei
Copy link
Member Author

It often fails on that initial push on Rust-Geo, only for the actual build to complete and the merge to go through, so who knows.

@groteworld
Copy link
Member

alright. publishing to crates.io now

@urschrei
Copy link
Member Author

✨thanks!

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.

None yet

2 participants