Geolocation Part II: Building Interactive Maps with Leaflet

“A map does not just chart, it unlocks and formulates meaning; it forms bridges between here and there, between disparate ideas that we did not know were previously connected.”
― Reif Larsen

A couple of weeks ago I wrote about using the Geolocation API, and walked through the minimal code necessary to get the user’s longitude and latitude. Now I want to take it just a step further, and show how to use Leaflet to show the users current location on a map.

The Setup

First you’re going to want to include all the necessary CSS and JavaScript files. You can download the files and host them yourself, or Leaflet hosts them on their own CDN, or they’re also available on CloudFlare’s cdnjs. We’ll use the Leaflet-hosted files here:

Those are all the required files for our basic example, then you’ll just need to add a container to hold the map, wherever you want it to appear on your page. We’ll use a <div>:

XHTML

1

2

3

<div id="leafletmap"></div>

Finally, the map container needs to have a defined height so we’ll set that in CSS. The map’s width will be flexible, so depending on your needs you may also want to set a max-width and/or a min-width.

XHTML

1

2

3

4

5

<style type="text/css"><!--

#leafletmap{height:200px;}

--></style>

Let’s Make a Map!

Now that all the setup’s done, we can create the map itself. The following code will create a new map object:

JavaScript

1

2

3

varmymap=L.map('leafletmap');

We’ve now got access to a new map object named “mymap”, and have passed in the ID of out map container <div>, so “mymap” is bound to that DOM element. The L.map() constructor function also accepts a set of options as its second parameter, so it you want to set a bunch of options when you initialize your map you can so like this, for example:

JavaScript

1

2

3

4

5

6

7

8

varmymap=L.map('leafletmap',{

center:[[40.775,-73.972]],

scrollWheelZoom:false,

inertia:true,

inertiaDeceleration:2000

});

Let’s not worry about that yet though, in our simple example we haven’t set any options–so all the default values and settings will apply–but you can also set these options later if you prefer. See all map() options. Let’s take a look at our map now:

You might notice that it doesn’t look like much yet. We still need to set the map’s view, which gives it a specific place in the world for the map to start: a latitude, a longitude, and a starting zoom-level:

JavaScript

1

2

3

mymap.setView([40.775,-73.972],15);

The first parameter passed into setView() represents the latitude and longitude, and the second parameter is the zoom level. Now we just need to add tiles.

Adding Tiles

What are tiles? According to the Open Street Map wiki, map tiles are “square bitmap graphics displayed in a grid arrangement to show a map.” In other words, map tiles are the actual graphics that make the map look like a map. They are typically 256px square images like the example shown here.

There are a number of different tile providers (or tileservers), some are free and open source, some are paid services. For the example here we will use OpenStreetMap tiles. OpenStreetMap is “a free editable map of the whole world”, with its data licensed under the Open Data Commons Open Database License. Just because the data is open source though, doesn’t mean that you’re free to use or abuse its tileservers however you wish, so it’s important to take a look at and abide by their Tile Usage Policy. Other options for tiles include CloudMade, Stamen, MapQuest, and others–you can even use Google, Bing, or Yandex tiles via their respective APIs by using one of these Leaflet plugins. Many of those tile providers will require you to create an account and get an API key, and limit you to X free tiles per month.

So we’re calling tilelayer() to create the tile layer, passing in the OSM URL first, then the second argument is an object containing the options for our new tile layer (including attribution is critical here to comply with licensing), and then the tile layer is added to the map using addTo(). Now we’ve finally got something that looks like a map!

What our map should look like now. (this is just a screen capture of it)

I hear Central Park is nice this time of year, but I want see myself on the map!

Ah yes, back to the Geolocation API! Now that we’ve seen how to build and display a basic map using Leaflet you can probably see that you could, if you wanted, get the user’s longitude and latitude using this method, and then pass the latitude and longitude into the setView() function discussed above. Fortunately, Leaflet makes it even simpler than that! You can just replace setView() with the locate() function, and Leaflet handles getting the user’s location for you and setting the map to show where the user is at.

JavaScript

1

2

3

mymap.locate({setView:true,maxZoom:15});

One other thing you may want to do is display a marker on the map at the user’s location, which you can do like this:

JavaScript

1

2

3

4

5

6

7

8

9

10

11

/** bind the locationfound event to the function onLocationFound()

in other words, tell Leaflet what to do once locate() is successful

**/

mymap.on('locationfound',onLocationFound);

functiononLocationFound(e){

// create a marker at the users "latlng" and add it to the map

L.marker(e.latlng).addTo(mymap);

}

And there you go, now you can create an interactive map using Leaflet, and show the user’s current location on said map– that is assuming that they click “Allow” on the little opt-in bar that appears whenever you attempt to access the users location. Remember that using the geolocation API to see where the user is at is always opt-in, as it should be.

4 Replies to “Geolocation Part II: Building Interactive Maps with Leaflet”

You think I could use geolocation anc leaflet or some other library to plot points and track location on my own custom map/graphic? In this context, say I have a map of a campground, and I want to give visitors navigation while onsite, but google or bing maps are of no use. Or perhaps I want to navigate trails in a national park.
Thoughts?