Table of Contents

Part II : discovering Symbology Encoging 1.1 further with UserStyles

In part I we've configured internal definition of styles, each called a NamedStyle, and this is by using SE 1.1 because deegree3 is based on it internally. But what if you are interesting as a client to get a map from a WMS with your custom style because there are interesting underlying data you want to visualize?

The interesting is that when a WMS service is combined with the SLD profile, then it comes with the UserStyle mechanism to allow external client to portray internal geodata in a custom way.

How to get more description of the geodata ?

Now the situation is you as a client which means you have no more access to the WMS console (as we had in part I). How can you get more information on what geodata the WMS service (you know available at http://localhost:8080/services/mywms) is able to offer ?

You know the service is able to answer to the mandatory WMS GetCapabilities operation :

To get more, we need the service WFS to be activated to access to new interesting operations, the first being the mandatory WFS GetCapabilities operation :

WFS DescribeFeatureType operation

To invoke it, we need to submit a POST HTTP request. By hand we use the REST Client firefox extension.

<DescribeFeatureType version="1.1.0" service="WFS" 
                     xmlns="http://www.opengis.net/wfs" 
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                     xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"> 
                     
</DescribeFeatureType> 
      <complexContent>
        <extension base="gml:AbstractFeatureType">
          <sequence>
            <element name="ID" minOccurs="0" type="decimal"/>
            <element name="NAME" minOccurs="0" type="string"/>
            <element name="METEO_AM" minOccurs="0" type="decimal"/>
            <element name="TEMP_AM" minOccurs="0" type="decimal"/>
            <element name="METEO_PM" minOccurs="0" type="decimal"/>
            <element name="TEMP_PM" minOccurs="0" type="decimal"/>
            <element name="geometry" minOccurs="0" type="gml:PointPropertyType"/>
          </sequence>
        </extension>
      </complexContent>

WFS GetFeature operation

Let's request some values for the NAME, METEO_AM and TEMP_AM properties:

<?xml version="1.0" encoding="UTF-8"?>
<GetFeature version="1.1.0" service="WFS" 
                xmlns="http://www.opengis.net/wfs" 
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
                xsi:schemaLocation="http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd"> 
                
	<Query typeName="meteocities">
	 <PropertyName>NAME</PropertyName>
	 <PropertyName>METEO_AM</PropertyName>
         <PropertyName>TEMP_AM</PropertyName>
	</Query>
</GetFeature>
  <gml:featureMember>
    <app:meteocities xmlns:app="http://www.deegree.org/app" gml:id="METEOCITIES_0">
      <app:NAME>Lausanne</app:NAME>
      <app:METEO_AM>19.00</app:METEO_AM>
      <app:TEMP_AM>26.00</app:TEMP_AM>
    </app:meteocities>
  </gml:featureMember>
  <gml:featureMember>
    <app:meteocities xmlns:app="http://www.deegree.org/app" gml:id="METEOCITIES_1">
      <app:NAME>Geneve</app:NAME>
      <app:METEO_AM>13.00</app:METEO_AM>
      <app:TEMP_AM>11.00</app:TEMP_AM>
    </app:meteocities>
  </gml:featureMember>
      <app:geometry>
        <gml:Point srsName="urn:ogc:def:crs:EPSG::4326">
          <gml:pos>46.525710 6.601897</gml:pos>
        </gml:Point>
      </app:geometry>

Get some more metadata description

But what do these values represents. We would need a kind of metadata catalog that is able to give more descriptive information. Did you notice that the result of a WMS GetCapabilities provide a metadata URL ? Have a look:

<MetadataURL type="ISO19115:2003">
  <Format>application/xml</Format>
  <OnlineResource xlink:type="simple" 
                  xlink:href="http://localhost/ogctuto/catalog-service/ogctuto-description.html#md_meteocities"/>
</MetadataURL>
meteocities weather and temperature data:
- METEO_AM (morning) / METEO_PM (afternoon) codes : 
  (1) ...
  (2) assez ensoleillé, passages nuageux 
  (...) ... 
  (6) éclaircies, averses isolées 
  (...)
  (9) nuageux, quelques averses
- TEMP_AM (morning) / TEMP_PM (afternoon) : temperatures in ° celsius

Our custom meteo sld:UserStyle

All meta information we were able to get is useful because we are now able to build a custom style with our nice weather symbols:

25.gif25.gif6.gif6.gif9.gif9.gif

The purpose is now to build a rich symbol like below for each city of our map:

Introducing the creation of a custom sld:UserStyle

All these internaly-defined NamedStyle that the WMS service offers are nice, but as an external client (versus the WMS manager), I would like to represent these lakes with my own style (without asking the WMS manager to add it as an internal NamedStyle). Indeed, until now, when requesting a WMS GetMap, we were able to link a NamedLayer only with a NamedStyle through the usual LAYERS and STYLES parameters.

To link with a custom style, we need to create a sld:UserStyle !

A sld:UserStyle is a standardized way to link a server-side layer (e.g. NamedLayer) with a client-side custom style defined with SE language. This WMS capability is enabled thanks to its SLD profile.

In other words, SLD does the link between WMS and SE. Let's see an example of a WMS request with SLD:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<StyledLayerDescriptor version="1.1.0" 
                       xmlns="http://www.opengis.net/sld" 
                       xmlns:se="http://www.opengis.net/se"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1/StyledLayerDescriptor.xsd"> 
    <NamedLayer>
        <se:Name>g4see98</se:Name>              
        <UserStyle>           
            <se:FeatureTypeStyle version="1.1.0">                             
                <se:Rule>
                    <se:PolygonSymbolizer>
                        <se:Fill>
                            <se:SvgParameter name="fill">#4563F9</se:SvgParameter>
                        </se:Fill>
                    </se:PolygonSymbolizer>
                    <se:PolygonSymbolizer>
                        <se:Fill>
                            <se:GraphicFill>
                                <se:Graphic>
                                    <se:Mark>
                                        <se:WellKnownName>CIRCLE</se:WellKnownName>
                                        <se:Fill>
                                            <se:SvgParameter name="fill">#B8DCEA</se:SvgParameter>
                                        </se:Fill>
                                        <se:Stroke>
                                            <se:SvgParameter name="stroke">#B8DCEA</se:SvgParameter>
                                        </se:Stroke>
                                    </se:Mark>
                                    <se:Size>8</se:Size>
                                </se:Graphic>
                            </se:GraphicFill>
                        </se:Fill>
                    </se:PolygonSymbolizer>
                </se:Rule>            
            </se:FeatureTypeStyle>      
        </UserStyle>
    </NamedLayer>
</StyledLayerDescriptor>

Towards a meteo style

Now that we know everything about the “meteocities” layer, we are be able to create a custom style so as to transform the precious meteo properties into meteo symbols and labels.

Step 1 : all cities except Rappelswil

Have a look to the meteosuisse map and you will notice there is no meteo information for Rapperswil. So we will have to ignore that specific feature before starting our meteo style.

We have previously discovered a first reason to use SLD (how to link with a custom style), here is a second by a way to filter features of a layer:

<StyledLayerDescriptor version="1.1.0" 
                       xmlns="http://www.opengis.net/sld" 
                       xmlns:se="http://www.opengis.net/se"
                       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                       xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1/StyledLayerDescriptor.xsd"> 
    <NamedLayer>
        <se:Name>meteocities</se:Name>      

        <LayerFeatureConstraints>
            <FeatureTypeConstraint>
                <Filter xmlns="http://www.opengis.net/ogc">
                    <PropertyIsNotEqualTo>
                        <PropertyName>ID</PropertyName>
                        <Literal>0</Literal>
                    </PropertyIsNotEqualTo>
                </Filter>
            </FeatureTypeConstraint>
        </LayerFeatureConstraints>

        <NamedStyle>
            <se:Name>pointCities</se:Name>
        </NamedStyle>
        
    </NamedLayer>
</StyledLayerDescriptor>

Step 2 : style the left symbol

Step 3 : style the right symbol

Step 4 : style for labels and separators

The complete style

<StyledLayerDescriptor version="1.1.0" xmlns="http://www.opengis.net/sld"
    xmlns:se="http://www.opengis.net/se" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1/StyledLayerDescriptor.xsd">

    <!-- 
    A rich style of rules to define weather symbologies. 
    These symbologies are applied to all cities except Rapperswil because of a LayerFeatureConstraints.
    LayerFeatureConstraints configures the step of selection of the features to give to the rendering engine.
    It uses the same encoding syntax as for filtering a rule of symbology (OGC Filter Encoding)
    
    GetMap URL
    http://localhost:8080/services?SLD=http://localhost/webmaptuto/sld/1.1/meteoGraphic.sld.xml&TRANSPARENT=true&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&FORMAT=image%2Fpng&SRS=EPSG%3A21781&BBOX=449413.2,47606,899958.4,311320.9&WIDTH=1000&HEIGHT=585
    -->

    <NamedLayer>
        <se:Name>meteocities</se:Name>

        <LayerFeatureConstraints>
            <FeatureTypeConstraint>
                <Filter xmlns="http://www.opengis.net/ogc">
                    <PropertyIsNotEqualTo>
                        <PropertyName>ID</PropertyName>
                        <Literal>0</Literal>
                    </PropertyIsNotEqualTo>
                </Filter>
            </FeatureTypeConstraint>
        </LayerFeatureConstraints>

        <UserStyle>

            <se:FeatureTypeStyle version="1.1.0">

                <!-- METEO_AM cloud symbols -->

                <se:Rule>
                    <Filter xmlns="http://www.opengis.net/ogc">
                        <PropertyIsEqualTo>
                            <PropertyName>METEO_AM</PropertyName>
                            <Literal>1</Literal>
                        </PropertyIsEqualTo>
                    </Filter>
                    <se:PointSymbolizer>
                        <se:Graphic>
                            <se:ExternalGraphic>
                                <se:OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
                                    xlink:href="http://localhost/ogctuto/meteo-symbols/cloud/1.gif"/>
                                <se:Format>image/gif</se:Format>
                            </se:ExternalGraphic>
                            <se:Displacement>
                                <se:DisplacementX>-22</se:DisplacementX>
                                <se:DisplacementY>0</se:DisplacementY>
                            </se:Displacement>
                        </se:Graphic>
                    </se:PointSymbolizer>
                </se:Rule>

                <!-- for all other symbols METEO_AM from 2 to 27 -->

                <se:Rule>
                    <Filter xmlns="http://www.opengis.net/ogc">
                        <PropertyIsEqualTo>
                            <PropertyName>METEO_AM</PropertyName>
                            <Literal>28</Literal>
                        </PropertyIsEqualTo>
                    </Filter>
                    <se:PointSymbolizer>
                        <se:Graphic>
                            <se:ExternalGraphic>
                                <se:OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
                                    xlink:href="http://localhost/ogctuto/meteo-symbols/cloud/28.gif"/>
                                <se:Format>image/gif</se:Format>
                            </se:ExternalGraphic>
                            <se:Displacement>
                                <se:DisplacementX>-22</se:DisplacementX>
                                <se:DisplacementY>0</se:DisplacementY>
                            </se:Displacement>
                        </se:Graphic>
                    </se:PointSymbolizer>
                </se:Rule>

                <!-- METEO_PM cloud symbols -->

                <se:Rule>
                    <Filter xmlns="http://www.opengis.net/ogc">
                        <PropertyIsEqualTo>
                            <PropertyName>METEO_PM</PropertyName>
                            <Literal>1</Literal>
                        </PropertyIsEqualTo>
                    </Filter>
                    <se:PointSymbolizer>
                        <se:Graphic>
                            <se:ExternalGraphic>
                                <se:OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost/ogctuto/meteo-symbols/cloud/1.gif"/>
                                <se:Format>image/gif</se:Format>
                            </se:ExternalGraphic>
                            <se:Displacement>
                                <se:DisplacementX>22</se:DisplacementX>
                                <se:DisplacementY>0</se:DisplacementY>
                            </se:Displacement>
                        </se:Graphic>
                    </se:PointSymbolizer>
                </se:Rule>        

                <!-- for all other symbols METEO_PM from 2 to 27 -->

                <se:Rule>
                    <Filter xmlns="http://www.opengis.net/ogc">
                        <PropertyIsEqualTo>
                            <PropertyName>METEO_PM</PropertyName>
                            <Literal>28</Literal>
                        </PropertyIsEqualTo>
                    </Filter>
                    <se:PointSymbolizer>
                        <se:Graphic>
                            <se:ExternalGraphic>
                                <se:OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://localhost/ogctuto/meteo-symbols/cloud/28.gif"/>
                                <se:Format>image/gif</se:Format>
                            </se:ExternalGraphic>
                            <se:Displacement>
                                <se:DisplacementX>22</se:DisplacementX>
                                <se:DisplacementY>0</se:DisplacementY>
                            </se:Displacement>
                        </se:Graphic>
                    </se:PointSymbolizer>
                </se:Rule>   

                <!-- text labels -->

                <se:Rule>
                    <se:TextSymbolizer>
                        <se:Label>
                            <PropertyName xmlns="http://www.opengis.net/ogc">NAME</PropertyName>
                        </se:Label>
                        <se:Font>
                            <se:SvgParameter name="font-family">Arial</se:SvgParameter>
                            <se:SvgParameter name="font-size">12</se:SvgParameter>
                        </se:Font>
                        <se:LabelPlacement>
                            <se:PointPlacement>
                                <se:Displacement>
                                    <se:DisplacementX>0</se:DisplacementX>
                                    <se:DisplacementY>-20</se:DisplacementY>
                                </se:Displacement>
                            </se:PointPlacement>
                        </se:LabelPlacement>
                    </se:TextSymbolizer>
                    <se:TextSymbolizer>
                        <se:Label>
                            <se:Concatenate fallbackValue="">
                                <se:StringValue>
                                    <se:FormatNumber fallbackValue="99">
                                        <se:NumericValue>
                                            <PropertyName xmlns="http://www.opengis.net/ogc">TEMP_AM</PropertyName>
                                        </se:NumericValue>
                                        <se:Pattern>#</se:Pattern>
                                    </se:FormatNumber>
                                </se:StringValue>
                                <se:StringValue>°</se:StringValue>
                            </se:Concatenate>
                        </se:Label>
                        <se:Font>
                            <se:SvgParameter name="font-family">Arial</se:SvgParameter>
                            <se:SvgParameter name="font-size">12</se:SvgParameter>
                        </se:Font>
                        <se:LabelPlacement>
                            <se:PointPlacement>
                                <se:Displacement>
                                    <se:DisplacementX>-15</se:DisplacementX>
                                    <se:DisplacementY>-35</se:DisplacementY>
                                </se:Displacement>
                            </se:PointPlacement>
                        </se:LabelPlacement>
                    </se:TextSymbolizer>
                    <se:TextSymbolizer>
                        <se:Label>
                            <se:Concatenate fallbackValue="">
                                <se:StringValue>
                                    <se:FormatNumber fallbackValue="99">
                                        <se:NumericValue>
                                            <PropertyName xmlns="http://www.opengis.net/ogc">TEMP_PM</PropertyName>
                                        </se:NumericValue>
                                        <se:Pattern>#</se:Pattern>
                                    </se:FormatNumber>
                                </se:StringValue>
                                <se:StringValue>°</se:StringValue>
                            </se:Concatenate>
                        </se:Label>
                        <se:Font>
                            <se:SvgParameter name="font-family">Arial</se:SvgParameter>
                            <se:SvgParameter name="font-size">12</se:SvgParameter>
                        </se:Font>
                        <se:LabelPlacement>
                            <se:PointPlacement>
                                <se:Displacement>
                                    <se:DisplacementX>15</se:DisplacementX>
                                    <se:DisplacementY>-35</se:DisplacementY>
                                </se:Displacement>
                            </se:PointPlacement>
                        </se:LabelPlacement>
                    </se:TextSymbolizer>

                </se:Rule>

                <!-- vertical line separators -->

                <se:Rule>
                    <se:PointSymbolizer>
                        <se:Graphic>
                            <se:ExternalGraphic>
                                <se:OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
                                    xlink:href="http://localhost/ogctuto/meteo-symbols/sp.gif"/>
                                <se:Format>image/gif</se:Format>
                            </se:ExternalGraphic>
                        </se:Graphic>
                    </se:PointSymbolizer>
                    <se:PointSymbolizer>
                        <se:Graphic>
                            <se:ExternalGraphic>
                                <se:OnlineResource xmlns:xlink="http://www.w3.org/1999/xlink"
                                    xlink:href="http://localhost/ogctuto/meteo-symbols/sp.gif"/>
                                <se:Format>image/gif</se:Format>
                            </se:ExternalGraphic>
                            <se:Displacement>
                                <se:DisplacementX>0</se:DisplacementX>
                                <se:DisplacementY>-35</se:DisplacementY>
                            </se:Displacement>
                        </se:Graphic>
                    </se:PointSymbolizer>
                </se:Rule>
            </se:FeatureTypeStyle>

        </UserStyle>
    </NamedLayer>

</StyledLayerDescriptor>

Misc