Maplibre-GL Places Layers
Get direct, fast access to global POI data
<!DOCTYPE html>
<html>
<head>
<!-- Include maplibregl javascript and css -->
<script src="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
<link href="https://unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css" rel="stylesheet">
<!-- Include targomo core -->
<script src="https://releases.targomo.com/core/latest.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 = [-118.254427, 34.046185]
// add the map and set the initial center
const map = new maplibregl.Map({
container: 'map',
style: client.basemaps.getGLStyleURL("Light"),
zoom: 13,
minZoom: 9,
center: lnglat
})
map.addControl(new maplibregl.NavigationControl())
// disable scroll zoom
map.scrollZoom.disable()
// POI mvt paths for cafes/coffee_shops and restaurants,
const tileSources = [{
type: 'cafe', color: 'black', textColor: 'white',
url: `https://api.targomo.com/pointofinterest/{z}/{x}/{y}.mvt?apiKey=${client.serviceKey}` +
'&group=coffee_shop&group=cafe&loadAllTags=true&layerType=node&layerGeometryDetailPerTile=5'
}, {
type: 'restaurant', color: 'orange', textColor: 'black',
url: `https://api.targomo.com/pointofinterest/{z}/{x}/{y}.mvt?apiKey=${client.serviceKey}` +
'&group=restaurant&loadAllTags=true&layerType=node&layerGeometryDetailPerTile=5'
}]
map.on('load', () => {
// pre-load icons
for (let icon of ['tgm-cafe', 'tgm-restaurant', 'tgm-circle']) {
map.loadImage(`https://releases.targomo.com/tgm-icons/images/${icon}.png`, (error, image) => {
if (error) throw error
if (!map.hasImage(icon)) map.addImage(icon, image, { sdf: true })
})
}
for (let source of tileSources) {
// add source
map.addSource(`poi-${source.type}-src`,{
type: 'vector',
tiles: [source.url],
minzoom: 9,
attribution: '<a href="https://www.targomo.com/developers/resources/attribution/" target="_blank">© Targomo</a>'
})
// add layer for individual pois
map.addLayer({
id: `poi-${source.type}`,
type: 'symbol',
source: `poi-${source.type}-src`,
'source-layer': 'poi',
layout: {
'icon-allow-overlap': true,
'icon-image': `tgm-${source.type}`,
'icon-size': 0.18
},
filter: ['==', ['get', 'numOfPois'], 1],
paint: {
'icon-color': source.color
}
})
// update cursor for layer
map.on('mouseenter', `poi-${source.type}`, () => { map.getCanvas().style.cursor = 'pointer' })
map.on('mouseleave', `poi-${source.type}`, () => { map.getCanvas().style.cursor = '' })
// add layer for clusters
map.addLayer({
id: `${source.type}-many`,
type: 'symbol',
source: `poi-${source.type}-src`,
'source-layer': 'poi',
layout: {
'icon-allow-overlap': true,
'icon-image': 'tgm-circle',
'icon-size': 0.3,
'text-field': '{numOfPois}',
'text-size': 8
},
filter: ['>', ['get', 'numOfPois'], 1],
paint: {
'icon-color': source.color,
'text-color': source.textColor
}
})
// update cursor for layer
map.on('mouseenter', `${source.type}-many`, () => { map.getCanvas().style.cursor = 'pointer' })
map.on('mouseleave', `${source.type}-many`, () => { map.getCanvas().style.cursor = '' })
}
map.on('click', event => {
let description = ''
// get all singular pois
const poiFeatures = map.queryRenderedFeatures(event.point).filter(feature => (/^poi-/g).test(feature.source))
// get all multiple pois
const poiManyFeatures = map.queryRenderedFeatures(event.point).filter(feature => (/-many$/g).test(feature.layer.id))
if (poiManyFeatures.length > 0) { // only show multiple if overlapping
description += `<strong>Multiple POIs</strong><br><em>${ poiManyFeatures[0].properties.numOfPois }
POIs here,<br>zoom in to see details</em>`
} else { // otherwise show singular
poiFeatures.forEach((f, i) => {
description += `<strong>POI: ${ f.properties.groupId.replace(/^\w/, c => c.toUpperCase()) }</strong><br>`
description += f.properties['tag-name'] ? f.properties['tag-name'] : '<em>Name not listed...</em>'
if (i < poiFeatures.length) { description += '<br>' }
})
}
// show popup
if (description.length > 1) {
new maplibregl.Popup()
.setLngLat(event.lngLat)
.setHTML(description).addTo(map)
}
})
})
</script></body>
</html>
Copied to clipboard