Leaflet part 1 - NieneB/webmapping_for_developers GitHub Wiki

Leaflet.js

Leaflet is an open-source JavaScript library for interactive web maps. It's lightweight, simple, and flexible, and is probably one of the most most popular open-source mapping library at the moment. Leaflet is developed by Vladimir Agafonkin (currently of MapBox) and other contributors.

Leaflet-logo

Leaflet creates "Slippy" maps with raster tiled base layers, user interaction like panning and zooming, and feature layers that you supply. It handles various basic tasks like converting data to map layers and mouse interactions, and it's easy to extend with plug-ins. It will also work well across most types of devices.

Web maps

Web maps are made up of many small, square images called tiles. These tiles are typically 256x256 pixels and are placed side-by-side in order to create the illusion of a very large seamless image. A big advantage: all these little tiles load way faster than one big map! This kind of map is called a "Slippy" map.

slippy map

Each zoom level has its own set of tiles. Zoom level 0 has 1 tile for the world. With each additional zoom level, the number of tiles increases exponentially. So zoom level 1 has 4 tiles for the world. Zoom level 2 has 16 tiles for the world ect. Learn more about the google tiling scheme.

Zoom levels

As you can see, map tiles are static raster images on the web. These tiles need to live somewhere on the web page. They need to know when to load and they need to react when you click or drag. Leaflet is a JavaScript library that allows us to do just that.

Setting up the basics

During the workshop we will work with a simple HTML page example. The examples can also be found in the git repository. Feel free to set up a folder and structure for yourself or work in any framework you'd like.

For this workshop, we assume you already know HTML,CSS and some JavaScript. If not see the Webmapping for Beginners workshop. This is almost the same workshop but includes more explanation about the basic concepts of HTML, CSS and JavaScript.

▶️ Create a basic HTML document.

<!DOCTYPE html>
  <html>
    <head>
      <title> My title </title>
    </head>
  <body>
    <H1>Example</H1>
    <script></script>
  </body>
</html>

Setting up Leaflet.js

▶️ Go to http://leafletjs.com/download.html to use the latest hosted version of Leaflet.

<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>

▶️ Place the leaflet.css Link in the <head> of your html file.

▶️ Place the leaflet.js script library in the <body>.

We will need a <div> were our map will be placed.

▶️ Place a <div> with an id="map" in the <body>

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

The map needs a height and width in order to be seen. Add a bit of CSS to the HTML document. The following is sufficient:

#map { 
  height: 500px; 
  width:100%;
} 

Creating our first map

Initialize a map by creating a L.map instance with JavaScript.

<script>
  //initialize the map         
  let map = L.map('map').setView([51.9741, 5.6688], 15);
</script>

ℹ️ let map = L.map('map') initializes the map variable and links it to our <div id="map"></div>. This will link the map content to the <div> container.

ℹ️ setView() centres the map at ([latitude, longitude], zoom level). The projection is Google Mercator.

Apart from the setView we did not pass any options when creating the map instance. So by default, all mouse and touch interactions on the map are enabled and it has zoom and attribution controls.

The map instance is customizable with Options. We will come back to this later.

🔗 Read the map instance documentation here.

Let's first add our Baselayer, because we do not have a map yet only the framework for the map.

A Base layer can also be called a basemap, reference map, TileLayer or tile provider. It consists of the multiple PNG images, so-called 'tiles'. It is possible to create tiles yourselves and host them yourselves. But this requires some GIS skills and map render/serving skills. Luckily there are also a lot of tile providers out there, offering you free or on subscription tile services.

We will add a base layer with the L.TileLayer instance and a Open Street Map provider.

🔗 Read the TileLayer documentation here.

▶️ Add a TileLayer to the map with the following code:

<script>
  //initialize the map         
  let map = L.map('map').setView([51.9741, 5.6688], 15);

  //Create base layer   
  let backgroundMap = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    maxZoom: 19,
    attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
  });
  // add layer to map instance
  backgroundMap.addTo(map);
</script>

ℹ️ We create a base-layer with L.tileLayer('http://...') this grasps the static tiles from the internet and Leaflet knows how handle them to make and interactive map.

ℹ️ backgroundMap.addTo() adds the tile layer to the map. Your map can contain multiple layers. You will see later on.

