如何聚合地图上的点
可以实时响应的算法
主要内容
- 调研过程
- 解决方案
- 算法分析
- 有趣的知识点
问题背景
在上一个分享中提到了若干种算法:
- kmeans & kmeans++:凸状数据?几个簇?
- dbscan:r 半径内有 m 各点,这两个值?
- optics:可靠的簇结构实现算法在哪里?
- density-peak:关键的点语焉不详。
另外,这些算法都不能保证『实时响应』
需要探索新的解决方案。
进一步探索
前端:
-
Leaflet.markercluster,leaflet 插件,效果华丽
-
PruneCluster,leaflet 插件,宣称性能更好,代码更精简
- GMap.markerclusterer & BMap.markerclusterer,coc 定律
-
kartograph,一个矢量地图库
后端:
- android-maps-utils,android 地图 sdk 源码
- geocluster-facet,elasticsearch 插件,开源解决方案
- maptimize,elasticsearch 插件,商业解决方案
算法概览
- server-side-clustering-of-geo-points-on-a-map-using-elasticsearch,讲述服务端解决方案,实现形式是 elasticsearch 插件,核心算法是 geohash。
- Too Many Markers!,一篇综述,描述问题并给出探索方案。
-
Let’s Keep Symbol Maps Clean And Tidy,通过合并并改变覆盖物样式来优化显示,给出了新的思路和公式。
算法实现
def add_to_closest_cluster(self, marker): distance = float('inf') # Some large number cluster_to_add_to = None pos = marker.get_latlng() for cluster in self.clusters: center = cluster.get_center() if center: d = get_distance(center.lat, center.lng, pos.lat, pos.lng) if d < distance: distance = d cluster_to_add_to = cluster if cluster_to_add_to and cluster_to_add_to.overlaps(marker): #print 'in bounds' cluster_to_add_to.add_marker(marker) else: #print 'new cluster' cluster = Cluster(self) cluster.add_marker(marker) self.clusters.append(cluster)
效果展示


广告时间
Life is short, you need Python -- Bruce Eckel
如何聚合地图上的点
something interesting - 1

感谢伟大的 github,这个问题算是有解的:无 API、纠偏数据库的依赖,精度可设置火星坐标 <-> GPS 坐标(二分法解决不可逆)https://github.com/googollee/eviltransform百度坐标 <-> 火星坐标(可逆加密算法)http://blog.csdn.net/coolypf/article/details/8569813
something interesting - 2
凸包是表达平面点集形式之一
凸包结果唯一,但是不能表达精确形状
『凹包』不唯一,但可根据参数选择较为精确的结果

gotcha
- web map 原理
- 墨卡托投影
- 火星坐标,地图产品坐标
- 计算几何知识:三角剖分,『凹包』
- python 科学计算、计算几何库的使用
- 进一步学习了数据可视化
next steps ...
地图产品上对用户产生有用的交互效果
离线数据可运营,可产生指导意义
性能再优化,探索不区分城市的『海量数据』方案
Questions ?
Thank you !
point-cluster-algorithms-in-map-2
By songchao
point-cluster-algorithms-in-map-2
如何聚合地图上的点(实时)
- 940