前言
地图标注是一个较为复杂的课题,此中技术难点可单独成文,本文暂不过多叙述,单说图层如何实现某个字段的自动标注。同时适用图层以点图层为主,线和面如果以Path的中心点为标注点也可参考(如何找寻面状要素的标注点是一技术难点,因为很多情况会导致标注点在面状要素外部,比如环等等),另本文适用于图层要素较多,存在标注叠盖冲突的情况。Leaflet的插件Leaflet.tooltip(原Leaflet.label),这个插件用来做标注,适合在图层要素较少的情况,这跟它的实现方式有关,它主要通过添加absolute的div来实现,所以当标注较多时,DOM元素也会随之增长,类似SVG。所以这个插件改名为Leaflet.tooltip是非常贴切的,Label是Label,tooltip是tooltip,popup是popup,不能混用,将tooltip设置为永久显示就变为标注只适用于特殊场合。
实现效果隐去了高德底图,避免不必要的麻烦。
图层数据量为10000-20000之间,运行流畅,处理了标注叠盖,如果不处理叠盖,将10000多个标注同时显示,运行也非常流畅,原因是用Canvas直接渲染,而非添加div或添加svg要素(5000个要素,就会让浏览器非常卡)。
实现思路
1.首先最重要的,渲染方式选择Canvas的fillText,具体原因上面已提,添加div或添加svg要素的方式优点在于方便交互,但无法胜任标注数量较多的情况。
2.继承Leaflet的Canvas(Renderer),原因是,Canvas Renderer已完成Canvas Container的创建和销毁(_initContainer和_destroyContainer),实现了当视图漫游缩放时响应更新(_update、_redraw和_draw),这些逻辑大部分可重用,无需重载,即使重载,也需要调用基类的逻辑。故继承,可省却大量逻辑。
3.标注是附属在空间要素上的,所以标注点的位置无需在响应Canvas视图的漫游缩放再进行transform。这点非常重要,标注的逻辑放在要素更新之后,即此时要素的空间坐标已完成transform。
4.如需处理标注重叠,可以通过记录当前已绘制标注的数组,对即将要绘制的标注进行bounds的intersect判断。参考,Leaflet的plugins页面给出的参考是该插件可重点看下源码实现,大致思路是想通的,但它的实现加入了一些不必要的元素,另外它的扩展性也有待加强。本文将在此基础上进行优化。
插件源码
本文需要对照源码进行阅读。
源码对应示例暂未上线,后期再补充,将会更新到Green GIS Manager托管示例。
源码解析
1.非核心代码,先可放一边,不影响整体逻辑。
a. 函数identify和事件响应