.. index:: single: WMS Server .. _wms_server: ***************************************************************************** WMS Server ***************************************************************************** :Author: Jeff McKenna :Contact: jmckenna at gatewaygeomatics.com :Last Updated: 2011-10-06 .. contents:: Table of Contents :depth: 2 :backlinks: top Introduction ============ A WMS (or Web Map Server) allows for use of data from several different servers, and enables for the creation of a network of Map Servers from which clients can build customized maps. The following documentation is based on the Open Geospatial Consortium's (OGC) `Web Map Server Interfaces Implementation Specification v1.1.1`_. MapServer v3.5 or more recent is required to implement WMS features. At the time this document was written, MapServer supports the following WMS versions: 1.0.0, 1.0.7, 1.1.0 (a.k.a. 1.0.8), 1.1.1 and 1.3.0 This document assumes that you are already familiar with certain aspects of MapServer: - MapServer application development and setting up .map files. - Familiarity with the WMS spec would be an asset. A link to the WMS specification document is included in the "WMS-Related Information" section below. Links to WMS-Related Information -------------------------------- - :ref:`MapServer WMS Client Howto ` - `WMS 1.1.1 specification`_ - `WMS 1.3.0 specification`_ - `Open Geospatial Consortium (OGC)`_ home page - `WMS-Dev mailing list and archive`_ - `WMS Cookbook`_ - `MapServer OGC Web Services Workshop`_ package - :ref:`MapServer Styled Layer Descriptor (SLD) Howto ` - :ref:`MapServer WMS Time Support Howto ` How does a WMS Work ------------------- WMS servers interact with their clients via the HTTP protocol. In most cases, a WMS server is a CGI program. This is also the case with MapServer. The WMS specification defines a number of request types, and for each of them a set of query parameters and associated behaviors. A WMS-compliant server MUST be able to handle at least the following 2 types of WMS requests: 1. **GetCapabilities:** return an XML document with metadata of the Web Map Server's information 2. **GetMap:** return an image of a map according to the user's needs. And support for the following types is optional: 1. **GetFeatureInfo:** return info about feature(s) at a query (mouse click) location. MapServer supports 3 types of responses to this request: - text/plain output with attribute info. - text/html output using MapServer query templates (see :ref:`template`) specified in the :ref:`CLASS` TEMPLATE parameter (the filename has to have an .html extension). The MIME type returned by the Class templates defaults to text/html and can be controlled using the metadata "wms_feature_info_mime_type". - application/vnd.ogc.gml, GML.1 or GML for GML features. 2. **DescribeLayer:** return an XML description of one or more map layers. To execute this: - for vector layers: to have a valid return the user needs to setup wfs_onlineresource (or ows_onlineresource) metadata either at the map level or at the layer level (the layer level metadata is the one which is used if both are defined) - for raster layers: the metadata is wcs_onlineresource with the same logic as above. 3. **GetLegendGraphic:** returns a legend image (icon) for the requested layer, with label(s). More information on this request can be found in the GetLegendGraphic section later in this doc. With respect to MapServer specifically, it is the "mapserv" CGI program that knows how to handle WMS requests. So setting up a WMS server with MapServer involves installing the :ref:`mapserv` CGI program and a setting up a mapfile with appropriate metadata in it. This is covered in the rest of this document. .. index:: pair: WMS Server; Setup Setting Up a WMS Server Using MapServer ======================================= Install the Required Software ----------------------------- WMS requests are handled by the :ref:`mapserv` :ref:`CGI` program. Not all versions of the mapserv program do include WMS support (it is included by default when you compile together with the PROJ library), so the first step is to check that your mapserv executable includes WMS support. One way to verify this is to use the "-v" command-line switch and look for "SUPPORTS=WMS_SERVER". (Unix users should refer to the :ref:`unix` document for any compiling instructions, and Windows users might want to use `MS4W`_, which comes ready with WMS/WFS support) Example 1. On Unix: :: $ ./mapserv -v MapServer version 4.6.1 OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF OUTPUT=SWF OUTPUT=SVG SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT SUPPORTS=WCS_SERVER INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE DEBUG=MSDEBUG Example 2. On Windows: :: C:\apache\cgi-bin> mapserv -v MapServer version 4.6.1 OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF OUTPUT=SWF OUTPUT=SVG SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT SUPPORTS=WCS_SERVER INPUT=JPEG INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE DEBUG=MSDEBUG .. index:: pair: WMS Server; Mapfile Setup a Mapfile For Your WMS ---------------------------- Each instance of WMS server that you setup needs to have its own mapfile. It is just a regular MapServer mapfile in which some parameters and some metadata entries are mandatory. Most of the metadata is required in order to produce a valid GetCapabilites output. Here is the list of parameters and metadata items that usually optional with MapServer, but are **required (or strongly recommended) for a WMS configuration:** **At the MAP level:** - Map NAME - Map PROJECTION - Map Metadata (in the WEB Object): - wms_title - wms_onlineresource - wms_srs (unless PROJECTION object is defined using "init=epsg:...") - wms_enable_request **And for each LAYER:** - Layer NAME - Layer PROJECTION - Layer METADATA - wms_title - wms_srs (optional since the layers inherit the map's SRS value) - Layer STATUS - Layers set to STATUS DEFAULT will always be sent to the client. - Layers set to STATUS ON or STATUS OFF can be requested by the client. - Layer TEMPLATE (required for GetFeatureInfo requests - see :ref:`template`) Let's go through each of these parameters in more detail: - **Map Name and wms_title:** WMS Capabilities requires a Name and a Title tag for every layer. The Map's NAME and wms_title metadata will be used to set the root layer's name and title in the GetCapabilities XML output. The root layer in the WMS context corresponds to the whole mapfile. - **Layer Name and wms_title metadata:** Every individual layer needs its own unique name and title. Layer names are also used in GetMap and GetFeatureInfo requests to refer to layers that should be included in the map output and in the query. Layer names must start with a letter when setting up a WMS server (layer names should not start with a digit or have spaces in them). - **Map PROJECTION and wms_srs metadata:** WMS servers have to advertise the projection in which they are able to serve data using EPSG projection codes (see `The EPSG web page`_ for more background on EPSG codes). Recent versions of the PROJ4 library come with a table of EPSG initialization codes and allow users to define a projection like this: .. code-block:: mapfile PROJECTION "init=epsg:4269" END (Note that "epsg" has to be in lowercase when used in the PROJ4 'init' directive.) If the :ref:`MAP` :ref:`PROJECTION` block is provided in the format "init=epsg:xxxx" then MapServer will also use this information to generate a tag for the top-level layer in the WMS capabilities document. BoundingBox is a mandatory element of WMS capabilities for WMS 1.3.0 (for WMS 1.1.0 it is optional, but it is good practice to allow MapServer to include it when possible). The above is sufficient for MapServer to recognize the EPSG code and include it in SRS tags in the capabilities output (wms_srs metadata is not required in this case). However, it is often impossible to find an EPSG code to match the projection of your data. In those cases, the "wms_srs" metadata is used to list one or more EPSG codes that the data can be served in, and the PROJECTION object contains the real PROJ4 definition of the data's projection. Here is an example of a server whose data is in an Lambert Conformal Conic projection (42304). It's capabilities output will advertize EPSG:4269 and EPSG:4326 projections (lat/lon), but the PROJECTION object is set to the real projection that the data is in: .. code-block:: mapfile NAME "DEMO" ... WEB ... METADATA "wms_title" "WMS Demo Server" "wms_onlineresource" "http://my.host.com/cgi-bin/mapserv?map=wms.map&" "wms_srs" "EPSG:4269 EPSG:4326" END END PROJECTION "init=epsg:42304" END ... END In addition to EPSG:xxxx projections, a WMS server can advertize projections in the AUTO:xxxx namespace. AUTO projections 42001 to 42005 are internally supported by MapServer. However, AUTO projections are useful only with smart WMS clients, since the client needs to define the projection parameters in the WMS requests to the server. For more information see Annex E of the `WMS 1.1.1 specification`_ and section 6.5.5.2 of the same document. See also the FAQ on AUTO projections at the end of this document. - **Layer PROJECTION and wms_srs metadata:** By default layers inherit the SRS of their parent layer (the map's PROJECTION in the MapServer case). For this reason it is not necessary (but still strongly recommended) to provide PROJECTION and wms_srs for every layer. If a layer PROJECTION is not provided then the top-level map projecion will be assumed. Layer PROJECTION and wms_srs metadata are defined exactly the same way as the map's PROJECTION and wms_srs metadata. For vector layers, if a PROJECTION block is provided in the format "init=epsg:xxxx" then MapServer will also use this information to generate a tag for this layer in the WMS capabilities document. BoundingBox is a mandatory element of WMS capabilities for WMS 1.3.0 (for WMS 1.1.0 it is optional, but it is good practice to allow MapServer to include it when possible). - **"wms_onlineresource" metadata:** The wms_onlineresource metadata is set in the map's web object metadata and specifies the URL that should be used to access your server. This is required for the GetCapabilities output. If wms_onlineresource is not provided then MapServer will try to provide a default one using the script name and hostname, but you shouldn't count on that too much. It is strongly recommended that you provide the wms_onlineresource metadata. See section 6.2.2 of the `WMS 1.1.1 specification`_ for the whole story about the online resource URL. Basically, what you need is a complete HTTP URL including the http:// prefix, hostname, script name, potentially a "map=" parameter, and and terminated by "?" or "&". Here is a valid online resource URL: :: http://my.host.com/cgi-bin/mapserv?map=mywms.map& By creating a wrapper script on the server it is possible to hide the "map=" parameter from the URL and then your server's online resource URL could be something like: :: http://my.host.com/cgi-bin/mywms? This is covered in more detail in the section "More About the Online Resource URL" below. - **"wms_enable_request" metadata:** Specify which requests to enable. If not specified, no requests will be enabled! See the explanation below. - **Configuring for GetFeatureInfo Requests:** You must set the layer TEMPLATE parameter for the layer to be queryable by GetFeatureInfo requests (see :ref:`template`). For requests of type "text/html" you should also set the layer HEADER and FOOTER parameters. As of MapServer 4.6 you must set the *gml_\** metadata for the layer attributes to be served (see the Layer Object metadata in the Reference Section later in this document). To include geometry, gml_geometries and gml_[geometry name]_type has to be specified. Here are working examples of GetFeatureInfo requests: `text/plain`_ / `text/html`_ / `gml`_ (for gml, your browser might ask you to save the file, if so save it locally as a .gml file and view it in a text editor) Test Your WMS Server -------------------- .. _wms_capabilities: Validate the Capabilities Metadata ********************************** OK, now that we've got a mapfile, we have to check the XML capabilities returned by our server to make sure nothing is missing. Using a web browser, access your server's online resource URL to which you add the parameters "SERVICE=WMS&VERSION=1.1.1&REQUEST=GetCapabilities" to the end, e.g. :: http://my.host.com/cgi-bin/mapserv?map=mywms.map&SERVICE=WMS&VERSION=1.1.1 &REQUEST=GetCapabilities Here is a working GetCapabilities request (note that the SERVICE parameter is required for all GetCapabilities requests): `http://demo.mapserver.org/cgi-bin/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetCapabilities`_ This should return a document of MIME type application/vnd.ogc.wms_xml, so your browser is likely going to prompt you to save the file. Save it and open it in a text editor (Emacs, Notepad, etc.), and you will see the returned XML from the WMS server. If you get an error message in the XML output then take necessary actions. Common problems and solutions are listed in the FAQ at the end of this document. If everything went well, you should have a complete XML capabilities document. Search it for the word "WARNING"... MapServer inserts XML comments starting with "