Tuesday, 28 January 2014

Using multiple maps with leaflet.js

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 .
----------------------------------------------------------

Leaflet has a great feature that allows you to easily switch between tile layers when viewing your map. It’s built right in to leaflet.js and (as usual) it’s simple to implement.
What we’re going to do is define the locations and appropriate attributions for two different sets of tiles and then tell leaflet to place a control on the map that allows us to switch. These different sets of tiles are referred to as ‘base layers’ and as such only one can be visible at any one time.
The end result is a small icon in the top right hand corner that looks like this…
Layers icon
And when we hover over it with our mouse it changes to show the different tile layers that we have defined for use.
Layers control with mouse over
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 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
};

L.control.layers(baseLayers).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 or the copy downloaded in the zip file with the book.)
The first block of code sets up the links that we will use for attribution;
var osmLink = '<a href="http://openstreetmap.org">OpenStreetMap</a>',
    thunLink = '<a href="http://thunderforest.com/">Thunderforest</a>';
This just makes it easier to add later when juggling multiple layers.
The we declare the URLs for the tiles and the attributions to display;
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;
Again, by declaring these as variables, the process of defining the distinct layers is simplified.
Which is what we do in the next block of code;
var osmMap = L.tileLayer(osmUrl, {attribution: osmAttrib}),
    landMap = L.tileLayer(landUrl, {attribution: thunAttrib});
Declaring the layers like this is pretty handy since now we have a single variable for each layer that has all the information associated with it that is required to display the tiles for that layer.
Now we add the map with the following lines of code;
var map = L.map('map', {
     layers: [osmMap] // only add one!
    })
    .setView([-41.2858, 174.78682], 14);
It looks a lot like our simple map example, but in this case we have added in an option called layers and set that to the osmMap layer. This will be the initial layer that is shown on the map/ I have a note there to say that it’s a good idea to only have one of your base layers in there. That’s because if you put more than two it will load both layers when the map first loads and we don’t need to do that unnecessarily.
The second last section of the code declares what our base layers are (there are other sorts of layers, but we’ll get to that later) and gives them appropriate text to display in the layers selection box.
var baseLayers = {
 "OSM Mapnik": osmMap,
 "Landscape": landMap
};
Then the last line adds the control for the baseLayers to the map
L.control.layers(baseLayers).addTo(map);
As I write this I am seriously considering creating a page and just adding as many layers as I have described in the tile layers section. Hmm… I’ll give that some thought.
As I mentioned earlier, 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 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