Mapbox-GL Basic Isochrones
Use 3d extrusion to overcome polygon overlapping
<!DOCTYPE html>
<html>
<head>
<!-- Include targomo core -->
<script src="https://releases.targomo.com/core/latest.min.js"></script>
<!-- Include mapboxgl javascript and css -->
<script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.6.0/mapbox-gl.js"></script>
<link href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.6.0/mapbox-gl.css" rel="stylesheet">
<!-- Include turf for view fitting -->
<script src="https://npmcdn.com/@turf/turf/turf.min.js"></script>
<style>
body,
html {
margin: 0;
width: 100%;
height: 100%;
}
#map {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<!-- where the map will live -->
<div id="map"></div>
<script>
// create targomo client
const client = new tgm.TargomoClient('westcentraleurope', '__targomo_key_here__')
// define a pair of coordinates, where the map should be centered
// and should serve a the source for polygonization
const lnglat = [13.37, 52.51];
const travelTimes = [300, 600, 900, 1200, 1500, 1800];
const timeColors = ['#006837', '#39B54A', '#8CC63F', '#F7931E', '#F15A24', '#C1272D'];
const attributionText = `<a href="https://www.targomo.com/developers/resources/attribution/" target="_blank">© Targomo</a>`;
// add the map and set the initial center to berlin
const map = new mapboxgl.Map({
container: 'map',
style: 'https://api.maptiler.com/maps/streets/style.json?key=__your_maptiler_api_key__',
zoom: 12,
pitch: 65,
center: lnglat,
attributionControl: false
})
.addControl(new mapboxgl.NavigationControl())
.addControl(new mapboxgl.AttributionControl({ compact: true, customAttribution: attributionText }));
// disable scroll zoom
map.scrollZoom.disable();
// define some options for the polygon service
const options = {
travelType: 'bike',
travelEdgeWeights: travelTimes,
maxEdgeWeight: 1800,
edgeWeight: 'time',
srid: 4326,
simplify: 200,
serializer: 'geojson',
buffer: 0.002
};
const sources = [
{ lat: lnglat[1], lng: lnglat[0], id: 1 }
]
// height stops function
function getHeightStops(travelTimes, heightFactor) {
return [
[travelTimes[0], travelTimes.length * (10 * heightFactor)],
[travelTimes[travelTimes.length - 1], travelTimes.length * heightFactor]
]
}
// color stop function
function getColorStops(times, colors) {
const colorsConfig = times.map((time, idx) => {
return [times[idx], colors[idx]];
});
return colorsConfig;
}
map.on('load', () => {
const marker = new mapboxgl.Marker()
.setLngLat(lnglat).addTo(map);
// call the Targomo service
client.polygons.fetch(sources, options).then((geojsonPolygons) => {
map.addLayer({
'id': 'polygons',
'type': 'fill-extrusion',
'source': {
'type': 'geojson',
'data': geojsonPolygons
},
'layout': {},
'paint': {
'fill-extrusion-base': 0,
'fill-extrusion-height': {
'property': 'time',
'stops': getHeightStops(travelTimes, 2)
},
'fill-extrusion-color': {
'property': 'time',
'stops': getColorStops(travelTimes, timeColors)
},
'fill-extrusion-opacity': .5
}
});
map.fitBounds(turf.bbox(geojsonPolygons), { padding: 20 });
});
})
</script>
</body>
</html>
Copied to clipboard