function getDistance(lat1, lon1, lat2, lon2) {
const R = 6371; // 地球半径,单位为千米
const dLat = ((lat2 - lat1) * Math.PI) / 180;
const dLon = ((lon2 - lon1) * Math.PI) / 180;
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos((lat1 * Math.PI) / 180) *
Math.cos((lat2 * Math.PI) / 180) *
Math.sin(dLon / 2) *
Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}
function aggregateMarkers(markers, distanceThreshold, maxCount) {
const aggregatedMarkers = [];
while (markers.length > 0) {
const marker = markers.shift();
const cluster = [marker];
for (let i = 0; i < markers.length; i++) {
const distance = getDistance(
marker.latitude,
marker.longitude,
markers[i].latitude,
markers[i].longitude
);
if (distance < distanceThreshold) {
cluster.push(markers.splice(i, 1)[0]);
i--;
}
}
if (cluster.length > maxCount) {
// 如果聚合后的标记点数量超过上限,可以进一步进行聚合或者采用其他方式显示
// 这里可以递归调用 aggregateMarkers 函数进行进一步聚合
const subClusters = aggregateMarkers(cluster, distanceThreshold, maxCount);
aggregatedMarkers.push(...subClusters);
} else {
// 计算聚合点的坐标,可以使用平均坐标或者其他方法
const latSum = cluster.reduce((sum, m) => sum + m.latitude, 0);
const lonSum = cluster.reduce((sum, m) => sum + m.longitude, 0);
const averageLat = latSum / cluster.length;
const averageLon = lonSum / cluster.length;
aggregatedMarkers.push({
latitude: averageLat,
longitude: averageLon,
count: cluster.length,
});
}
}
return aggregatedMarkers;
}
export default {
data() {
return {
markers: [],
};
},
onLoad() {
// 假设 markers 数组已经有初始的标记点数据
this.markers = aggregateMarkers(this.markers, 50, 50);
},
};
{
latitude: averageLat,
longitude: averageLon,
count: cluster.length,
iconPath: 'path/to/aggregated_icon.png',
callout: {
content: `聚合点,包含 ${cluster.length} 个标记点`,
display: 'ALWAYS',
},
}
通过以上步骤,就可以在 UniApp 中实现点位聚合,提高地图的性能和可读性。需要根据实际情况调整聚合条件和显示样式,以满足不同的需求。
希望本文对你有所帮助!如果你有任何问题或建议,欢迎在评论区留言。
关注我看更多有意思的文章哦!