将JSON加载到GeoDataFrame中

25

我在尝试将包含GIS数据的以下JSON文件(https://data.cityofnewyork.us/resource/5rqd-h5ci.json)加载到GeoDataFrame时遇到了困难。

当我尝试设置几何图形时,以下代码失败了。

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()

2
未来参考注意事项:此JSON文件似乎不是有效的GeoJSON格式。对于这种文件,您可以更轻松地使用geopandas.read_file(..) - joris
4个回答

34

对于使用Web地图库的人...

如果GeoJSON被包含在FeatureCollection中,通常情况下通过Web地图库(例如我的情况是Leaflet)将其导出到GeoJSON字符串中,那么你只需要将列表传递到from_features()中的features即可:

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())

输出:

                                            geometry
0  POLYGON ((36.394272 -18.626726, 36.394272 -18....

简单易懂。


这是一个更好的答案,特别是对于最近升级geopandas并遇到以前的GeoDataFrame构造函数回归问题的人们。 - Tobbey
.from_featuresfeatures 列表上也能完美运行。 - CharlesG

21

由于geopandas.GeoDataFrame构造函数似乎没有构建来处理JSON对象作为Python数据结构的能力,所以设置几何图形会失败。因此,它会抱怨该参数不是有效的几何对象。您必须将其解析为某些geopandas.GeoDataFrame能够理解的内容,例如shapely.geometry.shape。以下是在我的环境中无错误运行的代码,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()

免责声明:我对地理学一窍不通。 直到我安装了geopandas并阅读了一些在线文档,我才知道这些库和这种数据的存在。


更加简洁:d['the_geom'] = d['the_geom'].apply(shape) - pgzmnk

3

结合以上答案,这对我很有效。

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')

1

更符合惯用方法的方式是使用从pandas继承的常规数据框函数和本地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()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接