#maptimeTO: leaflet.js

Let's make some web maps using Leaflet.js!

In this tutorial, we will use basic HTML, CSS, and JavaScript (specifically, the Leaflet JavaScript library) to create a series of progressively complex web maps.

HTML (HyperText Markup Language) allows us to structure content for our web page. Our map will be contained in an element within an HTML file.

CSS (Cascading Style Sheets) gives us control of the style and visual presentation of our web page. We will use it in the placement and sizing of the map and to customize some Leaflet elements.

JS (JavaScript) gives us the ability to add interactivity to our web page. We will use it to pull in map tiles to our web page, add data (or content layers), and handle user interaction with the map.

So, what exactly is Leaflet?

Leaflet is an open-source JavaScript library that gives us code to create interactive, mobile friendly web maps. Think of it as a collection (or library) of prewritten JavaScript that does some of the heavy lifting/scripting of web map stuff for us. We will interact with the library through its well documented API. It has a small file size but is packed with useful features and can be extended even further with plugins.

Setup

For this guide you will need:

Basic Map of Toronto Centered on Mozilla Offices

Here is the base map we'll build first:

view example

Create a basic HTML document

Open a file editor > Create a new file > Save the file using a .html extension.

Next, set up the structure of the web page by adding the following markup to the file:


<!DOCTYPE html>

<html>

<head>

<title>Leaflet Web Map</title>

<style>

</style>

</head>

<body>

<script>

</script>

</body>

</html>

Reference the Leaflet CSS and JavaScript Files

To make use of Leaflet we need to reference its CSS and JavaScript files in the HTML file.

You can reference the hosted Leaflet files or download copies, host them locally, and reference those. Let's reference the hosted files. To do so, insert the following code into the <head> section of the HTML page:


<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />

<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>

Add Map Div and Style It

Leaflet requires a <div> element to contain the map and that that <div> element have a set height.

Create a <div> element with the id of "map" to contain the map by adding the following to the HTML <body>:


<div id="map"></div>
	

To create a map that is 960 px by 500 px add the following CSS code between the <style> tags in the <head> section of the HTML page:


#map {
width: 960px;
height: 500px;
}
	

Now the HTML and CSS are set. The basic structure and style of our web page is in place. All we need to do is add some JavaScript and we'll have a web map!

Initialize Map

The first script we will write pulls in some map tiles and configures a few basic map settings.

Enter the following JavaScript between the <script> tags of the HTML file.


<script>

    var map = L.map('map',{
    center: [43.64701, -79.39425],
    zoom: 15
    });

    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

</script>

	

The code is now complete so the file should now look like this:


<!DOCTYPE html>

<html>

<head>

<title>Leaflet Web Map</title>

<link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />

<script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>

<style>
#map {
    width: 960px;
    height:500px;
}
</style>

</head>

<body>

    <div id="map"></div>

<script>

    var map = L.map('map',{
    center: [43.64701, -79.39425],
    zoom: 15
    });

    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

</script>

</body>

</html>

Here is breakdown of the script:

The script creates the 'map' variable, assigns it a new L.map object and passes it the id (‘map’ in this case) of the div element in which the map is to be contained. The script goes on to pass some options that set an initial center point and zoom level for the map. Essentially, this creates a map on the page that we can manipulate.

Next, the script creates a new L.tileLayer object, specifying a particular set of tiles to be loaded into the map container and passes in an 'attribution' option. In this case OpenStreetMap tiles are used but there are many map tile providers. Experiment with different sets and remember to always properly attribute the data and imagery used! As tiles are the basis of web maps, it is worth learning more about them. For detailed information see Anatomy of a Web Map, by Alan McConchie and Beth Schechter of Maptime and Stamen.

Finally, the addTo() method is used to add the tile layer to the map.

Make sure to save the file and then open it with a web browser.

You should see a web map centered on the Mozilla Toronto offices!

Modify the Base Map

Let's go ahead and make two minor adjustments to the script. The map will look the same but be a little more user friendly. The code will be sleeker as well.

view example


<script>

    var map = L.map('map',{scrollWheelZoom:false}).setView([43.64701, -79.39425], 15);

    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

</script>
		

First, remove the 'center' and 'zoom' options from the L.map constructor.

Next, modify the script to deactivate the scrollWheelZoom interactivity option so that we don't accidentally zoom the map when we are trying to scroll down the page. This is done by passing 'scrollWheelZoom: false' as an option to L.map(). This can be a particularly important usability issue if the map is large or if there is content above and/or below it.

Finally, set the initial center and zoom level with the setView() method.

The map should look just like our first one but we can't control the zoom level by scrolling and the code is a bit streamlined.

Now we have a customized base map with which to build on.

Add a WMS Layer to the Map

This example adds a Web Map Service (WMS) Weather Overlay to the map.

view example


<script>

    var map = L.map('map').setView([43.64701, -79.39425], 3);

    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

    L.tileLayer.wms("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi", {
    	layers: 'nexrad-n0r-900913',
        format: 'image/png',
        transparent: true,
        attribution: "Weather data © 2012 IEM Nexrad"
    }).addTo(map);

