Vector Tiles
Overview
This example displays Mapbox Vector Tiles for a simplified countries dataset from Natural Earth.
Mapfile Configuration
The Mapbox Vector Tile (MVT) output format is available if MapServer is built with MVT support enabled, as in the case of the MapServer Docker image used by the workshop. No particular changes are required in a Mapfile to serve vector tiles.
Adding Vector Tiles to OpenLayers
There are two ways to request vector tiles from MapServer:
-
Using Tile Mode, as in the Image Tiles example. The only change is to add
&map.imagetype=mvtto the request string. -
Using a WMS interface, and adding the following to the request strings -
&FORMAT=application/x-protobuf.
In this example we are using the tile mode approach, based on the
OpenLayers vector tile example. We supply a template URL, and make sure we include &map.imagetype=mvt as part of the querystring:
new VectorTileLayer({
source: new VectorTileSource({
format: new MVT(),
url:
mapserverUrl + mapfilesPath + 'vector-tiles.map&MODE=tile&TILE={x}+{y}+{z}&LAYERS=countries&map.imagetype=mvt',
}),
style: function (feature) {
return new Style({
stroke: new Stroke({
color: 'rgb(66, 133, 244)', // Light blue border color
width: 2, // Border width
})
});
},
}),
Code
Example
- Local OpenLayers example: http://localhost:7001/vector-tiles.html
vector-tiles.js
import '../css/style.css';
import MVT from 'ol/format/MVT.js';
import Map from 'ol/Map.js';
import VectorTileLayer from 'ol/layer/VectorTile.js';
import VectorTileSource from 'ol/source/VectorTile.js';
import View from 'ol/View.js';
import { Fill, Stroke, Style } from 'ol/style.js';
// https://openlayers.org/en/latest/examples/mapbox-vector-tiles.html
const mapserverUrl = import.meta.env.VITE_MAPSERVER_BASE_URL;
const mapfilesPath = import.meta.env.VITE_MAPFILES_PATH;
const map = new Map({
layers: [
new VectorTileLayer({
source: new VectorTileSource({
format: new MVT(),
url:
mapserverUrl + mapfilesPath + 'vector-tiles.map&MODE=tile&TILE={x}+{y}+{z}&LAYERS=countries&map.imagetype=mvt',
}),
style: function (feature) {
return new Style({
stroke: new Stroke({
color: 'rgb(66, 133, 244)', // Light blue border color
width: 2, // Border width
}),
// fill: new Fill({
// color: 'rgba(66, 133, 244, 0.4)' // semi-transparent blue fill
//})
});
},
}),
],
target: 'map',
view: new View({
center: [-472202, 7530279],
zoom: 2,
}),
});
vector-tiles.map
MAP
NAME "Vector Tiles"
EXTENT -20037508.34 -20048966.1 20037508.34 20048966.1
SIZE 256 256
PROJECTION
"epsg:3857"
END
LAYER
NAME "countries"
TYPE POLYGON
PROJECTION
"epsg:4326"
END
EXTENT -180.0 -90.0 180.0 90
STATUS OFF
# If want to include attributes in the tiles add
# the METADATA block
METADATA
"gml_include_items" "all"
"gml_types" "auto"
END
CONNECTIONTYPE FLATGEOBUF
DATA "data/naturalearth/ne_110m_admin_0_countries.fgb"
END
END
Exercises
- Update the layer to use the
data/naturalearth/ne_110m_lakesdataset. - Update the OpenLayers style to use a blue fill for the lakes. In the
Stylefunction you will need to uncomment thefillJavaScript. Experiment with different colour values for thefillandstroke.