pydeck: Closer integration with Python geospatial ecosystem
See original GitHub issueTarget Use case
Judging from my own experience, I would expect that most or at least many users of pydeck would be using it to visualize data that they’ve modified using other tools in the Python geospatial ecosystem. Using for example tools like Shapely, for planar geometric operations using the underlying GEOS library, or GeoPandas, which extends Pandas to integrate with Shapely.
The usual layout of a GeoDataFrame
, the main class in GeoPandas, is one feature per row, with a geometry
column that contains each row’s geometry.
As far as I can tell, there is currently no integration with such existing libraries. Most of the existing pydeck examples (on the website at least) pass URLs to Deck.gl for loading the data. This is understandable, since these examples are ported from the Deck.gl docs, but I don’t think it’s a true representation of how most users would pass data to Deck.gl.
Proposed feature
There are a couple ways in which integration could be improved.
__geo_interface__
The __geo_interface__
attribute is a standard implemented by several Python GIS packages, including GeoPandas, Shapely, and others.
As defined here, it essentially allows you to get a GeoJSON representation of data, regardless of the package/class the data is in.
For example with a GeoDataFrame
, the __geo_interface__
is respective of the data passed:
import geopandas as gpd
features = [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [125.6, 10.1]
},
"properties": {
"name": "Dinagat Islands"
}
},{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [125, 10]
},
"properties": {
"name": "Water"
}
}]
gdf = gpd.GeoDataFrame.from_features(features)
gdf.__geo_interface__
# {'type': 'FeatureCollection',
# 'features': [{'id': '0',
# 'type': 'Feature',
# 'properties': {'name': 'Dinagat Islands'},
# 'geometry': {'type': 'Point', 'coordinates': (125.6, 10.1)},
# 'bbox': (125.6, 10.1, 125.6, 10.1)},
# {'id': '1',
# 'type': 'Feature',
# 'properties': {'name': 'Water'},
# 'geometry': {'type': 'Point', 'coordinates': (125.0, 10.0)},
# 'bbox': (125.0, 10.0, 125.0, 10.0)}],
# 'bbox': (125.0, 10.0, 125.6, 10.1)}
gdf.geometry.unary_union.__geo_interface__
# {'type': 'MultiPoint', 'coordinates': ((125.0, 10.0), (125.6, 10.1))}
gdf.geometry[0].__geo_interface__
# {'type': 'Point', 'coordinates': (125.6, 10.1)}
Supporting this would enable interconnection with a large part of the ecosystem. You could just check for the presence of the __geo_interface__
attribute on the data object passed to pydeck.
However there are still some questions, like what if a user asks for a LineLayer
but passes in a set of Point
geometries, instead of LineString
geometries. Or what if a user asks for a ScatterplotLayer
, but passes a LineString
or Polygon
geometry? Should automatic conversion happen? Should there be validation on the Python side?
Coordinate Reference System
Several packages include metadata on the CRS the data is in. When a user is working with data in non-WGS84, it’s easy to forget to transform the data into the right CRS. It might be possible to print a warning if it’s clear the data is not in WGS84, but there might not be a non-hacky way to do this.
Something like
if data.__class__.__name__ == 'GeoDataFrame':
crs = data.crs
# might not be a non-hacky way to check equality to WGS84
if crs and crs != WGS84:
print('Warning: Data might not be in WGS84')
To Do List
- Add label and assign to milestone
- Coding
- Doc update
- What’s new update
- Test
Issue Analytics
- State:
- Created 3 years ago
- Reactions:4
- Comments:11
Top GitHub Comments
+1 as someone who just spent a lot of time wrestling a GeoDataFrame into an acceptable format for pydeck. Very supportive of this!
Glad to see the interest here–I’ll put this feature in pydeck 0.5. I’ll get this out within six weeks. I’ll update this issue when there’s a beta published.
@ibgreen Probably going this route to start and we can change the implementation later