矢量图层
矢量图层提供 Leaflet 在地图上绘制几何图形的系统。矢量图层系统由形状类(Path、Polyline、Polygon、Circle、CircleMarker、Rectangle)、渲染后端(Canvas、SVG)和几何处理工具组成。
本页提供矢量图层架构的概览以及组件如何协同工作。关于各个矢量形状的详细信息,请参阅 3.4.1 页(矢量图形)。关于渲染器实现详情和绘制策略,请参阅 3.4.2 页(矢量渲染系统)。关于基于瓦片的栅格图层,请参阅 3.2 页。关于带图标的点标记,请参阅 3.3 页。
矢量图层架构
矢量图层系统围绕 Path 作为所有矢量形状的基类的层次类结构构建。架构通过 Renderer 抽象将几何定义与渲染实现分离。
矢量图层类层次结构
关键架构组件
| 组件 | 文件 | 用途 |
|---|---|---|
Path | src/layer/vector/Path.js12 | 抽象基类,提供通用样式和渲染器集成 |
Renderer | src/layer/vector/Renderer.js26 | 渲染后端的抽象基类,扩展 BlanketOverlay |
Canvas | src/layer/vector/Canvas.js35 | 使用 <canvas> 元素的即时模式渲染器 |
SVG | src/layer/vector/SVG.js35 | 使用 SVG DOM 元素的保留模式渲染器 |
每个矢量图层定义其几何和样式选项,而渲染器处理坐标转换、裁剪和实际的绘制操作。这种分离允许相同的矢量图层使用不同的后端进行渲染。
Path 基类
Path 类 (src/layer/vector/Path.js12) 作为所有矢量覆盖物的抽象基类。它扩展 Layer 并提供通用样式选项、渲染器协调和生命周期管理。
Path 选项
| 选项 | 类型 | 默认值 | 描述 |
|---|---|---|---|
stroke | Boolean | true | 是否沿路径绘制描边 |
color | String | '#3388ff' | 描边颜色 |
weight | Number | 3 | 描边宽度(像素) |
opacity | Number | 1.0 | 描边不透明度 |
lineCap | String | 'round' | 描边末端的形状 |
lineJoin | String | 'round' | 描边拐角处的形状 |
dashArray | String | null | 描边虚线模式 |
dashOffset | String | null | 虚线模式中开始绘制前的距离 |
fill | Boolean | false | 是否用颜色填充路径 |
fillColor | String | null | 填充颜色(默认为 color) |
fillOpacity | Number | 0.2 | 填充不透明度 |
fillRule | String | 'evenodd' | 如何确定形状内部 |
interactive | Boolean | true | 路径是否响应指针事件 |
bubblingPointerEvents | Boolean | true | 事件是否冒泡到地图 |
Path 生命周期和渲染器协调
Path 类通过定义良好的生命周期与渲染器协调:
Path-渲染器交互生命周期
生命周期中的关键方法:
| 方法 | 位置 | 用途 |
|---|---|---|
beforeAdd() | src/layer/vector/Path.js78-82 | 通过 map.getRenderer(this) 从地图获取渲染器 |
onAdd() | src/layer/vector/Path.js84-88 | 使用渲染器初始化路径并触发绘制 |
onRemove() | src/layer/vector/Path.js90-92 | 从渲染器中移除路径 |
_reset() | src/layer/vector/Path.js134-138 | 投影坐标并更新可视化 |
_clickTolerance() | src/layer/vector/Path.js140-144 | 返回点击检测容差(像素) |
矢量形状类型概览
Leaflet 提供五个具体的矢量形状类。每个都扩展 Path 并添加特定于形状的几何处理。
| 形状类 | 文件 | 扩展 | 用途 |
|---|---|---|---|
Polyline | src/layer/vector/Polyline.js51 | Path | 连接的线段,支持多线 |
Polygon | src/layer/vector/Polygon.js54 | Polyline | 带孔洞支持的闭合填充形状 |
Rectangle | src/layer/vector/Rectangle.js30 | Polygon | 轴对齐的矩形边界 |
CircleMarker | src/layer/vector/CircleMarker.js16 | Path | 固定像素半径的圆 |
Circle | src/layer/vector/Circle.js25 | CircleMarker | 地理半径(米) |
矢量形状处理管道
形状处理步骤
每个矢量形状遵循以下通用处理管道:
- 坐标转换 - 将输入数组规范化为
LatLng实例 - 投影 - 使用地图 CRS 将地理坐标转换为像素坐标
- 裁剪 - 移除视口边界外的部分以提高性能
- 简化 - 使用 Douglas-Peucker 算法减少点数(折线/多边形)
- 渲染 - 委托给渲染器的
_updatePoly()或_updateCircle()
smoothFactor 选项(默认:1.0)控制简化的激进程度。较高的值提高性能但降低精度。
关于每个形状类的 API 和几何处理的详细信息,请参阅 3.4.1 页(矢量图形)。
渲染系统集成
矢量图层将所有绘制操作委托给 Renderer 实现。地图基于浏览器能力自动选择渲染器,或者开发者可以显式指定一个。
渲染器选择流程
渲染器比较
| 特性 | Canvas | SVG |
|---|---|---|
| 绘制模式 | 即时模式(所有图层到一个 canvas) | 保留模式(每个图层一个 DOM 元素) |
| 性能 | 大量图层(100+)时更好 | 少量交互图层时更好 |
| 点击检测 | 通过 _containsPoint() 手动检测 | 原生浏览器事件 |
| 内存使用 | 低(单个 canvas 缓冲区) | 较高(每个图层的 DOM 节点) |
| CSS 样式 | 不适用 | 通过 className 选项支持 |
| DOM 集成 | 最小化 | 完整的 DOM 树 |
| 实现 | src/layer/vector/Canvas.js35 | src/layer/vector/SVG.js35 |
渲染器接口方法
两个渲染器都实现了这些 Path 调用的关键方法:
| 方法 | 用途 | Canvas 实现 | SVG 实现 |
|---|---|---|---|
_initPath(layer) | 初始化图层结构 | 创建设绘制顺序节点 | 创建 <path> 元素 |
_addPath(layer) | 注册进行渲染 | 链接到绘制列表 | 追加到 SVG 容器 |
_removePath(layer) | 取消注册图层 | 从绘制列表取消链接 | 从 DOM 移除 |
_updatePath(layer) | 重绘几何 | 触发重绘请求 | 更新路径 d 属性 |
_updateStyle(layer) | 应用样式更改 | 触发重绘 | 更新 SVG 属性 |
_updatePoly(layer, closed) | 渲染折线/多边形 | 绘制到 2D 上下文 | 生成路径字符串 |
_updateCircle(layer) | 渲染圆形 | 绘制弧线到上下文 | 生成弧线路径 |
关于渲染器实现、绘制顺序管理和点击检测策略的详细信息,请参阅 3.4.2 页(矢量渲染系统)。
坐标系和投影流程
矢量图层在渲染期间使用多个坐标系。理解这个流程对于性能优化和正确定位至关重要。
坐标转换管道
坐标系
| 系统 | 类型 | 原点 | 用途 |
|---|---|---|---|
| LatLng | 地理 | 赤道/本初子午线 | 来自用户的输入坐标 |
| Layer Point | 像素 | 地图像素原点(缩放相关) | 内部几何计算 |
| Container Point | 像素 | 地图容器的左上角 | DOM 定位(pane、覆盖层) |
每个形状类中的 _project() 方法使用地图的 CRS(坐标参考系统)将地理坐标转换为图层点。然后渲染器使用这些图层点进行绘制。
投影实现示例:
// 来自 Polyline._projectLatlngs()
const ring = latlngs.map(latlng => this._map.latLngToLayerPoint(latlng));样式和交互
矢量图层通过路径选项系统和事件处理集成支持动态样式和用户交互。
动态样式
setStyle() 方法允许运行时样式更改:
layer.setStyle({
color: 'red',
weight: 5,
opacity: 0.8
});样式更新触发特定于渲染器的更新方法,这些方法有效地应用视觉更改而无需重新创建几何数据。
图层排序
矢量图层通过 bringToFront() 和 bringToBack() 方法支持 Z 顺序操作。实现因渲染器而异:
- Canvas:维护绘制顺序列表并触发重绘
- SVG:使用
toFront()/toBack()重新排序 DOM 元素