D3 Tips and Tricks v4

Wednesday, 29 January 2014

Overlaying information on a leaflet.js map


The following post is a portion of the Leaflet Tips and Tricks book which is free to download. To use this post in context, consider it with the others in this blog or just download the the book as a pdf / epub or mobi .
----------------------------------------------------------

In the previous post we described how to declare and switch between more than one tile layer. Tile layers are described as ‘base layers’ in the sense that only one of them will be visible at a time and they will form the ‘base’ of the map.
However, it is obvious that a really useful thing to be able to do would be to add information to our map so that different features or areas can be highlighted. These features or areas will exist on top of the base layer so that they have context. In Leaflet these can be set up as ‘overlays’ where an object or group of elements can be added to a map.
Overlays are treated in much the same way as base layers. In the sense that they are declared and controlled using similar methods but Leaflet is clever enough to recognise that more as many overlays as desired can exist on an individual base layer.
What we aim to do in setting out an example map using an overlay is to add one to our previous base layer switching example. The end result will be the same icon in the top right corner of the map;
Layers icon
But this time when we move our mouse over it, it will present an option to select ‘Interesting places’.
Overlay selection
And when selected it will show a series of markers with a connecting line.
Overlay on a map
As with the base layer switching example, there is no change to the HTML part of our code from the simple map example. The full code for this example can be found here on GitHub (and there’s a copy in the appendices) and a working example is here on bl.ocks.org. The only change is in the JavaScript portion. and that looks like the following;
var coolPlaces = new L.LayerGroup();

L.marker([-41.29042, 174.78219])
    .bindPopup('Te Papa').addTo(coolPlaces),
L.marker([-41.29437, 174.78405])
    .bindPopup('Embassy Theatre').addTo(coolPlaces),
L.marker([-41.2895, 174.77803])
    .bindPopup('Michael Fowler Centre').addTo(coolPlaces),
L.marker([-41.28313, 174.77736])
    .bindPopup('Leuven Belgin Beer Cafe').addTo(coolPlaces),
L.polyline([
    [-41.28313, 174.77736],
    [-41.2895, 174.77803],
    [-41.29042, 174.78219],
    [-41.29437, 174.78405]
    ]
    ).addTo(coolPlaces);

var osmLink = '<a href="http://openstreetmap.org">OpenStreetMap</a>',
    thunLink = '<a href="http://thunderforest.com/">Thunderforest</a>';

var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
    osmAttrib = '&copy; ' + osmLink + ' Contributors',
    landUrl = 'http://{s}.tile.thunderforest.com/landscape/{z}/{x}/{y}.png',
    thunAttrib = '&copy; '+osmLink+' Contributors & '+thunLink;

var osmMap = L.tileLayer(osmUrl, {attribution: osmAttrib}),
    landMap = L.tileLayer(landUrl, {attribution: thunAttrib});

var map = L.map('map', {
     layers: [osmMap] // only add one!
    })
    .setView([-41.2858, 174.78682], 14);

var baseLayers = {
 "OSM Mapnik": osmMap,
 "Landscape": landMap
};

var overlays = {
 "Interesting places": coolPlaces
};

L.control.layers(baseLayers,overlays).addTo(map);
(There are a few lines in this printed example which may word wrap, so if you want a version to copy/paste from, I recommend that you use the on-line copy.)
There are only really two differences between this block of script and that for the base layers example.
The first is where we define what our overlay will be made up of.
var coolPlaces = new L.LayerGroup();

L.marker([-41.29042, 174.78219])
    .bindPopup('Te Papa').addTo(coolPlaces),
L.marker([-41.29437, 174.78405])
    .bindPopup('Embassy Theatre').addTo(coolPlaces),
L.marker([-41.2895, 174.77803])
    .bindPopup('Michael Fowler Centre').addTo(coolPlaces),
L.marker([-41.28313, 174.77736])
    .bindPopup('Leuven Belgin Beer Cafe').addTo(coolPlaces),
L.polyline([
    [-41.28313, 174.77736],
    [-41.2895, 174.77803],
    [-41.29042, 174.78219],
    [-41.29437, 174.78405]
    ]
    ).addTo(coolPlaces);
Here we declare a new LayerGroup called coolPlaces (var coolPlaces = new L.LayerGroup();). Then we simply define a set of markers and a polyline (see the earlier sections on these two elements for a fuller description) and add them to our coolPlaces layer.
The second change to our code is right at the end of the block of code.
var overlays = {
 "Interesting places": coolPlaces
};

L.control.layers(baseLayers,overlays).addTo(map);
Here we declare our overlays (there is only one (coolPlaces), but you can add as many as you want) usingvar overlays = {<put overlays here>}. Then we add overlays to our layers control so that it knows to include the layer in the screen widget.
And that’s all there is to it!
As stated earlier, the full code for this example can be found here on GitHub (and there’s a copy in the appendices) an online example is here on bl.ocks.org and there is a copy of all the files that appear in the book that can be downloaded (in a zip file) when you download the book from Leanpub.


The description above (and heaps of other stuff) is in the Leaflet Tips and Tricks book that can be downloaded for free (or donate if you really want to :-)).

No comments:

Post a Comment