Layer Base Class
Purpose and Scope
本文档描述了 Layer 基类,它为 Leaflet 中的所有 Layer 类型提供了基础架构。Layer Class 定义了 Layer 必须遵循的生命周期契约,管理 Layer-Map 关系,处理用于 z-order 的 Pane 分配,并与事件系统集成。
关于特定 Layer 实现(瓦片、Marker、Vector)的信息,请参阅 Tile Layers and Grid System、Markers and Icons 和 Vector Layers。关于 Layer 集合的信息,请参阅 Layer Groups and Feature Groups。
Class Overview
Layer Class 作为 Leaflet 中所有 Layer 的抽象基类。它扩展了 Evented 以提供事件功能,并定义了所有 Layer 实现必须遵循的契约。
Class Hierarchy
Sources: src/layer/Layer.js1-29
Default Options
Layer Class 定义了所有 Layer 继承的三个默认选项:
| Option | Type | Default | Description |
|---|---|---|---|
pane | String | 'overlayPane' | Layer 将被渲染到的 Map Pane 名称 |
attribution | String | null | 显示在 Attribution Control 中的 Attribution 文本 |
bubblingPointerEvents | Boolean | true | 指针事件是否应该冒泡到 Map |
Sources: src/layer/Layer.js31-45
Lifecycle Management
Layer 遵循定义良好的生命周期,协调它们被添加到 Map 和从 Map 中移除的过程。此生命周期确保正确的初始化、清理和事件处理。
Lifecycle Flow Diagram
Extension Methods
子类必须实现以下方法以正确参与 Layer 生命周期:
onAdd(map)
Purpose: 创建 Layer 的 DOM 元素并将它们添加到适当的 Map Pane。当 Layer 被添加到 Map 且 Map 就绪时调用此方法。
Responsibilities:
- 为 Layer 创建 DOM 元素
- 使用
getPane()将元素添加到 Map Pane - 将事件监听器附加到 Map 事件
- 执行任何需要 Map 就绪的初始化
onRemove(map)
Purpose: 清理 Layer 的 DOM 元素并移除事件监听器。当 Layer 从 Map 中移除时调用此方法。
Responsibilities:
- 从 Pane 中移除 DOM 元素
- 分离事件监听器
- 清理在
onAdd()中分配的任何资源
getEvents() (Optional)
Purpose: 返回一个将 Map 事件名称映射到处理器方法的对象。Layer System 自动管理添加和移除这些监听器。
Return value: 类似 { viewreset: this._reset, move: this._update } 的对象
beforeAdd(map) (Optional)
Purpose: 在 Layer 被添加到 Map 之前调用,在事件初始化之前,且不等待 Map 就绪。用于早期初始化。
Internal Lifecycle Coordination
当 Map 变为就绪状态时,_layerAdd 方法协调 Layer 的生命周期:
Public API
Layer Class 提供了几个用于添加、移除和查询 Layer 的方法。
Layer Management Methods
| Method | Parameters | Returns | Description |
|---|---|---|---|
addTo(map) | map: LeafletMap 或 LayerGroup | this | 将 Layer 添加到给定的 Map 或 LayerGroup |
remove() | None | this | 从其当前活动的 Map 中移除 Layer |
removeFrom(obj) | obj: LeafletMap 或 LayerGroup | this | 从给定的 Map 或 LayerGroup 中移除 Layer |
addTo Method
addTo 方法是用户将 Layer 添加到 Map 的主要方式:
Implementation: 该方法简单地委托给 map.addLayer(this) 并返回 this 以启用方法链式调用。
remove Method
remove 方法从其当前 Map 中移除 Layer:
Implementation detail: 它调用 removeFrom(this._map || this._mapToAdd),如果 Layer 已被添加但 Map 尚未就绪,则使用 _mapToAdd 作为回退。
Utility Methods
| Method | Parameters | Returns | Description |
|---|---|---|---|
getPane(name) | name: String (optional) | HTMLElement | 返回 Pane 元素;如果省略名称,返回 Layer 的默认 Pane |
getAttribution() | None | String | 返回此 Layer 的 Attribution 文本 |
addInteractiveTarget(targetEl) | targetEl: HTMLElement | this | 将元素注册为交互目标 |
removeInteractiveTarget(targetEl) | targetEl: HTMLElement | this | 注销交互目标 |
Pane System
Leaflet 使用 Pane System 来管理 Layer 的 z-order。每个 Layer 被渲染到特定的 HTML Pane 中,这决定了它相对于其他 Layer 的堆叠顺序。
Pane Resolution
getPane 方法灵活地解析 Pane 引用:
Example usage:
layer.getPane()- 返回 Layer 的默认 Pane(通常是'overlayPane')layer.getPane('shadowPane')- 如果设置了layer.options.shadowPane,则返回shadowPane,否则直接查找'shadowPane'
Common Pane Names
虽然 Layer Class 默认为 'overlayPane',但不同的 Layer 类型使用不同的 Pane:
| Pane Name | Typical Usage | Default z-index |
|---|---|---|
mapPane | 所有其他 Pane 的容器 | auto |
tilePane | Tile Layer(GridLayer, TileLayer) | 200 |
overlayPane | Vector Shapes, Image Overlays | 400 |
shadowPane | Marker Shadows | 500 |
markerPane | Marker Icons | 600 |
tooltipPane | Tooltips | 650 |
popupPane | Popups | 700 |
Attribution System
Attribution System 允许 Layer 声明版权和数据源信息,这些信息显示在 Attribution Control 中。
Attribution Flow
Implementation
getAttribution 方法简单地返回 attribution 选项:
getAttribution() {
return this.options.attribution;
}Usage example:
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
});Interactive Targets
交互目标系统允许 Layer 注册在被点击或交互时应该触发 Layer 事件的 DOM 元素。
Target Registration
Methods
addInteractiveTarget(targetEl): 通过以下方式将 DOM 元素注册为交互目标:
- 使用
Util.stamp()为元素标记唯一 ID - 在
map._targets[id]中存储 Layer 引用
removeInteractiveTarget(targetEl): 通过从 map._targets 中删除其条目来注销交互目标。
Use case: Vector Layer 使用此功能注册其 SVG/Canvas 元素,以便对这些元素的点击触发 Layer 上的事件。
Event Integration
Layer Class 通过继承自 Evented 和与 Map 生命周期的协调,与 Leaflet 的事件系统集成。
Layer Events
| Event | Fired When | Event Data |
|---|---|---|
add | Layer 被添加到 Map(在 onAdd 之后) | Generic Event |
remove | Layer 从 Map 中移除(在 onRemove 之后) | Generic Event |
Event Registration Pattern
Layer 可以使用 getEvents 方法自动注册和注销事件处理器:
Benefit: 此模式确保当 Layer 被移除时自动清理事件监听器,防止内存泄漏。
Map Integration
Layer Class 通过扩展方法和 Layer Registry 与 LeafletMap Class 紧密集成。
Map Layer Registry
Map 在 _layers 中维护所有活动 Layer 的注册表:
Map Methods for Layer Management
Layer.js 文件使用管理 Layer 的方法扩展了 LeafletMap:
| Method | Description |
|---|---|
addLayer(layer) | 验证 Layer,分配唯一 ID,存储在注册表中,触发生命周期 |
removeLayer(layer) | 调用 onRemove,从注册表中移除,触发事件 |
hasLayer(layer) | 检查 Layer 是否在注册表中 |
eachLayer(fn, context) | 遍历所有注册的 Layer |
addLayer Implementation Details
Map 上的 addLayer 方法执行几个重要步骤:
- Validation: 确保对象具有
_layerAdd方法 - Deduplication: 使用
Util.stamp()检查 Layer 是否已添加 - Early storage: 在 Map 就绪之前将 Layer 存储在
_mapToAdd中 - beforeAdd hook: 如果存在,调用可选的
beforeAdd(map) - Deferred initialization: 使用
whenReady()将_layerAdd延迟到 Map 就绪
Zoom Level Coordination
Map 跟踪定义 Zoom 限制的 Layer 以协调 Map 的有效 Zoom 范围:
Layer Event Propagation to Map
当 Layer 被添加或移除时,Layer 和 Map 都会触发事件:
| Action | Layer Event | Map Event | Event Data |
|---|---|---|---|
| Layer added | layer.fire('add') | map.fire('layeradd', {layer}) | {layer: Layer} |
| Layer removed | layer.fire('remove') | map.fire('layerremove', {layer}) | {layer: Layer} |
Comparison with Control
虽然 Layer 和 Control 都代表可以添加到 Map 的对象,但它们服务于不同的目的:
| Aspect | Layer | Control |
|---|---|---|
| Purpose | 显示地理数据 | 提供 UI 控件 |
| Base class | Extends Evented | Extends Class |
| Positioning | 地理定位 | 在角落容器中定位 |
| Lifecycle methods | onAdd, onRemove, beforeAdd, getEvents | onAdd, onRemove |
| Container | 渲染到 Map Pane | 渲染到 Control 角落 |
| Event integration | 通过 getEvents 的完整事件系统 | 手动事件处理 |
| Examples | TileLayer, Marker, Polygon | Zoom Control, Attribution Control |
Code Entity Reference
Key Classes and Files
| Entity | File | Purpose |
|---|---|---|
Layer | src/layer/Layer.js29-117 | 所有 Layer 的基类 |
LeafletMap.addLayer | src/layer/Layer.js155-173 | 将 Layer 添加到 Map |
LeafletMap.removeLayer | src/layer/Layer.js177-196 | 从 Map 中移除 Layer |
LeafletMap.hasLayer | src/layer/Layer.js200-202 | 检查 Layer 是否在 Map 上 |
LeafletMap.eachLayer | src/layer/Layer.js212-217 | 遍历 Layer |
Key Properties
| Property | Location | Type | Purpose |
|---|---|---|---|
_map | Layer instance | LeafletMap | 对父 Map 的引用 |
_mapToAdd | Layer instance | LeafletMap | 早期初始化期间的临时引用 |
_zoomAnimated | Layer instance | Boolean | Layer 是否参与 Zoom 动画 |
_layers | Map instance | Object | 按 stamp ID 的所有 Layer 注册表 |
_zoomBoundLayers | Map instance | Object | 具有 Zoom 约束的 Layer |
_targets | Map instance | Object | 用于事件路由的元素 ID 到 Layer 的映射 |