























Styled Layer Descriptor(SLD)是OGC制定的地图样式描述标准,用于定义如何渲染地理数据。SLD使用XML语法描述地图的视觉呈现方式,包括颜色、符号、线型、填充等。
SLD的核心价值:
一个典型的SLD文档结构如下:
<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.0.0"
xsi:schemaLocation="http://www.opengis.net/sld StyledLayerDescriptor.xsd"
xmlns="http://www.opengis.net/sld"
xmlns:ogc="http://www.opengis.net/ogc"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<NamedLayer>
<Name>图层名称</Name>
<UserStyle>
<Name>样式名称</Name>
<Title>样式标题</Title>
<FeatureTypeStyle>
<Rule>
<Name>规则名称</Name>
<Title>规则标题</Title>
<!-- 过滤条件 -->
<ogc:Filter>...</ogc:Filter>
<!-- 比例尺条件 -->
<MinScaleDenominator>1000</MinScaleDenominator>
<MaxScaleDenominator>100000</MaxScaleDenominator>
<!-- 符号化器 -->
<PointSymbolizer>...</PointSymbolizer>
<LineSymbolizer>...</LineSymbolizer>
<PolygonSymbolizer>...</PolygonSymbolizer>
<TextSymbolizer>...</TextSymbolizer>
<RasterSymbolizer>...</RasterSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
</NamedLayer>
</StyledLayerDescriptor>
NamedLayer vs UserLayer:
FeatureTypeStyle:
Rule:
创建新样式:
关联样式到图层:
使用简单的圆形符号:
<?xml version="1.0" encoding="UTF-8"?>
<StyledLayerDescriptor version="1.0.0"
xmlns="http://www.opengis.net/sld"
xmlns:ogc="http://www.opengis.net/ogc">
<NamedLayer>
<Name>points</Name>
<UserStyle>
<Title>Simple Point</Title>
<FeatureTypeStyle>
<Rule>
<PointSymbolizer>
<Graphic>
<Mark>
<WellKnownName>circle</WellKnownName>
<Fill>
<CssParameter name="fill">#FF0000</CssParameter>
</Fill>
<Stroke>
<CssParameter name="stroke">#000000</CssParameter>
<CssParameter name="stroke-width">1</CssParameter>
</Stroke>
</Mark>
<Size>10</Size>
</Graphic>
</PointSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
</NamedLayer>
</StyledLayerDescriptor>
GeoServer支持以下预定义符号(WellKnownName):
| 符号 | 说明 |
|---|---|
| circle | 圆形 |
| square | 正方形 |
| triangle | 三角形 |
| star | 五角星 |
| cross | 十字 |
| x | X形 |
| diamond | 菱形 |
| arrow | 箭头 |
使用外部图像文件作为点符号:
<PointSymbolizer>
<Graphic>
<ExternalGraphic>
<OnlineResource xlink:type="simple"
xlink:href="http://localhost:8080/geoserver/styles/icons/hospital.png"/>
<Format>image/png</Format>
</ExternalGraphic>
<Size>24</Size>
</Graphic>
</PointSymbolizer>
使用相对路径:
<ExternalGraphic>
<OnlineResource xlink:type="simple"
xlink:href="icons/hospital.png"/>
<Format>image/png</Format>
</ExternalGraphic>
图标文件应放在GeoServer数据目录的styles文件夹下。
根据属性值使用不同的符号:
<FeatureTypeStyle>
<!-- 医院 -->
<Rule>
<Name>Hospital</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>type</ogc:PropertyName>
<ogc:Literal>hospital</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<PointSymbolizer>
<Graphic>
<ExternalGraphic>
<OnlineResource xlink:type="simple" xlink:href="icons/hospital.png"/>
<Format>image/png</Format>
</ExternalGraphic>
<Size>20</Size>
</Graphic>
</PointSymbolizer>
</Rule>
<!-- 学校 -->
<Rule>
<Name>School</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>type</ogc:PropertyName>
<ogc:Literal>school</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<PointSymbolizer>
<Graphic>
<ExternalGraphic>
<OnlineResource xlink:type="simple" xlink:href="icons/school.png"/>
<Format>image/png</Format>
</ExternalGraphic>
<Size>20</Size>
</Graphic>
</PointSymbolizer>
</Rule>
</FeatureTypeStyle>
根据数值属性设置符号大小:
<PointSymbolizer>
<Graphic>
<Mark>
<WellKnownName>circle</WellKnownName>
<Fill>
<CssParameter name="fill">#3366FF</CssParameter>
</Fill>
</Mark>
<Size>
<ogc:Mul>
<ogc:Div>
<ogc:PropertyName>population</ogc:PropertyName>
<ogc:Literal>100000</ogc:Literal>
</ogc:Div>
<ogc:Literal>5</ogc:Literal>
</ogc:Mul>
</Size>
</Graphic>
</PointSymbolizer>
简单的实线样式:
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#FF0000</CssParameter>
<CssParameter name="stroke-width">2</CssParameter>
<CssParameter name="stroke-linecap">round</CssParameter>
<CssParameter name="stroke-linejoin">round</CssParameter>
</Stroke>
</LineSymbolizer>
线条属性说明:
| 属性 | 说明 | 可选值 |
|---|---|---|
| stroke | 线条颜色 | 十六进制颜色值 |
| stroke-width | 线条宽度 | 像素值 |
| stroke-opacity | 透明度 | 0-1 |
| stroke-linecap | 线端样式 | butt, round, square |
| stroke-linejoin | 连接样式 | miter, round, bevel |
| stroke-dasharray | 虚线模式 | 如 "5 2" |
| stroke-dashoffset | 虚线偏移 | 像素值 |
<!-- 虚线 -->
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#333333</CssParameter>
<CssParameter name="stroke-width">2</CssParameter>
<CssParameter name="stroke-dasharray">10 5</CssParameter>
</Stroke>
</LineSymbolizer>
<!-- 点线 -->
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#333333</CssParameter>
<CssParameter name="stroke-width">2</CssParameter>
<CssParameter name="stroke-dasharray">2 5</CssParameter>
<CssParameter name="stroke-linecap">round</CssParameter>
</Stroke>
</LineSymbolizer>
<!-- 点划线 -->
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#333333</CssParameter>
<CssParameter name="stroke-width">2</CssParameter>
<CssParameter name="stroke-dasharray">10 5 2 5</CssParameter>
</Stroke>
</LineSymbolizer>
通过多个符号化器实现套壳线效果:
<FeatureTypeStyle>
<Rule>
<!-- 底层宽线(外边框) -->
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#000000</CssParameter>
<CssParameter name="stroke-width">5</CssParameter>
<CssParameter name="stroke-linecap">round</CssParameter>
</Stroke>
</LineSymbolizer>
<!-- 顶层窄线(内部填充) -->
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#FFFF00</CssParameter>
<CssParameter name="stroke-width">3</CssParameter>
<CssParameter name="stroke-linecap">round</CssParameter>
</Stroke>
</LineSymbolizer>
</Rule>
</FeatureTypeStyle>
根据道路等级显示不同样式:
<FeatureTypeStyle>
<!-- 高速公路 -->
<Rule>
<Name>Highway</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>road_class</ogc:PropertyName>
<ogc:Literal>highway</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#E34234</CssParameter>
<CssParameter name="stroke-width">6</CssParameter>
</Stroke>
</LineSymbolizer>
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#FF6B5B</CssParameter>
<CssParameter name="stroke-width">4</CssParameter>
</Stroke>
</LineSymbolizer>
</Rule>
<!-- 主干道 -->
<Rule>
<Name>Primary</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>road_class</ogc:PropertyName>
<ogc:Literal>primary</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#FFA500</CssParameter>
<CssParameter name="stroke-width">4</CssParameter>
</Stroke>
</LineSymbolizer>
</Rule>
<!-- 次要道路 -->
<Rule>
<Name>Secondary</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>road_class</ogc:PropertyName>
<ogc:Literal>secondary</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#FFD700</CssParameter>
<CssParameter name="stroke-width">2</CssParameter>
</Stroke>
</LineSymbolizer>
</Rule>
</FeatureTypeStyle>
在线上重复显示符号:
<LineSymbolizer>
<Stroke>
<GraphicStroke>
<Graphic>
<Mark>
<WellKnownName>circle</WellKnownName>
<Fill>
<CssParameter name="fill">#000000</CssParameter>
</Fill>
</Mark>
<Size>6</Size>
</Graphic>
</GraphicStroke>
<CssParameter name="stroke-dasharray">12 12</CssParameter>
</Stroke>
</LineSymbolizer>
简单的填充和边框:
<PolygonSymbolizer>
<Fill>
<CssParameter name="fill">#00FF00</CssParameter>
<CssParameter name="fill-opacity">0.5</CssParameter>
</Fill>
<Stroke>
<CssParameter name="stroke">#000000</CssParameter>
<CssParameter name="stroke-width">1</CssParameter>
</Stroke>
</PolygonSymbolizer>
使用图案进行填充:
<PolygonSymbolizer>
<Fill>
<GraphicFill>
<Graphic>
<Mark>
<WellKnownName>shape://slash</WellKnownName>
<Stroke>
<CssParameter name="stroke">#000000</CssParameter>
<CssParameter name="stroke-width">1</CssParameter>
</Stroke>
</Mark>
<Size>8</Size>
</Graphic>
</GraphicFill>
</Fill>
<Stroke>
<CssParameter name="stroke">#000000</CssParameter>
<CssParameter name="stroke-width">1</CssParameter>
</Stroke>
</PolygonSymbolizer>
预定义填充图案:
根据数值属性进行颜色分级:
<FeatureTypeStyle>
<!-- 第一级 -->
<Rule>
<Name>Low</Name>
<ogc:Filter>
<ogc:PropertyIsLessThan>
<ogc:PropertyName>population</ogc:PropertyName>
<ogc:Literal>100000</ogc:Literal>
</ogc:PropertyIsLessThan>
</ogc:Filter>
<PolygonSymbolizer>
<Fill>
<CssParameter name="fill">#FFFFB2</CssParameter>
</Fill>
</PolygonSymbolizer>
</Rule>
<!-- 第二级 -->
<Rule>
<Name>Medium</Name>
<ogc:Filter>
<ogc:And>
<ogc:PropertyIsGreaterThanOrEqualTo>
<ogc:PropertyName>population</ogc:PropertyName>
<ogc:Literal>100000</ogc:Literal>
</ogc:PropertyIsGreaterThanOrEqualTo>
<ogc:PropertyIsLessThan>
<ogc:PropertyName>population</ogc:PropertyName>
<ogc:Literal>500000</ogc:Literal>
</ogc:PropertyIsLessThan>
</ogc:And>
</ogc:Filter>
<PolygonSymbolizer>
<Fill>
<CssParameter name="fill">#FECC5C</CssParameter>
</Fill>
</PolygonSymbolizer>
</Rule>
<!-- 第三级 -->
<Rule>
<Name>High</Name>
<ogc:Filter>
<ogc:PropertyIsGreaterThanOrEqualTo>
<ogc:PropertyName>population</ogc:PropertyName>
<ogc:Literal>500000</ogc:Literal>
</ogc:PropertyIsGreaterThanOrEqualTo>
</ogc:Filter>
<PolygonSymbolizer>
<Fill>
<CssParameter name="fill">#FD8D3C</CssParameter>
</Fill>
</PolygonSymbolizer>
</Rule>
</FeatureTypeStyle>
使用函数进行连续颜色渐变:
<PolygonSymbolizer>
<Fill>
<CssParameter name="fill">
<ogc:Function name="Interpolate">
<ogc:PropertyName>population</ogc:PropertyName>
<ogc:Literal>0</ogc:Literal>
<ogc:Literal>#FFFFB2</ogc:Literal>
<ogc:Literal>500000</ogc:Literal>
<ogc:Literal>#FD8D3C</ogc:Literal>
<ogc:Literal>1000000</ogc:Literal>
<ogc:Literal>#BD0026</ogc:Literal>
<ogc:Literal>color</ogc:Literal>
</ogc:Function>
</CssParameter>
</Fill>
</PolygonSymbolizer>
<TextSymbolizer>
<Label>
<ogc:PropertyName>name</ogc:PropertyName>
</Label>
<Font>
<CssParameter name="font-family">Arial</CssParameter>
<CssParameter name="font-size">12</CssParameter>
<CssParameter name="font-style">normal</CssParameter>
<CssParameter name="font-weight">bold</CssParameter>
</Font>
<Fill>
<CssParameter name="fill">#000000</CssParameter>
</Fill>
</TextSymbolizer>
添加白色描边使文字在复杂背景上更清晰:
<TextSymbolizer>
<Label>
<ogc:PropertyName>name</ogc:PropertyName>
</Label>
<Font>
<CssParameter name="font-family">Arial</CssParameter>
<CssParameter name="font-size">14</CssParameter>
</Font>
<Halo>
<Radius>2</Radius>
<Fill>
<CssParameter name="fill">#FFFFFF</CssParameter>
</Fill>
</Halo>
<Fill>
<CssParameter name="fill">#333333</CssParameter>
</Fill>
</TextSymbolizer>
点要素标注位置:
<TextSymbolizer>
<Label>
<ogc:PropertyName>name</ogc:PropertyName>
</Label>
<LabelPlacement>
<PointPlacement>
<AnchorPoint>
<AnchorPointX>0.5</AnchorPointX>
<AnchorPointY>0</AnchorPointY>
</AnchorPoint>
<Displacement>
<DisplacementX>0</DisplacementX>
<DisplacementY>10</DisplacementY>
</Displacement>
<Rotation>0</Rotation>
</PointPlacement>
</LabelPlacement>
<Font>
<CssParameter name="font-family">Arial</CssParameter>
<CssParameter name="font-size">12</CssParameter>
</Font>
<Fill>
<CssParameter name="fill">#000000</CssParameter>
</Fill>
</TextSymbolizer>
线要素标注位置:
<TextSymbolizer>
<Label>
<ogc:PropertyName>name</ogc:PropertyName>
</Label>
<LabelPlacement>
<LinePlacement>
<PerpendicularOffset>5</PerpendicularOffset>
</LinePlacement>
</LabelPlacement>
<Font>
<CssParameter name="font-family">Arial</CssParameter>
<CssParameter name="font-size">10</CssParameter>
</Font>
<Fill>
<CssParameter name="fill">#333333</CssParameter>
</Fill>
<VendorOption name="followLine">true</VendorOption>
<VendorOption name="maxAngleDelta">30</VendorOption>
</TextSymbolizer>
GeoServer提供了丰富的标注冲突处理选项:
<TextSymbolizer>
<Label>
<ogc:PropertyName>name</ogc:PropertyName>
</Label>
<Font>
<CssParameter name="font-family">Arial</CssParameter>
<CssParameter name="font-size">12</CssParameter>
</Font>
<!-- 允许重叠 -->
<VendorOption name="conflictResolution">false</VendorOption>
<!-- 允许部分标注显示在地图外 -->
<VendorOption name="partials">true</VendorOption>
<!-- 标注优先级 -->
<Priority>
<ogc:PropertyName>population</ogc:PropertyName>
</Priority>
<!-- 标注间距 -->
<VendorOption name="spaceAround">10</VendorOption>
<!-- 多边形标注重复 -->
<VendorOption name="repeat">200</VendorOption>
</TextSymbolizer>
在Linux服务器上使用中文字体:
# Ubuntu/Debian
sudo apt install fonts-wqy-microhei fonts-wqy-zenhei
# CentOS/RHEL
sudo yum install wqy-microhei-fonts wqy-zenhei-fonts
<Font>
<CssParameter name="font-family">WenQuanYi Micro Hei</CssParameter>
<CssParameter name="font-size">12</CssParameter>
</Font>
根据地图比例尺显示不同样式:
<FeatureTypeStyle>
<!-- 小比例尺(大范围) -->
<Rule>
<Name>Small Scale</Name>
<MinScaleDenominator>100000</MinScaleDenominator>
<PointSymbolizer>
<Graphic>
<Mark>
<WellKnownName>circle</WellKnownName>
<Fill>
<CssParameter name="fill">#FF0000</CssParameter>
</Fill>
</Mark>
<Size>5</Size>
</Graphic>
</PointSymbolizer>
</Rule>
<!-- 大比例尺(小范围) -->
<Rule>
<Name>Large Scale</Name>
<MaxScaleDenominator>100000</MaxScaleDenominator>
<PointSymbolizer>
<Graphic>
<Mark>
<WellKnownName>circle</WellKnownName>
<Fill>
<CssParameter name="fill">#FF0000</CssParameter>
</Fill>
</Mark>
<Size>15</Size>
</Graphic>
</PointSymbolizer>
<TextSymbolizer>
<Label>
<ogc:PropertyName>name</ogc:PropertyName>
</Label>
<Font>
<CssParameter name="font-family">Arial</CssParameter>
<CssParameter name="font-size">12</CssParameter>
</Font>
</TextSymbolizer>
</Rule>
</FeatureTypeStyle>
使用ElseFilter处理未匹配的要素:
<FeatureTypeStyle>
<Rule>
<Name>Highway</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>type</ogc:PropertyName>
<ogc:Literal>highway</ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#FF0000</CssParameter>
<CssParameter name="stroke-width">4</CssParameter>
</Stroke>
</LineSymbolizer>
</Rule>
<!-- 其他所有道路 -->
<Rule>
<Name>Other Roads</Name>
<ElseFilter/>
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#999999</CssParameter>
<CssParameter name="stroke-width">1</CssParameter>
</Stroke>
</LineSymbolizer>
</Rule>
</FeatureTypeStyle>
使用多个FeatureTypeStyle控制渲染顺序:
<UserStyle>
<!-- 第一层:填充 -->
<FeatureTypeStyle>
<Rule>
<PolygonSymbolizer>
<Fill>
<CssParameter name="fill">#AAFFAA</CssParameter>
</Fill>
</PolygonSymbolizer>
</Rule>
</FeatureTypeStyle>
<!-- 第二层:边框 -->
<FeatureTypeStyle>
<Rule>
<PolygonSymbolizer>
<Stroke>
<CssParameter name="stroke">#006600</CssParameter>
<CssParameter name="stroke-width">2</CssParameter>
</Stroke>
</PolygonSymbolizer>
</Rule>
</FeatureTypeStyle>
<!-- 第三层:标注 -->
<FeatureTypeStyle>
<Rule>
<TextSymbolizer>
<Label>
<ogc:PropertyName>name</ogc:PropertyName>
</Label>
</TextSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
GeoServer支持CSS样式语言,提供了更简洁的样式定义方式:
/* 点样式 */
* {
mark: symbol(circle);
mark-size: 10;
:mark {
fill: #FF0000;
stroke: #000000;
}
}
/* 线样式 */
* {
stroke: #0000FF;
stroke-width: 2;
}
/* 面样式 */
* {
fill: #00FF00;
fill-opacity: 0.5;
stroke: #000000;
}
/* 属性等于 */
[type = 'highway'] {
stroke: #FF0000;
stroke-width: 4;
}
/* 属性大于 */
[population > 1000000] {
fill: #FF0000;
}
/* 属性模糊匹配 */
[name like '%Beijing%'] {
mark-size: 20;
}
/* 多条件 */
[type = 'primary'][lanes > 2] {
stroke-width: 4;
}
/* 在指定比例尺范围内 */
[@scale < 100000] {
mark-size: 15;
label: [name];
}
[@scale >= 100000] {
mark-size: 5;
}
* {
label: [name];
font-family: "Arial";
font-size: 12;
font-fill: #333333;
halo-color: white;
halo-radius: 2;
label-offset: 0 10;
}
/* 线沿线标注 */
[type = 'road'] {
label: [name];
label-follow-line: true;
label-max-angle-delta: 30;
}
| 方面 | CSS | SLD |
|---|---|---|
| 语法复杂度 | 简洁 | 冗长 |
| 学习曲线 | 较低 | 较高 |
| 功能完整性 | 略有限制 | 完整 |
| 互操作性 | GeoServer特有 | OGC标准 |
| 性能 | 运行时转换为SLD | 直接使用 |
建议:对于简单样式使用CSS,对于复杂样式或需要互操作性的场景使用SLD。
本章详细介绍了GeoServer的地图样式系统:
良好的地图样式设计是制作专业地图的关键。通过灵活运用SLD和CSS,可以创建美观且信息丰富的地图可视化效果。
在下一章中,我们将学习GeoServer的安全管理,包括用户认证、访问控制和数据安全。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。