A modern open-source JavaScript library for mobile-friendly interactive maps.

Maptime Boulder: January 14, 2015

Jim McAndrew • @jimmyrocksjim@loc8.us

Overview

  • Has all of the features that most developers need to create web maps
  • Works seamlessly across all major desktop and mobile platforms
  • Designed with performance and usability in mind

History

  • Created as an alternative to larger mapping libraries like Google Maps and OpenLayers
  • Originally funded as a tool to be used with OpenStreetMap
  • Mapbox is currently funding the majority of development, and has hired its creator

Users

  • Flickr
  • foursquare
  • Pinterest
  • craigslist
  • Data.gov
  • Wikimedia
  • Meetup
  • Mapbox
  • CartoDB
  • OpenStreetMap
  • Many more online map tools…

Leaflet Demo

Create a basic Leaflet map

Create a basic HTML Container

<!DOCTYPE html>
<html>

  <head>
    <title>
      Leaflet Demo
    </title>
  </head>

  <body>
  </body>
  
</html>

Create a basic Leaflet map

Include the Leaflet library CSS

  <head>
    <title>
      Leaflet Demo
    </title>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
  </head>

Create a basic Leaflet map

Include the Leaflet library JavaScript

  <body>
    <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
  </body>

Create a basic Leaflet map

Create a "div" for the map

  <body>
    <div id="map"></div>
    <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
  </body>

Create a basic Leaflet map

Style the "div"

  <head>
    <title>
    Leaflet Demo
    </title>
    <style>
      body,
      html {
        height: 100%;
      }
      #map {
        width: 100%;
        height: 100%;
     }
    </style>
  </head>

Create a basic Leaflet map

Create a script tag

  <body>
    <div id="map"></div>
    <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
    <script>
    
    </script>
  </body>

Create a basic Leaflet map

Create a map and assign it to the "div" element

var map = L.map('map').setView([40.018, -105.278], 15);

Create a basic Leaflet map

Create a tileLayer and assign it to the map

L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.png', {
  maxZoom: 18,
  attribution: 'OpenStreetMap and MapQuest',
  subdomains: '1234',
  type: 'map'
}).addTo(map);

Create a basic Leaflet map

Add a marker to the map

var marker = L.marker([40.018, -105.278]).addTo(map);

Add popups

Include Boulder Data

  <body>
    <div id="map"></div>
    <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
    <script src="http://mapsarecool.com/maptime2015/boulder_restaurants.geojson"></script>
    <script>
       ...
    </script>
  </body>

Style the data

Add a custom marker

  L.geoJson(boulderData, {
    pointToLayer: function(feature, latlng) {
      return L.circleMarker(latlng);
    }
  }).addTo(map);

Style the data

Style the marker

  L.geoJson(boulderData, {
    pointToLayer: function(feature, latlng) {
      return L.circleMarker(latlng, {
        color: 'white',
        fillOpacity: 1,
        radius: 6
      });
    }
  }).addTo(map);

Style the data

Define the colors

var colors = {
  'bar': '#8e44ad',
  'cafe': '#e74c3c',
  'pub ': '#16a085',
  'restaurant': '#f1c40f'
};

Style the data

Link the colors

  L.geoJson(boulderData, {
    pointToLayer: function(feature, latlng) {
      return L.circleMarker(latlng, {
        color: 'white',
        fillColor: colors[feature.properties.amenity],
        fillOpacity: 1,
        radius: 6
      });
    }
  }).addTo(map);

Add popups

Include Handlebars

  <body>
    <div id="map"></div>
    <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
    <script src="http://mapsarecool.com/maptime2015/boulder_restaurants.geojson"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.min.js"></script>
    <script>
       ...
    </script>
  </body>

Add popups

Create a function to generate the popup content

