Mapbox-GL Tiled Multigraph
People will walk 15 minutes to go to a coffee shop - where are the areas in San Francisco which are not within 15 minutes of a coffee shop?
<!DOCTYPE html>
<html>
<head>
<!-- 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 targomo core -->
<script src="https://releases.targomo.com/core/latest.min.js"></script>
<!-- Include micro progress bar -->
<script src="https://www.targomo.com/developers/scripts/mipb.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('northamerica', '__targomo_key_here__');
// Coordinates to center the map
const lnglat = [-122.45, 37.774];
const attributionText = `<a href="https://www.targomo.com/developers/resources/attribution/" target="_blank">© Targomo</a>`;;
// set the progress bar
const pBar = new mipb({ fg: "#FF8319" });
pBar.show();
// add the map and set the initial center to berlin
const map = new mapboxgl.Map({
container: 'map',
style: 'https://api.maptiler.com/maps/positron/style.json?key=__your_maptiler_api_key__',
zoom: 12,
center: lnglat,
attributionControl: false
})
.addControl(new mapboxgl.NavigationControl())
.addControl(new mapboxgl.AttributionControl({ compact: true, customAttribution: attributionText }));
// disable scroll zoom
map.scrollZoom.disable();
// here we're deciding that we want walk coverage, 15 minutes (900s), symbolized as hexagons
const multigraphOptions = {
edgeWeight: "time",
travelType: "walk",
maxEdgeWeight: 900,
multigraph: {
aggregation: {
type: "routing_union"
},
layer: {
type: "hexagon"
},
serialization: {
format: "mvt"
}
}
};
map.on("load", async () => {
const dataurl = 'https://raw.githubusercontent.com/targomo/data-exports/master/overpass/cuisine_coffee_shop_san_francisco.geojson';
// get OSM coffee shop dataset
const coffeeShops = await fetch(dataurl).then(async (data) => {
return JSON.parse(await data.text());
});
// add coffee shops to map
map.addLayer({
id: "coffee",
type: "circle",
paint: {
"circle-radius": 3,
"circle-color": "#666"
},
source: {
type: "geojson",
data: coffeeShops
}
});
// create formatted 'sources' for analysis
const sources = coffeeShops.features.map((coffee) => {
return {
id: coffee.properties['@id'],
lat: coffee.geometry.coordinates[1],
lng: coffee.geometry.coordinates[0]
}
});
// get the MVT tile url for the multigraph tiles
const mgUrl = await client.multigraph.getTiledMultigraphUrl(
sources, multigraphOptions, "mvt"
);
// add the tiled multigraph
map.addLayer({
id: "multigraph",
type: "fill",
source: {
type: "vector",
tiles: [ mgUrl ],
minzoom: 6,
maxzoom: 20
},
"source-layer": "aggregation",
layout: {},
paint: { // symbolize hexagons on a Green-Yellow-Red interpolated scale
"fill-opacity": 0.6,
"fill-outline-color": "rgba(255,255,255,0.15)",
"fill-color": [
"interpolate-hcl",
["linear"],
["get", "w"], // "w" is the "edgeWeight", which in this case is time
0, "#1a9641", 450, "#ffffbf", 900, "#d7191c"
]
}
}, "coffee");
pBar.hide();
// Change the cursor to a pointer when the mouse is over the hex layer
map.on("mouseenter", "multigraph", function() {
map.getCanvas().style.cursor = "pointer";
});
// Change it back to a pointer when it leaves.
map.on("mouseleave", "multigraph", function() {
map.getCanvas().style.cursor = "";
});
map.on("click", "multigraph", function(e) {
var description = `${Math.round(
e.features[0].properties.w / 60
)} minute walk<br>to closest coffee shop`;
new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML(description)
.addTo(map);
});
});
</script>
</body>
</html>
Copied to clipboard