Styling with CSS
GeoTools 中的 CSS 样式模块提供了一种简洁、易用的机制,使用类似 CSS 的语法创建地图样式。这种语法在内部被转换为 SLD(Styled Layer Descriptor)样式,可被各种渲染系统使用。此方法提供了比 SLD XML 更易于人类阅读的替代方案,同时保持了与 OGC 标准的兼容性。
CSS 样式概述
CSS 样式模块允许开发人员使用熟悉的类似 CSS 的语法定义地图样式。然后,这些样式被转换为 GeoTools 和符合 OGC 的渲染系统所需的更冗长的 SLD 表示。
CSS 语法
选择器
CSS 样式由选择器和属性声明组成。选择器确定要设置样式的要素,而属性定义它们的样式方式。
CSS 模块支持几种类型的选择器:
- 类型选择器: 按类型名称定位要素(
states,topp:states) - ID 选择器: 按 ID 定位特定要素(
#states.2) - 属性选择器: 基于属性值进行筛选(
[population > 100000]) - 比例尺选择器: 在特定的比例尺范围内应用样式(
[@scale < 10000],[@z > 5]) - 伪类选择器: 为符号的特定部分设置样式(
:mark,:stroke,:fill)
选择器可以使用以下方式组合:
- AND: 简单地将选择器彼此相邻放置(
states [population > 100000]) - OR: 用逗号分隔选择器(
states, counties)
属性
属性定义要素的视觉外观。CSS 模块支持与 CSS 和 SLD 类似的属性:
- Stroke 属性:
stroke,stroke-width,stroke-opacity,stroke-dasharray - Fill 属性:
fill,fill-opacity - Mark 属性:
mark,mark-size,mark-rotation - Label 属性:
label,font-family,font-size,font-weight,font-style - Graphic 属性:
graphic,graphic-size,graphic-opacity - Raster 属性:
raster-channels,raster-opacity,raster-contrast-enhancement
CSS 样式示例
以下是一个简单的 CSS 样式示例,创建具有红色圆形符号的点图层:
* {
mark: symbol(circle);
mark-size: 6px;
}
:mark {
fill: red;
}这等同于以下 SLD:
<PointSymbolizer>
<Graphic>
<Mark>
<WellKnownName>circle</WellKnownName>
<Fill>
<CssParameter name="fill">#ff0000</CssParameter>
</Fill>
</Mark>
<Size>6</Size>
</Graphic>
</PointSymbolizer>CSS 到 SLD 转换
转换过程
CSS 到 SLD 的转换过程涉及几个关键步骤:
- 解析: 使用
CssParser将 CSS 文本解析为Stylesheet对象 - 规则组织: 按 z-index 和要素类型名称组织规则
- 规则组合: 组合规则以创建一组不重叠的规则
- SLD 生成: 将组合的规则转换为 SLD 规则和符号化器
转换模式
CSS 转换器支持多种转换模式,用于控制规则的组合和优化方式:
- Exclusive: 通过计算精确的域覆盖来生成完全互斥的规则
- Simple: 在 FeatureTypeStyle 中设置"exclusive"评估模式,并依赖渲染器查找第一个匹配的规则
- Flat: 在不进行复杂的域覆盖计算的情况下更直接地合并规则
- Auto: 根据规则复杂度在 Exclusive 和 Simple 模式之间选择
可以通过在 CSS 文件开头使用指令来设置转换模式:
@mode "Simple";
* { stroke: black; }规则组合和域覆盖
转换器组合 CSS 规则以创建不重叠的 SLD 规则。这是使用 DomainCoverage 类完成的,该类跟踪"域"(比例尺范围和筛选器的组合)的哪些部分被不同的规则覆盖。
幂集生成
为了正确处理规则组合,CSS 转换器使用 RulePowerSetBuilder 生成输入规则的过滤幂集。这确保考虑所有可能的规则组合,同时避免会导致矛盾选择器的组合。
Z-Index 和多层支持
CSS 模块通过 z-index 属性支持符号化器的 z 顺序排列。这允许精确控制符号的绘制顺序,类似于 Web 开发中的 CSS。
Z-Index 使用
* {
fill: black;
stroke: white;
z-index: 0;
}
[population > 1000000] {
fill: red;
z-index: 1;
}CSS 转换器还可以通过为每组相同名称的要素类型创建单独的 NamedLayer 来生成多层 SLD。这是使用 translateMultilayer 方法完成的。
高级功能
伪类
伪类允许为符号的特定部分设置样式:
* {
mark: symbol(circle);
}
:mark {
fill: red;
stroke: black;
}表达式和函数
CSS 模块支持属性值中的表达式和函数,包括用方括号包围的 CQL 表达式:
* {
label: [name];
font-size: [population / 10000 + 8];
}
[category = 'park'] {
fill: symbol('circle');
}
:fill {
fill: #00FF00;
}供应商选项
供应商特定选项使用 -gt- 前缀支持:
* {
label: [name];
-gt-label-follow-line: true;
-gt-label-max-displacement: 50;
}使用 CSS 转换器
基本使用
在代码中使用 CSS 转换器:
// 将 CSS 文本解析为 Stylesheet
Stylesheet ss = CssParser.parse(cssText);
// 创建转换器
CssTranslator translator = new CssTranslator();
// 转换为 Style 对象
Style style = translator.translate(ss);
// 或者转换为多层 SLD
StyledLayerDescriptor sld = translator.translateMultilayer(ss);指令
可以使用指令来配置转换过程:
@mode "Simple";
@styleName "My Style";
@styleTitle "My Style Title";
@styleAbstract "This is a description of my style";
@maxOutputRules "5000";
@autoThreshold "100";
* {
fill: #888888;
}系统架构
CSS 样式模块架构由几个关键组件组成:
转换工作流程
以下是 CSS 到 SLD 转换工作流程的详细视图:
与 GeoTools 集成
CSS 样式模块与更广泛的 GeoTools 样式框架集成。转换后的样式可以在接受 GeoTools 样式的任何地方使用,例如渲染器、WMS 服务或地图查看器。
结论
CSS 样式模块为创建地图样式提供了比原始 SLD 更简洁和可读的替代方案。它支持广泛的样式功能,从基本的填充和描边属性到复杂的表达式和多层样式。转换过程确保与 OGC 标准的兼容性,同时提供更友好的开发体验。
虽然 CSS 模块目前位于 GeoTools 的"不受支持"类别中,但它功能齐全并在生产环境中使用,特别是在 GeoServer 的 CSS 样式扩展中。
对于希望从事地理空间样式开发的开发人员,CSS 模块提供了编程样式的表现力和 SLD 的标准化之间的强大折衷方案。