.. index:: 
   pair: WMS Server; Dimension requests

.. _wms_dimension:

*****************************************************************************
 WMS Dimension
*****************************************************************************

:Author: Yewondwossen Assefa
:Contact: yassefa at dmsolutions.ca
:Last Updated: 2013/10/08

.. contents:: Table of Contents
    :depth: 2
    :backlinks: top

Introduction
============

A WMS server can provide support for several type of dimensions such as time, 
elevation or other types of dimensions (for example, satellite images in different wavelength bands).
For temporal dimension, please refer to :ref:`WMS Time Support <wms_time>`.
This document describes support for the elevation dimension and other type of dimensions


Links to WMS-Related Information
--------------------------------

- :ref:`MapServer WMS Server HowTo <wms_server>`
- :ref:`WMS Time Support HowTo <wms_time>`


Enabling Dimension Support in MapServer
=======================================

Setting Up a WMS Layer with dimension support
---------------------------------------------

To have a valid WMS layer with dimension support, the user has to define the following 
metadata at the layer level:

- *wms_dimensionlist*: (*Mandatory*) comma separated list of dimension names available for the layer

- *wms_[dimensionname]_item*: (*Mandatory*)  this is the name of the field in the DB that 
  contains the dimension values.

- *wms_[dimensionname]_units*: (*Mandatory*)  Attribute indicating units of dimensional axis.
  If the dimensional quantity has no units (e.g. band number in a
  multi-wavelength sensor), use the null string: "". If the
  dimensional quantity has units, unit names should be taken from the Unified
  Code for Units of Measure (UCUM) if UCUM has an appropriate entry. When UCUM
  is used, the mandatory units attribute shall be an appropriate entry from the
  UCUM “name” column.

- *wms_[dimensionname]_extent*: (*Mandatory*)  defines a valid set of values for the dimension

- *wms_[dimensionname]_default*: (*Optional*)  this value is used if it is defined and the 
  dimension value is missing in the request.  



Specifying Dimension Extents
****************************

Dimension Extents can be declared with the following syntax for the
*wms_[dimensionname]_extent* metadata (see Annex C.3 in the
`WMS 1.1.1 specification`_ document for a full description):

1. *value* - a single value.

2. *value1,value2,value3,...* - a list of multiple values.

3. *min/max/resolution* - an interval defined by its lower and upper
   bounds and its resolution.  This is supported in MapServer (note that 
   the resolution is not supported however).
   
4. *min1/max1/res1,min2/max2/res2,...* - a list of multiple intervals.


Example WMS-Server Layer
************************

.. code-block:: mapfile

  LAYER
    NAME "lakes_elev"
    METADATA
      "wms_title"         "Lakes"
      "wms_description"   "Lakes"
      "wms_dimensionlist" "elevation, text_dimension"
      "wms_elevation_item" "ELEV"
      "wms_elevation_extent" "500, 490, 480"
      "wms_elevation_units" "meters"
      "wms_elevation_default" "500"
      "wms_text_dimension_item" "text_dimen"
      "wms_text_dimension_extent" "first, second, third"
       "wms_text_dimension_units" "my_units"
       "wms_enable_request" "*"
    END
    TYPE POLYGON   
    ..
    
  END

GetCapabilities Output
======================

If your layer is set up properly, requesting the capabilities on the server 
outputs one or several Dimension elements. Here is an example of a GetCapabilities result for
a layer configured for two dimensions (wms 1.3.0):

.. code-block:: guess

    <Layer queryable="0" opaque="0" cascaded="0">
        <Name>lakes_elev</Name>
        <Title>Lakes</Title>
        <CRS>EPSG:4326</CRS>
        <EX_GeographicBoundingBox>
        <westBoundLongitude>0.000178263</westBoundLongitude>
        <eastBoundLongitude>0.0034202</eastBoundLongitude>
        <southBoundLatitude>-0.002134</southBoundLatitude>
        <northBoundLatitude>0.000313775</northBoundLatitude>
	<BoundingBox CRS="EPSG:4326" minx="-0.002134" miny="0.000178263" maxx="0.000313775" maxy="0.0034202" />
        <Dimension name="elevation" units="meters" default="500" multipleValues="1" nearestValue="0">500, 490, 480</Dimension>
        <Dimension name="text_dimension" units="my_units"  multipleValues="1"  nearestValue="0">first, second, third</Dimension>
    </Layer>            

Supported Dimension Requests
============================

A request parameter name is constructed by concatenating the prefix "dim\_" with the
sample dimension Name (the value of the name attribute of the corresponding
<Dimension> and <Extent> elements in the Capabilities XML). The resulting
"dim_name" is case-insensitive. The use of the "dim\_" prefix is to avoid clashes between
server-defined dimension names and current or future OGC Web Service specifications.
(Time and Elevation, being predefined, do not use the prefix.) (section C.4.2)

- *single value*: for example: ...&elevation=500&...
- *multiple values*: for example: ...&dim_text_dimension=first,second&...
- *single range value*: for example: ...&elevation=480/490&...
- *multiple range values*: for example: ...&elevation=480/490,490/500&...


Processing Dimension Requests 
=============================

When MapServer process a valid dimension wms parameter, It will process it into
expressions and set it on the :ref:`LAYER` `FILTER` object.
If there was already a Logical “MapServer expressions”, It will be concatenated with it.

For example a request such as  &elevation=490/500&... on a MapServer layer (with an empty FILTER) would give
.. code-block:: mapfile

  FILTER (([ELEV] >= 490 AND [ELEV] <= 500))


For example a request such as  &elevation=600&... on a postgis layer with an existing FILTER  would give
.. code-block:: guess

- FILTER (elev > 500) #before request
- FILTER ((elev > 500) and (((ELEV = 600)))) #after request

.. #### rST Link Section ####

.. _`WMS 1.1.1 specification`: http://www.opengeospatial.org/docs/01-068r2.pdf