var popupContent = function(properties) {
  var content = '<div class="popup">' +
    '<span class="title">{{name}}</span><br/>' +
    '{{address}}<br/>' +
    '<hr/>' +
    '<span class="title">Amenity</span>: {{amenity}}<br/>' +
    '<span class="title">Cuisine</span>: {{cuisine}}<br/>' +
    '</div>';
  return Handlebars.compile(content)(properties);
};

Add popups

Add an "onEachFeature" section

  L.geoJson(boulderData, {
    pointToLayer: function(feature, latlng) {
      return L.circleMarker(latlng, {
        color: 'white',
        fillColor: colors[feature.properties.amenity],
        fillOpacity: 1,
        radius: 6
      });},
    onEachFeature: function(feature, layer) {
      return layer.bindPopup(popupContent(feature.properties));
    }
  }).addTo(map);

Final Map Code

(For Copy & Paste)
<!DOCTYPE html>
<html>

<head>
  <title>
    #maptime Boulder Leaflet Demo
  </title>
  <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
  <style>
    body,
    html {
      height: 100%;
    }
    #map {
      width: 100%;
      height: 100%;
    }
  </style>
</head>

<body>
  <div id="map"></div>
  <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
  <script src="http://mapsarecool.com/maptime2015/boulder_restaurants.geojson"></script>
  <script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.min.js"></script>
  <script>
    var map = L.map('map').setView([40.018, -105.278], 15);
    var colors = {
      'bar': '#8e44ad',
      'cafe': '#e74c3c',
      'pub ': '#16a085',
      'restaurant': '#f1c40f'
    };

    var popupContent = function(properties) {
      var content = '<div class="popup">' +
        '<span class="title">{{name}}</span><br/>' +
        '{{address}}<br/>' +
        '<hr/>' +
        '<span class="title">Amenity</span>: {{amenity}}<br/>' +
        '<span class="title">Cuisine</span>: {{cuisine}}<br/>' +
        '</div>';
      return Handlebars.compile(content)(properties);
    };

    L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/{type}/{z}/{x}/{y}.png', {
      maxZoom: 18,
      attribution: 'OpenStreetMap and MapQuest',
      subdomains: '1234',
      type: 'map'
    }).addTo(map);

    var marker = L.marker([40.018, -105.278]).addTo(map);

    L.geoJson(boulderData, {
      pointToLayer: function(feature, latlng) {
        return L.circleMarker(latlng, {
          color: 'white',
          fillColor: colors[feature.properties.amenity],
          fillOpacity: 1,
          radius: 6
        });},
      onEachFeature: function(feature, layer) {
        return layer.bindPopup(popupContent(feature.properties));
      }
    }).addTo(map);

  </script>
</body>

</html>

Plugins

Leaflet plugins

http://leafletjs.com/plugins.html

leaflet.draw

Add CSS link

  <head>
    <title>
      Leaflet Demo
    </title>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.css" />
  </head>

leaflet.draw

Add JavaScript link

  <body>
    <div id="map"></div>
    <script src="http://cdn.leafletjs.com/leaflet-0.7.3/leaflet.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/reqwest/1.1.5/reqwest.min.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0/handlebars.min.js"></script>
    <script src="http://leaflet.github.io/Leaflet.draw/leaflet.draw.js"></script>
    <script>
       ...
    </script>
  </body>

leaflet.draw

Sample Code

var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);

var drawControl = new L.Control.Draw({
  draw: {
    position: 'topleft',
    polygon: {
      title: 'Draw a sexy polygon!',
      allowIntersection: false,
      drawError: {
        color: '#b00b00',
        timeout: 1000
      },
      shapeOptions: {
        color: '#bada55'
      },
      showArea: true
    },
    polyline: {
      metric: false
    },
    circle: {
      shapeOptions: {
        color: '#662d91'
      }
    }
  },
  edit: {
    featureGroup: drawnItems
  }
});
map.addControl(drawControl);

map.on('draw:created', function (e) {
  var type = e.layerType,
    layer = e.layer;

  if (type === 'marker') {
    layer.bindPopup('A popup!');
  }

  drawnItems.addLayer(layer);
});

Thanks!