Wednesday, November 07, 2012

Apply combined fill on multiple fields in geoserver SLD

Imagine you want to add a style to a map layer where the style is applied based on values of two attribute fields. Implementation like below seems quite logical if you see it, but I was quite surprised it works out of the box in geoserver... (Alternative would be to add the layer twice or have 10*10 rules, each field 1 value times each field 2 value)

The use case is a polygon fill based on crop cultivar as background-fill color and association (other crop that is mixed in) represented as a hash-pattern on top of the fill.

In geoserver you can add two featurestyles to a layer user style, the first implementing the background fill based on field A and a second style based on field B

<StyledLayerDescriptor> 
<NamedLayer>
<UserStyle>
<Name>test_style</Name>
<FeatureTypeStyle> ...</FeatureTypeStyle>
<FeatureTypeStyle>... </FeatureTypeStyle>
</UserStyle> 
</NamedLayer>
<StyledLayerDescriptor>

In featuretypestyle 1 now define the backgroundfill based on field 1
...
<Rule>
<Name>Cavendish</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>cultivar_type</ogc:PropertyName>
<ogc:Literal><![CDATA[1]]></ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<PolygonSymbolizer>
<Fill><CssParameter name="fill">#FF0000</CssParameter></Fill>
</PolygonSymbolizer>
</Rule>
....
And in featuretypestyle 2 define the hash-pattern based on field 2

...
<Rule>
<Name>Associated with established perennial crops</Name>
<ogc:Filter>
<ogc:PropertyIsEqualTo>
<ogc:PropertyName>association</ogc:PropertyName>
 <ogc:Literal><![CDATA[1]]></ogc:Literal>
</ogc:PropertyIsEqualTo>
</ogc:Filter>
<PolygonSymbolizer>
<PolygonSymbolizer>
<Fill>
<GraphicFill>
<Graphic>
<Mark>
<WellKnownName>shape://vertline</WellKnownName>
<Stroke><CssParameter name="stroke">#000000</CssParameter></Stroke>
</Mark>
</Graphic>
</GraphicFill>
</Fill>
<Stroke><CssParameter name="stroke">#6E6E6E</CssParameter><CssParameter name="stroke-width">1</CssParameter>
</Stroke>
</PolygonSymbolizer>
</Rule>
...





This will result in a combined style as follows



A potential challenge here is the legend-display, but the two featurestyles are nicely placed after each other...