AIGC标识 用 Python 按行政编码提取一条乡镇 GeoJSON 边界

效果与目标

拿到一个包含多个区域的 GeoJSON 文件后,项目可能只需要其中一个乡镇的轮廓。本文做一个小工具:输入文件、行政编码和输出文件,生成只包含匹配要素的 FeatureCollection。它保留匹配要素的属性和几何,不修改原始文件,也不请求地图接口。适合将已取得的数据整理成单区域文件,再交给地图工具使用。

本文实际使用吉林省通化市东昌区的一份本地数据,筛选编码 220502200 对应的环通乡。输入文件有 11 个要素,输出有 1 个;运行后比较过输出要素与输入中的匹配要素,属性和几何一致。该结果只说明这份文件和本次运行,不代表所有地区数据的覆盖、时效或边界精度。

数据和环境准备

准备一份可用的 GeoJSON 文件。本文示例来自地图数据项目已有的东昌区文件,文件名为 220502.json。它的顶层 type 是 FeatureCollection,features 是要素数组;各要素的 properties.code 为行政编码,properties.name 为名称,geometry 保存边界。该文件的环通乡几何类型为 Polygon;同一输入中也有 MultiPolygon,筛选时不需要转换几何。

先复制一份数据到工作目录,再进行操作。示例文件来自项目已有本地数据,文末公开入口不保证提供相同文件;读者需准备自己的兼容边界文件,实际字段和验证结果可能不同,不要把行政编码列表当作边界文件。准备 Python 3,无需安装第三方包。本文不推断数据坐标系或授权范围,叠加其他图层前应向数据提供方确认。

第一步:确认编码和文件结构

把 220502.json 和下面的 extract.py 放在同一个目录。打开 JSON,检查顶层 type 与 features,再查看目标要素的 properties.code。本例用字符串 220502200 做精确匹配,而不是按名称模糊搜索,避免同名区域误选;编码应保持字符串形式,以免丢失可能存在的前导零。

GeoJSON 的 FeatureCollection 可以包含多个 Feature。本工具只筛选数组,完整保留选中项的 properties 与 geometry,不会简化、多边形合并、重投影或计算面积。如果同一个编码对应多个要素,代码会全部保留,并在命令行显示数量;这不自动意味着数据有误,需要结合原数据核对。

第二步:保存完整代码

将以下代码保存为 extract.py:

import argparse
import json
from pathlib import Path


def main():
    parser = argparse.ArgumentParser(description="按行政编码提取 GeoJSON 要素")
    parser.add_argument("input", type=Path, help="输入 GeoJSON 文件")
    parser.add_argument("code", help="要查找的行政编码")
    parser.add_argument("output", type=Path, help="输出 GeoJSON 文件")
    args = parser.parse_args()

    if args.input.resolve() == args.output.resolve():
        parser.error("输出路径不能与输入路径相同")
    with args.input.open(encoding="utf-8") as file:
        collection = json.load(file)
    if collection.get("type") != "FeatureCollection" or not isinstance(collection.get("features"), list):
        parser.error("输入必须是包含 features 数组的 FeatureCollection")
    matches = [feature for feature in collection["features"]
               if str((feature.get("properties") or {}).get("code", "")) == args.code]
    if not matches:
        parser.error(f"未找到编码 {args.code},没有写入输出文件")
    result = {**collection, "features": matches}
    with args.output.open("w", encoding="utf-8") as file:
        json.dump(result, file, ensure_ascii=False, separators=(",", ":"))
    print(f"找到 {len(matches)} 个要素,已写入 {args.output}")


if __name__ == "__main__":
    main()

程序先阻止输入与输出指向同一路径,再检查顶层类型和数组,随后以 properties.code 精确筛选。找不到编码时通过参数错误退出,不创建输出文件;如果输出文件已经存在,正常匹配后会覆盖它,使用前请选一个新的输出文件名。输出保留输入集合中的其他顶层字段,并把 features 替换为匹配结果。

第三步:运行并检查结果

在这两个文件所在目录打开终端,运行:

python3 extract.py 220502.json 220502200 220502200.json

本次运行输出 找到 1 个要素,已写入 220502200.json。打开新文件,应看到 type 仍为 FeatureCollection,features 数组仅含一个要素,名称为环通乡、编码为 220502200,几何类型为 Polygon。可以把文件导入支持 GeoJSON 的地图软件检查轮廓;是否能正确叠加其他底图还取决于坐标系等信息。

再试一个输入中不存在的编码,例如:

python3 extract.py 220502.json 999999999 missing.json

程序应提示未找到编码并以非零状态退出,不创建 missing.json。本次也验证了这一失败路径。实际使用时应在干净的输出路径测试:如果同名旧文件本来就存在,失败不会删除它,不能仅凭文件存在判断本次成功。

常见问题

为什么找不到区域? 先检查输入文件是否为该区域的上级或目标要素集合,再查看实际编码字段是否叫 code、值是否完整。不同来源的属性名可能不同,需要按真实数据修改筛选逻辑。名称存在不代表编码一定相同,也不要用前缀匹配替代精确匹配。

输出能直接用于 ECharts 吗? 输出仍是 FeatureCollection,可作为后续地图接入的输入;具体显示还需要注册地图并配置图表,不能仅凭成功导出就认定所有地图组件或坐标系统均兼容。

文件含多个面或岛屿怎么办? 工具保留原始 Polygon 或 MultiPolygon,不拆分也不重新计算。遇到无效几何、缺失属性或格式错误时,应先核对来源并使用专门的 GIS 工具检查;本示例不是完整的 GeoJSON 合法性校验器。

数据与源码

地图数据入口:https://geojson.hxkj.vip/

既有地图示例项目:https://github.com/TangSY/echarts-map-demo

本文的 extract.py 完整代码已列在上面;它是本教程示例,并未声称已推送到上述仓库。

posted @ 2026-11-02 09:26  HashTang  阅读(2)  评论(0)    收藏  举报