在百度地图中绘制多边形覆盖物可以使用jsapi的BMapGL.Polygon,随着项目投入使用,绘制的多边形越来越多,导致页面卡顿明显,项目经理直呼受不了。于是我加了一天班,用MapVGL的mapvgl.PolygonLayer替换了BMapGL.Polygon,页面不再卡顿,操作上舒适了很多,但是又诞生了新的问题:因为地图的标注点还是采用BMapGL的BMapGL.Marker进行渲染,导致 PolygonLayer图层直接覆盖在标注点之上。
最初想的解决方案是,地图标注点也更换为MapVGL的渲染方式(即IconLayer),但试验后发现IconLayer生成的标注点大小随着屏幕分辨率的大小而改变,并不符合业务需要,更何况标注点还集成了点波纹、数字形式的label角标、popup形式的label、鼠标聚焦效果等,更换为MapVGL渲染意味着很多功能需要推翻重来,会耗费很多的时间精力。
一筹莫展。直到再次查看MapVGL文档时,我才发现了个好消息。MapVGL的图层可以和百度地图底图融合,这样一来可以解决PolygonLayer在标注点之上的问题了。但也有坏消息,如图。
![7](/img/7.jpg)
“慎用”说了两次,说明情况确实不简单,网上甚至找不到这类解决方案,我只好自己踩坑。于是有了这篇博客。
一、可以把融合步骤与添加图层分离
经过测试,添加图层操作并不是异步的,只是融合函数异步,所以我把这两步操作分离
1 | // 将mapvgl的canvas容器与地图底图融合,解决对应PolygonLayer覆盖在marker上的问题(较慢,异步执行) |
二、添加对应的PolygonLayer
有了融合图层容器mapViewFusion,可以使用addLayer添加图层
1 | let layer = new mapvgl.PolygonLayer({ |
三、添加PolygonLayer后,地图底图会消失
在进行第2步之后,地图底图会莫名奇妙消失,使用鼠标滚轮缩放地图后,地图底图恢复。解决方案:添加PolygonLayer后,马上执行地图zoom缩放。
1.定义缩放函数,对zoom先加0.001,再减0.001。
1 | // 切换zoom尝试刷新地图画布,消除mapvgl底图融合的影响 |
2.添加PolygonLayer图层后,调用tryRefreshMap函数。
完整代码
1 | let layer = new mapvgl.PolygonLayer({ |
四、并不是所有图层都适合添加到mapViewFusion
在没有融合图层容器之前,我已经使用了普通的MapVGL容器:
1 | // 初始化MapVGL容器:mapView |
有了mapViewFusion后,我自然而然想到要把mapView里的图层都添加到mapViewFusion,mapView容器就可以删除掉,方便图层管理。但是,并不是所有图层都适合添加到融合图层容器,比如说波纹点图层RippleLayer,添加到mapViewFusion后,波纹失去了动画效果,只有在地图缩放过程才会有波纹动画;热力点图层HeatPointLayer也是一样,只有在地图缩放过程才会渲染……
所以,这类图层只能按照原来的方案,添加到普通的MapVGL容器。因此,地图需要两个MapVGL容器,一个是普通图层容器mapView,一个是融合图层容器mapViewFusion。PolygonLayer适合添加到mapViewFusion容器,而RippleLayer,HeatPointLayer适合添加到mapView容器。
五、融合图层容器会影响普通图层容器的渲染
在调试过程中,总会发现波纹点图层RippleLayer虽然添加到普通图层容器,也具备正常的动画效果,但在某些情况下会再次停止动画。测试后发现,是因为地图大小改变,波纹动画失效。之前不会有这个问题,所以考虑是受到融合图层容器的影响。
解决方案:地图大小改变后,销毁并重新创建mapView容器
1 | // 受mapvgl底图融合影响,必须在渲染波纹前销毁并重新创建mapvgl容器 |
六、在某些情况下,添加到融合容器的PolygonLayer也会出现问题
最近对PolygonLayer增加鼠标拾取的效果,用鼠标拾取多边形时,地图底图又失效了……目前的解决方案是需要拾取的时候,添加到mapView容器;不需要拾取时,再添加到mapViewFusion容器。