2. 处理GeoJSON数据格式
任务说明
本案例将完成一个完整的GeoJSON处理闭环:读取GeoJSON文件 → 转换为GeoDataFrame → 执行属性查询 → 执行空间过滤。使用Python的GeoPandas库实现,输入数据为内嵌的示例GeoJSON(包含北京市三个城区的面要素及人口属性),最终输出各步骤的结果行数与过滤后的要素。
实现代码
import geopandas as gpd
from shapely.geometry import Polygon
import json
# 1. 准备示例GeoJSON数据(内嵌,保证独立可复现)
geojson_data = {
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {"name": "东城区", "population": 65.2, "area_km2": 41.8},
"geometry": {
"type": "Polygon",
"coordinates": [[[116.40, 39.90], [116.43, 39.90], [116.43, 39.94], [116.40, 39.94], [116.40, 39.90]]]
}
},
{
"type": "Feature",
"properties": {"name": "西城区", "population": 113.7, "area_km2": 50.7},
"geometry": {
"type": "Polygon",
"coordinates": [[[116.35, 39.90], [116.38, 39.90], [116.38, 39.94], [116.35, 39.94], [116.35, 39.90]]]
}
},
{
"type": "Feature",
"properties": {"name": "朝阳区", "population": 354.5, "area_km2": 470.8},
"geometry": {
"type": "Polygon",
"coordinates": [[[116.43, 39.90], [116.50, 39.90], [116.50, 39.97], [116.43, 39.97], [116.43, 39.90]]]
}
}
]
}
# 将字典写入临时文件(模拟真实读取场景)
with open("beijing_districts.geojson", "w", encoding="utf-8") as f:
json.dump(geojson_data, f, ensure_ascii=False)
# 2. 读取GeoJSON文件并转换为GeoDataFrame
gdf = gpd.read_file("beijing_districts.geojson")
print("=== 读取GeoJSON并转换 ===")
print(f"类型: {type(gdf).__name__}")
print(f"要素数量: {len(gdf)}")
print(f"列名: {list(gdf.columns)}")
print(gdf[["name", "population", "area_km2"]].to_string(index=False))
# 3. 属性查询:筛选人口大于100万的区
attr_result = gdf[gdf["population"] > 100]
print("\n=== 属性查询(人口 > 100万)===")
print(f"命中数量: {len(attr_result)}")
print(attr_result["name"].tolist())
# 4. 空间过滤:筛选与给定点(天安门附近)相交的区
from shapely.geometry import Point
tiananmen_point = Point(116.397, 39.908) # 天安门坐标
spatial_result = gdf[gdf.intersects(tiananmen_point)]
print("\n=== 空间过滤(与天安门点相交)===")
print(f"命中数量: {len(spatial_result)}")
print(spatial_result["name"].tolist())
# 5. 验证:检查空间过滤结果的几何有效性
assert len(spatial_result) > 0, "空间过滤结果为空,请检查坐标范围"
print("\n验证通过:空间过滤返回了有效要素")
代码说明
代码首先在内存中构建一个包含三个北京市区县面要素的GeoJSON字典,并写入临时文件以模拟真实文件读取。使用gpd.read_file()读取后自动转换为GeoDataFrame。属性查询通过布尔索引实现,筛选population大于100万的区县;空间过滤则利用intersects()方法,判断每个面要素是否与天安门坐标点相交。最后通过断言验证空间过滤结果非空。
运行与验证
依赖安装:
pip install geopandas shapely
运行方式:将上述代码保存为geojson_processing.py,在Python环境中执行:
python geojson_processing.py
预期输出与判定标准:
- 读取阶段输出3个要素,列名包含
name、population、area_km2和geometry; - 属性查询输出
['西城区', '朝阳区'](人口均大于100万); - 空间过滤输出
['东城区', '西城区'](天安门位于东城区与西城区交界附近,两个面均与之相交); - 程序无异常退出且断言通过,即表示处理流程正确。