Loading JSON into a GeoDataFrame

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.