Maplibre-GL Planning Multi-stop Scenarios

What’s the most efficient way to bike to Seattle’s central brewpubs?
<!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 turf for geographic analysis -->
    <script src="https://npmcdn.com/@turf/turf/turf.min.js"></script>
    <!--  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__')
        // set the progress bar
        const pBar = new mipb({ fg: '#FF8319' })
        // Coordinates to center the map
        const microbreweries = [
            [47.65924, -122.36559, 'Hale\'s Ales Brewery'],
            [47.64906, -122.34445, 'Fremont Brewing'],
            [47.65786, -122.31356, 'Big Time Brewery'],
            [47.66823, -122.29916, 'Ravenna Brewing Company'],
            [47.66150, -122.31981, 'Floating Bridge Brewing'],
            [47.66666, -122.37252, 'Obec Brewing'],
            [47.61161, -122.34527, 'Cloudburst Brewing'],
            [47.61429, -122.34567, 'Belltown Brewing'],
            [47.60949, -122.34285, 'Old Stove Brewing'],
            [47.6519, -122.35399, 'Aslan Brewing']
        ]
        
        const targets = turf.featureCollection(
            microbreweries.map(m =>
                turf.point(m.slice(0, 2).reverse(), { name: m[2] })
            )
        )
        
        const center = turf.center(targets)
        const start = [-122.34964, 47.62145]
        // generate 15 random delivery locations
        targets.features.forEach((f, i) => f.properties.id = 'delivery' + (i + 1))
        
        // add the map and set the initial center
        const map = new maplibregl.Map({
            container: 'map',
            style: client.basemaps.getGLStyleURL('Light'),
            zoom: 10,
            pitch: 30,
            center: center.geometry.coordinates
        }).addControl(new maplibregl.NavigationControl())
        
        // disable scroll zoom
        map.scrollZoom.disable()
        // zoom to limits of target points
        map.fitBounds(turf.bbox(targets), { padding: 20 })
        
        // add draggable source
        const marker = new maplibregl.Marker({
            draggable: true
        }).setLngLat(start).addTo(map)
        // react to marker move
        marker.on('dragend', getRoute)
        
        async function getRoute() {
            // show progress bar
            pBar.show()
            const routingConfig = {
                optimizationAlgorithm: 'GREEDY_TSP',
                stores: [{
                    uuid: 'depot1',
                    address: marker.getLngLat()
                }],
                orders: targets.features.map((f) => {
                    return {
                        uuid: f.properties.id,
                        storeUuid: 'depot1',
                        address: {
                            lat: f.geometry.coordinates[1],
                            lng: f.geometry.coordinates[0],
                            avgHandlingTime: 250
                        }
                    }
                }),
                transports: [{
                    vehicle: {
                        uuid: 'v1',
                        storeUuid: 'depot1'
                    }
                }],
                optimizationMetadata: {
                    geojsonCreation: 'ROUTING_SERVICE',
                    travelOptions: {
                        travelType: 'bike',
                        maxEdgeWeight: 7200,
                        serviceUrl: 'https://api.targomo.com/northamerica/',
                        serviceKey: client.serviceKey
                    }
                }
            }
        
            const url = `https://api.targomo.com/fleetplanner/v1/api/key-auth/optimizations?key=${client.serviceKey}`
        
            try {
                const data = await fetch(url, {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify(routingConfig)
                })
                const routingResults = await data.json()
                map.getSource('routes').setData(routingResults.tours[0].featureCollection)
                // hide progress bar
                pBar.hide()
            } catch (error) {
                console.error(error)
            }
        }
        
        map.on('load', () => {
            map.addSource('targets', {
                type: 'geojson',
                data: targets
            })
            
            map.addLayer({
                id: 'targetsLayer',
                type: 'circle',
                source: 'targets',
                paint: {
                    'circle-radius': 8,
                    'circle-color': '#ff7800'
                }
            })
        
            map.addSource('routes', {
                type: 'geojson',
                data: turf.featureCollection([]),
                attribution: '<a href="https://www.targomo.com/developers/resources/attribution/" target="_blank">&copy; Targomo</a>'
            })
        
            map.addLayer({
                id: 'routesLayer',
                type: 'line',
                source: 'routes',
                layout: {
                    'line-join': 'round',
                    'line-cap': 'round'
                },
                paint: {
                    'line-color': '#00242B',
                    'line-width': 5
                },
                filter: ['==', '$type', 'LineString']
            }, 'targetsLayer')
        
            getRoute()
        })
    </script></body>
</html>
content_copy
Copied to clipboard