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

Add proximity and buffer_metric functionalities with metric option based on finding local UTM #336

Merged
merged 21 commits into from
Jan 20, 2023

Conversation

rhugonnet
Copy link
Member

@rhugonnet rhugonnet commented Jan 8, 2023

Summary

This PR adds a proximity() function to the Vector and Raster classes that mirrors GDAL's proximity not implemented in rasterio (rasterio/rasterio#319), and a buffer_metric() method for the Vector class to avoid the trouble of reprojecting from geographic system, buffer, than reverse-projecting, based on finding a local UTM zone.
It also adds a Raster method equal_georeferenced_grid to check if two rasters have the same georeferencing.

In details

Proximity

The proximity is computed using scipy.distance_transform_edt (https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.distance_transform_edt.html).

The functioning is as follows:

  • For Raster classes, the proximity can be either computed directly from target values of the array self.data, or from a Vector passed as argument that is automatically rasterized on self. For target values, the default behaviour is the same as GDAL: a list of any number of values can be passed. If none are passed, all non-zero values are targets. For the distance unit, I also implemented both "pixel" and "georeferenced", but put the default as "georeferenced" contrary to GDAL's "pixel".

  • For Vector classes, the proximity can be computed from self by passing a Raster object to rasterize the vector on.

The resulting proximity values are thoroughly tested against GDAL Python's gdal.ComputeProximity() with artificial and real Raster data. All results are the same, except for very complex case where a few percentage of values (<1%) differ by ~1% (not even a floating point issue, GDAL's algorithm is simply slightly different for some cases).

Additionally, any geometry_type can be passed to rasterize the Vector object with (default: boundary, which is the most common). And an in_or_out option can be passed to include only the outside or inside proximity for a geometry that have an area (Polygon, MultiPolygon, etc).

Buffer metric

This function is to avoid the trouble of reprojecting a Vector in a local metric system for buffering without deformation, and then reverse-projecting. This involves finding the local metric system wanted, reprojecting to it, recreating ageopandas.GeoDataFrame object in the right CRS with the buffer geopandas.GeoSeries, and reverse-projecting.

For now this function only supports reprojecting in the local UTM which, for speed, is approximated by the latitude/longitude coordinates of the centroid of non-projected vector (centroid are not exactly the same depending on projections, but generally robust enough?).

Two new functions latlon_to_utm and utm_to_epsg in projtools help converting coordinates to UTM zone and to related EPSG (maybe there's some new stuff out there, but a couple years ago the utm Python package didn't allow UTM zones near poles, which was annoying, and I didn't know of any package that could interpret the UTM zone into an EPSG code).

All functions of projtools and the buffer_metric method in Vector are tested. I also added the metric argument in buffer_without_overlap function, which does the same procedure.

Issues closed

This PR:

And adds tests for all.

@rhugonnet
Copy link
Member Author

Tests all passing locally (= will be all good PR #335 is merged)

Copy link
Contributor

@erikmannerfelt erikmannerfelt left a comment

Choose a reason for hiding this comment

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

Awesome functionality!

Copy link
Member

@adehecq adehecq left a comment

Choose a reason for hiding this comment

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

Nice ! 😄

@rhugonnet
Copy link
Member Author

Merging here as well!

@rhugonnet rhugonnet merged commit 931c9dc into GlacioHack:main Jan 20, 2023
@rhugonnet rhugonnet deleted the local_utm_buffer branch January 20, 2023 06:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants