I'm having difficulty loading the following JSON containing GIS data (https://data.cityofnewyork.us/resource/5rqd-h5ci.json) into a GeoDataFrame.
The following code fails when I try to set the geometry.
import requests
import geopandas as gpd
data = requests.get("https://data.cityofnewyork.us/resource/5rqd-h5ci.json")
gdf = gpd.GeoDataFrame(data.json())
gdf = gdf.set_geometry('the_geom')
gdf.head()
For people who are using web mapping libraries...
If the GeoJSON is wrapped in a FeatureCollection
, as they often are when exported to a GeoJSON string by web mapping libraries (in my case, Leaflet), then all you need to do is pass the list at features
to from_features()
like so:
import geopandas as gpd
study_area = json.loads("""
{"type": "FeatureCollection", "features": [{"type": "Feature", "properties": {}, "geometry": {"type": "Polygon", "coordinates": [[[36.394272, -18.626726], [36.394272, -18.558391], [36.489716, -18.558391], [36.489716, -18.626726], [36.394272, -18.626726]]]}}]}
""")
gdf = gpd.GeoDataFrame.from_features(study_area["features"])
print(gdf.head())
Output:
geometry
0 POLYGON ((36.394272 -18.626726, 36.394272 -18....
Easy peasy.
Setting the geometry fails because the geopandas.GeoDataFrame
constructor doesn't appear to be built to handle JSON objects as python data structures. It therefore complains about the argument not being a valid geometry object. You have to parse it into something that geopandas.GeoDataFrame
can understand, like a shapely.geometry.shape
. Here's what ran without error on my side, Python 3.5.4:
#!/usr/bin/env python3
import requests
import geopandas as gpd
from shapely.geometry import shape
r = requests.get("https://data.cityofnewyork.us/resource/5rqd-h5ci.json")
r.raise_for_status()
data = r.json()
for d in data:
d['the_geom'] = shape(d['the_geom'])
gdf = gpd.GeoDataFrame(data).set_geometry('the_geom')
gdf.head()
A disclaimer: I know absolutely nothing about Geo anything. I didn't even know these libraries and this kind of data existed until I installed geopandas
to tackle this bounty and read a little bit of online documentation.
Combining the above answers, this worked for me.
import pandas as pd
import geopandas as gpd
from shapely.geometry import shape
nta = pd.read_json( r'https://data.cityofnewyork.us/resource/93vf-i5bz.json' )
nta['the_geom'] = nta['the_geom'].apply(shape)
nta_geo = gpd.GeoDataFrame(nta).set_geometry('geometry')
A more idiomatic way that uses regular dataframe functions inherited from pandas
, and the native GeoDataFrame.from_features
:
gdf = gpd.GeoDataFrame(data.json())
# features column does not need to be stored, this is just for illustration
gdf['features'] = gdf['the_geom'].apply(lambda x: {'geometry': x, 'properties': {}})
gdf2 = gpd.GeoDataFrame.from_features(gdf['features'])
gdf = gdf.set_geometry(gdf2.geometry)
gdf.head()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With