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 rust-proj as an optional feature within geo #192

Merged
merged 7 commits into from
Apr 8, 2018

Conversation

urschrei
Copy link
Member

Continuing the discussion from #190 and #32.

Introduction

rust-proj is currently (as of 0.3.0) using PROJ v4.9.x, and depends upon Geo for its Point type. However, we now have a proj-sys crate, with low-level bindings to PROJ v5.0.0. Unfortunately, rust-proj's dependency on Geo means that we can't directly use its functions within Geo, as this introduces a circular dependency (see #190).

This PR:

  • Re-implements rust-proj's functionality as an optional feature ("proj") within Geo using proj-sys
    • it has to be optional, as it requires PROJ v5.0.0 to be present
  • Makes two new traits –Project and Convert – available to any geometries implementing the MapCoordsFallible trait (see Implement a MapCoordsFallible trait #191), allowing them to be (inverse) projected to and from Geodetic coordinates, and converted between projections. This functionality is a slightly more granular version (in keeping with the new PROJ API, which makes the same distinction) of what's possible using pyproj and Shapely geometries (see here for the official example):
from shapely.geometry import Point, LineString
import pyproj
# LineString in projected coordinates (OSGB36)
ls = LineString([(548295.39, 182498.46), (548296.39, 182499.46)])
osgb36=pyproj.Proj("+init=EPSG:27700")
eastings, northings = list(zip(*ls.coords))
# inverse-project to geodetic lon, lat coordinates (WGS 84)
conv_ls = zip(*osgb36(eastings, northings, inverse=True))
# compare to command-line proj output
assert conv_ls == [(0.13774816464635564, 51.52142699952049), (0.1377629902608001, 51.5214357231341)]

I propose that we leave rust-proj at 0.3.0, clearly marking it as deprecated, directing users to install Geo with the proj feature if they want v5.0.x features, and linking to proj-sys for implementers who don't wish to use Geo, for whatever reason.

We can also (as per my and @turboladen's discussion in #32) highlight the availability of this feature more clearly, if need be.

// is signalled by the choice of enum used as input to the PJ_COORD union
// PJ_LP signals projection of geodetic coordinates, with output being PJ_XY
// and vice versa, or using PJ_XY for conversion operations
pub fn new(definition: &str) -> Option<Proj> {

Choose a reason for hiding this comment

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

Having never used PROJ directly, what's an example str that one would pass in here? WKT of the projection?

Choose a reason for hiding this comment

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

Nevermind--I just realized that's a dumb question. 😬

@turboladen
Copy link

Sweet!

@urschrei urschrei force-pushed the reprojection branch 4 times, most recently from e29c288 to b5dac15 Compare March 15, 2018 22:22
src/lib.rs Outdated
@@ -45,4 +51,6 @@ pub mod prelude {
pub use algorithm::from_postgis::FromPostgis;
#[cfg(feature = "postgis-integration")]
pub use algorithm::to_postgis::ToPostgis;
#[cfg(feature = "projection")]

Choose a reason for hiding this comment

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

Maybe I missed it, but I don't see projection as a defined feature--should this be feature = "proj"?

Copy link
Member Author

Choose a reason for hiding this comment

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

It absolutely should. Fixed!

@urschrei urschrei force-pushed the reprojection branch 2 times, most recently from 9798583 to 4beefbc Compare March 19, 2018 12:41
Also make Project and Convert available as traits on any type that
implements MapCoords
Not totally sure how it's going to work yet
It depends on MapCoordsFallibleInplace, which is a bad idea
Copy link
Member

@frewsxcv frewsxcv left a comment

Choose a reason for hiding this comment

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

this is great, nice work @urschrei!

@frewsxcv
Copy link
Member

frewsxcv commented Apr 8, 2018

bors r+

bors bot added a commit that referenced this pull request Apr 8, 2018
192: Implement rust-proj as an optional feature within geo r=frewsxcv a=urschrei

Continuing the discussion from #190 and #32.

## Introduction
`rust-proj` is currently (as of `0.3.0`) using PROJ v4.9.x, and depends upon `Geo` for its `Point` type. However, we now have a `proj-sys` crate, with low-level bindings to PROJ v5.0.0. Unfortunately, `rust-proj's` dependency on `Geo` means that we can't directly use its functions within `Geo`, as this introduces a circular dependency (see #190).
### This PR:
- Re-implements `rust-proj`'s functionality as an optional feature ("`proj`") within `Geo` using `proj-sys`
    - it has to be optional, as it requires PROJ v5.0.0 to be present
- Makes two new traits –`Project` and `Convert` – available to any geometries implementing the `MapCoordsFallible` trait (see #191), allowing them to be (inverse) projected to and from Geodetic coordinates, and converted between projections. This functionality is a slightly more granular version (in keeping with the new PROJ API, which makes the same distinction) of what's possible using `pyproj` and `Shapely` geometries (see [here](http://shapely.readthedocs.io/en/stable/manual.html#other-transformations) for the official example):
```python
from shapely.geometry import Point, LineString
import pyproj
# LineString in projected coordinates (OSGB36)
ls = LineString([(548295.39, 182498.46), (548296.39, 182499.46)])
osgb36=pyproj.Proj("+init=EPSG:27700")
eastings, northings = list(zip(*ls.coords))
# inverse-project to geodetic lon, lat coordinates (WGS 84)
conv_ls = zip(*osgb36(eastings, northings, inverse=True))
# compare to command-line proj output
assert conv_ls == [(0.13774816464635564, 51.52142699952049), (0.1377629902608001, 51.5214357231341)]
```

I propose that we leave `rust-proj` at 0.3.0, clearly marking it as deprecated, directing users to install `Geo` with the `proj` feature if they want v5.0.x features, and linking to `proj-sys` for implementers who don't wish to use `Geo`, for whatever reason.

We can also (as per my and @turboladen's discussion in #32) highlight the availability of this feature more clearly, if need be.

Co-authored-by: Stephan Hügel <urschrei@gmail.com>
@bors
Copy link
Contributor

bors bot commented Apr 8, 2018

Build succeeded

@bors bors bot merged commit 1822cef into georust:master Apr 8, 2018
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