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

Handle geopandas and shapely geometries via geo_interface link #1000

Merged
merged 15 commits into from
May 18, 2021

Conversation

weiji14
Copy link
Member

@weiji14 weiji14 commented Mar 4, 2021

Description of proposed changes

Enabling PyGMT to use GeoPandas data structures! This includes plotting geopandas.GeoDataFrame tables and running data processing tasks. Works by converting the GeoJSON __geo_interface__ representation to an OGR_GMT file format and passing that into GMT.

Preview API doc example at https://pygmt-git-geopandasintegration-gmt.vercel.app/api/generated/pygmt.info.html.

Example code (note that the should work directly in PyGMT v0.4.0 since #1000 is merged!):

import geopandas as gpd
import pygmt
import shapely.geometry

# Create a geopandas GeoDataFrame
gdf = gpd.GeoDataFrame(
    geometry=[shapely.geometry.Polygon([(20, 10), (23, 10), (23, 14), (20, 10)])],
)

pygmt.info(table=gdf, per_column=True)
# array([20., 23., 10., 14.])

References:

TODO:

Fixes #608

Reminders

  • Run make format and make check to make sure the code follows the style guide.
  • Add tests for new features or tests that would have caught the bug that you're fixing.
  • Add new public functions/methods/classes to doc/api/index.rst.
  • Write detailed docstrings for all functions/methods.
  • If adding new functionality, add an example to docstrings or tutorials.

Slash Commands

You can write slash commands (/command) in the first line of a comment to perform
specific operations. Supported slash commands are:

  • /format: automatically format and lint the code
  • /test-gmt-dev: run full tests on the latest GMT development version

@weiji14 weiji14 added the feature Brand new feature label Mar 4, 2021
@weiji14 weiji14 added this to the 0.4.0 milestone Mar 4, 2021
Initial stab at allowing PyGMT to accept Python objects
that implement __geo_interface__, i.e. a GeoJSON-like
format. Works by conversion to a temporary OGR_GMT file,
which can then be read natively by GMT . This is currently
tested via `pygmt.info` in test_geopandas.py on a
geopandas.GeoDataFrame object only. Will handle raw
GeoJSON dict-like objects properly via fiona in subsequent
iterations.
pygmt/src/info.py Outdated Show resolved Hide resolved
Hacky attempt to handle non-geopandas objects (e.g.
shapely.geometry) that have a __geo_interface__ dictionary
property associated with it. Still assumes that geopandas
is installed (along with fiona), so not a perfect solution.
Also added another test with different geometry types.
Comment on lines 149 to 156
# with memfile.open(driver="GeoJSON") as collection:
# # Get schema from GeoJSON
# schema = collection.schema
# # Write to temporary OGR_GMT format file
# with fiona.open(
# fp=tmpfile.name, mode="w", driver="OGR_GMT", schema=schema
# ) as ogrgmtfile:
# ogrgmtfile.write(geojson.__geo_interface__)
Copy link
Member Author

Choose a reason for hiding this comment

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

This was my failed attempt to convert a GeoJSON string to an OGR_GMT (*.gmt) format file purely using fiona (i.e. no geopandas installed). The problem I found was that a schema had to be set, and that requires a lot of lines of code to do, which is why I stuck to using geopandas in the lines above.

If someone can figure out a good way to solve the schema problem, that would be fantastic!

Copy link
Member Author

Choose a reason for hiding this comment

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

Ok, I've removed this chunk of unusable code in 34de789. Hopefully this can be revisited in the future so that GeoJSON objects can be converted into OGR_GMT purely using fiona without the need for installing geopandas (a bit of a big dependency).

@@ -45,11 +45,14 @@ jobs:
# python-version: 3.7
# isDraft: true
# Pair Python 3.7 with NumPy 1.17 and Python 3.9 with NumPy 1.20
# Only install geopandas on Python 3.9/NumPy 1.20
Copy link
Member

Choose a reason for hiding this comment

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

What's the reason for this?

Copy link
Member Author

@weiji14 weiji14 Apr 6, 2021

Choose a reason for hiding this comment

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

Since geopandas is an optional dependency, probably good to have a test matrix that doesn't include it.

Co-Authored-By: Michael Grund <michaelgrund@users.noreply.github.com>
@weiji14 weiji14 marked this pull request as ready for review May 12, 2021 23:23
Copy link
Member

@seisman seisman left a comment

Choose a reason for hiding this comment

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

Looks great.

@seisman seisman added the final review call This PR requires final review and approval from a second reviewer label May 13, 2021
@weiji14
Copy link
Member Author

weiji14 commented May 17, 2021

Checking with @michaelgrund if you have any other comments on this geopandas integration PR? If not, I'll merge in the next 24 hours.

@weiji14 weiji14 changed the title Plot geopandas and shapely geometries via __geo_interface__ link Handle geopandas and shapely geometries via __geo_interface__ link May 18, 2021
@weiji14 weiji14 merged commit 5695f17 into master May 18, 2021
@weiji14 weiji14 deleted the geopandas_integration branch May 18, 2021 01:17
@weiji14 weiji14 removed the final review call This PR requires final review and approval from a second reviewer label May 18, 2021
@weiji14 weiji14 changed the title Handle geopandas and shapely geometries via __geo_interface__ link Handle geopandas and shapely geometries via geo_interface link May 24, 2021
sixy6e pushed a commit to sixy6e/pygmt that referenced this pull request Dec 21, 2022
…enericMappingTools#1000)

Initial stab at allowing PyGMT to accept Python objects
that implement __geo_interface__, i.e. a GeoJSON-like
format. Works by conversion to a temporary OGR_GMT file,
which can then be read natively by GMT . This is currently
tested via `pygmt.info` in test_geopandas.py on a
geopandas.GeoDataFrame object only. Will handle raw
GeoJSON dict-like objects properly via fiona in subsequent
iterations.

* Add intersphinx mapping to geopandas docs
* Create tempfile_from_geojson function to handle __geo_interface__
* Add geopandas.GeoDataFrame to list of allowed table inputs to info
* Handle generic __geo_interface__ objects via fiona and geopandas

Hacky attempt to handle non-geopandas objects (e.g.
shapely.geometry) that have a __geo_interface__ dictionary
property associated with it. Still assumes that geopandas
is installed (along with fiona), so not a perfect solution.
Also added another test with different geometry types.

* Install geopandas on the Python 3.9/NumPy 1.20 test build only
* Mention optional geopandas dependency in install and maintenance docs
* Tweak tempfile_from_geojson docstring and remove unused fiona code
* Add geopandas.GeoDataFrame to standardized table-classes filler text

Co-authored-by: Michael Grund <michaelgrund@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Brand new feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Integration with geopandas to plot shapely geometries
3 participants