OpenLayers 3+: Adding a layer switcher

Antonis Christofides
GIS tips
Published in
4 min readJul 6, 2017

OpenLayers 2 used to have a LayerSwitcher control. With it you could choose different layers to show on the map. This control is gone in OpenLayers 3.

LayerSwitcher in OpenLayers 2

In OpenLayers 3+, there are currently two ways to have a layer switcher; the easiest one is to use a third-party one; and the most versatile is to make it yourself. In this post we will use a third-party one.

The currently fashionable layer switcher control is Matt Walker’s LayerSwitcher. You include its CSS and JavaScript in the HTML, and then you can use it like this:

map.addControl(new ol.control.LayerSwitcher());

If you add this line to the previous post’s code, here is what the result will be:

The reason the map background is not listed is that the layer has no title; if you add one, it will show, like this:

OpenLayers 2 distinguished between base layers and overlay layers. The base layers were the background of the map; only one base layer could be shown at a time. The overlay layers (also called non-base layers) was stuff that could be superimposed on the background.

Here Open Cycle Map is used as background, with two of five possible overlay layers visible

OpenLayers 3+ doesn’t have this distinction. It just draws layers one on top of the other. If a layer is opaque, it hides the layers behind it. This is why in the previous post we defined the opaque Open Street Map first, then adding two WFS layers to show on top of it.

In the context of a layer switcher, however, the distinction of base vs. overlay layers is useful, because it helps make the switcher saner. For this reason, Matt Walker’s LayerSwitcher requires you to add type: 'base' to any layer that you want to act as “base” layer. So take this example, where we have two “base” layers and two “overlay” layers:

var corineUrl = 'http://filotis.itia.ntua.gr/mapserver?SERVICE=WFS&' +
'VERSION=1.1.0&REQUEST=GetFeature&TYPENAME=biotopes_corine&' +
'SRSNAME=EPSG:4326&OUTPUTFORMAT=gml3';
var naturaUrl = 'http://filotis.itia.ntua.gr/mapserver?SERVICE=WFS&' +
'VERSION=1.1.0&REQUEST=GetFeature&TYPENAME=biotopes_natura&' +
'SRSNAME=EPSG:4326&OUTPUTFORMAT=gml3';
var cadastreUrl = 'http://gis.ktimanet.gr/wms/wmsopen/wmsserver.aspx';
var map = new ol.Map({
target: 'map',
layers: [new ol.layer.Tile({
title: 'Open Street Map',
source: new ol.source.OSM(),
type: 'base'
}),
new ol.layer.Tile({
title: 'Greek Cadastre',
type: 'base',
visible: false,
source: new ol.source.TileWMS({
url: cadastreUrl
})
}),
new ol.layer.Vector({
title: 'Corine biotopes',
source: new ol.source.Vector({
format: new ol.format.WFS(),
url: corineUrl
})
}),
new ol.layer.Vector({
title: 'Natura biotopes',
source: new ol.source.Vector({
format: new ol.format.WFS(),
url: naturaUrl
})
})],
view: new ol.View({
projection: 'EPSG:4326',
center: [24, 38], zoom: 6
})
});
map.addControl(new ol.control.LayerSwitcher());

Here is the result:

You may have noticed that, in the code, I specified visible: false to make the Cadastre background map initially invisible. If I don’t specify it, Open Street Map briefly shows and is then gradually covered by the Cadastre map. It makes no sense for more than one base map to be visible, so it is good practice to take care of initial visibility in the code. The layer switcher will take care of the rest.

The final adjustment we are going to make is to group the layers in order to achieve a more elegant layout in the layer switcher:

var corineUrl = 'http://filotis.itia.ntua.gr/mapserver?SERVICE=WFS&' +
'VERSION=1.1.0&REQUEST=GetFeature&TYPENAME=biotopes_corine&' +
'SRSNAME=EPSG:4326&OUTPUTFORMAT=gml3';
var naturaUrl = 'http://filotis.itia.ntua.gr/mapserver?SERVICE=WFS&' +
'VERSION=1.1.0&REQUEST=GetFeature&TYPENAME=biotopes_natura&' +
'SRSNAME=EPSG:4326&OUTPUTFORMAT=gml3';
var cadastreUrl = 'http://gis.ktimanet.gr/wms/wmsopen/wmsserver.aspx';
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Group({
title: 'Base map',
layers: [
new ol.layer.Tile({
title: 'Open Street Map',
source: new ol.source.OSM(),
type: 'base'
}),
new ol.layer.Tile({
title: 'Greek Cadastre',
type: 'base',
visible: false,
source: new ol.source.TileWMS({
url: cadastreUrl
})
})
]
}),
new ol.layer.Group({
title: 'Data',
layers: [
new ol.layer.Vector({
title: 'Corine biotopes',
source: new ol.source.Vector({
format: new ol.format.WFS(),
url: corineUrl
})
}),
new ol.layer.Vector({
title: 'Natura biotopes',
source: new ol.source.Vector({
format: new ol.format.WFS(),
url: naturaUrl
})
})
]
})
],
view: new ol.View({
projection: 'EPSG:4326',
center: [24, 38], zoom: 6
})
});
map.addControl(new ol.control.LayerSwitcher());

This is the result:

--

--

Antonis Christofides
GIS tips

I help scientists and engineers bring their models to the web