Now you have made our first basic web map!

▶️ Open your HTML file in your browser!

Do you see your map? Great!

Changing Map options

We can also define our map options before and pass it into the map instance on creation, like this:

let options = {
    zoom: 12,
    center: [52.38031476, 4.90273476],
    maxZoom: 19,
    minZoom: 6,
    maxBounds: [[ 51.8716, 3.8133], [ 52.8271, 6.4494]]
} 
let map = L.map('map', options );

🔗 Use the Leaflet documentation to see all the map options

▶️ Change the map instance to using the options object.

▶️ Change the center coordinates, zoom level and the bounds. For example, focus the map on a company you work for. (or use you home address).

ℹ️ Looking for a specific place to centre on? Find your coordinates here: mapcoordinates.net

ℹ️ The minZoom and maxZoom restrict the map from zooming in or out further then those zoom levels. If you want to know how far "zoomed" in you are, have a look at this description of scales and examples about zoom levels.

ℹ️ The maxBounds are the coordinates of a bounding box to which the user is restricted. Check the latlngbounds documentation. 🔗 Finding easy creation of bounding boxes at: https://boundingbox.klokantech.com/

A boundingbox is an important geo type to know. It represents a rectangular geographical area on a map. Defining a bounding box works different in different frameworks. But mostly takes in 2 coordinates for 2 corners, left top and right bottom to define a rectangle.

‼️ Tip!

Using these kind of map options, limits the use of the map to a great extent! When using a paid subscription plan on a tile provider this can be very useful. But also the IX design can be improved with these settings. People are directed to what you want to show them on the map and cannot "get lost" or use the map for different purposes. So do not forget about what you want the user to see and use these map options! :)

Different tiles

There are many different tile providers! Just copy their example code, replacing your own code starting from L.tileLayer (... ); Have a look at this Leaflet provider preview application.

▶️ Try out some different styles in your map!

▶️ What happens if you add multiple base layers to your map?

Hash Plug-in

Leaflet.js contains only the most basic task for making a web map. That why it is so light-weight and fast. Ideal for small maps on mobile applications with limited internet access.

If you want to have more elaborate functionality in your map we will need to add plugins.

A useful (and small) plugin for example is Leaflet-hash plugin. This plugin shows the position of your web map in the url of your web page. It gives the z: zoom level and the x and y coordinate. Now you can always return to the map where you last opened it, or share a specific location with someone else!

▶️ Add this plug-in to your html file.

<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-hash/0.2.1/leaflet-hash.js"></script>

▶️ In the custom code we will add the hash to our map. Put the code under the map variable:

// Hash in URL
let hash = new L.Hash(map);

That's it!

‼️ NOTE!

The inital z/x/y map position set in your code only works when initializing the map for the first time. Refreshing the browser with the z/x/y hash in the url will re-open the map at this last location, not the initial location you set in your code!

If you want to go back to your original location set in your code, remove the z/x/y hash from the url to refresh the map.

Dealing with Map Events

Every time something happens in Leaflet, e.g. user clicks on a marker or map zoom changes, the corresponding object sends an event which you can subscribe to with a function. It allows you to react to user interaction:

function onMapClick(e) {
  alert("You clicked the map at " + e.latlng);
}

map.on('click', onMapClick);

▶️ Add the click event to your map.

Each object has its own set of events — see documentation for details. The first argument of the listener function is an event object — it contains useful information about the event that happened. For example, map click event object (e in the example above) has latlng property which is a location at which the click occurred.

▶️ Use the documentation to see if you can find the clicked pixel coordinates instead of the latitude longitude coordinates.

Pop-up

Let’s improve our example by using a popup instead of an alert:

let popup = L.popup();

function onMapClick(e) {
  popup
    .setLatLng(e.latlng)
    .setContent("You clicked the map at " + e.latlng.toString())
    .openOn(map);
}

map.on('click', onMapClick);

▶️ Add the popup functionality to your map.

Read more about the L.popup() instance at the documentation

Try clicking on the map and you will see the coordinates in a popup.

▶️ See if you can use the documentation to assign a class name to your popup and change the color of the popup with CSS.

➡️ Continue to Leaflet part 2 to add points, markers, circles and polygons to our map.

⚠️ **GitHub.com Fallback** ⚠️