JavaScript中按属性值分组GeoJSON features的实现方法
GeoJSON按ASSETID分组归集实现方案
不需要引入jQuery或其他第三方工具库,原生JavaScript即可实现需求,也不需要写冗余的多层for循环,核心逻辑是按ASSETID做单次遍历分组,时间复杂度为O(n),性能表现稳定。
实现思路
- 以
ASSETID为分组键建立映射表,映射表的每个值对应最终输出的单个feature - 单次遍历原始features数组:
- 若当前
ASSETID未在映射表中存在记录,就初始化对应feature,geometry取当前要素的几何信息(同ASSETID的要素几何在你的场景中是一致的,直接取首次匹配到的即可),properties初始化为空数组 - 若当前
ASSETID已存在记录,直接将当前要素的properties追加到对应feature的properties数组中
- 若当前
- 遍历完成后,将映射表中存储的所有feature取出,和原FeatureCollection的基础属性(type、title等)组装,就是最终需要的结果
注意:你给出的预期输出示例存在笔误,ASSETID为200的feature坐标错误写成了100对应的坐标,且properties数组中混入了ASSETID为100的属性,实际处理后200对应的properties只会归集自身的两条属性,坐标为
[525177, 164509]。
实现代码
/** * 按ASSETID分组归集GeoJSON要素 * @param {Object} originalGeoJSON 原始GeoJSON FeatureCollection * @returns {Object} 处理后的GeoJSON */ function groupGeoJSONByAssetId(originalGeoJSON) { const assetGroupMap = {}; for (const feature of originalGeoJSON.features) { const assetId = feature.properties.ASSETID; // 初始化新资产分组 if (!assetGroupMap[assetId]) { assetGroupMap[assetId] = { type: "Feature", geometry: feature.geometry, properties: [] }; } // 归集当前属性,深拷贝避免污染原始数据 assetGroupMap[assetId].properties.push(structuredClone(feature.properties)); } return { type: originalGeoJSON.type, title: originalGeoJSON.title, features: Object.values(assetGroupMap) }; } // 调用示例:传入原始GeoJSON对象即可得到处理结果 const processedResult = groupGeoJSONByAssetId(yourOriginalGeoJSONData);
补充说明
- 如果不需要做数据隔离,避免后续修改处理结果影响原始数据,可以去掉
structuredClone,直接push原始properties对象即可 - 如果业务场景中存在同ASSETID但geometry不一致的情况,可以在初始化分组时增加几何一致性校验,或者根据需求做几何合并、取最新几何等调整
- 如果更习惯函数式写法,也可以用
Array.reduce替代for...of循环实现同样的分组逻辑,核心处理逻辑和上述代码完全一致
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

