最直接方法是用nlohmann/json解析GeoJSON:先解析为json对象,再按"type"分支处理Point/LineString/Polygon等坐标结构,忽略已废弃的crs字段,解析后缓存为原生C++结构提升性能。

用 nlohmann/json 读取 GeoJSON 文件最直接
GeoJSON 本质是 JSON,C++ 没有标准地理解析库,所以第一步不是找“GIS库”,而是选一个靠谱的 JSON 解析器。目前最稳妥的选择是 nlohmann/json:头文件即用、支持嵌套对象/数组、能清晰区分 Feature、Geometry、coordinates 等字段。
常见错误是试图手写 std::regex 或 rapidjson 手动遍历 DOM——既容易漏掉 MultiPolygon 的多层嵌套,又难处理 properties 中任意键名。用 nlohmann/json 可以直接按路径取值:
auto j = nlohmann::json::parse(json_str);
auto type = j["type"].get<std::string>(); // "FeatureCollection"
auto features = j["features"]; // json array
for (auto& f : features) {
auto geom = f["geometry"];
auto geom_type = geom["type"].get<std::string>(); // "Point", "LineString", etc.
auto coords = geom["coordinates"]; // or ["geometries"] for GeometryCollection
}
区分 Point / LineString / Polygon 的坐标结构
GeoJSON 对不同几何类型用了完全不同的坐标组织方式,硬编码一个解析逻辑会崩溃。必须根据 geometry["type"] 分支处理:
-
Point→coordinates是长度为 2 或 3 的数组:[lon, lat]或[lon, lat, alt] -
LineString→coordinates是数组的数组:[[lon,lat], [lon,lat], ...] -
Polygon→coordinates是三维数组,第一项是外环,后续是内环(洞):[[[lon,lat],...], [[lon,lat],...]] -
MultiPolygon→ 坐标是四维:外层是多个 Polygon,每 Polygon 再套环
忽略这点会导致 at() 报 out_of_range 或静默丢数据。建议封装一个 get_coordinates() 函数,输入 geom,输出 std::vector<std::vector<double>>(点列表)或更明确的自定义结构。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
注意 crs 字段已废弃,别依赖它
旧版 GeoJSON 规范允许带 "crs": {"type": "name", "properties": {"name": "EPSG:4326"}},但 RFC 7946(现行标准)明确移除了 crs 字段。所有坐标默认为 WGS84 经纬度(EPSG:4326),单位是十进制度,轴序是 [longitude, latitude]。
如果你的输入数据里还含 crs,说明它不是合规 GeoJSON,解析时应直接忽略该字段,不要尝试做坐标系转换——C++ 里没轻量级投影库能安全接住这个需求。真要转坐标,导出经纬度后交给 PROJ C API 处理,别在 JSON 解析阶段掺和。
性能关键:避免重复解析同一文件多次
如果程序需频繁查 Feature 属性或空间关系(比如判断某点是否在 Polygon 内),别每次调用都 json::parse() 整个文件。应该一次解析后,把关键数据转成原生结构缓存:
- 用
std::vector<Feature>存所有要素,Feature含std::string id、json properties、Geometry geometry - 把
Polygon的外环点序列转成std::vector<std::pair<double,double>>,供后续射线法判断 - 若需快速空间查询,导出为
boost::geometry::model::polygon或用libspatialindex构建 R-tree
GeoJSON 文件可能达 MB 级,json::parse() 是纯 CPU 密集操作,反复调用会明显拖慢响应。解析和业务逻辑必须分层。

















