geoserver官方文档里提到了短划线符号交替,效果如下:
传送门:Alternating symbols with dash offsets
其实挺好实现的。但其中一些值的计算还得总结一下,不然时间久了会遗忘。
此例中,是将线按虚线和圆圈的样式组合在一起。只要计算好圆圈的位置,将其放在虚线的间隔中心即可。
1
首先是虚线的样式,sld
内容如下:
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#0000ff</CssParameter>
<CssParameter name="stroke-width">2</CssParameter>
<CssParameter name="stroke-dasharray">50 20</CssParameter>
</Stroke>
</LineSymbolizer>
通过<CssParameter name="stroke-dasharray">50 20</CssParameter>
来设置虚线。
结果是“50像素线段,20像素间隔”如此往复,实际效果如下:
为了后文方便,这里定义一些名词;线段部分(50)和间隔部分(20),一个线段部分和一个间隔部分为一个线段组(70)。
2
然后是圆圈的样式。sld
如下:
<LineSymbolizer>
<Stroke>
<GraphicStroke>
<Graphic>
<Mark>
<WellKnownName>circle</WellKnownName>
<Stroke>
<CssParameter name="stroke">#0000ff</CssParameter>
<CssParameter name="stroke-width">1</CssParameter>
</Stroke>
</Mark>
<Size>6</Size>
</Graphic>
</GraphicStroke>
<CssParameter name="stroke-dasharray">50 20</CssParameter>
</Stroke>
</LineSymbolizer>
这里需要说明<GraphicStroke></GraphicStroke>
之间设置了符号的类型、样式、大小;设置方法与点图层样式一致,详见点样式。
符号也可以修改,只需要替换WellKnownName
中的值就行。可用符号见符号。
当前样式也是通过<CssParameter name="stroke-dasharray">50 20</CssParameter>
来将圆圈分隔开,这个操作和虚线是一致的。
如图,左侧为未添加间隔,右侧为添加间隔后。可以看到,这种样式实质上就是将线段部分用圆圈显示出来了。但现在的效果还是多个圆圈粘在一起,我们要的是一个圆圈。
其实只要让线段部分的长度等于符号大小(Size),就可以一次只显示一个圆圈:
代码改为<CssParameter name="stroke-dasharray">6 70</CssParameter>
。
关于第二个参数(即圆圈之间的间隔),暂且先让它等于线段组的长度,后面详细分析。
3
最后将虚线与圆圈组合在一起进行微调。
我们的最终目标是“一截线段,空白,一个圆圈,空白”,如此往复。当前已经做好了线段和圆圈,只需要调整位置即可。
当前样式:
直接达到目的不太现实,应该先将圆圈与线段对齐,再统一调整圆圈的位置。
出现上图中问题的原因是每个符号的大小占了一定位置(6),需要扣掉这个大小;所以第二个参数应该填入70-6=64。
再使用<CssParameter name="stroke-dashoffset">
可以将符号向起始位置移动一定像素。
注意,是起始位置!我一开始以为是向下移动,调了半天一直对不上。
具体移动的数值,就是上图中绿色的x。所以也就是符号大小的一半加间隔部分长度的一半,即3+10=13。
最终效果为:
完整sld
为:
<?xml version="1.0" encoding="ISO-8859-1"?>
<StyledLayerDescriptor version="1.0.0"
xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/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>aaa</Name>
<UserStyle>
<Title>circle and dash</Title>
<FeatureTypeStyle>
<Rule>
<Title>circle and dash</Title>
<LineSymbolizer>
<Stroke>
<CssParameter name="stroke">#ff0000</CssParameter>
<CssParameter name="stroke-width">2</CssParameter>
<CssParameter name="stroke-dasharray">50 20</CssParameter>
</Stroke>
</LineSymbolizer>
<LineSymbolizer>
<Stroke>
<GraphicStroke>
<Graphic>
<Mark>
<WellKnownName>circle</WellKnownName>
<Stroke>
<CssParameter name="stroke">#0000ff</CssParameter>
<CssParameter name="stroke-width">1</CssParameter>
</Stroke>
</Mark>
<Size>6</Size>
</Graphic>
</GraphicStroke>
<CssParameter name="stroke-dasharray">6 64</CssParameter>
<CssParameter name="stroke-dashoffset">13</CssParameter>
</Stroke>
</LineSymbolizer>
</Rule>
</FeatureTypeStyle>
</UserStyle>
</NamedLayer>
</StyledLayerDescriptor>
4
知道了关键几个参数的计算方法,以后无论对线段、间隔、符号的要求如何,理论上都可以实现。
配合这篇博文,可以达到如下有趣的效果