MapServer and GeoTIFF mosaic example

I have been writing a GeoTIFF exporter from a propitiatory GIS system for a client who wishes to use MapServer as a WMS Server.

As part of the exporter I needed to write out an example MAP file which is pretty much complete with only a couple of modifications required by the user.

The following is an example of the MAP FILE:

MAP
 NAME "wales_imagery"   # This needs to be unique
 STATUS ON
 SIZE 400 300  # default size - kind of ignored for WMS
 # Symbol list - This is relative to the .map file.
 SYMBOLSET "../../apps/etc/symbols.txt"  # UPDATE
 IMAGECOLOR 255 255 255
 # Font list - This is relative to the.map file.
 FONTSET "../../apps/etc/fonts.txt"  # UPDATE

OUTPUTFORMAT
 NAME "png"
 DRIVER AGG/PNG
 MIMETYPE "image/png"
 IMAGEMODE RGBA
 TRANSPARENT ON
 EXTENSION "png"
 FORMATOPTION "GAMMA=0.75"
END
OUTPUTFORMAT
 NAME "gif"
 DRIVER GD/GIF
 MIMETYPE "image/gif"
 IMAGEMODE PC256
 EXTENSION "gif"
END
OUTPUTFORMAT
 NAME "png8"
 DRIVER AGG/PNG8
 MIMETYPE "image/png; mode=8bit"
 IMAGEMODE RGB
 EXTENSION "png"
 FORMATOPTION "QUANTIZE_FORCE=on"
 FORMATOPTION "QUANTIZE_COLORS=256"
 FORMATOPTION "GAMMA=0.75"
END
OUTPUTFORMAT
 NAME "jpeg"
 DRIVER AGG/JPEG
 MIMETYPE "image/jpeg"
 IMAGEMODE RGBA
 TRANSPARENT ON
 EXTENSION "jpg"
 FORMATOPTION "GAMMA=0.75"
END
OUTPUTFORMAT
 NAME "svg"
 DRIVER CAIRO/SVG
 MIMETYPE "image/svg+xml"
 IMAGEMODE RGBA
 EXTENSION "svg"
END
OUTPUTFORMAT
 NAME "pdf"
 DRIVER CAIRO/PDF
 MIMETYPE "application/x-pdf"
 IMAGEMODE RGBA
 TRANSPARENT ON
 EXTENSION "pdf"
END
OUTPUTFORMAT
 NAME "GTiff"
 DRIVER GDAL/GTiff
 MIMETYPE "image/tiff"
 IMAGEMODE RGB
 EXTENSION "tif"
END
OUTPUTFORMAT
 NAME "kml"
 DRIVER KML
 MIMETYPE "application/vnd.google-earth.kml.xml"
 IMAGEMODE RGBA
 TRANSPARENT ON
 EXTENSION "kml"
END
OUTPUTFORMAT
 NAME "kmz"
 DRIVER KMZ
 MIMETYPE "application/vnd.google-earth.kmz"
 IMAGEMODE RGBA
 TRANSPARENT ON
 EXTENSION "kmz"
END
OUTPUTFORMAT
 NAME "cairopng"
 DRIVER CAIRO/PNG
 MIMETYPE "image/png"
 IMAGEMODE RGBA
 TRANSPARENT ON
 EXTENSION "png"
END
OUTPUTFORMAT
 NAME "myUTFGrid"
 DRIVER UTFGRID
 FORMATOPTION "LABELS=true"
 FORMATOPTION "UTFRESOLUTION=4"
 FORMATOPTION "DUPLICATES=false"
END
#
# End of OUTPUTFORMAT definitions
#

 # Extents :
 EXTENT 304430.5800000000 5586579.0200000005 500356.8900000000 5874520.2599999998
 UNITS METERS # units the extent is in.

 # Where to find shapefile data - This is relative to the MapServer '.map' file
 SHAPEPATH "../../apps/maps/wales_imagery" # UPDATE

 # Maximum image request size
 MAXSIZE 4096

 WEB
