源码分析之Leaflet中的LayerGroup
概述
LayerGroup
是一个图层组,通过继承Layer
基类,提供了一种管理多个图层(如标记、多边形等)的容器机制,比如地图的添加/移除操作等。
源码分析
源码实现
LayerGroup
的源码实现如下:
export var LayerGroup = Layer.extend({initialize:function(layers,options){Util.setOptions(this,options);this._layers={};var i,len;if(layers){for(i=0,len=layers.length;i<len;i++){this.addLayer(layers[i])}}},addLayer:function(layer){var id= this.getLayerId(layer);this._layers[id]=layer;if(this._map){this._map.addLayer(layer)}return this;},removeLayer:function(layer){var id = layer in this._layers ? layer :this.getLayerId(layer);if(this._map && this._layers[id]){this._map.removeLayer(this._layers[id])}delete this._layers[id];return this;},hasLayer:function(layer){var layerId = typeof layer === 'number' ? layer:this.getLayerId(layer);return layerId in this._layers;},clearLayers:function(){return this.eachLayer(this.removeLayer,this)},invoke:function(methodName){var args = Array.prototype.slice.call(argument,1),i,layer;for(i in this._layers){layer =this._layers[i];if(layer[methodName]){layer[methodName].apply(layer,args);}}return this;},onAdd:function(map){this.eachLayer(map.addLayer,map)},onRemove:function(map){this.eachLayer(map.removeLayer,map)},eachLayer:function(method,context){for(var i in this._layers){method.call(context,this._layers[i])}return this;},getLayer:function(id){return this._layers[id]},getLayers:function(){var layers = [];this.eachLayer(layers.push,layers);return layers},setZIndex:function(zIndex){return this.invoke('setZIndex',zIndex)},getLayerId:function(layer){return Util.stamp(layer)},
})export var layerGroup=function(layers,options){return new LayerGroup(layers,options)
}
源码解析
1.类定义与继承
-
继承:
LayerGroup
继承自Layer
,意味着LayerGroup
具有Layer
的所有属性和方法,本身也是一个图层,但其主要职责是负责管理子图层。 -
工厂函数:
LayerGroup
函数提供了创建实例的快捷方式
2.初始化方法initialize
-
选项处理:
Util.setOptions
将options
合并到实例属性中。 -
图层存储:
_layers
是一个对象,以键值对形式存储子图层,键是图层ID
(通过Util.stamp
生成) -
初始图层添加:如果传入
layers
数组,则遍历并调用addLayer
逐个添加
3.核心方法解析
-
addLayer(layer)
:- 生成唯一ID:通过
getLayerId
(内部调用Util.stamp
)为图层生成唯一标识 - 存储图层:将图层存入
_layers
对象 - 自动添加到地图:如果当前
LayerGroup
已添加到地图,则子图层也会立即加入地图
- 生成唯一ID:通过
-
removeLayer(layer)
:- 查找图层:通过
getLayerId
查找图层 - 从地图移除:如果当前
LayerGroup
已添加到地图,则子图层也会立即从地图移除 - 删除存储:从
_layers
中删除图层
- 查找图层:通过
-
hasLayer(layer)
:- 查找图层:通过
getLayerId
查找图层 - 返回存在性:返回
true
或false
- 查找图层:通过
-
clearLayers()
:- 遍历移除:调用
eachLayer
遍历所有子图层,调用removeLayer
逐个移除
- 遍历移除:调用
4.批量操作
-
invoke(methodName, ...args)
:- 批量调用:遍历所有子图层,调用指定方法(如
setZIndex
),并传递参数 - 返回
this
:支持链式调用
- 批量调用:遍历所有子图层,调用指定方法(如
-
eachLayer(method,context)
:- 遍历执行:遍历所有子图层,执行指定方法,可传递上下文
5.地图生命周期钩子
onAdd(map)
与onRemove(map)
- 自动代理子图层:当
LayerGroup
添加到地图时,会自动调用子图层的addLayer
方法,移除时调用removeLayer
方法
- 自动代理子图层:当
6.辅助方法
-
getLayer(id)
与getLayers()
- 按ID获取图层:直接通过ID查找
- 获取全部图层数组:利用
eachLayer
将对象形式的图层转换为数组
-
setZIndex(zIndex)
- 批量设置ZIndex:调用
invoke
批量设置子图层的ZIndex
- 批量设置ZIndex:调用
7.工具方法getLayerId
- 生成唯一ID:内部调用
Util.stamp
,确保每个图层都有唯一的ID
设计思想
1.组合模式:LayerGroup
本身是Layer
,同时管理多个子图层,形成树形结构
2.代理机制:通过重写onAdd
/onRemove
,自动管理子图层的地图添加/移除
3.批量操作:提供invoke
和eachLayer
实现高效批量控制
4.ID管理:利用Util.stamp
确保图层唯一标识,避免冲突
总结
LayerGroup
的核心就是维护一个图层集合,并代理这些图层的方法调用,通过组合模式,可以方便批量操作多个图层,提升代码复用性和易用性。