Styling with GeoNode (Basics)

This section introduces the concepts of the Styled Layer Descriptor (SLD) markup language.

SLD is the styling engine used by the GIS backend (i.e. GeoServer). It allows us to create beautiful and informative portryals out of raw geospatial data.

In this section you will also use the CSS extension module that allows you to build map styles using a compact, expressive styling language already well known to most web developers: Cascading Style Sheets. The standard CSS language has been extended to allow for map filtering and managing all the details of a map production.

The examples will have styles in SLD and CSS language.

WARNING: CSS styling is supported by GeoServer only, which is the default GIS backend provided with GeoNode. In the official GeoServer documentation you can find useful references as the SLD Cookbook and the CSS Cookbook.

Uploading and Replacing the Layer Default Style

This procedure allows us to quickly update and replace the current layer default style with a new one from the hard disk.

WARNING: Currently this procedure works only with SLD files

  • Before using the style, we will need to sligthly modify it in order to match the correct field names of the Mainrd Layer

  • Go to the Mainrd layer detail page; click on the Attributes tab panel just below the map preview

    • Take note of the LABEL_NAME attribute and remember that SLD is case sensitive

    image

  • Click on the system File Browser, navigate to /opt/data/sample_data/user_data

    • RIGHT-CLICK with the mouse on the file named foss4g_mainrd.sld

    • Select and click Open with Other Application

    image

  • Click on View all applications button and then select Text Editor and Select image

  • Change the label_name to uppercase LABEL_NAME, click Save and close image

  • Go to the Mainrd layer detail page; click on the Editing Tools button and the on Style > Upload image

  • From the Style Upload page, click on the Choose files button and navigate to /opt/data/sample_data/user_data, select the file foss4g_mainrd.sld and then click on Open image

  • Click on Upload file and, once finished, on Return to Layer image

    WARNING: If the page does not refresh correctly, click together CTRL-SHIFT-CANC and clear the browser image cache from the last hour

    image

  • Go back to the layer detail page, refresh the page; notice how the Legend has changed and also the styling of the layer. Trying to zoom in, you will notice also some labels appering. image

  • Go ahead and update the Thumbnail by clicking on the Editing Tools menu and then on the Thumbnail > Set link image

  • Once the thumbnail has been saved image

  • Go back to the layers list and verify is has been updated image

Adding more Base Layers and Styles

Boulder City Limits

  • From the location /opt/data/sample_data/pretty_maps/data/boulder upload the layer BoulderCityLimits image

  • From the location /opt/data/sample_data/pretty_maps/styles upload the style foss4g_citylimits.sld image

  • The layer and legend should appear as shown here image

  • Set the thumbnail as we have done previously