# Where the GeoTIFF data can be found.This is relative to the MapServer '.map' file.
IMAGEPATH "../../apps/maps/wales_imagery" # UPDATE
IMAGEURL "/ms_tmp/"
METADATA
 "wms_title" "WMS Server"
 "wms_onlineresource" "http://mapserver:8080/cgi-bin/mapserv.exe?map=wales_imagery.map&" # UPDATE IP address/name

 # The projections offered via the WMS server
 "wms_srs" "EPSG:4326 EPSG:32630"  # UPDATE with any additional EPSG codes you want to offer.

 "wms_feature_info_mime_type" "text/plain"
 "wms_abstract" "This server was setup by damian.dixon at gmail.com"
 "ows_enable_request" "*"
END # Metadata
 END # WEB

 # Default EPSG of the data - MapServer will re-project the data to one of the requested 'wms_srs' EPSGs.
 PROJECTION
"init=EPSG:32630"
 END

 # Start of layer definitions
 #
 # Layers are defined in order of display(if not via a WMS)
 #
 LAYER
# WMS Layer name
NAME "wales_imagery"

# Metadata to return in capabilities document.
METADATA
 "wms_title" "wales_imagery"
 "wms_include_items" "all"
END

# Should be ON / DEFAULT / OFF
STATUS ON

# The projection the data is in.
PROJECTION
 # This is the data EPSG code.
 "init=EPSG:32630"
END

  # Specify the RGBA bands to use
  PROCESSING "BANDS=1,2,3,4"

# Specify the Shapefile that contains the tile index data.
TILEINDEX "wales_imagery.shp"
TILEITEM "Location"

# What the layer type is.
TYPE RASTER
 END # layer

END # Map File

GeoTIFF setup

The GeoTIFF is written out as a pyramid file with an Alpha band.

Because  the extent of the data may be quite huge the output is split into an 4 by 2 grid. Basically 8 top level GeoTIFF files.

The number of levels contained in the GeoTIFF is based on the data in the original GIS system and the number of levels of detail being exported.

If the map scale gap between the levels of detail is too great another pyramid level is added.

Each top level tile has a slight overlap to ensure that the images appear to be seamless.

Transparency

There are a couple of interesting points in the MAP file:
  1. Enabling Transparency in the WMS tile returned.
  2. Specifying a Transparent pixel in the input GeoTIFF.

Transparency in a WMS GetMap response

This is enabled by specifying the format is ARGB

OUTPUTFORMAT
  NAME "png"
  DRIVER AGG/PNG
  MIMETYPE "image/png"
  IMAGEMODE RGBA
  TRANSPARENT ON
  EXTENSION "png"
  FORMATOPTION "GAMMA=0.75"
END

Transparent pixel

There are two ways of specifying Alpha value.

The first is to specified in the LAYER section an RGB to convert to transparent as follows:

        OFFSET 255 255 255

The values specified represent the pixel colour value. White is a poor choice. Black can also be a poor choice as lettering is usually black. The colour needs to really be unique, i.e. not used in the image other than to indicate to mask the value out.

The second approach is to specify the alpha channel in the data as follows:

PROCESSING "BANDS=1,2,3,4"

The channel numbers represent R, G, B and alpha in that order.

I am using the second approach because I can generate an alpha channel. However to generate the alpha channel I am using exactly the approach that MapServer is using in the first approach. While this takes time to process you do save time and disk space when compressing and writing out the tile.

The following links have further information about transparency:

Combining the GeoTIFF Mosaic

The GeoTIFFs are combined using a Tiled Index using the following command:

gdaltindex wales_imagery.shp *.tif

The paths specified to the GeoTIFF files must be relative to the shapefile that is created and to where the GIS data will be deployed in MapServer.

In the MAP file I specify where the Shapefile and GeoTIFFs can be found:

SHAPEPATH "../../apps/maps/wales_imagery"
IMAGEPATH "../../apps/maps/wales_imagery"

In the LAYER section you specify you are using a Tile Index as follows:

# Specify the Shapefile that contains the tile index data.
TILEINDEX "wales_imagery.shp"
TILEITEM "Location"

You specify the shapefile as the TILEINDEX.

Deploying the MAP File

The quickest and easiest way to deploy the MAP file is to put it into the cgi-bin directory.

This will be immediately picked up by the Server and accessible. You can tweak the file at anytime and the changes are automatically picked up.

The data is normally specified relative to the MAP file.

Please contact me if you need a similar tool at damian.dixon at gmail.com to discuss.

Comments