Published on GEOG 585: Web Mapping (https://www.e-education.psu.edu/geog585)

Home > Lessons > Lesson 4: Drawing and querying maps on the server using WMS

Lesson 4: Drawing and querying maps on the server using WMS

The links below provide an outline of the material for this lesson. Be sure to carefully read through the entire lesson befor returning to Canvas to submit your assignments.
Note: You can print the entire lesson by clicking on the "Print" link above.

Overview

Up to this point, you have largely worked with data on your local machine using QGIS. In this lesson, you'll take a step into the web world by making some of your map layers available on GeoServer as web services. 

This lesson focuses on web services that use the Open Geospatial Consortium (OGC) Web Map Service (WMS) specification. GIS professionals have been using WMS to draw FOSS web maps for years. WMS doesn't use the latest and slickest technology, but it's a functional and widespread specification that's important for you to understand and feel comfortable with.

As part of this lesson, you'll practice serving some of your term project data as a WMS; however, you are not required to use the layer in your term project if you decide there is a more appropriate format. As you'll see in the next few lessons, there are various other ways to draw layers in a web map.

Objectives

  • Identify the pros and cons to using a dynamically drawn web map service (as opposed to a tiled service).
  • Recognize the role of OGC in defining open geospatial web service specifications.
  • List the basic functions of a WMS and describe how and why each would be invoked.
  • Expose GIS datasets as a WMS using GeoServer.
  • Use SLDs to define layer styling in a WMS. Create the SLDs using code and using the GUI environment of QGIS.
  • Identify and critique a WMS used in a public-facing web site.

Checklist

  • Read the Lesson 4 materials on this page.
  • Complete the two walkthroughs.
  • Complete the Lesson 4 assignment.

Dynamically drawn map services

There are various ways to get a map to show up in someone's web browser. One way is for the server to send predrawn map images (or tiles) to the browser, another way is for the server to send a bunch of text and attributes that the browser draws, and a third way is to draw the map on the server at the time of request and send the browser the completed map image. This third way is what we'll discuss in this lesson. It's sometimes called a dynamic map service because, being drawn on the fly, it reflects the most recent picture of the data. Contrast this with the tiled map approach, which represents a static picture of the data taken at one point in time (when all the tiles were generated).

Advantages of dynamically drawn map services

Because dynamically drawn map services retrieve the data and draw it at the time of request, they are useful for gaining a situational awareness of the most recent state of the data. They may be the only reasonable way to depict many features that are changing at the same time (such as the positions of each vehicle in a large fleet). Dynamically drawn maps may also be the best solution at large scales where tiled maps become too cumbersome to generate, store, or maintain.

Maps dynamically drawn through WMS allow you to apply a wide range of symbols and styles using a concept called Styled Layer Descriptors (SLDs), which is described later in this lesson. If you enjoy using the QGIS authoring environment for your maps, you can export an SLD and import it into GeoServer, thereby allowing web users to apply the same styling that you configured on the desktop. Map layers drawn by the web browser may not be able to use symbols as complex as ones drawn by the server.

Disadvantages of dynamically drawn map services

Waiting for the server to draw the map can be a slow painful experience, especially if there are many layers to render. A wait time of 2 - 3 seconds that may be considered acceptable on the desktop may not be tolerated by edgy web map users who are neither knowledgeable nor sympathetic to the type of back end technology being used. People now expect every map to perform as fast as Google Maps and, without using tiles, this can be difficult to achieve.

Dynamically drawn services are also much more susceptible to overload than tiled services if you have many users deciding they want to see the map at the same time. This presents a paradox: you want your map to be useful, but the more exposure it gets, the slower it will run if the server technology is not scalable.

If you know you have a limited audience for your application (such as a small municipality, or a team of scientists), you may safely decide that the performance of your dynamically drawn map service is "good enough." This can spare you the work of generating and maintaining a tiled service.

Server software for dynamically drawn maps

In this course, you'll use GeoServer for drawing dynamic map services through WMS. Other FOSS software that can do this includes:

  • Map Server [1] - Sometimes called the "Minnesota Map Server," this was developed at the University of Minnesota in the 1990s.
  • QGIS Server [2] - This is a promising-looking extension for QGIS that allows you to publish your QGIS map directly through WMS. It is currently not available for Windows.
  • Deegree [3] - Java-based FOSS for GIS web services, born out of Germany in the early 2000s.
  • Others? - Because WMS is an open specification, any developer with enough skill and gumption can develop server software that supports it. Have you used any other FOSS software for creating WMS? Let us know about it in the course forums.

Proprietary GIS software such as Esri ArcGIS for Server also supports WMS and other OGC specifications. Although Esri has their own format for map services, many of their clients have interoperability requirements mandating that their web services be available through WMS. Hence, when you publish a map service in ArcGIS for Server, you see a checkbox that can allow the service to speak through WMS specifications.

Open specifications for web map services

In the previous lesson, you learned about some open formats for data stored on your machine as files and databases. Now, let's examine some of the open specifications for web services that draw maps.

What is a specification document?

Recall from Lesson 1 that a web service receives a user request and sends back a response. In order for web services to work across platforms, the syntax for the requests and responses needs to be consistent and openly described in what is called a "specification" document. When software developers create a server or a client that supports the web service, they treat the specification document as their Bible; it is a contract that must be closely honored in order for web services to correctly function.

To get a feel for what a specification looks like, take a minute to browse the Open Geospatial Consortium (OGC) WMS specification [4] (especially Section 7). Don't worry too much about what this all means. We'll dive into some of that later in the lesson. Just notice that there are clearly defined methods and parameters that you and the server must use if you want to communicate with the service.

Because specifications must describe every method and parameter of the web service, they can appear to be long and complicated documents. Fortunately, you rarely have to use the specification directly, because you will work with relatively user-friendly servers and clients are designed to abstract away the complexity of working with web services. For example, later in this lesson, you'll use GeoServer to create a WMS and QGIS to display the WMS on a map. You don't have to refer to the WMS specification in order to do this, because these programs take care of formulating the request and working with the response. You can be certain, however, that the developers of GeoServer and QGIS had to examine the WMS specification in great detail when writing their source code.

OGC W*S specifications

The OGC is an industry consortium that develops open specifications for spatial data and web services. The OGC is comprised of representatives from private companies, government organizations, NGOs, and universities.

OGC has produced a series of specifications for GIS web services named in the format Web _____ Service (sometimes abbreviated as W*S). For example:

  • Web Map Services (WMS) return a rasterized image of a map drawn by the server. This doesn't allow much complex analysis, but it is so useful for visualization that WMS has become the most widely implemented and supported of the W*S services.
    The basic WMS draws the map on the fly, but additions to the WMS specification provide syntax for requesting predrawn image tiles from the server. To get started, we'll just work with the dynamically drawn WMS.
  • Web Feature Services (WFS) return vector geometries and attributes allowing for spatial analysis and editing. The vector features are communicated in XML using Geography Markup Language (GML), itself an open specification defined by the OGC for transferring vector feature data.
  • Web Coverage Services (WCS) return blocks of data called coverages (not to be confused with the old vector Arc/INFO coverages) that are commonly used for raster display and analysis.
  • Web Processing Services (WPS) allow a user to invoke geoprocessing operations on the server.

Virtually all FOSS GIS servers and some proprietary ones have engineered their web services to communicate through OGC specifications. Additionally, many client APIs for developing web maps, such as OpenLayers and Leaflet, support WMS as web map layers. Desktop GIS programs like QGIS support the use of WMS as layers. In fact, the buttons OGC buttons in QGIS allow you to add (from left to right) WMS, WCS, and WFS web services as layers in QGIS.

The GeoServices REST Specification

In 2010, the proprietary GIS software company Esri released an open document called the GeoServices REST Specification (now the GeoServices API [5]) describing the request and response patterns used by default for its ArcGIS for Server web services. (Although I mentioned that you can enable OGC communication on an ArcGIS for Server service, this option is not the default.)

The GeoServices REST Specification uses a RESTful pattern of communication with the web services. Whereas the OGC services offer a simple list of methods that typically return XML (when they're not returning an image), REST exposes information in a navigable hierarchy of URLs that can return focused packets of HTML, JSON, images, or other data types. For example, using REST and the GeoServices REST specification, you can invoke http://<server>/MapServer/layers/ to get a list of layers in a map service and http://<server>/MapServer/layers/0 to get information about the first layer in the service (with index 0), and so forth.

Although ArcGIS for Server had already been using this pattern of communication for several years, Esri eventually placed the specification online as an open document so that developers would feel encouraged (or at least legally allowed) to implement clients and servers supporting this pattern.

Some controversy around the specification erupted in 2013 when a slightly modified version of the document (with the Esri references scrubbed out) was submitted to a vote for adoption as an OGC specification. Proponents, including Esri, argued that the OGC lacked a nimble, RESTful alternative to the W*S specifications (this lesson previously linked to a 2013 Esri User Conference Q & A item elaborating this argument, but this document has since been taken offline). Opponents expressed concern [6] about functional overlap with existing service types, and claimed that OGC adoption of the specification would give Esri an unfair advantage in competing for contracts. The uproar was significant enough to get the specification pulled from the voting process.

Although the GeoServices REST Specification is not an OGC specification, I am mentioning it in this lesson as an example of a specification that was voluntarily made open by a proprietary software vendor for the purposes of encouraging interoperability and the proliferation of the vendor's platform. It is likely that you will encounter this specification at some point in your career if you do any development with web services that somebody has hosted on ArcGIS for Server.

Basics of the WMS specification

The Open Geospatial Consortium (OGC) Web Map Service (WMS) specification provides a pattern for serving maps through web services. The WMS receives a request detailing the bounding box (or extent) of the map, the layers to include, the projection to use, and other parameters. It returns a rasterized map image in a common format such as JPG, GIF, or PNG. It does not return any actual GIS data, although an optional part of the specification describes how a user can query any pixel of the service to retrieve attribute information.

WMS has been around since the year 2000 and was supported by some of the earliest FOSS GIS servers. It is still widely supported today in FOSS and proprietary GIS software. Although it has been sometimes criticized as clunky, WMS has enabled a greater degree of interoperability in the world of online mapping.

Consider WMS as an option if you do need a high level of interoperability and you don't require lightning fast performance or the ability to handle dozens of concurrent users. If you need greater performance and scalability, you should consider tiled maps, including the OGC-endorsed WMTS (Web Map Tile Service) specification. Tiled map services are described in the next lesson.

Requesting a map from a WMS using the GetMap operation

The best way to get familiar with WMSs is to look at a real one. Therefore, make a close examination of the following URL and then open the link in a web browser:

http://esdac.jrc.ec.europa.eu/viewer/geoserver/geonode/wms?
SERVICE=WMS&
version=1.1.1&
REQUEST=GetMap&
LAYERS=oc_top&
STYLES=&
BBOX=-10.6152245918,31.5809474906,34.8097169992,70.0960552072&
SRS=EPSG:4326&
FORMAT=image/png&
WIDTH=1200&
HEIGHT=900
[7]

This request uses the WMS's GetMap operation to retrieve a map of percentage of organic carbon content in the topsoil in European Union countries. I found this WMS on the European Soil Data Centre (ESDAC) [8] web portal.  

 EU soils WMS
Figure 4.1

Although a WMS can perform several types of operations, GetMap is the most common. It's the one that sends you back a map image.

The root piece of a WMS URL (in this case http://esdac.jrc.ec.europa.eu/viewer/geoserver/geonode/wms [9]?) can be formed in various ways, but the parameters following the ? must be formatted according to the WMS specification. Let's examine the parameters used in the above URL.

Enter Table caption
Parameter Example value Notes
SERVICE WMS Indicates that a WMS is being called.
VERSION 1.1.1 The version of the WMS specification that this WMS can be expected to comply with
REQUEST GetMap This is the operation being requested from the WMS. The GetMap method is the most common operation called on a WMS and is the one that actually returns a map image. The GetCapabilities method is another common operation that returns you some XML metadata describing what the WMS can do.
LAYERS oc_top A comma-delimited list of layers that the WMS should include when it draws the map. Some WMSs (like this one) are treated as collections of separate layers that are not intended to be drawn together. Other WMSs have the layers designed to be overlayed or drawn in groups.
STYLES In this parameter, you can define your own styles to apply to the WMS when it is drawn. We did not submit this parameter, therefore we get the default styling defined on the server.
SRS EPSG:4326 The coordinate system that the WMS will use when it draws the map. Here it is specified using an EPSG code (which you saw in previous lessons). Clients can request the WMS to be drawn in WGS 84 (EPSG:4326) or any coordinate system that the WMS publisher has explicitly enabled on the WMS. If you're not sure what coordinate systems the WMS publisher has enabled, then you could use the GetCapabilities method to find out before requesting a map image.
BBOX -10.6152245918,31.5809474906,
34.8097169992,70.0960552072
The rectangular extent of the map to be returned by the WMS. This is given by specifying the coordinates of the lower left corner and the upper right corner in a comma delimited fashion.
FORMAT image/png The image format that should be returned by the WMS. In this case, the server will return a PNG. Your choice can affect the performance of your service. For remotely sensed imagery, a format like image/jpeg might result in less data being transferred between the server and the client (and therefore a faster draw time).
WIDTH 1200 The width, in pixels, of the image to be returned.
HEIGHT 900 The height, in pixels, of the image to be returned.

When you request a map from a WMS, there are some required parameters that you must supply and some optional parameters that you may decide to supply if the WMS publisher has implemented them. All the parameters in the above table are required. Optional parameters can display things like time and elevation dimensions. Table 8 in Section 7.3.2 of the Version 1.3.0 WMS Specification [4] shows all parameters for the GetMap request and whether they are required or optional. If you have questions about how to format the parameters, you can always refer to the specification; however, most GIS software gives you user-friendly interfaces for interacting with WMSs so that you don't have to formulate the URLs yourself.

Other WMS operations

Besides the GetMap request, WMS supports one other required operation (GetCapabilities) and an optional operation (GetFeatureInfo).

GetCapabilities

The GetCapabilities request returns metadata about the service, which you can use as a guide when making other types of requests. Here's what a GetCapabilities request would look like for our European soil threats WMS:

http://esdac.jrc.ec.europa.eu/viewer/geoserver/geonode/wms?SERVICE=WMS&REQUEST=GetCapabilities [10]

Notice that this URL is much less complex than the GetMap one. When you call GetCapabilities, you usually don't know much about the service yet; therefore, you aren't required to supply a bunch of parameters. You are essentially asking, "Tell me what this service contains and what it can do."

Take a look through the XML response returned in your web browser when you hit the above URL

Notice that you can see information about each layer in the WMS, which is helpful when you are making a GetMap request and you want to know the appropriate names to specify for the LAYERS parameter.

<Layer queryable="1" opaque="0">
   <Name>oc_top</Name>
   <Title>OC_TOP: Topsoil Organic Carbon</Title>
   <Abstract>
       OC_TOP = Topsoil organic carbon content. The list of authorised codes and their corresponding meanings is given in the following table: OC_TOP = Topsoil organic carbon content. Code Value -------------- H = High ( > 6 %) M = Medium (2 - 6 %) L = Low (1 - 2 %) V = Very low ( < 1 %)
  </Abstract>
   ...
</Layer>

You can also see a list of the spatial reference systems that the service publisher has decided to support for the layer.

<CRS>EPSG:4326</CRS>
<CRS>CRS:84</CRS>

GetFeatureInfo

GetFeatureInfo is an optional method that the service publisher can enable, allowing users to query the attribute data of a WMS layer at a specific location. This makes it possible to add interactive elements such as informational popups without enlisting the help of a second web service.

When you make a GetFeatureInfo request, you supply many of the same parameters as the GetMap request, with the addition of the screen coordinates of the pixel you want to query.

The European soils example says that the oc_top layer is queryable, so try the following query URL to query for the feature at coordinates x=600 and y=400 within the map image with width=1200 and height=900: 

http://esdac.jrc.ec.europa.eu/viewer/geoserver/geonode/wms?
SERVICE=WMS&
version=1.1.1&
REQUEST=GetFeatureInfo&
LAYERS=oc_top&
STYLES=&
SRS=EPSG:4326&
BBOX=-10.6152245918,31.5809474906,34.8097169992,70.0960552072&
FORMAT=image/png&
WIDTH=1200&
HEIGHT=900&
QUERY_LAYERS=oc_top&
INFO_FORMAT=text/plain&
X=600&
Y=400
[11]

The returned plain text response in this case will tell you that there is a polygon feature with ID 31985 and organic carbon content high (H) at this location:

Results for FeatureType 'http://h05-dev-vm44.jrc.it:oc_top':
--------------------------------------------
the_geom = [GEOMETRY (Polygon) with 75 points]
objectid = 31985
oc_top = H
--------------------------------------------

GetFeatureInfo is somewhat of a wildcard, because the WMS specification does not mandate any particular structure or format for the returned information. If you don't know who published the service, you must make a request and examine the response in order to understand how to work with the returned information. The GetCapabilities response can show you the supported INFO_FORMATs you can request:

<GetFeatureInfo>
   <Format>text/plain</Format>
   <Format>application/vnd.ogc.gml</Format>
   <Format>text/xml</Format>
   ...
</GetFeatureInfo>

Applying styles and symbols to a WMS

The OGC allows some flexibility to adjust the map symbols used in WMS layers. This is accomplished by referencing a chunk of XML called a Styled Layer Descriptor (SLD). An SLD describes all the symbol sizes, colors, and markers that should be applied within the WMS. SLDs are complex enough that they have their own OGC specification documents [12] defining how they are supposed to operate.

SLDs can be designed by either the service publisher or the client. To formulate a really useful SLD, you have to know a little bit about the layers in the WMS. You can get this by calling the optional DescribeLayer operation on the WMS.

Once you've created the XML for your SLD, you can apply it in one of several ways. The most common way is to put the SLD in its own file on a web server somewhere and reference the URL of that file when you make a GetMap request. There is an optional SLD parameter in the GetMap request that you can use for this very purpose. Another way is to use the optional SLD_BODY parameter of the GetMap request and just provide the relevant chunk of XML directly in the URL of the request. This obviously can create long and unwieldy URLs, and requires a lot of special character encoding or escaping.

The XML used with SLDs can get verbose and tends to contain many nested levels. Because of this, it's unlikely that you'll sit down to compose an SLD from scratch. Instead, you'll probably start with a sample and adjust it to meet your needs. Alternatively, you can use the GUI environment from QGIS to style a layer and then save it out as an SLD. This is extraordinarily useful, but it has at least one big limitation: QGIS does not currently export labeling information into the SLD.

Both approaches (starting an SLD from an existing sample and exporting an SLD from QGIS) are covered in the lesson walkthrough.

SLDs and GeoServer

GeoServer maintains your data information and your style information completely separate. In the Layers page you define what datasets you want to serve, and in the Styles page you define all the SLDs you want available. The Publishing tab of the Edit Layer page is the (somewhat obscure) place where you connect the dots and define which style will be applied to your layer.

 Edit Layer page
Figure 4.2
 Another Edit Layer page
Figure 4.3

In the above graphic, the GeoServer administrator has examined the pool of all styles added to GeoServer (left) and selected three of those (right) to be available for use with the FarmersMarkets layer. The WMS will advertise these three styles for the layer and will use the one called FarmersMarkets if the user does not specify a different style in the STYLES parameter of the GetMap request.

The examples below are not functional, but they show you the URL structure for requesting different styles.

GetMap request that uses the default style ("FarmersMarkets"):

http://localhost:8080/geoserver/philadelphia/wms?service=WMS&version=1.1.0&request=GetMap&layers=philadelphia:FarmersMarkets&styles=&bbox=-8377237.031452011,4854963.883290707,-8357515.816574659,4877579.355521561&width=446&height=512&srs=EPSG:3857&format=image%2Fpng

GetMap request that overrides the default style and uses the style named "point" instead:

http://localhost:8080/geoserver/philadelphia/wms?service=WMS&version=1.1.0&request=GetMap&layers=philadelphia:FarmersMarkets&styles=point&bbox=-8377237.031452011,4854963.883290707,-8357515.816574659,4877579.355521561&width=446&height=512&srs=EPSG:3857&format=image%2Fpng

Notice that the latter URL includes styles=point, indicating that GeoServer should use the SLD named "point" to draw the layer. Alternatively the user could have specified styles=FarmersMarketsLabeled.

Required reading

Before you move on, please read the following pages of GeoServer documentation. This contains general information about SLDs, technical notes about how SLDs are applied in GeoServer, and a set of example SLDs that you can use to get started when it comes time to make your own. You'll get some practice with this technology during the walkthrough, but it is well worth your time to become familiar with this particular section of the documentation. In fact, it might be wise to read it both before and after you complete the walkthrough in order for you to confirm your learning and absorb the maximum amount of information.

  • Introduction to SLD [13]
  • Working with SLD [14]
  • SLD Cookbook [15]
  • Three or four examples of your choosing from the SLD Cookbook

Walkthrough: Serving and styling a WMS with GeoServer

In this walkthrough, you'll get some practice serving some geographic data as a WMS using GeoServer. The exercise will progress from simple to complex in the following manner:

  • Serving a single layer as a WMS using the default styling
  • Applying a style to the WMS using an SLD
  • Viewing the WMS in QGIS

The next walkthrough will go into more depth with SLDs and group layers.

As you complete these walkthroughs, think of some of your own data you'd like to serve as a WMS in fulfillment of the Lesson 4 assignment. You won't be required to use this WMS in your term project, but you can if you choose.

Serving a single layer as a WMS using the default styling

Let's start out by serving a single layer as a WMS. We'll stick with Philadelphia in this lesson so that we can eventually pull in some of the base layers that we clipped and projected previously. The first layer we'll work with is a polygon dataset of Philadelphia neighborhoods that I derived from a Zillow.com [16] shapefile.

  1. Download Neighborhoods.zip [17] and extract the contents into your Philadelphia data folder so that the files can be found at a path like c:\data\Philadelphia\Neighborhoods.shp. This data is already projected into EPSG:3857 and it doesn't need to be clipped for this exercise.
  2. Start GeoServer by clicking All Programs > GeoServer > Start GeoServer.
  3. Start the GeoServer Web Admin Page and log in with your administrator account (the username is probably "admin" with password "geoserver"). Refer to Lesson 2 if you need a refresher.

    The first thing you will do is create a workspace and a store. A workspace is a place where you can organize datasets for a project. A store is an actual folder or database. A workspace can contain multiple stores. Our scenario is pretty simple because you'll have one workspace and one store; however, if your data were spread out among many folders or databases, you would need to create more stores.
  4. In the left-hand menu, click Workspaces. You'll see some sample workspaces.
  5. Click Add New Workspace.
  6. In the Name field, type geog585.
  7. In the Namespace URI field type http://localhost:8080/geoserver/geog585 [18] and then click Submit. The Namespace URI doesn't have to be a real URL; it only needs to be a unique identifier. The GeoServer documentation suggests using a URL- like structure with the name of the workspace appended to it.
     Creating a new workspace in GeoServer
    Figure 4.4
  8. In the left-hand menu, click Stores and click Add New Store.

    Examine the types of stores you can add. Notice that if you are going to use raster data with GeoServer, you need to add it as a separate store from your vector data. In this exercise, we'll just be working with the folder of vector shapefiles of Philadelphia that you've collected during this course. This should be located at a path similar to c:\data\Philadelphia.
  9. Click Directory of spatial files (shapefiles).
  10. Complete the dialog box as in the graphic below, designating philadelphia as the name of the data source and browsing to your Philadelphia data folder where prompted to specify the directory of shapefiles.
     New data store
    Figure 4.5
    When you are finished, click Save. Note that you can create this store even though there are raster files in it. If you wanted to use the rasters, though, you would have to specify a separate store in GeoServer.

    Now you will go one level further and specify the actual shapefile that you want to expose as a layer.
  11. Click Layers > Add a New Layer. You'll be prompted to choose the store that will supply the layer.
  12. Choose to add the layer from geog585:philadelphia. You should see a list of layers from your Philadelphia folder.
  13. Find the Neighborhoods layer and click its Publish link.
     Publish layer
    Figure 4.6
  14. At this point, you'll see a lot of options for publishing the layer. Leave the defaults near the top of the page, but scroll down until you come to the Coordinate Reference Systems section of the page and set it up as in the image below. Note that instead of manually filling in the bounding box coordinates, you just need to click the links Compute from data and Compute from native bounds in order to fill in the bounding boxes. Prior to doing this, you need to make sure you declare your SRS as EPSG:3857 and that you set your SRS handling to Force declared. This allows you to serve data that is using the common web-based Mercator projection.
     Setting the layer CRS
    Figure 4.7

    Various programs have different ways of interpreting EPSG:3857, and some of them don't always match. I have found that if I do not set Force declared, my WMS is offset from other EPSG:3857 data by about 20 km when I try to display it all in QGIS.
  15. Scroll down to the bottom of the page and click Save.

    You should now see your layer appearing in the layer list. Let's take a look at it in a preview window.
  16. In the left-hand menu, click Layer Preview. Then find your layer in the list.
  17. Choose to preview your layer as a WMS in the OpenLayers example window.
     Selecting the WMS preview in OpenLayers
    Figure 4.8
    You should see a basic map like this:
     Basic WMS layer preview in OpenLayers
    Figure 4.9
    Notice the URL parameters above are the standard ones that you've learned about for WMS requests.

Styling the WMS using SLDs

The above WMS indeed contains the Philadelphia neighborhoods, but there are no labels and we didn't get to choose the color scheme. In this part of the walkthrough, you'll use an SLD to apply a blue outline and labels with no fill. This will allow the neighborhoods WMS to act as a thematic layer that you can place on top of other base layers.

To work with SLDs in GeoServer, you first add the SLD under the Styles list. Then you can go back into the layer properties and apply the style. Decoupling the styles and the layers in this fashion allows you to reuse a particular style on multiple layers.

The first thing we'll do is prepare the SLD, starting with an existing sample and then modifying it to meet our needs.

  1. Open the SLD Cookbook to the Polygon with styled label [19] example. This comes pretty close to what we want, so we're going to start with it.
  2. Click View and download the full "Polygon with styled label" SLD. You will see the XML of the SLD example.
  3. Use your browser's save option to save the page contents with a file extension of .sld. For example: polygonwithstyledlabel.sld

    Do not copy and paste the XML out of the browser window, or you may fail to get the full XML headers and GeoServer won't like it. You must save the page as a .sld file.
  4. Open the .sld file in a text editor like Notepad and take a close look at the PolygonSymbolizer and TextSymbolizer options. You should see something like this:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    		<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>Polygon with styled label</Name>
    		    <UserStyle>
    		      <Title>SLD Cook Book: Polygon with styled label</Title>
    		      <FeatureTypeStyle>
    		        <Rule>
    		          <PolygonSymbolizer>
    		            <Fill>
    		              <CssParameter name="fill">#40FF40</CssParameter>
    		            </Fill>
    		            <Stroke>
    		              <CssParameter name="stroke">#FFFFFF</CssParameter>
    		              <CssParameter name="stroke-width">2</CssParameter>
    		            </Stroke>
    		          </PolygonSymbolizer>        
    		          <TextSymbolizer>
    		            <Label>
    		              <ogc:PropertyName>name</ogc:PropertyName>
    		            </Label>
    		            <Font>
    		              <CssParameter name="font-family">Arial</CssParameter>
    		              <CssParameter name="font-size">11</CssParameter>
    		              <CssParameter name="font-style">normal</CssParameter>
    		              <CssParameter name="font-weight">bold</CssParameter>
    		            </Font>
    		            <LabelPlacement>
    		              <PointPlacement>
    		                <AnchorPoint>
    		                  <AnchorPointX>0.5</AnchorPointX>
    		                  <AnchorPointY>0.5</AnchorPointY>
    		                </AnchorPoint>
    		              </PointPlacement>
    		            </LabelPlacement>
    		            <Fill>
    		              <CssParameter name="fill">#000000</CssParameter>
    		            </Fill>
    		            <VendorOption name="autoWrap">60</VendorOption>
    		            <VendorOption name="maxDisplacement">150</VendorOption>
    		          </TextSymbolizer>
    		        </Rule>
    		      </FeatureTypeStyle>
    		    </UserStyle>
    		  </NamedLayer>
    		</StyledLayerDescriptor>
    Notice the places where the stroke and fill colors are specified, as well as the text weight and font. Also notice the tags marked VendorOption, which are not part of all SLDs but are supported by GeoServer as a special means of finding suitable label locations (maxDisplacement) and forcing the labels to wrap after reaching a certain length (autoWrap). See this GeoServer documentation [20] for details.

    Let's edit the SLD to make a blue outline with a hollow fill, as well as blue labels. It is also critical that we change the name of the field that is supplying the label text (specified in the tag ogc:PropertyName). By default, in this example, the field is "name" but in our neighborhoods shapefile it is "NAME". The case sensitivity matters.
  5. Replace your original SLD text with the following, either carefully editing line by line or completely copying and pasting the text below. Make sure you understand which lines changed and why.
    <?xml version="1.0" encoding="ISO-8859-1"?>
    		<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>Polygon with styled label</Name>
    		   <UserStyle>
    		    <Title>SLD Cook Book: Polygon with styled label</Title>
    		    <FeatureTypeStyle>
    		     <Rule>
    		<PolygonSymbolizer>
    		       <Stroke>
    		        <CssParameter name="stroke">#133E73</CssParameter>
    		        <CssParameter name="stroke-width">2</CssParameter>
    		       </Stroke>
    		      </PolygonSymbolizer>     
    		      <TextSymbolizer>
    		       <Label>
    		        <ogc:PropertyName>NAME</ogc:PropertyName>
    		       </Label>
    		       <Font>
    		        <CssParameter name="font-family">Arial</CssParameter>
    		        <CssParameter name="font-size">11</CssParameter>
    		        <CssParameter name="font-style">normal</CssParameter>
    		        <CssParameter name="font-weight">bold</CssParameter>
    		       </Font>
    		       <LabelPlacement>
    		        <PointPlacement>
    		         <AnchorPoint>
    		          <AnchorPointX>0.5</AnchorPointX>
    		          <AnchorPointY>0.5</AnchorPointY>
    		         </AnchorPoint>
    		        </PointPlacement>
    		       </LabelPlacement>
    		       <Fill>
    		        <CssParameter name="fill">#133E73</CssParameter>
    		       </Fill>
    		       <VendorOption name="autoWrap">60</VendorOption>
    		       <VendorOption name="maxDisplacement">150</VendorOption>
    		      </TextSymbolizer>
    		     </Rule>
    		    </FeatureTypeStyle>
    		   </UserStyle>
    		  </NamedLayer>
    		</StyledLayerDescriptor>
  6. Save this text file (making sure you keep the extension as .sld) and open the GeoServer Web Admin Page.
  7. In the GeoServer Web Admin Page, click the Styles link in the left-hand menu.

    Notice there are some styles pre-loaded for you. You can also define your own, which we'll do.
  8. Click Add a new style.
  9. Before giving the style a name and a workspace, scroll down below the code window and click the Choose File button.
  10. Browse to the .sld file you just created, then click the Upload link. You should see the code load into the window.
  11. Now name your SLD PolygonWithStyledLabel and place it in the geog585 workspace.
     Add style
    Figure 4.10
  12. Scroll to the bottom of the page and click Submit to create your style. Before doing this, you can click Validate to make sure your XML is acceptable to GeoServer.

    You can come back to this page any time to make edits to your SLD. Any services using the SLD will be immediately updated.

    Now let's apply this SLD to the neighborhoods layer.
  13. In the left-hand menu, click Layers.
  14. Find your neighborhoods layer in the table and click the actual link that says Neighborhoods. This should take you to the Edit Layer page.
  15. Click the Publishing tab and scroll down to WMS Settings.
  16. In the Available Styles list, find your geog585:PolygonWithStyledLabel style and click the arrow button to move it over. Then set the Default style to PolygonWithStyledLabel.
     Setting the style on a layer
    Figure 4.11
    Notice that a layer can advertise various styles, but you can choose which one gets applied by default. The alternate style in this case would be the basic gray polygon.
  17. Click Save to preserve your changes.
  18. Use the Layer Preview link to preview your neighborhoods in the OpenLayers viewer as you did earlier in this walkthrough.
     Previewing the styled layer
    Figure 4.12

This is still not perfect (notice the many labels overlapping features), but it is progress, and it has opened the door to editing the style through other XML options defined in the SLD and GeoServer documentation.

In general, labeling is a tricky subject with web maps. Labeling is computationally intensive and relies on complex rules that can slow down the map drawing. The labeling rules available with GeoServer and WMS are relatively simple compared to the logic used by a desktop program like QGIS or ArcMap. Because of these issues, web map authors sometimes rely on alternative mechanisms such as interactive popups or text that changes dynamically depending on where you point or click the mouse (or tap the display). Fetching this information on demand is faster than waiting for thousands of labels to be placed and eliminates the reliance on complex labeling algorithms.

Viewing the WMS in QGIS

There are lots of clients you can use to view a WMS. You already saw how your WMS could be previewed with OpenLayers. Now let's take a few minutes to see how QGIS works with WMS layers. This is important if you want to bring web services into your desktop maps as backgrounds or thematic layers.

  1. Launch QGIS, start a new project, and click the Add WMS/WMTS Layer button. Add WMS/WMTS Layer
  2. In the Layers tab, click the New button. Here you will put the properties of your GeoServer workspace. All the layers in your workspace are exposed through the same root WMS URL.
  3. Enter the name as Geog585 Layers and the URL as http://localhost:8080/geoserver/geog585/wms [21]? as shown below. Notice that the geog585 in the URL is the name of the workspace you created in GeoServer.
     Making a WMS connection in QGIS
    Figure 4.13
  4. Click OK and then click Connect.
  5. Select the Neighborhoods layer and click Change. A WMS by default can display itself in EPSG:4326 (WGS 84 geographic coordinates) or any other coordinate systems that the server administrator would like to support. Your WMS supports EPSG:3857 and that's what you'd like to request from the server here in your maps.
  6. Set the coordinate reference system to EPSG:3857 and click OK.
  7. Make sure your dialog box looks like the one below. Click Add to add the layer, and then click Close to close the dialog box.
     Adding the neighborhoods WMS in QGIS
    Figure 4.14
    You should see the layer added to the display like this:
     WMS layer in QGIS
    Figure 4.15
    This is a good time to use the OpenLayers plugin that you may already have installed in Lesson 3. If you did not, please have a look at section "Processing spatial data with FOSS" [22] again. Let's put a simple basemap beneath this to give it some geographic context.se
  8. In QGIS, click Web > OpenLayers plugin > OSM/Stamen > Stamen Watercolor/OSM.
  9. Rearrange your layers so that the OSM streets are on the bottom.
     A WMS "mashup"
    Figure 4.16

Congratulations! You have just made a (somewhat strange) "mashup" that brings in web services from two different servers. In future lessons, you'll learn how to do this in a more practical fashion in a web application.

QGIS not only displays WMS layers; it can also help you create SLDs. In the next walkthrough, you'll make some SLDs using QGIS and learn how to group WMS layers together using GeoServer.

Walkthrough: Advanced styling and group layers with WMS

You've learned how to serve and style a single layer as a WMS using GeoServer and some basic SLD examples. Now, you'll go a bit further and use QGIS to set up your styles for you. You'll also see how you can group multiple WMS layers using GeoServer.

Some of the steps require you to apply the skills you learned in the previous walkthrough. You may need to pause and review in order to complete these steps.

Creating SLDs with QGIS

QGIS allows you to save out your current layer symbology as an SLD. You then apply the SLD in GeoServer using the same procedure you learned in the previous walkthrough. Styling layers in QGIS is a lot easier than writing XML. However, be aware that some features, such as labels, are not saved in the SLD. Also, the style may look slightly different when you apply it in GeoServer. Be prepared to use some trial and error to get things exactly right.

Let's style a couple of the other Philadelphia base layers that we used in previous lessons, such as roads and the city boundary. We'll eventually group these together with the neighborhoods layer within the same WMS.

  1. Use the procedure from the previous walkthrough to publish your Philadelphia/roads.shp and Philadelphia/city_limits.shp files as layers in GeoServer. This should be relatively easy because you do not have to create a new workspace and store. Use the geog585 workspace and the philadelphia store that you already set up. Just start from the step where you click the Layers link in the left-hand menu.

    When you finish, you should have two new layers in your layer list.
     Published layers
    Figure 4.17
  2. Launch QGIS and add the Philadelphia/roads.shp and Philadelphia/city_limits.shp files as layers. Make sure you are adding the shapefiles, not the newly published WMS services.

    Note: If the layers are vertically offset by 20 km, right-click each layer in the layer list and click Set Layer CRS. Then set the CRS to EPSG:3857. Even though you projected all these layers to EPSG:3857 using OGR, sometimes QGIS needs you to tell it to use its definition for EPSG:3857.
  3. Style the city limits as a very light gray fill with no outline.
  4. Style the roads as a slightly darker gray, using a thin line (the default width is fine). You should have something like this:
     Styling the layers in QGIS
    Figure 4.18
  5. In the layer list, double-click the roads layer to display the Style tab of the Layer Properties dialog box.
  6. Click Style > Save Style > SLD File and save it anywhere as grayroads.sld.
     Saving an SLD in QGIS
    Figure 4.19
  7. Go back to the GeoServer Web Admin page and click Styles in the left-hand menu.
  8. Use the procedure from the previous walkthrough to create a new style called grayroads. As part of this process, upload the grayroads.sld file that you saved out of QGIS.
  9. Use the procedure from the previous walkthrough to apply your grayroads style as the default style for the Philadelphia roads layer that you have published in GeoServer. Preview your layer in OpenLayers to ensure the styling was applied as expected.
     Previewing the style in OpenLayers
    Figure 4.20
    The above steps are significant because you were able to achieve the desired styling without editing any XML.
  10. Repeat the above steps for the light gray city boundary style. Specifically, save the light gray polygon styling out as an SLD, create a style in GeoServer using this SLD, and then apply it as the default style for the city_limits layer. If you run into trouble, post a message on the course discussion forums.

Grouping multiple layers in a WMS using GeoServer

In some cases, you'll use WMS for your thematic layer and lay it in on top of a non-WMS basemap that uses tiles. This is what you did in the previous walkthrough. In some cases, when you have a very simple map, you may use a WMS for both the thematic layers and the base layers. Let's take a look at how GeoServer allows you to group multiple layers together in a single WMS. We'll use the neighborhoods layer, the city boundaries layer, and the roads layer that you have already published and styled in your geog585 workspace.

  1. Open the GeoServer Web Admin page and click Layer Groups in the left-hand menu.
  2. Click Add new layer group.
  3. Set up the first four properties as follows:
    Name - NeighborhoodMap
    Title - Philadelphia Neighborhood Map
    Abstract - Map of Philadelphia neighborhoods using data derived from Zillow.com
    Workspace - geog585
  4. Scroll down, and add your three layers using the Add Layer link. Use the arrows to put them in the order shown below. Notice that the top layer in the list is drawn first, the second layer in the list is drawn on top of that, etc., resulting in a layer list in reverse order from what you'd expect.
     Layer order
    Figure 4.21
  5. Scroll up a bit, and set the coordinate reference system to EPSG:3857. Then click Generate Bounds to calculate the bounding coordinates for the service.
     Setting bounds for the group layer
    Figure 4.22
  6. Go to the Tile Caching tab, and uncheck the first three checkboxes under Tile cache configuration. Although GeoServer allows you to create a tile cache for this layer, we will focus on creating caches in the next lesson using a program called TileMill that has superior drawing options.
  7. Click Save. You should see your new group layer in the list.
  8. Use the Layer Preview link to preview your group layer in the OpenLayers viewer. You should see something like the styling below (note that I have zoomed in the preview from its initial extent).
     Previewing the group layer in OpenLayers
    Figure 4.23
  9. Open a new map in QGIS, and connect to the group layer using the techniques from the previous walkthrough. Remember to set the CRS to EPSG:3857.
     Adding the group layer in QGIS
    Figure 4.24
    The layer should appear in your QGIS layer list as a single entity:
     Viewing the group layer in QGIS
    Figure 4.25

If you get an error when adding the layer, try cleaning out your QGIS WMS cache by clicking the Settings menu > Options and then clicking the Clear button under Cache settings.

This exercise has shown how you can style any number of layers and group them together as a dynamically drawn WMS in GeoServer. If you have many layers to combine, it's faster and more scalable to use tiles, which you'll learn about in the next lesson. However, the techniques you've learned with WMS are sufficient to launch a quick and easy web map if you'll only have a few layers or a limited number of people using the map.

Lesson 4 assignment: Review a WMS and serve some of your term project data as a WMS

As you've completed the walkthroughs, you've hopefully begun to think about ways that you could serve your own term project data as a WMS. You are not required to use a WMS in your term project, but I would like you to get some more practice with it using your own data. If you like the result, you're welcome to use it in your term project submission.

The assignment this week has two parts:

  1. Find a public-facing WMS that we have not used in this class, and post a review on the Lesson 4 assignment (part 1) forum on Canvas. Please note that you should write about a public WMS and not about a web map that uses data from a WMS. The review should include the following:

    - the URL for the WMS;
    - the organization that published the WMS and what technology they used (if you can figure that out);
    - a description of the layers available in the WMS (what you learned in section "Basics of the WMS specification" may help you obtain information about the layers);
    - a critique of the styling in the WMS and how it might be improved using the approaches in this lesson.
  2. Using GeoServer and the techniques learned in this lesson, serve some of your term project data as a WMS. This can be a single layer or a group layer, but it should use custom styling that goes beyond the GeoServer default style. Assemble a word processor document with a report containing the following and submit it to the Lesson 4 (part 2) drop box:

    - a description of the layer you served;
    - a screenshot of the layer(s) in the GeoServer layer list;
    - a description of how you made the style;
    - a screenshot of the style page in GeoServer (including as much of the SLD code as possible);
    - a screenshot of the WMS displayed in the OpenLayers preview;

    Above & beyond: Successful delivery of the above requirements is sufficient to earn 90% on this assignment. The remaining 10% is reserved for efforts that go "above & beyond" the minimum requirements. For this, browse through the examples from the SLD Cookbook [15] and adapt an approach described there (but not detailed in the lesson materials!) to achieve some advanced styling of your data by manually editing the SLD code. Make sure you mention what you did for above & beyond points in the document you submit.

Source URL: https://www.e-education.psu.edu/geog585/node/696

Links
[1] http://mapserver.org/
[2] http://docs.qtibia.ro/en/docs/user_manual/working_with_ogc/ogc_server_tutorial.html
[3] http://www.deegree.org/
[4] http://portal.opengeospatial.org/files/?artifact_id=14416
[5] http://geoservices.github.io/
[6] http://wiki.osgeo.org/wiki/Geoservices_REST_API
[7] http://esdac.jrc.ec.europa.eu/viewer/geoserver/geonode/wms?SERVICE=WMS&amp;version=1.1.1&amp;REQUEST=GetMap&amp;LAYERS=oc_top&amp;STYLES=&amp;BBOX=-10.6152245918,31.5809474906,34.8097169992,70.0960552072&amp;SRS=EPSG:4326&amp;FORMAT=image/png&amp;WIDTH=1200&amp;HEIGHT=900
[8] http://esdac.jrc.ec.europa.eu/
[9] http://esdac.jrc.ec.europa.eu/viewer/geoserver/geonode/wms
[10] http://esdac.jrc.ec.europa.eu/viewer/geoserver/geonode/wms?SERVICE=WMS&amp;REQUEST=GetCapabilities
[11] http://esdac.jrc.ec.europa.eu/viewer/geoserver/geonode/wms?SERVICE=WMS&amp;version=1.1.1&amp;REQUEST=GetFeatureInfo&amp;LAYERS=oc_top&amp;STYLES=&amp;SRS=EPSG:4326&amp;BBOX=-10.6152245918,31.5809474906,34.8097169992,70.0960552072&amp;FORMAT=image/png&amp;WIDTH=1200&amp;HEIGHT=900&amp;QUERY_LAYERS=oc_top&amp;INFO_FORMAT=text/plain&amp;X=600&amp;Y=400
[12] http://www.opengeospatial.org/standards/sld
[13] http://docs.geoserver.org/stable/en/user/styling/sld/introduction.html
[14] http://docs.geoserver.org/stable/en/user/styling/sld/working.html
[15] http://docs.geoserver.org/stable/en/user/styling/sld/cookbook/index.html
[16] http://www.zillow.com/howto/api/neighborhood-boundaries.htm
[17] https://www.e-education.psu.edu/geog585/sites/www.e-education.psu.edu.geog585/files/lesson4/Neighborhoods.zip
[18] http://localhost:8080/geoserver/geog585
[19] http://docs.geoserver.org/stable/en/user/styling/sld/cookbook/polygons.html#polygon-with-styled-label
[20] http://docs.geoserver.org/latest/en/user/styling/sld/reference/labeling.html
[21] http://localhost:8080/geoserver/geog585/wms
[22] https://www.e-education.psu.edu/geog585/node/692