Skip to content

Line Styling

Overview

In this exercise we're going to display the road network from OpenStreetMap for Tartu, Estonia.

The diagram below shows the Mapfile directives used for the map:

Mapfile classes used in the Lines map

Layers

A MapServer LAYER represents a dataset that will be displayed in your map. In this example we have a single "roads" layer, defined below:

LAYER
  NAME "roads"
  TYPE LINE
  STATUS OFF  
  ...

Key attributes for the layer are:

  • the NAME is used by client applications to refer to the LAYER and should be unique.
  • the STATUS is a slightly confusing property. When we use a client application such as OpenLayers, we want to set this to OFF and let the client request layers. A STATUS of default means the layer will always be visible whether the client requests it or not.
  • all layers have a TYPE which decides how the layer should be drawn. We use a simple LINE type to display the roads.

Data Sources

To define the data for the layer we need to set the DATA property:

LAYER
  ...
  CONNECTIONTYPE FLATGEOBUF
  DATA "data/osm/roads.fgb"

MapServer can display many different vector formats. In this case we are pointing to a FlatGeobuf file on disk so we set the CONNECTIONTYPE to FLATGEOBUF. FlatGeobuf can be simpler to use than Shapefiles, as they are a single file and don't have any restrictions on attribute names.

The path to the roads.fgb is added to the DATA property and is relative to the Mapfile.

Styling

In this example all roads will be in the same CLASS and displayed in a single STYLE:

CLASS
  STYLE
    COLOR 50 50 50
  END
END

Code

Tip

Note the layer name in layer=roads is case-sensitive and had to match the LAYER NAME in the Mapfile exactly.

Javascript
import '../css/style.css';
import ImageWMS from 'ol/source/ImageWMS.js';
import Map from 'ol/Map.js';
import OSM from 'ol/source/OSM.js';
import View from 'ol/View.js';
import { Image as ImageLayer, Tile as TileLayer } from 'ol/layer.js';

const mapserverUrl = import.meta.env.VITE_MAPSERVER_BASE_URL;
const mapfilesPath = import.meta.env.VITE_MAPFILES_PATH;

const layers = [
    //new TileLayer({
    //    source: new OSM(),
    //}),
    new ImageLayer({
        extent: [2968743.65508978, 8038921.67212233, 2982981.8632402, 8053818.05714347],
        source: new ImageWMS({
            url: mapserverUrl + mapfilesPath + 'lines.map&',
            params: { 'LAYERS': 'roads', 'STYLES': '' }, // 'type'
            ratio: 1
        }),
    }),
];
const map = new Map({
    layers: layers,
    target: 'map',
    view: new View({
        center: [2975862.75916499, 8046369.8646329],
        zoom: 14,
    }),
});
Mapfile
MAP
  NAME "Roads"
  EXTENT 26.668678 58.339241 26.796582 58.409410
  SIZE 800 600

  PROJECTION
    "init=epsg:4326"
  END

  WEB
    METADATA
      "ows_enable_request" "*"
      "ows_srs" "EPSG:4326 EPSG:3857"
    END
  END

  LAYER
    NAME "roads"
    TYPE LINE
    STATUS OFF    
    CONNECTIONTYPE FLATGEOBUF
    DATA "data/osm/roads.fgb"
    CLASS
      STYLE
        COLOR 50 50 50
      END
    END
  END
END

Exercises

  1. Change the STYLE to use a different RGB colour.
  2. Add a WIDTH property to the STYLE.
  3. Add a second STYLE block to the CLASS, but use a larger width to create stacked lines. Styles are drawn in the order they appear in the Mapfile.
  4. Experiment with adding a PATTERN to the line style for example PATTERN 5 5 END.