如何将含Polygon类型JSON的DataFrame转换为GeoDataFrame?
问题
现有一个DataFrame,其中footprint列存储的是{'type': 'Polygon'}格式的Python字典对象,数据示例如下:
df.head(2) osm_id osm_address osm_building osm_building:levels footprint plus_code ground_height building_height roof_height osm_name osm_office osm_type osm_website osm_operator 739615941 739615941.0 10 Rhodes Avenue University Estate Cape Town house 2 {'type': 'Polygon', 'coordinates': [[[264275.9... 4FRW3C6X+WRG 96.75 6.9 103.65 NaN NaN NaN NaN NaN 740820432 740820432.0 100 Upper Roodebloem Road University Estate Ca... house 2 {'type': 'Polygon', 'coordinates': [[[264379.7... 4FRW3F62+R87 85.37 6.9 92.27 NaN NaN NaN NaN NaN
单个footprint数据示例:
df.footprint[0] {'type': 'Polygon', 'coordinates': [[[264275.99887603114, 6241813.834685098], [264278.1042860146, 6241837.7936792765], [264273.2223782305, 6241838.438089997], [264272.6105920747, 6241830.67597108], [264271.28497070284, 6241830.787288936], [264270.08650652826, 6241814.253691107], [264275.99887603114, 6241813.834685098]]]}
尝试以下代码解析后,所有特征返回None:
def parse_geom(geom_str): try: return shape(json.loads(geom_str)) except (TypeError, AttributeError): # Handle NaN and empty strings return None df['footprint'] = df['footprint'].apply(parse_geom)
需要将footprint列中的Polygon类型数据解析为GeoDataFrame的geometry列。
解决方案
问题出在原代码的json.loads(geom_str):footprint列的内容已经是Python字典,不是JSON字符串,调用json.loads会触发异常,最终返回None。
正确解析步骤
- 直接使用
shapely.geometry.shape()处理字典对象,生成shapely几何对象 - 将处理后的列指定为GeoDataFrame的geometry列,并设置正确的坐标参考系(CRS)
代码实现
from shapely.geometry import shape import geopandas as gpd # 修正解析函数 def parse_geom(geom_dict): try: return shape(geom_dict) except (TypeError, AttributeError): return None # 生成geometry列 df['geometry'] = df['footprint'].apply(parse_geom) # 转换为GeoDataFrame,替换为你的数据对应的CRS(示例为UTM 34S) gdf = gpd.GeoDataFrame(df.drop('footprint', axis=1), geometry='geometry', crs="EPSG:32734")
兼容混合格式场景
如果footprint列同时存在JSON字符串和Python字典的混合情况,可以增加类型判断:
import json from shapely.geometry import shape import geopandas as gpd def parse_geom(geom): try: # 先判断是否为JSON字符串,是则解析为字典 if isinstance(geom, str): geom_dict = json.loads(geom) else: geom_dict = geom return shape(geom_dict) except (TypeError, AttributeError, json.JSONDecodeError): return None df['geometry'] = df['footprint'].apply(parse_geom) gdf = gpd.GeoDataFrame(df.drop('footprint', axis=1), geometry='geometry', crs="EPSG:32734")
内容的提问来源于stack exchange,提问作者arkriger
相关产品推荐
相关产品推荐

