样式和 CSS
本文档解释 OpenLayers 中的样式系统,涵盖地图组件的 CSS 样式和矢量图层的程序化样式。有关使用 Style 类的矢量要素样式,请参阅样式对象。
OpenLayers 中的 CSS 类
OpenLayers 使用一组预定义的 CSS 类来控制地图元素的外观和行为。这些类在 CSS 模块中定义为常量,并应用于整个库的各个组件。
预定义的 CSS 类
CSS 模块中定义了以下 CSS 类:
| CSS 类 | 目的 | 使用 |
|---|---|---|
| ol-hidden | 隐藏元素 | 应用于应该不可见的要素或元素 |
| ol-selectable | 使元素可选择 | 应于应该由用户选择的元素 |
| ol-unselectable | 使元素不可选择 | 应用于应禁用文本选择的元素 |
| ol-unsupported | 指示不支持的功能 | 当功能在当前浏览器中不支持时应用 |
| ol-control | 控件的基类 | 应用于所有地图控件元素 |
| ol-collapsed | 指示折叠状态 | 当折叠时应用于可折叠元素 |
字体工具
CSS 模块还提供用于解析字体规范的工具,对于文本样式很有用:
const fontParams = getFontParameters('bold 12px Arial');
// 返回包含字体属性的对象:style、variant、weight、size 等2
此函数将 CSS 字体简写语法解析为单个组件。
样式化矢量图层
OpenLayers 提供了两种主要的样式化矢量数据的方法,特别是在 WebGL 中:
- Flat 样式:定义样式属性的 JavaScript 对象
- 自定义着色器:使用 WebGL 着色器的高级样式
Flat 样式结构
Flat 样式通过属性-值对定义矢量要素的可视外观:
{
'fill-color': 'rgba(255, 255, 255, 0.6)',
'stroke-color': '#333',
'stroke-width': 2,
'circle-radius': 5,
'circle-fill-color': '#FF0000'
}2
3
4
5
6
7
Flat 样式可以包含引用要素属性的表达式:
{
'fill-color': ['get', 'color'],
'stroke-width': ['*', ['get', 'importance'], 2],
'circle-radius': ['min', 8, ['get', 'size']]
}2
3
4
5
样式规则和过滤
可以使用带有过滤器的样式规则有条件地应用样式:
[
{
filter: ['==', ['get', 'type'], 'highway'],
style: {
'stroke-color': '#FF0000',
'stroke-width': 3
}
},
{
else: true,
style: {
'stroke-color': '#666666',
'stroke-width': 1
}
}
]2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
这种方法允许根据属性对不同要素应用不同的样式。
WebGL 矢量图层样式
WebGLVector 和 WebGLVectorTile 图层使用 WebGL 为大型数据集提供高性能渲染。这些图层使用专门的样式系统,将 flat 样式转换为 WebGL 着色器。
WebGL 样式的工作原理
让我们看看 WebGL 样式系统的架构:
样式过程涉及:
- 样式解析:Flat 样式被解析为着色器组件
- 缓冲区生成:几何图形被转换为 WebGL 缓冲区
- 着色器编译:GLSL 着色器被编译用于渲染
- 渲染:在 WebGL 渲染过程中应用样式
样式变量
样式变量提供了一种无需重新创建 WebGL 缓冲区即可更新某些样式属性的方法,从而在动画或高亮要素时提高性能:
// 定义带有变量的样式
const layer = new WebGLVectorLayer({
source: vectorSource,
style: {
'fill-color': ['var', 'fillColor'],
'stroke-color': ['var', 'strokeColor']
},
variables: {
fillColor: 'rgba(255, 0, 0, 0.5)',
strokeColor: '#000000'
}
});
// 稍后,更新变量以更改样式
layer.updateStyleVariables({
fillColor: 'rgba(0, 0, 255, 0.5)'
});2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
这种方法比更改整个样式更有效,因为它只更新 WebGL 着色器中的 uniform 值,而不是重新生成缓冲区。
WebGL 矢量样式渲染器
WebGL 样式系统的核心是 VectorStyleRenderer 类,它将样式转换为 WebGL 着色器并管理缓冲区创建和渲染。
关键属性和特性
样式渲染器系统支持各种可视属性:
- 填充样式:颜色、图案
- 描边样式:颜色、宽度、线端、线连接、图案
- 符号样式:大小、颜色、形状、图像
- 文本样式:字体、颜色、大小、对齐
这些都可以指定为字面值或计算要素属性的表达式。
WebGL 样式处理
将 flat 样式转换为 WebGL 渲染涉及几个步骤:
- 解析:Flat 样式被解析为着色器组件
- 缓冲区创建:几何图形被处理为 WebGL 缓冲区
- 着色器生成:GLSL 着色器从样式表达式生成
- 渲染:着色器和缓冲区用于渲染要素
WebGL Worker
为了更好的性能,缓冲区生成被卸载到 WebGL worker:
这种方法在处理大型数据集期间使主线程保持响应。
命中检测
WebGL 图层支持命中检测(检查哪个要素位于单击点下),这是通过要素 ID 的颜色编码实现的:
- 要素使用唯一颜色渲染到离屏缓冲区
- 单击点时,读取该点的颜色
- 颜色被解码以识别要素
即使有数千个要素,这也允许高效的命中检测。
图层特定 CSS
创建 WebGL 矢量图层时,可以指定要应用于图层 canvas 元素的 CSS 类名:
const layer = new WebGLVectorLayer({
className: 'my-custom-layer',
source: vectorSource,
style: {...}
});2
3
4
5
这允许对图层的容器进行自定义 CSS 样式。
最佳实践
- 性能:对频繁更改的属性使用样式变量
- 可重用性:定义可以组合的可重用样式组件
- 条件:使用过滤器根据要素属性应用不同的样式
- 表达式:利用表达式动态计算样式属性
- 缓存:对于静态样式,避免不必要地重新创建它们
在样式化数千个要素时,使用适当样式策略的 WebGL 图层可以显著优于基于 canvas 的渲染。