We've made maps using Google Fusion Table and CartoDB but now we're going to learn how to make one from scratch.
It's good to understand the mechanics of what programs like CartoDB or Silk is using to make their maps to see what's flexible and customizable in the future.
This tutorial will show you how to take a dataset with latitude and longitude columns, map it and style it using Leaflet.js, an open source Javascript library. It's extremely versatile for building many types of interactive maps.
We'll be mapping out Dunkin' Donuts locations in Connecticut.
Download the dataset here.
Set up the HTML by creating a new file on your computer called leaflet.html
and paste the code below in it.
The code above sets up the <html>
and links to the leaflet.css
and leaflet.js
CDN files.
Next, we need to set up the div for where the map will appear and also the javascript to build the map.
Replace the code in leaflet.html
with the code below.
Here's what the code above is doing:
#map
is set to 200px
height in the CSS section <style></style>
<div id="map"></div>
is the HTML body and where the map will be rendered.<script></script
is the Javascript that builds out the map using the Leaflet library parameters. var map = L.map('map').setView([41.651426, -72.690940], 8);
The line above sets the variable map and L.map('map')
directs the function building the map to render in the div id map
(Remember <div id="map"></div>
?). The latitude and longitude within setView([])
is where the map should be centered and that's followed by 8
which is the level of zoom it should start at.
Beneath that is
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="http://mapbox.com">Mapbox</a>',
}).addTo(map);
So L.tileLayer
sets the base layer tiles.
At the end, .addTo(map)
pipes latitude, longitude, and zoom information in the variable map
above it.
Save the file and open it in a browser.
Congratulations, you've coded a mapa> from scratch.
But we're just getting started. Let's add data to the map.
Insert these lines of code between var map
and L.tileLayer
var marker = L.marker([41.763919, -72.681897]).addTo(map);
marker.bindPopup("<b>Hello</b><br><a href='http://www.trendct.org'>-TrendCT.org</a>");
L.marker()
is function for an icon on the map with the latitude and longitude.
And bindPopup
is the HTML you want to appear in the pop up window when people click on it.
Here's what the code looks like
Here's how the marker looks
Let's get the data. Visit this link.
This is what the data looked like after I scraped it from the Dunkin' Donuts website.
But Leaflet needs these addresses to be translated to latitude and longitude.
To do that, you'll need to 1) concatenate the address, city, state, and zipcode columns into one new column and then 2) geocode the new column.
Here are some good services to geocode batches of addresses:
However, we can skip all that for now. Just click on the Formatted tab at the bottom.
I've already done the hard work for you.
OK, copy the data in the Formatted tab of the spreadsheet and paste it into the top window of Mr. Data Converter
Select JSON - Row Arrays
in the Output as pulldown menu.
Copy the data output in the bottom window and paste it into your code above L.tilelayer
.
Add var dlist =
before it and add ;
to the end.
This turns it into a Javascript array.
Next, delete the marker code we added before:
var marker = L.marker([41.763919, -72.681897]).addTo(map);
marker.bindPopup("<b>Hello</b><br><a href='http://www.trendct.org'>-TrendCT.org</a>");
And replace it with
for (var i = 0; i < dlist.length; i++) {
circle = new L.circle([dlist[i][1],dlist[i][2]], 500, {
fillOpacity: .8,
color: '#ffa500',
fillColor: '#ffa500',
weight:3,
radius:40,
stroke: true
})
.bindPopup(dlist[i][0])
.addTo(map);
}
This is a loop function that will go through an array of data we just added var dlist
and add a circle to the map after it finds the latitude and longitude in each row.
The options below circle
are various styles like color and opacity and how big the circles will be.
Here are more options for styling circles.
Also, let's make the height of the map larger. Change #map
to 400px
.
#map { height: 400px; }
This what your code should look like.
And here's the map!
Pretty cool, right?
I swapped out the tile link so it would make the orange pop out more.
We're adding some additional CSS to the <style>
section of the HTML.
This sets the dimensions of the box and the font size, as well as other things like padding and color.
Also in the <body>
part of the HTML, we're adding a div for the legend to be rendered in.
This is that part of the code.
Adding all those lines of CSS and HTML looks like this.
The legend is in the bottom right corner.
And here's the complete code.