Leaflet Reachability Service
Showing precise reachability times for London banks (by car - max. 30 minutes)
<!DOCTYPE html>
<html>

<head>
  <!--  Include leaflet libs -->
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.0.3/dist/leaflet.css">
  <script src="https://unpkg.com/leaflet@1.0.3/dist/leaflet-src.js" crossorigin=""></script>
  <!--  Include targomo leaflet full build -->
  <script src="https://releases.targomo.com/leaflet/latest-full.min.js"></script>
  <!-- D3 libs for colors and interpolation  -->
  <script src="https://d3js.org/d3-color.v1.min.js"></script>
  <script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
  <script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
  <!--  Include micro progress bar  -->
  <script src="https://targomo.com/developers/scripts/mipb.min.js"></script>
  <style>
    html,
    body {
      width: 100%;
      height: 100%;
      margin: 0;
    }

    #map {
      width: 100%;
      height: 100%;
    }
  </style>
</head>

<body>
  <!--  where the map will live  -->
  <div id="map"></div>

  <script>
    async function initMap() {
      const client = new tgm.TargomoClient('britishisles', '__targomo_key_here__');

      // set the progress bar
      const pBar = new mipb({ fg: "#FF8319", style: { zIndex: 500 } });
      pBar.show();

      // map center and reachability source
      const sourcePoint = { id: 0, lat: 51.513396, lng: -0.158282 };

      const maxTime = 1800;

      // add the map and set the initial center to berlin
      const map = L.map('map', {
        scrollWheelZoom: false
      }).setView([sourcePoint.lat, sourcePoint.lng], 11);
      const attributionText = `<a href='https://targomo.com/developers/resources/attribution/' target='_blank'>&copy; Targomo</a>`
      map.attributionControl.addAttribution(attributionText);

      // create the filter start marker
      const sourceMarker = L.marker((sourcePoint), { zIndexOffset: 1000 }).addTo(map);

      // add a basemap
      const tilesUrl = 'https://api.maptiler.com/maps/darkmatter/{z}/{x}/{y}@2x.png?key=__your_maptiler_api_key__';
      const tileLayer = L.tileLayer(tilesUrl, {
          tileSize: 512, zoomOffset: -1,
          minZoom: 1, crossOrigin: true
      }).addTo(map);

      const dataurl = 'https://raw.githubusercontent.com/targomo/data-exports/master/overpass/amenity_bank_london.geojson';

      // get OSM banks dataset
      const banks = await fetch(dataurl).then(async (data) => {
        return JSON.parse(await data.text());
      })

      // create formatted 'targets' for analysis
      const targets = banks.features.map((bank) => {
        return {
          id: bank.properties['@id'],
          lat: bank.geometry.coordinates[1],
          lng: bank.geometry.coordinates[0]
        }
      });

      // you need to define some options for the reachability service
      const options = {
        travelType: 'car',
        maxEdgeWeight: maxTime,
        edgeWeight: 'time'
      };

      // calculate reachability of banks
      const reachability = await client.reachability.locations([sourcePoint], targets, options);

      // assign reachablility to original GeoJSON
      banks.features.forEach((bank) => {
        const match = reachability.find((location) => {
          return location.id === bank.properties['@id']
        });
        bank.properties.travelTime = match ? match.travelTime : -1;
      });

      pBar.hide();

      // set style based on travelTime
      function geojsonMarkerOptions(props) {
        var scaleVal = 1 - (props.travelTime / maxTime);
        var rgb = d3.rgb(d3.interpolateRdYlGn(scaleVal));
        return {
          radius: 3,
          fillColor: props.travelTime > -1 ? rgb : '#666',
          color: "#000",
          weight: 0.5,
          opacity: 1,
          fillOpacity: 1
        }
      };

      // create map layer from banks data
      const banksLayer = L.geoJSON(banks, {
        pointToLayer: (feature, latlng) => {
          // display as circle
          return L.circleMarker(latlng, geojsonMarkerOptions(feature.properties));
        },
        onEachFeature: (feature, layer) => {
          // add popup
          if (feature.properties && feature.properties.name) {
            const time = feature.properties.travelTime > -1 ?
              Math.round((feature.properties.travelTime / 60) * 10) / 10 :
              'not reachable'
            const popupContent = `<strong>${feature.properties.name}</strong>
            <br><strong>Time:</strong> ${time}`
            layer.bindPopup(popupContent);
          }
        }
      }).addTo(map);
    }

    initMap()

  </script>
</body>

</html>
content_copy
Copied to clipboard