Mapbox-GL Tiled Places Context
Showing the tiled POIs is great, but lets add reachability into the mix. Drag the pin to re-calculate.
<!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('westcentraleurope', '__targomo_key_here__');
// Coordinates to center the map
const lnglat = [2.38208, 48.8697];
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" });
// 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();
const marker = new mapboxgl.Marker({
draggable: true
}).setLngLat(lnglat).addTo(map);
// definition for OSM subway entrances
const osmQuery = {
key: 'railway',
value: 'subway_entrance'
}
// 30 minutes
const maxEdgeWeight = 1800;
marker.on('dragend', registerAndRefreshMap);
function getPoiUrl(uuid){
return [`https://api.targomo.com/pointofinterest/reachability/${uuid}/{z}/{x}/{y}.mvt?apiKey=${client.serviceKey}` +
`&loadAllTags=true&layerType=node`];
}
// register the initial reachability context request
var uuid = ''
async function registerInitialRequest(){
uuid = await registerNewRequest(marker);
}
registerInitialRequest();
map.on('load', () => {
map.addLayer({
'id': 'poi',
'type': 'circle',
'source': {
'type': 'vector',
'tiles': getPoiUrl(uuid),
'minzoom': 9
},
'source-layer': 'poi',
'paint': {
'circle-radius': ['+', 3, ['sqrt', ['get', 'numOfPois']]],
'circle-color': [
'case',
['!=', ['get', 'edgeWeight'], null],
[
"interpolate-lab",
['exponential', 1],
['get', 'edgeWeight'],
0, 'hsl(120,70%,50%)',
maxEdgeWeight/2, 'hsl(60,70%,50%)',
maxEdgeWeight, 'hsl(0,70%,50%)'
],
'#666'
]
}
});
// Change the cursor to a pointer when the mouse is over the poi layer
map.on("mouseenter", "poi", () => {
map.getCanvas().style.cursor = "pointer";
});
// Change it back to a pointer when it leaves.
map.on("mouseleave", "poi", () => {
map.getCanvas().style.cursor = "";
});
// popup with type, name and walk time, if relevant
map.on("click", "poi", (e) => {
const props = e.features[0].properties;
let description = '';
if(props.numOfPois == 1) {
description += `<strong>POI: ${props.groupId.replace(/^\w/, c => c.toUpperCase())}</strong><br>`;
const tags = JSON.parse(e.features[0].properties.tags);
description += tags.name ? tags.name : '<em>Name not listed...</em>';
}
else {
description += `<strong>${props.numOfPois} POIs</strong>`;
}
const edgeWeight = e.features[0].properties.edgeWeight;
if(edgeWeight != null){
const walkTime = edgeWeight ? Math.round((edgeWeight / 60) * 10) / 10 : null;
description += walkTime ? `<br><strong>Walk time: </strong>${walkTime} minutes` : '';
}
// append description to popup
new mapboxgl.Popup()
.setLngLat(e.lngLat)
.setHTML(description).addTo(map);
});
});
async function registerNewRequest(marker) {
const curLatLng = marker.getLngLat();
const options = {
maxEdgeWeight: maxEdgeWeight,
travelType: 'walk',
edgeWeight: 'time',
osmTypes: [osmQuery]
}
// register a new reachability context and return its uuid
const uuid = await client.pois.reachabilityRegister([{ id: 0, lat: curLatLng.lat, lng: curLatLng.lng }], options);
return uuid;
}
async function registerAndRefreshMap() {
// show the progress bar
pBar.show();
const poiReachabilityUuid = await registerNewRequest(marker);
map.getSource('poi').tiles = getPoiUrl(poiReachabilityUuid);
var sourceCache = map.style.sourceCaches['poi'];
// Force a refresh, so that the map will be repainted without you having to touch the map
if(sourceCache != null){
map.style.sourceCaches['poi'].clearTiles();
map.style.sourceCaches['poi'].update(map.transform);
map.triggerRepaint();
}
// hide the progress bar
pBar.hide();
}
</script></body>
</html>
Copied to clipboard