Buildings

  • From the location /opt/data/sample_data/pretty_maps/data/boulder upload the layer Buildings050714 WARNING: pay attention to select the files shown in figure, do not include the .sld and .xml ones

    image

  • From the location /opt/data/sample_data/pretty_maps/styles upload the style foss4g_buildings.sld

  • Notice that the Legend presents 3 different symbols, notice also that no feature will be visibile unless you zoom very close to the buildings image

  • By taking a closer look at the style source code, we can notice that:

    • We have a set of Rule elements each one constrained by some ScaleDenominator limits.

    • The Shadow rule, defines also a Displacement making the polygons translate on the X-Y layer

    <?xml version="1.0" encoding="UTF-8"?>
      <sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" version="1.0.0">
        <sld:UserLayer>
          <sld:LayerFeatureConstraints>
            <sld:FeatureTypeConstraint/>
          </sld:LayerFeatureConstraints>
          <sld:UserStyle>
            <sld:Name>Buildings050714</sld:Name>
            <sld:Title/>
            <sld:IsDefault>1</sld:IsDefault>
            <sld:FeatureTypeStyle>
              <sld:Rule>
                <sld:Name>Shadow</sld:Name>
                <sld:MinScaleDenominator>5000.0</sld:MinScaleDenominator>
                <sld:MaxScaleDenominator>15000.0</sld:MaxScaleDenominator>
                <sld:PolygonSymbolizer>
                  <sld:Geometry>
                    <ogc:Function name="offset">
                      <ogc:PropertyName>the_geom</ogc:PropertyName>
                      <ogc:Literal>6.0</ogc:Literal>
                      <ogc:Literal>-6.0</ogc:Literal>
                    </ogc:Function>
                  </sld:Geometry>
                  <sld:Fill/>
                </sld:PolygonSymbolizer>
              </sld:Rule>
            </sld:FeatureTypeStyle>
            <sld:FeatureTypeStyle>
              <sld:Rule>
                <sld:Name>Label</sld:Name>
                <sld:MaxScaleDenominator>10000.0</sld:MaxScaleDenominator>
                <sld:PolygonSymbolizer>
                  <sld:Fill>
                    <sld:CssParameter name="fill">#FF0000</sld:CssParameter>
                  </sld:Fill>
                </sld:PolygonSymbolizer>
                <sld:TextSymbolizer>
                  <sld:Label>
                    <ogc:PropertyName>LABEL_NAME</ogc:PropertyName>
                  </sld:Label>
                  <sld:Font>
                    <sld:CssParameter name="font-family">Arial</sld:CssParameter>
                    <sld:CssParameter name="font-size">12.0</sld:CssParameter>
                    <sld:CssParameter name="font-style">normal</sld:CssParameter>
                    <sld:CssParameter name="font-weight">normal</sld:CssParameter>
                  </sld:Font>
                  <sld:LabelPlacement>
                    <sld:PointPlacement>
                      <sld:AnchorPoint>
                        <sld:AnchorPointX>
                          <ogc:Literal>0.5</ogc:Literal>
                        </sld:AnchorPointX>
                        <sld:AnchorPointY>
                          <ogc:Literal>0.5</ogc:Literal>
                        </sld:AnchorPointY>
                      </sld:AnchorPoint>
                      <sld:Displacement>
                        <sld:DisplacementX>
                          <ogc:Literal>0.0</ogc:Literal>
                        </sld:DisplacementX>
                        <sld:DisplacementY>
                          <ogc:Literal>0.0</ogc:Literal>
                        </sld:DisplacementY>
                      </sld:Displacement>
                      <sld:Rotation>
                        <ogc:Literal>0.0</ogc:Literal>
                      </sld:Rotation>
                    </sld:PointPlacement>
                  </sld:LabelPlacement>
                  <sld:Halo>
                    <sld:Radius>
                      <ogc:Literal>2</ogc:Literal>
                    </sld:Radius>
                    <sld:Fill>
                      <sld:CssParameter name="fill">#FFFFFF</sld:CssParameter>
                    </sld:Fill>
                  </sld:Halo>
                  <sld:Fill>
                    <sld:CssParameter name="fill">#000000</sld:CssParameter>
                  </sld:Fill>
                  <sld:VendorOption name="autoWrap">100</sld:VendorOption>
                  <sld:VendorOption name="maxDisplacement">50</sld:VendorOption>
                </sld:TextSymbolizer>
              </sld:Rule>
              <sld:Rule>
                <sld:Name>fill</sld:Name>
                <sld:MaxScaleDenominator>25000.0</sld:MaxScaleDenominator>
                <sld:PolygonSymbolizer>
                  <sld:Fill>
                    <sld:CssParameter name="fill">#B3B3B3</sld:CssParameter>
                  </sld:Fill>
                </sld:PolygonSymbolizer>
              </sld:Rule>
            </sld:FeatureTypeStyle>
          </sld:UserStyle>
        </sld:UserLayer>
      </sld:StyledLayerDescriptor>
    
  • Set the thumbnail as we have done previously

Parcels

  • From the location /opt/data/sample_data/pretty_maps/data/boulder upload the layer Parcels image

  • From the location /opt/data/sample_data/pretty_maps/styles upload the style foss4g_parcels.sld; the layer appear only at very high levels of zoom image

  • Set the thumbnail as we have done previously

