Files
noodl-docs/library/modules/mapbox/guides/directions.md
Eric Tuvesson 53f0d6320e Initial commit
Co-Authored-By: kotte <14197736+mrtamagotchi@users.noreply.github.com>
Co-Authored-By: mikaeltellhed <2311083+mikaeltellhed@users.noreply.github.com>
Co-Authored-By: Tore Knudsen <18231882+torekndsn@users.noreply.github.com>
Co-Authored-By: Michael Cartner <32543275+michaelcartner@users.noreply.github.com>
2023-09-05 12:08:55 +02:00

3.6 KiB

Directions

Create a request to Directions API

TODO: Add more info about "overview" (full, simplified, or false)

// Get the Mapbox access token from Noodl project settings
const access_token = Noodl.getProjectSettings().mapboxAccessToken;

// For using the API to handle min/max road width, we have to use the "driving" profile.
// https://docs.mapbox.com/api/navigation/directions#optional-parameters-for-the-mapboxdriving-profile
const routingProfile = "driving";

// Encode the coordinates to be URL-safe
const coordinates = encodeURIComponent([fromCoordinate, toCoordinate].join(";"));

// Define query parameters for the API request
// 
// Playground by Mapbox to test out all the features:
// https://docs.mapbox.com/playground/directions/
const queryParams = {
    access_token, // Provide the access token
    alternatives: true,
    continue_straight: true,
    geometries: "geojson",
    language: "en",
    overview: "simplified",
    steps: true,
    // The max vehicle height, in meters. If this parameter is provided, the
    // Directions API will compute a route that includes only roads with a height
    // limit greater than or equal to the max vehicle height. max_height must be
    // between 0 and 10 meters. The default value is 1.6 meters. Coverage for road
    // height restriction may vary by region.
    max_height,
    // The max vehicle width, in meters. If this parameter is provided, the
    // Directions API will compute a route that includes only roads with a width
    // limit greater than or equal to the max vehicle width. max_width must be
    // between 0 and 10 meters. The default value is 1.9 meters. Coverage for road
    // width restriction may vary by region.
    max_width,
};

// Construct the query string from the query parameters
const query = Object.keys(queryParams)
    .filter((key) => !!queryParams[key]) // Filter out empty values
    .map((key) => `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`)
    .join('&');

// Set the endpoint URL for the Mapbox directions API
const ENDPOINT = 'https://api.mapbox.com/directions/v5/mapbox';

// Make the API request and get the response as JSON
const response = await fetch(`${ENDPOINT}/${routingProfile}/${coordinates}?${query}`);
const json = await response.json();

if (json.code === "Ok") {
  Outputs.Routes = jsonroutes;
  Outputs.Success();
} else {
  Outputs.Failure();
}

Draw the route:

Script.Inputs = {
  MapboxObject: "object",
  Routes: "array"
};

Script.Outputs = {
  Done: "signal",
};


Script.Signals = {
  Update() {
    const map = Script.Inputs.MapboxObject;

    const route = Script.Inputs.Routes[0];

    function createOrUpdateSource(id, newSource) {
      const source = map.getSource(id);
      if (source) {
        source.setData(newSource.data);
      } else {
        map.addSource(id, newSource);
      }
    }

    function createOrUpdateLayer(newLayer) {
      const layer = map.getLayer(newLayer.id);
      if (layer) {
        if (newLayer.paint) {
          Object.keys(newLayer.paint).forEach((key) => {
            layer.setPaintProperty(key, newLayer.paint[key]);
          });
        }
      } else {
        map.addLayer(newLayer);
      }
    }

    createOrUpdateSource('route', {
      'type': 'geojson',
      'data': {
        'type': 'Feature',
        'properties': {},
        'geometry': route.geometry,
      }
    });

    createOrUpdateLayer({
      'id': 'route',
      'type': 'line',
      'source': 'route',
      'layout': {
        'line-join': 'round',
        'line-cap': 'round'
      },
      'paint': {
        'line-color': '#888',
        'line-width': 8
      }
    });
  },
};