Mapbox-GL Planning Multi-stop Scenarios
What's the most efficient way to bike to Seattle's central brewpubs?
local_activityThe fleetplanner service is a custom offering, and you need to contact us to get set-up. Check our plans for details.
<!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 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://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));

        const attributionText = `<a href='https://targomo.com/developers/resources/attribution/' target='_blank'>&copy; Targomo</a>`

        // add the map and set the initial center
        const map = new mapboxgl.Map({
            container: 'map',
            style: 'https://api.maptiler.com/maps/positron/style.json?key=__your_maptiler_api_key__',
            zoom: 10,
            pitch: 30,
            center: center.geometry.coordinates,
            attributionControl: false
        })
        .addControl(new mapboxgl.NavigationControl())
        .addControl(new mapboxgl.AttributionControl({ compact: true, customAttribution: attributionText }));

        // 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 mapboxgl.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([])
            }); 
            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