Skip to content

样式和 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 等

此函数将 CSS 字体简写语法解析为单个组件。

样式化矢量图层

OpenLayers 提供了两种主要的样式化矢量数据的方法,特别是在 WebGL 中:

  1. Flat 样式:定义样式属性的 JavaScript 对象
  2. 自定义着色器:使用 WebGL 着色器的高级样式

Flat 样式结构

Flat 样式通过属性-值对定义矢量要素的可视外观:

{
  'fill-color': 'rgba(255, 255, 255, 0.6)',
  'stroke-color': '#333',
  'stroke-width': 2,
  'circle-radius': 5,
  'circle-fill-color': '#FF0000'
}

Flat 样式可以包含引用要素属性的表达式:

{
  'fill-color': ['get', 'color'],
  'stroke-width': ['*', ['get', 'importance'], 2],
  'circle-radius': ['min', 8, ['get', 'size']]
}

样式规则和过滤

可以使用带有过滤器的样式规则有条件地应用样式:

[
  {
    filter: ['==', ['get', 'type'], 'highway'],
    style: {
      'stroke-color': '#FF0000',
      'stroke-width': 3
    }
  },
  {
    else: true,
    style: {
      'stroke-color': '#666666',
      'stroke-width': 1
    }
  }
]

这种方法允许根据属性对不同要素应用不同的样式。

WebGL 矢量图层样式

WebGLVectorWebGLVectorTile 图层使用 WebGL 为大型数据集提供高性能渲染。这些图层使用专门的样式系统,将 flat 样式转换为 WebGL 着色器。

WebGL 样式的工作原理

让我们看看 WebGL 样式系统的架构:

样式过程涉及:

  1. 样式解析:Flat 样式被解析为着色器组件
  2. 缓冲区生成:几何图形被转换为 WebGL 缓冲区
  3. 着色器编译:GLSL 着色器被编译用于渲染
  4. 渲染:在 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)'
});

这种方法比更改整个样式更有效,因为它只更新 WebGL 着色器中的 uniform 值,而不是重新生成缓冲区。

WebGL 矢量样式渲染器

WebGL 样式系统的核心是 VectorStyleRenderer 类,它将样式转换为 WebGL 着色器并管理缓冲区创建和渲染。

SVG
100%

关键属性和特性

样式渲染器系统支持各种可视属性:

  • 填充样式:颜色、图案
  • 描边样式:颜色、宽度、线端、线连接、图案
  • 符号样式:大小、颜色、形状、图像
  • 文本样式:字体、颜色、大小、对齐

这些都可以指定为字面值或计算要素属性的表达式。

WebGL 样式处理

将 flat 样式转换为 WebGL 渲染涉及几个步骤:

  1. 解析:Flat 样式被解析为着色器组件
  2. 缓冲区创建:几何图形被处理为 WebGL 缓冲区
  3. 着色器生成:GLSL 着色器从样式表达式生成
  4. 渲染:着色器和缓冲区用于渲染要素

WebGL Worker

为了更好的性能,缓冲区生成被卸载到 WebGL worker:

SVG
100%

这种方法在处理大型数据集期间使主线程保持响应。

命中检测

WebGL 图层支持命中检测(检查哪个要素位于单击点下),这是通过要素 ID 的颜色编码实现的:

  1. 要素使用唯一颜色渲染到离屏缓冲区
  2. 单击点时,读取该点的颜色
  3. 颜色被解码以识别要素

即使有数千个要素,这也允许高效的命中检测。

图层特定 CSS

创建 WebGL 矢量图层时,可以指定要应用于图层 canvas 元素的 CSS 类名:

const layer = new WebGLVectorLayer({
  className: 'my-custom-layer',
  source: vectorSource,
  style: {...}
});

这允许对图层的容器进行自定义 CSS 样式。

最佳实践

  1. 性能:对频繁更改的属性使用样式变量
  2. 可重用性:定义可以组合的可重用样式组件
  3. 条件:使用过滤器根据要素属性应用不同的样式
  4. 表达式:利用表达式动态计算样式属性
  5. 缓存:对于静态样式,避免不必要地重新创建它们

在样式化数千个要素时,使用适当样式策略的 WebGL 图层可以显著优于基于 canvas 的渲染。