Google drivetime isobands from Matrix API

Drivetime isobands generated with Turf from Google Distance Matrix API calls.

HTML

<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css">
<script src="https://cdn.jsdelivr.net/npm/@turf/turf@5/turf.min.js"></script>
<div id="map" class="map"></div>

CSS

html,
body {
  height: 100%;
  width: 100%;
  position: fixed;
  padding: 0;
  margin: 0;
  border: 0;
}

.map {
  height: 100%;
  width: 100%;
}

JavaScript

// My public Google key. Please replace this with your own key.
let key = 'AIzaSyDAQthyG-P3xrKOHobd1YLJOrtUdVsEd20';

// The origin of the catchment.
let lng = -1,
  lat = 53;

// Distance of travel in seconds.
let distance = 3600;

// Each detail level adds 24 sample points to the query.
let detail = 3;

// Distance in seconds divided by the reach defines the radius for the sample points circle.
let reach = 30;

// Center map on the origin.
let map = L.map('map', {
  center: [lat, lng],
  zoom: 6
});

map.createPane('labels');
map.getPane('labels').style.zIndex = 550;
map.getPane('labels').style.pointerEvents = 'none';

L.tileLayer(`https://api.mapbox.com/styles/v1/dbauszus/ciozrimi3002bdsm8bjtn2v1y/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZGJhdXN6dXMtcHJpdmF0ZSIsImEiOiJjamJiYzlkbzIwdzdoMnBteHkwNWNiM215In0.cBbyFwMqnikqvlZD2RS3DA`).addTo(map);

L.tileLayer(`https://api.mapbox.com/styles/v1/dbauszus/cj9puo8pr5o0c2sovhdwhkc7z/tiles/256/{z}/{x}/{y}?access_token=pk.eyJ1IjoiZGJhdXN6dXMtcHJpdmF0ZSIsImEiOiJjamJiYzlkbzIwdzdoMnBteHkwNWNiM215In0.cBbyFwMqnikqvlZD2RS3DA`, {
  pane: 'labels'
}).addTo(map);

let data = {};

data.circlePoints = [];

// Create sample points from circles.
for (let i = 1; i <= (detail * 2); i++) {

  let circle = turf.circle(
    [lng, lat],
    (10 * Math.pow(i, 3)) / (10 * Math.pow(detail * 2, 3)) * (distance / reach), {
      units: 'kilometers',
      steps: 12
    });

  // Rotate alternate circles.
  if (i % 2 === 0) circle = turf.transformRotate(circle, 15, {
    pivot: [lng, lat]
  });

  data.circlePoints = data.circlePoints.concat(turf.explode(circle).features.slice(1));
}

// Deep clone the circlePoints as samplePoints.
data.samplePoints = JSON.parse(JSON.stringify(data.circlePoints));

// Create destinations array from samplePoints.
let destinations = data.samplePoints.map(pt => {
  return [
    parseFloat(pt.geometry.coordinates[1].toFixed(6)),
    parseFloat(pt.geometry.coordinates[0].toFixed(6))
  ]
});

// Self executing...