最近在项目使用百度地图做了一版地图可视化页面,需要开发落点聚合的功能。点聚合可以用百度地图MapVGL可视化库,但是这个样式实在太丑了,不符合需求,只好用回之前百度地图 JavaScript API3.0的点聚合插件,因为不支持bmapgl版本,所以需要做一些适配。传送门:百度地图开源库
一、先下载对应的两个源码文件TextIconOverlay和MarkerClusterer,引入项目中。下载的是不经过丑化的js文件,因为后续还需要改源码;
二、进行关键字替换,将BMap替换为BMapGL,而且必须是全字替换;
三、接着就可以使用最简单的调用示例进行调试调用。官网参考示例:https://lbsyun.baidu.com/index.php?title=jspopular3.0/guide/conflux 。 但是会出现一个问题,就是虽然能使用点聚合功能,但是在拖拽地图的时候,聚合点会自动消失,拖拽结束后才会出现,解决办法:将TextIconOverlay中的对应位置的markerMouseTarget改成markerPane,改变点聚合自定义覆盖物所在的地图容器。
当然了,本质上是地图事件监听问题,上面的问题也可以采取另一种解决方案,不过麻烦一点。可以参考这篇:https://www.jianshu.com/p/302e2803517a 。
四、本以为这里就结束了,但是我发现JS API3.0的聚合示例是可以点击聚合点进行点扩散的,用在bmapgl版本就失效了,甚至在技术网站找不到解决方案,只好自己看看源码,看到了MarkerClusterer文件里的这一段代码:
很明显是setViewport失效了,导致点聚合点击无法扩散。打印下这个thatBounds,再查下API就找到了原因:因为JS API3.0的setViewport接收的是Bounds实例,但是在百度地图WebGL版本,setViewport接收的是Point类型的数组,导致setViewport失效。那就好办了,在源码把Bounds实例转换成Point类型的数组就可以解决。
1 | const points = Object.values(thatBounds); |
改完后查看效果,点击聚合点确实可以进行扩散。但是还没完。。。因为当聚合点很多的时候,点击分散效果会变得很卡,甚至浏览器直接卡死……只好继续排查原因,最后发现原来是click事件会触发很多次,差不多就明白了,有多少点聚合在一起,就会额外触发对应的次数。有100个点聚合在一起,click就触发了100次,加上WebGL版本的setViewport性能比JSAPI版本要差,使得卡顿变得更加明显。解决方法:使用了lodash的节流函数throttle,使得虽然click触发了多次,但是setViewport只执行一次,最终解决卡顿问题!
1 | // MarkerClusterer.js |
1 | // 页面文件中 |
之所以要使用自定义事件将setViewport放在页面文件中执行,是应对以后需求大佬需要基于这个点击做一些额外的操作,我就先这么做吧,毕竟惊喜无处不在。