Mapping with Leaflet

2015-03-27T3:16:00Z

About Leaflet

Leaflet is an open-source JavaScript library for making web and mobile friendly interactive maps. It offers all the standard mapping abilities you would expect from an web map and being based in JavaScript, Leaflet maps are compatible in most desktop and mobile browsers.

Leaflet is designed to be light weight, simple to use and perform well. The API is well documented on the Leaflet website with some tutorials to get you started. The map on on the front page is an adaptation of the Interactive Choropleth Map tutorial. There are also host of plugins available to extend the functionality of your map.

To learn more visit the Leaflet website and check out the twitter page to see some great examples of how Leaflet is being used.

Basic Leaflet Map

  1. It is simple to make a basic Leaflet map. Start with a minimal HTML document (HTML5 in this case) and insert the leaflet CSS and JavaScript file into the header. I use the CDN versions but the files are available for download or local use.

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8"/>
        <title>Leaflet Map</title>
        
        
      </head>
      <body>
      
      </body>
    </html>

  2. Add a div anywhere in the body of the document and give it an id="map" attribute.

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8"/>
        <title>Leaflet Map</title>
        
        
      </head>
      <body>
        <div id="map"></div>
      </body>
    </html>

  3. Add a CSS element in the document head and define the height of the map element..

    
    

  4. Configure the map by inserting a script tag in the body somewhere below the map element and add a tile layer for a base layer.

    <script>
    
      var map = L.map('map').setView([30.266, -97.756], 14);
      
      L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpg', {
       subdomains: '1234',
       attribution: '© OpenStreetMap'
      }).addTo(map);
      
    </script>
    

    Line 3 in the above snippet creates a variable named map that represents the map object on the page. It also sets the map's view, or center point, to the location 30.266, -97.756 and the zoom level to 14.

    Lines 5 - 8 initialize the MapQuest-OSM tile layer and add it to the map. Line 5 contains the formatted URL for the tile layer. You may notice that there are a few non-typical characters in the URL. The {s} is a place holder for the tile server's subdomains. Subdomians are usually either a, b, c, d or 1, 2, 3, 4. The subdoamins help serving tiless when there are multiple requests coming from the same browser. the {z} is a place holder for the zoom level while the {x} and {x} are place holders for the tile coordinates. No need to worry too much about the actual values that go there because Leaflet will populate them as needed to retrieve the correct tiles.

    Always remember to be courteous when using other's data sources and properly attribute them.

  5. Finish the map by adding a few markers and a styled GeoJSON layer in the script block.

    // define some markers (points)
    L.marker([30.25999, -97.744610]).bindPopup("Bats
    A great place to watch the bats.").addTo(map); L.marker([30.265422, -97.740462]).bindPopup("Coffee anyone?").addTo(map); // create a GeoJSON polygon to put in the map var geoJSON = { 'type': 'Feature', 'properties':{'name':'Auditorium Shores','address':'800 W Riverside Drive, Austin, TX 78704'}, 'geometry': { 'type': 'Polygon', 'coordinates': [ [ [-97.749489,30.26268], [-97.75085,30.26322], [-97.75197,30.26352], [-97.75287,30.26405], [-97.75453,30.26426], [-97.75662,30.26067], [-97.75022,30.25860], [-97.74943,30.25985], [-97.74837,30.26233], [-97.74948,30.26268] ] ] } } // add the GeoJSON polygon to the map L.geoJson(geoJSON, { style: {weight: 2, color: '#8B0000', fillColor: '#DC143C', fillOpacity: 0.3}, onEachFeature: function (feature, layer) { layer.bindPopup('' + feature.properties.name + '
    ' + feature.properties.address); } }).addTo(map);

    There are a a couple things going on in this snippet. Lines 2 & 3 define a simple marker with a popup and add them to the map.

    Lines 6 - 16 create a GeoJSON polygon. If you are not familiar with GeoJSON, I would recommend reading about it. In my opinion, GeoJSON is the best way to get information out of GIS into a Leaflet map.

    Lines 19 - 24 create a geoJSON layer and add the above GeoJSON polygon to the map. You may also noticed the style property on the geoJSON layer is a JSON object and that the popups use regular HTML syntax. Because Leaflet utilizes HTML5 and CSS, most layers, features and properties can be set using standard JavaScript variables and functions. That's a huge benefit when mapping complex layers.

The Final Product

Here is the final map. With only a few lines of code and no expenses, we have a fully functional and interactive web map. If you are interested, there is a fullscreen version of this map here.

And here is the final source used to construct the map.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8"/>
    <title>Leaflet Map</title>
    
    
    
  </head>
  <body>
    <div id="map"></div>
    <script>
      var map = L.map('map').setView([30.266, -97.756], 14);
  
      L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/map/{z}/{x}/{y}.jpg', {
        subdomains: '1234',
        attribution: '© OpenStreetMap'
      }).addTo(map);
                        
     // define some markers (points) 
     L.marker([30.25999, -97.744610]).bindPopup("Bats
A great place to watch the bats.").addTo(map); L.marker([30.265422, -97.740462]).bindPopup("Coffee anyone?").addTo(map); var geoJSON = { 'type': 'Feature', 'properties':{'name':'Auditorium Shores','address':'800 W Riverside Drive, Austin, TX 78704'}, 'geometry': { 'type': 'Polygon', 'coordinates': [ [ [-97.749489,30.26268], [-97.75085,30.26322], [-97.75197,30.26352], [-97.75287,30.26405], [-97.75453,30.26426], [-97.75662,30.26067], [-97.75022,30.25860], [-97.74943,30.25985], [-97.74837,30.26233], [-97.74948,30.26268] ] ] } } L.geoJson(geoJSON, { style: { weight: 2, color: '#8B0000', fillColor: '#DC143C', fillOpacity: 0.3 }, onEachFeature: function (feature, layer) { layer.bindPopup('' + feature.properties.name + '
' + feature.properties.address); } }).addTo(map); </script> </body> </html>