发布于2026-07-18 阅读(0)
扫一扫,手机访问
先抛出一个核心判断:在 C++ 里解析 GeoJSON 的 FeatureCollection,最省事的办法就是用 nlohmann/json 这个库。它天然支持嵌套结构,对 type、features、properties 这些字段名完全兼容,不需要你提前定义 schema。但前提是——输入必须合法,否则 json::parse() 会直接抛异常,不处理就等于崩溃。

GeoJSON 本质上就是 JSON,C++ 没有原生支持,硬写解析器纯属重复造轮子。直接用 nlohmann/json 是最稳妥的方案。具体操作很简单:
json j = json::parse(json_str) 加载字符串;如果从文件读,先用 std::ifstream 读成 std::string 再 parse。if (j.at("type") != "FeatureCollection"),防止误传 Feature 或 Geometry 类型。j.at("features") 返回的是 json::array_t,遍历时用 for (const auto& f : j.at("features")),别用 size() + 下标——nlohmann 的 range-for 更安全,也少写一行。GeoJSON 的 Feature 是三层嵌套:feature → geometry → coordinates 和 feature → properties → {任意键值}。nlohmann/json 不做类型推断,所有字段访问都得显式调用 .at() 或 .value(),否则遇到缺失字段就会炸。
一个典型错误:直接写 f["geometry"]["coordinates"]。一旦某个 feature 缺了 geometry,程序直接 terminate。正确的做法是逐层防御性访问:
f.contains("geometry"),再检查 f.at("geometry").contains("type") 和 f.at("geometry").contains("coordinates")。Point 是 [x,y](长度为2的数组),LineString 是 [[x,y], [x,y]](二维数组),Polygon 是三维(外环+内环)。用 f.at("geometry").at("coordinates").size() 判断维度,别硬转成 std::vector> 。properties 是自由结构,先检查 f.at("properties").is_object(),再用 .value("name", "") 安全取默认值,千万别用 .at("name")——万一没有这个字段,直接崩溃。nlohmann/json 只管把数字当 double 解出来,它不管这是 WGS84 经纬度还是 Web Mercator 米制坐标。GeoJSON 规范明确要求坐标为 [longitude, latitude](即 EPSG:4326),但实际数据经常不守规矩——比如国内某些导出工具会输出 GCJ-02 偏移坐标,或者把 coordinates 顺序写成 [lat, lon]。
解析代码里不要做坐标转换,但必须让调用方能轻易干预。常见做法是在解析循环里暴露原始 coordinates 数组的引用,而不是立刻转成自定义的 Point 结构体。
auto pt = Point{coord[0].get(), coord[1].get()} 这种紧耦合代码,一旦上层想换坐标系就得改底层。std::vector> 或 json 类型的 coordinates 字段,由上层决定是否调用 PROJ 或 GDAL 做转换。struct Coord { double x; double y; }; 而非 lat/lon 命名,避免语义误导。一个含上千 features 的 GeoJSON 文件,用 json::parse() 生成的 DOM 树内存占用可能达到数 MB,而且每次访问 .at("features")[i].at("geometry") 虽然是 O(1) 但带有 hash 查找开销。在高频场景(比如实时渲染)下,反复解析同一份数据是明显的瓶颈。
真正该优化的不是解析逻辑本身,而是复用策略和视口裁剪。解析是一次性的,后续操作应该基于内存中已有的 json 对象,而不是反复从字符串重 parse。
const json& 引用传递,禁止 json j = parsed_json 这种隐式拷贝——深拷贝成本很高。geometry 的 coordinates 极值)做过滤,别等全部解析完再遍历。json::dump() 回写调试——日志直接打印 j.at("features").size() 和前几个 f.at("properties").dump() 就够了,整个 dump 太慢。解析 GeoJSON 的难点从来不在语法层面,而在于地理语义的模糊性:坐标顺序、CRS 声明缺失、空 geometry、混合 geometry type……这些都不会报 JSON 错误,但会让下游计算彻底失效。所以每一步访问都得带校验,宁可多写几行 contains(),也不要靠文档赌数据质量。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8