[GIS] Convert GeoJSON to GeoPandas GeoDataframe

geodataframegeojsongeopandaspythonrasterio

I created the following GeoJSON object with this code:

from rasterio.features import shapes

polys = []
for shape, value in shapes(segments, transform=affine):
    polys.append(shape)

[{'type': 'Polygon',
  'coordinates': [[(670625.0016573452, 5282947.795216726),
    (670625.0016573452, 5282927.795216726),
    (670626.0016573452, 5282927.795216726),
    (670626.0016573452, 5282928.795216726),
    (670627.0016573452, 5282928.795216726),
    (670628.0016573452, 5282928.795216726),
    (670628.0016573452, 5282929.795216726),
    (670631.0016573452, 5282929.795216726),
    (670632.0016573452, 5282929.795216726),
    (670632.0016573452, 5282930.795216726),
    (670633.0016573452, 5282930.795216726),
    (670634.0016573452, 5282930.795216726),
    (670634.0016573452, 5282931.795216726),
    (670635.0016573452, 5282931.795216726),
    (670635.0016573452, 5282929.795216726),
    (670636.0016573452, 5282929.795216726),
    (670636.0016573452, 5282931.795216726),
    (670637.0016573452, 5282931.795216726),
    (670638.0016573452, 5282931.795216726),
    (670638.0016573452, 5282932.795216726),
    (670639.0016573452, 5282932.795216726),
    (670640.0016573452, 5282932.795216726),
    (670640.0016573452, 5282933.795216726),
    (670641.0016573452, 5282933.795216726),
    (670641.0016573452, 5282934.795216726),
    (670642.0016573452, 5282934.795216726),
    (670642.0016573452, 5282935.795216726),
    (670643.0016573452, 5282935.795216726),
    (670643.0016573452, 5282943.795216726),
    (670644.0016573452, 5282943.795216726),
    (670644.0016573452, 5282947.795216726),
    (670625.0016573452, 5282947.795216726)]]},
 {'type': 'Polygon',
  'coordinates': [[(670871.0016573452, 5282947.795216726),
    (670871.0016573452, 5282945.795216726),
    (670872.0016573452, 5282945.795216726),
    (670872.0016573452, 5282933.795216726),
    (670873.0016573452, 5282933.795216726),
    (670873.0016573452, 5282932.795216726),
    (670874.0016573452, 5282932.795216726),
    (670874.0016573452, 5282928.795216726),
    (670876.0016573452, 5282928.795216726),
    (670876.0016573452, 5282929.795216726),
    (670877.0016573452, 5282929.795216726),
    (670877.0016573452, 5282928.795216726),
    (670880.0016573452, 5282928.795216726),
    (670880.0016573452, 5282929.795216726),
    (670883.0016573452, 5282929.795216726),
    (670884.0016573452, 5282929.795216726),
    (670884.0016573452, 5282930.795216726),
    (670885.0016573452, 5282930.795216726),
    (670885.0016573452, 5282929.795216726),
    (670892.0016573452, 5282929.795216726),
    (670893.0016573452, 5282929.795216726),
    (670893.0016573452, 5282934.795216726),
    (670894.0016573452, 5282934.795216726),
    (670895.0016573452, 5282934.795216726),
    (670895.0016573452, 5282936.795216726),
    (670894.0016573452, 5282936.795216726),
    (670894.0016573452, 5282935.795216726),
    (670893.0016573452, 5282935.795216726),
    (670893.0016573452, 5282940.795216726),
    (670892.0016573452, 5282940.795216726),
    (670892.0016573452, 5282943.795216726),
    (670893.0016573452, 5282943.795216726),
    (670893.0016573452, 5282944.795216726),
    (670894.0016573452, 5282944.795216726),
    (670894.0016573452, 5282945.795216726),
    (670893.0016573452, 5282945.795216726),
    (670893.0016573452, 5282947.795216726),
    (670871.0016573452, 5282947.795216726)]]}]

I attempted to load the GeoJSON into a GeoPandas GeoDataframe using the following approach (note that polys is the GeoJSON object above):

import geopandas as gpd

polys_gdf = gpd.GeoDataFrame(polys).set_geometry('coordinates')

Which yielded the following error:

TypeError: Input must be valid geometry objects: [[(670625.0016573452,
5282947.795216726), (670625.0016573452, 5282927.795216726), (670626.0016573452, 5282927.795216726), (670626.0016573452,
5282928.795216726), (670627.0016573452, 5282928.795216726), (670628.0016573452, 5282928.795216726), (670628.0016573452,
5282929.795216726), (670631.0016573452, 5282929.795216726), (670632.0016573452, 5282929.795216726), (670632.0016573452,
5282930.795216726), (670633.0016573452, 5282930.795216726), (670634.0016573452, 5282930.795216726), (670634.0016573452,
5282931.795216726), (670635.0016573452, 5282931.795216726), (670635.0016573452, 5282929.795216726), (670636.0016573452,
5282929.795216726), (670636.0016573452, 5282931.795216726), (670637.0016573452, 5282931.795216726), (670638.0016573452,
5282931.795216726), (670638.0016573452, 5282932.795216726), (670639.0016573452, 5282932.795216726), (670640.0016573452,
5282932.795216726), (670640.0016573452, 5282933.795216726), (670641.0016573452, 5282933.795216726), (670641.0016573452,
5282934.795216726), (670642.0016573452, 5282934.795216726), (670642.0016573452, 5282935.795216726), (670643.0016573452,
5282935.795216726), (670643.0016573452, 5282943.795216726), (670644.0016573452, 5282943.795216726), (670644.0016573452,
5282947.795216726), (670625.0016573452, 5282947.795216726)]]

How can I properly load the GeoJSON into a GeoPandas GeoDataframe?

Best Answer

With a list of GeoJSON-like Python geo interface geometries, simply use shapely.geometry.shape (GeoPandas uses shapely, see also Python Geo_interface applications)

from shapely.geometry import shape
geom = [shape(i) for i in polys]
gpd.GeoDataFrame({'geometry':geom})
                         geometry
0  POLYGON ((670625.0016573452 5282947.795216726,...
1  POLYGON ((670871.0016573452 5282947.795216726,...