如何提取多位置商家数组的位置生成一维列表供useSupercluster使用?
提取商家多位置生成一维GeoJSON列表方案
问题背景
需要从包含单个或多个位置的商家列表中提取所有位置,生成一维的GeoJSON Feature列表,传入useSupercluster用于谷歌地图标记。当前用嵌套map得到的是嵌套数组,不符合需求。
原数据结构
{"count": 3,"next": null,"previous": null,"results": [{"id": 3,"name": "2 locations","absolute_url": "/2-locations/","image": "http://localhost:8000/uploads/IMG_0025_zNIdvu2.jpg","locations": [{"pk": 4,"Address": "Petržalka, Slovakia","latitude": "48.1108126915612","longitude": "17.111585515344235","hello": "hello"},{"pk": 5,"Address": "Ružinov, Slovakia","latitude": "48.1575967","longitude": "17.162797799999986","hello": "hello"}],"latitude": "48.1591643","longitude": "17.05184429999999","addressGmap": "Karlova Ves, Slovakia"},{"id": 2,"name": "test 2","absolute_url": "/test-2/","image": "http://localhost:8000/uploads/IMG_0020_sHsf4S8.jpg","locations": [{"pk": 2,"Address": "Svätý Jur, Slovakia","latitude": "48.25433740000002","longitude": "17.21190739999998","hello": "hello"}],"latitude": "48.2502","longitude": "17.2","addressGmap": "Svätý Jur, Slovakia"},{"id": 1,"name": "Flo Bratislava","absolute_url": "/flo-bratislava/","image": "http://localhost:8000/uploads/airplane-gdfcad3235_1280_rySWbtC.png","locations": [{"pk": 1,"Address": "Bratislava-Hrad, Slovakia","latitude": "48.144833000000006","longitude": "17.10037926931151","hello": "hello"}],"latitude": "48.3006","longitude": "17.11","addressGmap": "Bratislava-Hrad, Slovakia"}]}
现有问题代码
const points = activities.map(activity => ( activity.locations.map(location => ( { type: "Feature", properties: { cluster: false, id: activity.pk, business: activity.name }, geometry: {type: "Point", coordinates: [activity.longitude,activity.latitude]} } )) )
这段代码会返回嵌套数组,每个商家对应一个子数组,子数组包含该商家的所有位置Feature,不符合useSupercluster需要的一维列表要求。
解决方案
方法1:使用Array.flatMap()(推荐)
flatMap会先对数组元素执行map操作,再将结果扁平化(深度为1),直接生成一维数组:
const points = activities.flatMap(activity => activity.locations.map(location => ({ type: "Feature", properties: { cluster: false, // 注意:原数据中商家没有pk字段,用activity.id;如果要标记位置的唯一ID,用location.pk id: activity.id, business: activity.name, locationId: location.pk // 可选:添加位置自身的ID }, geometry: { type: "Point", // 注意:应该用location的经纬度,而非商家的默认经纬度 coordinates: [parseFloat(location.longitude), parseFloat(location.latitude)] } })) );
方法2:使用Array.reduce()
通过reduce累加数组,将每个商家的位置Feature数组合并到结果中:
const points = activities.reduce((acc, activity) => { const locationFeatures = activity.locations.map(location => ({ type: "Feature", properties: { cluster: false, id: activity.id, business: activity.name, locationId: location.pk }, geometry: { type: "Point", coordinates: [parseFloat(location.longitude), parseFloat(location.latitude)] } })); return acc.concat(locationFeatures); }, []);
关键修正点
- 扁平化数组:用
flatMap或reduce+concat替代嵌套map,避免生成嵌套结构。 - 经纬度来源:原代码错误使用了商家的默认经纬度,应改为对应位置的
location.longitude和location.latitude,同时注意将字符串转为数字(parseFloat)。 - ID字段修正:原数据中商家对象的唯一标识是
id而非pk,位置的唯一标识是location.pk,可根据需求选择使用。
内容的提问来源于stack exchange,提问作者user2068020
相关产品推荐
相关产品推荐