</script>
  	    

This code changes the zoom level in the setView() method to 3 and using L.tileLayer.wms() displays a WMS service as a tile layer on the map. Like the L.tilelayer() function, L.tilelayer.wms() is passed the url to the service provider and a set of options.

Add a Default Marker to the Map

This example adds a default Leaflet marker on the Mozilla Toronto offices.

view example


<script>

    var map = L.map('map', {scrollWheelZoom:false}).setView([43.64701, -79.39425], 15);

    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

    var marker = L.marker([43.64701, -79.39425]).addTo(map);

</script>
  	    

This code creates a marker variable and assigns it a marker object with a particular point using L.marker(). The marker is then added to the map with the addTo() method.

Add a Custom Marker to the Map

This example adds a custom marker (a Firefox icon) on the Mozilla Toronto offices.

view example


<script>

    var map = L.map('map', {scrollWheelZoom:false}).setView([43.64701, -79.39425], 15);

    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

    var firefoxIcon = L.icon({
        iconUrl: 'http://joshuafrazier.info/images/firefox.svg',
        iconSize: [38, 95], // size of the icon
        });

    var marker = L.marker([43.64701, -79.39425], {icon: firefoxIcon}).addTo(map);

</script>
  	    

This code creates the ‘firefoxIcon’ variable and assigns it an icon marker using L.icon().

A few options are passed to L.icon():

The ‘firefoxIcon’ variable is then passed to the ‘icon’ option of L.marker().

Add a Popup to the Marker

This example adds a standard popup to the custom marker. It is activated upon click.

view example


<script>

    var map = L.map('map', {scrollWheelZoom:false}).setView([43.64701, -79.39425], 15);

    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

    var firefoxIcon = L.icon({
        iconUrl: 'http://joshuafrazier.info/images/firefox.svg',
        iconSize: [38, 95], // size of the icon
        });

    L.marker([43.64701, -79.39425], {icon: firefoxIcon}).bindPopup('Mozilla Toronto Office').addTo(map);

</script>
  	    

This code adds a popup to marker click by using the bindPopup() method.

Customize the Popup on the Marker

This example adds HTML content and a custom style to the popup.

view example


<style>
#map {
    width: 960px;
    height:500px;
}
.custom .leaflet-popup-tip,
.custom .leaflet-popup-content-wrapper {
    background: #e93434;
    color: #ffffff;
}
</style>
  	    

This CSS code is added to the head of the HTML file. It adds styles for the class 'custom' which we will create in our script.


<script>

    var map = L.map('map', {scrollWheelZoom:false}).setView([43.64701, -79.39425], 15);

    L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
    }).addTo(map);

    var firefoxIcon = L.icon({
        iconUrl: 'http://joshuafrazier.info/images/firefox.svg',
        iconSize: [38, 95], // size of the icon
        popupAnchor: [0,-15]
        });

    var customPopup = "Mozilla Toronto Offices<br/>
<img src='http://joshuafrazier.info/images/maptime.gif' alt='maptime logo gif' width='350px'/>";
var customOptions = { 'maxWidth': '500', 'className' : 'custom' } L.marker([43.64701, -79.39425], {icon: firefoxIcon}).bindPopup(customPopup,customOptions).addTo(map); </script>

This code first adds a 'popupAnchor' option to the icon. The values set moves the popup higher so that more of the icon is visible.

Then it creates the variable ‘customPopup’ and assigns it some HTML content.

Next it creates the variable ‘customOptions’ and specifies a few options:

The bindPopup method takes HTML content and options as arguments. The variables created are passed into the method.

*Note, by default the maximum width of a popup is set to 300px. Sometimes you might want it wider, particularly if you want to add content to it that is larger than 300px. To avoid content spilling out of the popup, make sure the 'maxWidth' option of popup is set larger than the width of content used.

Next Steps

Examples of how to easily add vector layers to a map:

Acknowledgements and Further Resources

One of the great things about Leaflet is that there are so many resources out there for you to consult. I perused all of the following to prepare this tutorial for MaptimeTO. Make sure to take advantage of them. And a special big ups to all the fellow Maptimers on this list from whose work I built on and around!

Anatomy of a Web Map, by Alan McConchie and Beth Schechter of Maptime and Stamen.

Leaflet tutorials on the official Leaflet website.

Leaflet.js Essentials, a book by Paul Crickard III.

Leaflet and Mapbox JavaScript API Fundamentals, a presentation by Mapbox's Rafa Gutierrez.

Leaflet Intro, a Maptime PDX presentation by Lyzi Diamond.

Leaflet Tutorial, written for Maptime Boston by Andy Woodruff and Ryan Mullins that gets into some more advanced techniques such as incorporating jQuery, external geojson files and the Leaflet.markercluster plugin into a project.

Leaflet.JS Introduction, by Thierry Nicola for JS Luxembourg.

Leaflet provider map, an open source Leaflet extension that contains configurations for various free tile providers.

Mapbox Guides and examples are great for learning about web maps in general in addition to Mapbox.js, which is built on top of Leaflet.


Find a mistake? Submit an Issue on Github!Back to Top