Using WMS with OpenLayers

From CUOSGwiki
Jump to navigationJump to search

Introduction

The goal of this project is to use freely available Web Map Service (WMS) layers with OpenLayers to create a dynamic map for use within a web browser. In particular, the hope was to include a land use layer for Canada, and the user could browse to a desired location to determine how the land is being used. If the user knows the coordinates of the place they want to view, they can modify the source code by entering the chosen longitude, latitude, and zoom level. Then when loading the map the images will be centered within the map window. For the following example, only GeoBase and Toporama WMS layers are used, and they can be accessed at no cost and without restrictions.

This tutorial contains a brief outline of Web Map Service (WMS) layers and OpenLayers, and then descriptions of the methods used to create the map displayed in Section 4. This includes discussion of the important aspects of the HTML code that generated the resulting map, as well as why the use of OpenLayers is suitable to achieve the desired goals.


Data and Mapping Tools

WMS Layers

WMS provides a HTTP interface for requesting geo-registered map images from one of more geospatial databases. A WMS request defines the geographic layer(s) and area of interest that will be processed.[1] There is then a response to the request where geo-registered map images (in the following example returned as a PNG) can be displayed within a browser.

If the user has included more than one WMS layer, they have the ability to specify which will be the base layer, and which will be overlay layers. If the user then wants multiple images to be combined, the overlay layers need to be designated transparent. This is not necessary, however, as the user may want only one layer to appear at a time. This can be done by making the transparent flag false for each of the overlay layers, and then the user can manually switch between layers through the web browser. With OpenLayers the ‘LayerSwitcher’ control, which can be added into the code, is a popup that allows the user to do this by simply selecting which layer they want to view.

There are six WMS layers being used in the following example. The first layer, which is being used as the base map is obtained from Geobase, and it contains foreign landmass political boundaries. The additional overlay layers which encompass all of Canada are as follows:

Surface water network (layer name: hydrography). Obtained from: NRCan's Toporama

Landcover (layer name: landcover:csc2000): Geobase

Primary Roads (layer name: nrn:roadnetwork:roadseg_primary): Geobase

Secondary Roads (layer name: nrn:roadnetwork:roadseg_secondary): Geobase

Cities (layer name:populated_places): NRCan's Toporama


The GeoBase and Toporama WMS support mandatory GetCapabilities and GetMap operations as defined in the OGC WMS standard, version 1.1.1. Get Capabilities is an operation that produces a descriptive XML document that includes general information on the WMS, as well as descriptions of each data layer. An example of this type of request addressed to GeoBase is http://ows.geobase.ca/wms/geobase_en?service=wms&request=GetCapabilities&version=1.1.1, and to NRCan’s Toporama is http://wms.ess-ws.nrcan.gc.ca/wms/toporama_en?VERSION=1.1.1&request=GetCapabilities&service=wms. This was used for this project and it allowed the user to fully understand what each layer was representing.


OpenLayers

OpenLayers is an open source JavaScript library that is used to display map data in web browsers. It is an Open Source Geospatial Foundation (OSGeo) project that supports map data from any source that uses Open Geospatial Consortium (OGC) standards as WMS or Web Feature Service (WFS). The OpenLayers library and full documentation can be obtained from http://openlayers.org/.


Methods

WMS Layers

The first step was to determine which WMS layers would be used for the project. Six layers were found using GeoBase and Natural Resources Canada’s Toporama data. Within the subsequent HTML code example, they are named ‘basemap,’ ‘water,’ ‘landcovercanada,’ ‘primary roads,’ ‘secondary roads,’ and ‘cities.’ What each layer represents is described below:

basemap – Foreign political boundaries at 1:10M scale

water – Surface water network of Canada

landcovercanada – Land cover information from 2000 for all of Canada. It is the result of vectorization of raster thematic data originating from Landsat 5 and Landsat 7 ortho-images, for agricultural and forest areas of Canada.

primary roads – Primary roads include mainly the Highways and Expressways, although this may vary according to each province.

secondary roads – Secondary roads include mainly the Arterial ways, although this may vary according to each province.

cities – Heavily populated areas


Further information regarding how the WMS layers are used within OpenLayers can be seen within the comments of the HTML code, such as how multiple WMS layers can be specified in a single OpenLayers layer. Also, note that the layers are placed in the reverse order in which they want to be viewed. In other words, ‘cities’ is placed at the as the last layer within the ‘layers’ variable so that it will be viewed on top of the other layers. If the landcover layer was instead placed as the final layer, it would cover all of the others.


OpenLayers Viewer

To build an OpenLayers viewer requires crafting HTML in which the viewer will be seen. This is done through the statement on line 14 of the following code. OpenLayers supports putting a map inside almost any HTML block element on the page. Also required is a script tag which includes the OpenLayers library to the page. This is shown in line 15 of the following code:

Openlayersviewercode.png

Figure 1: Displaying the HTML code required to craft the OpenLayers viewer and include the OpenLayers library to the page.

