GeoJSON是一种基于JSON的地理空间数据格式,FeatureCollection是其中用于聚合多个地理要素的核心类型,每个要素包含几何形状、属性信息等核心内容。在C++中解析这类数据,需要先明确GeoJSON的结构规范,再选择合适的解析方案实现数据提取。

GeoJSON FeatureCollection结构说明
标准的FeatureCollection结构由type字段和features数组组成,features数组中的每个元素是独立的Feature对象,每个Feature包含type、geometry、properties三个核心字段。geometry字段描述几何形状,包含type和coordinates;properties字段存储自定义属性键值对。示例如下:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [116.397428, 39.90923]
},
"properties": {
"name": "北京天安门",
"type": "地标"
}
}
]
}
解析方案选择
C++中解析JSON的常用库有nlohmann/json、RapidJSON等,其中nlohmann/json使用简单、接口友好,适合快速实现GeoJSON解析。本文选择nlohmann/json作为解析依赖,首先需要引入该库,可通过包管理器安装或下载头文件引入项目。
定义对应数据结构
为了方便存储解析后的地理数据,需要先定义对应的C++结构体,匹配GeoJSON的层级结构:
#include <string>
#include <vector>
#include <nlohmann/json.hpp>
using json = nlohmann::json;
// 几何结构基类
struct Geometry {
std::string type; // 几何类型:Point、LineString、Polygon等
virtual ~Geometry() = default;
};
// 点几何结构
struct PointGeometry : public Geometry {
std::vector<double> coordinates; // 坐标数组,格式为[经度, 纬度]
};
// Feature结构
struct Feature {
std::string type; // 固定为Feature
std::shared_ptr<Geometry> geometry; // 几何对象指针
json properties; // 属性信息,使用json存储灵活键值对
};
// FeatureCollection结构
struct FeatureCollection {
std::string type; // 固定为FeatureCollection
std::vector<Feature> features; // 要素数组
};
解析实现逻辑
解析过程需要按照GeoJSON的层级逐层提取数据,首先解析最外层的type和features数组,再遍历数组解析每个Feature的geometry和properties。
几何对象解析函数
根据geometry的type字段创建不同的几何对象实例,提取对应的坐标数据:
std::shared_ptr<Geometry> parseGeometry(const json& geomJson) {
std::string geomType = geomJson["type"];
if (geomType == "Point") {
auto point = std::make_shared<PointGeometry>();
point->type = geomType;
// 提取坐标数组
for (const auto& coord : geomJson["coordinates"]) {
point->coordinates.push_back(coord.get<double>());
}
return point;
}
// 可扩展其他几何类型:LineString、Polygon等
return nullptr;
}
Feature解析函数
解析单个Feature对象,关联几何和属性数据:
Feature parseFeature(const json& featureJson) {
Feature feature;
feature.type = featureJson["type"];
// 解析几何对象
feature.geometry = parseGeometry(featureJson["geometry"]);
// 提取属性信息
feature.properties = featureJson["properties"];
return feature;
}
FeatureCollection解析函数
解析最外层的FeatureCollection结构,整合所有要素:
FeatureCollection parseFeatureCollection(const std::string& jsonStr) {
FeatureCollection fc;
json j = json::parse(jsonStr);
fc.type = j["type"];
// 遍历features数组解析每个要素
for (const auto& featureItem : j["features"]) {
fc.features.push_back(parseFeature(featureItem));
}
return fc;
}
完整实战示例
以下是一个完整的调用示例,读取GeoJSON字符串并解析输出要素信息:
#include <iostream>
int main() {
// 示例GeoJSON字符串
std::string geoJsonStr = R"({
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [116.397428, 39.90923]
},
"properties": {
"name": "北京天安门",
"type": "地标"
}
},
{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [121.473701, 31.230416]
},
"properties": {
"name": "上海外滩",
"type": "景点"
}
}
]
})";
try {
FeatureCollection fc = parseFeatureCollection(geoJsonStr);
std::cout << "解析到的要素数量:" << fc.features.size() << std::endl;
for (const auto& feature : fc.features) {
std::cout << "要素类型:" << feature.type << std::endl;
if (feature.geometry->type == "Point") {
auto* point = dynamic_cast<PointGeometry*>(feature.geometry.get());
if (point) {
std::cout << "经度:" << point->coordinates[0]
<< ",纬度:" << point->coordinates[1] << std::endl;
}
}
// 输出属性信息
if (feature.properties.contains("name")) {
std::cout << "名称:" << feature.properties["name"] << std::endl;
}
}
} catch (const std::exception& e) {
std::cerr << "解析失败:" << e.what() << std::endl;
}
return 0;
}
注意事项
- 解析前需要校验JSON字符串的合法性,避免解析异常导致程序崩溃
- GeoJSON的坐标顺序为经度在前、纬度在后,与部分地图API的坐标顺序可能不同,需要注意转换
- 如果需要支持更多几何类型,可以在parseGeometry函数中扩展对应的解析逻辑
- 属性信息使用json类型存储,可根据实际需求转换为自定义的结构体,提升访问效率
C++GeoJSONFeatureCollectionJSON解析修改时间:2026-07-23 07:36:30