Maps
Open Source
February 12, 2015

Leaflet: Seven rarely used features

Moritz Klack
@moklick
In this post I will share some Leaflet features with you I wish I knew earlier. It should help you to use the full power of Leaflet and not only stick to the map related functions.
You can find all the utility and helper functions of Leaflet at the latter part of the documentation. I will give you an overview over the most useful ones.
Usually I don't check out all the functions of a library, but if I have a specific problem I look up how the API can help me with that. I discovered the following features far too late. They are great helpers and maybe help you to kill some dependencies, if you start using them.
If you are going to develop a map application with Leaflet, it's also a good idea to check out the Plugins. Maybe there is already a solution for one of your problems.

1. Classes

Javascript (< ES6) lacks the implementation of native classes. For this Leaflet brings along a nice helper to create classes with features like inheritance, includes, statics and options.
If we want to create an overlay class for example, we could do something like this:
var Overlay = L.Class.extend({
// this is the constructor
initialize: function (selector, options) {
L.Util.setOptions(this, options);
this._selector = selector;
// create overlay here
},
// these are the default options
options: {
isActive: false,
background: 'rgba(0,0,0,0.25)',
},
// this is a public function
toggle: function () {
this.isActive = !this.isActive;
// toggle overlay here...
},
});
Now we can easily create an instance of our new class and call its methods:
var overlay = new Overlay('#overlay', { background: 'rgba(255,255,255,0.1)' });
overlay.toggle();
As you can see this is a very clean way to structure the code. By using classes we are also able to create subclasses. This could be useful if we have different types of modals for example. For this we could implement a BaseModal class and specific classes like InfoModal or PromptModal that inherit from the BaseModal superclass:
// create BaseModal superclass
var BaseModal = L.Class.extend({
initialize: function (isActive) {
this.isActive = isActive;
},
// define base functions here
});
// create a subclass of BaseModal
var InfoModal = BaseModal.extend({
initialize: function (isActive) {
// init BaseModal class
BaseModal.prototype.initialize.call(this, isActive);
},
// define some InfoModal specific functions here
});

2. Templating

In map applications we often have to create tooltips, legends or other generic elements. The L.Util.template function can help us with this. It takes a template string and an object that includes the template data:
var tooltipTemplate =
'In the district live <strong>{persons} persons<strong>.<br />' +
'{children} of them are children, {adults} adults and {seniors} seniors';
var tooltipData = {
persons: 1400,
children: 400,
adults: 800,
seniors: 200,
};
var tooltipContent = L.Util.template(tooltipTemplate, tooltipData);
// returns: 'In the district live <strong>1400 persons</strong>.<br />400 of them are children, 800 adults and 200 seniors'
// now we can add the HTML to a certain element
L.DomUtil.get('tooltip').innerHTML = tooltipContent;
As you can see we are also allowed to use HTML in the template string.
Colors Of Europe
Interactive Data Visualization (Zeit Online)
Are you interested in a collaboration?
We are specialized in creating custom data visualizations and web-based tools.
Learn more

3. Extend Function

If we pass options to a function we often want to merge them with default options. Normally I would use the extend function of lodash or jquery but Leaflet also includes a L.Util.extend function:
var defaultOptions = {
zoom: 9,
center: [52.52, 13.42],
};
var initMap = function (opts) {
// extend passed options with the default options#
// if we pass { zoom : 12 }, options would be { zoom : 12, center : [52.52, 13.42] }
var options = L.Util.extend(opts, defaultOptions);
// initialize map
};

4. DOM Utils

Leaflet has plenty of DOM utility functions that help us to work with the DOM. So for example if we want to create a DOM node we could use the L.DomUtil.create function:
// create div element with the class 'overlay' and append it to the body
L.DomUtil.create('div', 'overlay', document.body);
// create span element with the class 'title' without appending it
var title = L.DomUtil.create('span', 'title');
There is also a L.DomUtil.get function but it only takes an id or the HTMLElement itself (wait what?!). It would be nice if we could pass a selector here, but that is not possible. Internally it does document.getElementById(id) if it's a string or returns the element.
Another very useful set of utility functions are the class helpers. We can add, remove or check if an element has a certain class with the following functions:
// add class 'dragging-mode' to the body
L.DomUtil.addClass(document.body, 'dragging-mode');
// remove class 'dragging-mode' from the body
L.DomUtil.removeClass(document.body, 'dragging-mode');
// check if the body has class 'dragging-mode'
var isDragging = L.DomUtil.hasClass(document.body, 'dragging-mode');

5. Browser and feature detection

If we have some functionality that does not work for a certain kind of browser or only should be displayed on mobile devices for example, we can detect these features with the L.Browser helper:
if (L.Browser.webkit) {
// webkit based browser detected
}
if (L.Browser.msTouch) {
// browser with Microsoft touch detected
}
There are lots of other features like L.Browser.mobile, L.Browser.retina or L.Browser.ie we can detect.

6. Line Simplifier

The L.LineUtil.simplify function is more map specific than the rest of the examples. It allows us to simplify a line by just passing an array of points and a tolerance value to the function:
var line = [
L.point(125, 250),
L.point(145, 230),
L.point(150, 200),
/* lots of more points */
];
var simplifiedLine = simplify(line, 0.75);
This really helps us to boost the performance of our application. You can see the effect of this function on the simplify.js website which visualizes the simplification.

7. Control

If we want to add some controls or boxes to our map the L.Control class is very useful. We can define a position in the options object and use the onAdd and onRemove functions to listen if our class got added or removed.
Let's say we want to create a legend for our map:
var Legend = L.Control.extend({
options: {
position: 'bottomright',
},
onAdd: function (map) {
var legend = L.DomUtil.create('div', 'map-legend', L.DomUtil.get('map'));
// here we can fill the legend with colors, strings and whatever
return legend;
},
});
map.addControl(new Legend());

That's it.

I hope this post helps you to use more Leaflet features in your next map application. If you have any questions just leave a comment or contact me via twitter.
Further Reading
webkid logo
webkid GmbH
Kohlfurter Straße 41/43
10999 Berlin
info@webkid.io
+49 30 232 575 450
Imprint
Privacy