Pointlm

  • From the location /opt/data/sample_data/pretty_maps/data/boulder upload the layer pointlm

  • From the location /opt/data/sample_data/pretty_maps/styles upload the style foss4g_point_landmark_ds_ns.sld

  • At a first glance, the layer appear as a set of grey suqare points; let’s take a closer look at the SLD definition

    <?xml version="1.0" encoding="UTF-8"?>
       <sld:StyledLayerDescriptor
       xmlns="http://www.opengis.net/sld"
       xmlns:sld="http://www.opengis.net/sld"
       xmlns:ogc="http://www.opengis.net/ogc"
       xmlns:gml="http://www.opengis.net/gml"
       xmlns:xlink="http://www.w3.org/1999/xlink" version="1.0.0">
    
         <sld:UserLayer>
           <sld:LayerFeatureConstraints>
             <sld:FeatureTypeConstraint/>
           </sld:LayerFeatureConstraints>
           <sld:UserStyle>
             <sld:Name>tl 2010 08013 pointlm</sld:Name>
             <sld:Title/>
             <sld:FeatureTypeStyle>
               <sld:Rule>
                 <sld:Name>landmarks</sld:Name>
                 <ogc:Filter>
                     <ogc:PropertyIsGreaterThan>
                       <ogc:Function name="strLength">
                         <ogc:PropertyName>IMAGE</ogc:PropertyName>
                       </ogc:Function>
                       <ogc:Literal>0</ogc:Literal>
                     </ogc:PropertyIsGreaterThan>
                 </ogc:Filter>
                 <sld:PointSymbolizer>
                   <sld:Graphic>
                     <sld:ExternalGraphic>
                       <sld:OnlineResource xlink:type="simple" xlink:href="./img/landmarks/${IMAGE}" />
                       <sld:Format>image/png</sld:Format>
                     </sld:ExternalGraphic>
                   </sld:Graphic>
                   <VendorOption name="labelObstacle">true</VendorOption>
                 </sld:PointSymbolizer>
                 <sld:TextSymbolizer>
                   <sld:Label>
                     <ogc:PropertyName>FULLNAME</ogc:PropertyName>
                   </sld:Label>
                   <sld:Font>
                     <sld:CssParameter name="font-family">Arial</sld:CssParameter>
                     <sld:CssParameter name="font-size">12.0</sld:CssParameter>
                     <sld:CssParameter name="font-style">normal</sld:CssParameter>
                     <sld:CssParameter name="font-weight">normal</sld:CssParameter>
                   </sld:Font>
                   <sld:LabelPlacement>
                     <sld:PointPlacement>
                       <sld:AnchorPoint>
                         <sld:AnchorPointX>
                           <ogc:Literal>0.5</ogc:Literal>
                         </sld:AnchorPointX>
                         <sld:AnchorPointY>
                           <ogc:Literal>1.0</ogc:Literal>
                         </sld:AnchorPointY>
                       </sld:AnchorPoint>
                       <sld:Displacement>
                         <sld:DisplacementX>
                           <ogc:Literal>0.0</ogc:Literal>
                         </sld:DisplacementX>
                         <sld:DisplacementY>
                           <ogc:Literal>-14.0</ogc:Literal>
                         </sld:DisplacementY>
                       </sld:Displacement>
                       <sld:Rotation>
                         <ogc:Literal>0.0</ogc:Literal>
                       </sld:Rotation>
                     </sld:PointPlacement>
                   </sld:LabelPlacement>
                   <sld:Halo>
                     <sld:Radius>
                       <ogc:Literal>1.5</ogc:Literal>
                     </sld:Radius>
                     <sld:Fill>
                       <sld:CssParameter name="fill">#FFFFFF</sld:CssParameter>
                     </sld:Fill>
                   </sld:Halo>
                   <sld:Fill>
                     <sld:CssParameter name="fill">#000033</sld:CssParameter>
                   </sld:Fill>
                   <sld:Priority>200000</sld:Priority>
                   <sld:VendorOption name="autoWrap">100</sld:VendorOption>
                 </sld:TextSymbolizer>
               </sld:Rule>
             </sld:FeatureTypeStyle>
           </sld:UserStyle>
         </sld:UserLayer>
       </sld:StyledLayerDescriptor>
    

    We can notice the notation xlink:href="./img/landmarks/${IMAGE}"; this is a GeoServer extension allowing us to read some values from the source layer attributes and use them to dynamically render the SLD.

    In that specific case, GeoServer looks for some file names accordingly to the ${IMAGE} attribute value into a relative folder named ./img/landmarks/.

    In order to correctly render this style, we will need to copy this folder containing the images correctly named, into the GeoServer styles folder.

    We will have also to give to that folder the correct permissions allowing GeoServer to be able to access it.

  • The first step is to copy the img folder into the correct GeoServer styles one

    • Open a system file browser window and go to /opt/data/sample_data/pretty_maps/styles

    • RIGHT-CLICK on the img folder

    • Select Copy from the side menu

    image

  • From the system file browser window go to /opt/data/geoserver_data/workspaces/geonode/; it will probably ask for ROOT permissions. Just insert the password geonode everytime it asks for image

  • Go to the styles folder inside the geonode workspace and hit CTRL+V; this will copy the img folder into the new location image

  • RIGHT-CLICK on the newly created img folder and click on the Properties link of the context menu image

  • Assign the permissions to the others group like shown in the figure below image

  • Refresh the layer page, you should be able to see the icons appearing on the map preview image

  • Set the thumbnail as we have done previously

Remaining Boulders Layers

  • From the location /opt/data/sample_data/pretty_maps/data/boulder upload the layers:

    • srtm_boulder

    • Streets

    • Trails

    • Wetlands_regulatory_area

    image

  • From the location /opt/data/sample_data/pretty_maps/styles upload the styles:

    • foss4g_dem2.sld to srtm_boulder

    • foss4g_streets.sld to Streets

    • foss4g_trails.sld to Trails

    • foss4g_wetlands.sld to Wetlands_regulatory_area