HTML Code

The following HTML code was used to produce Figure 2 shown below. Within the code there are comments (<!-- -->) that describe what the subsequent pieces of code are accomplishing.


<!DOCTYPE html>
<html>
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
   <meta name="apple-mobile-web-app-capable" content="yes">
   <title>OpenLayers WMS Test</title>
   <link rel="stylesheet" href="../theme/default/style.css" type="text/css">
   <link rel="stylesheet" href="style.css" type="text/css">
 </head>
 <body onload="init()">
   <h1 id="title">OpenLayers WMS Example</h1>
   <div id="shortdesc">Displaying WMS layers:</div>
   <div id="map" class="mediummap"></div>
   <script type="text/javascript" src="OpenLayers.js"></script>
   <script type="text/javascript"> 
     
      <!-- Enter the desired center location of the map as well as the zoom level. These will be called after the map has been 
created using the map.setCenter control. --> 
     var lon = -75.6981200;
     var lat = 45.4111700;
     var zoom = 3;
     var map, layer;
       function init() {
        <!-- Define the WMS layers that will be used to generate the map. Multiple WMS layers can be placed in a single OpenLayers 
        layer, as is the case here. --> 
        <!-- Each layer could also be set up as its own variable, and then all of the variables could be called at the end during 
        the map.addLayers() step. Both methods will work. --> 
        <!-- The multiple WMS layers within the single OpenLayers layer is all one statement, and the first WMS layer listed will 
        be considered the base layer. -->  
        <!-- The other layers are then considered the overlay layers. These must be made transparent. Note the transparent flag is 
        set as true within each WMS layer. --> 	
        <!-- Note the isBaseLayer flag within each of the overlay layers, which is set as false. The first layer does not 
        need this flag as it is understood to be the base layer. --> 
        <!-- Note the use of png images, which support transparency. --> 	
           var layers = 
               [
                   new OpenLayers.Layer.WMS(
                       "basemap",
                       "http://ows.geobase.ca/wms/geobase_en",
                       {
                           layers: 'reference:landmass:international_10m'
                       }),
                   new OpenLayers.Layer.WMS(
                       "water",
                       "http://wms.ess-ws.nrcan.gc.ca/wms/toporama_en",
                       {
                           layers: 'hydrography',
                           transparent: 'true',
                           format: 'image/png'
                       },
                       {
                           isBaseLayer: false
                       }),
                   new OpenLayers.Layer.WMS(
                       "landcovercanada",
                       "http://ows.geobase.ca/wms/geobase_en",
                       {
                           layers: 'landcover:csc2000',
                           transparent: 'true',
                           format: 'image/png'
                       },
                       {
                           isBaseLayer: false
                       }),
                   new OpenLayers.Layer.WMS(
                       "primaryroads",
                       "http://ows.geobase.ca/wms/geobase_en",
                       {
                           layers: 'nrn:roadnetwork:roadseg_primary',
                           transparent: 'true',
                           format: 'image/png'
                       },
                       {
                           isBaseLayer: false
                       }),
                   new OpenLayers.Layer.WMS(
                       "secondaryroads",
                       "http://ows.geobase.ca/wms/geobase_en",
                       {
                           layers: 'nrn:roadnetwork:roadseg_secondary',
                           transparent: 'true',
                           format: 'image/png'  
                       },
                       {
                           isBaseLayer: false
                       }),
                   new OpenLayers.Layer.WMS(
                       "cities",
                       "http://wms.ess-ws.nrcan.gc.ca/wms/toporama_en",
                       {
                           layers: 'populated_places',
                           transparent: 'true',
                           format: 'image/png'
                       },
                       {
                           isBaseLayer: false
                       })
               ]; 
           <!-- Define the projection of the map. Codes, their associated projections, and documentation can be found at 
           http://trac.osgeo.org/proj/ (PROJ.4) or http:spatialreference.org --> 
           var mapprojection = new OpenLayers.Projection("EPSG:42304");
           
           <!-- Creating bounds for the layers in projected coordinates --> 
           var full = new OpenLayers.Bounds(-2300000, -1000000, 2700000, 3500000);
           var init = new OpenLayers.Bounds(300000, -800000, 1300000, 200000);
           
           <!-- Set up a variable to hold the map object, and create the map. --> 
           var map = new OpenLayers.Map('map', 
               {
                   projection: mapprojection,
                   maxExtent: full,
                   restrictedExtent: full
               });
           <!-- Add the layers to the map. In this case only 'layers' has to be called because multiple WMS layers were placed in
           a single OpenLayers layer --> 
           map.addLayers(layers);
           map.zoomToExtent(init);
           map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
           //map.addControl(new OpenLayers.Control.PanZoomBar);//
           //map.addControl( new OpenLayers.Control.LayerSwitcher() );//
       };
   </script>
 </body>
</html>

Resulting Map

References

OGC WMS Standards [2]