How to get Directions in JavaScript from the Stadia Maps Geospatial API¶
Free
Starter
Standard
Professional
This tutorial will walk you through the process of getting directions using the Stadia Maps Geospatial APIs. We'll get directions between two points from the Stadia Maps Geospatial API using vanilla JavaScript, and visualize the route using MapLibre GL JS.
Tip
We've done our best to make useful examples that you can play with in JSFiddle, but if you're itching to integrate with your existing code locally, read on!
If you're running a local development server on localhost
or 127.0.0.1
, you should be able to copy+paste the
code into your existing app—everything should just work ™! Before deploying to a live web server, you will
need to sign up for a Stadia Maps account and add your domain or
set up an API key in the client dashboard.
You can find out more about how we authenticate requests in the Authentication & Limits documentation.
A simple route function¶
Let's start by writing a function that gets a route from the API. We've written all the boilerplate, so you can focus on the parameters.
function simple_route(start_lat, start_lon, end_lat, end_lon, costing, callback) {
// Build a request body for the route request
var body = {
"locations": [
{
"lat": start_lat,
"lon": start_lon,
"type": "break"
},
{
"lat": end_lat,
"lon": end_lon,
"type": "break"
}
],
"costing": costing,
};
var oReq = new XMLHttpRequest();
oReq.open("POST", "https://api.stadiamaps.com/route/v1", true);
oReq.onload = function() {
var jsonData = JSON.parse(this.responseText);
callback(jsonData);
};
oReq.onerror = function(e) {
console.error(e);
}
oReq.onabort = function(e) {
console.error(e);
}
oReq.send(JSON.stringify(body));
}
The first four parameters (start_lat
, start_lon
, etc.) are the coordinates you want the route to start and end
at.
The next argument is the costing model. This is a fancy term that essentially means mode of travel. The most common
values are auto
, bicycle
, and pedestrian
.
Tip
Our API reference has a list of all possible costing models
(look at the costingModel
schema) and other parameters available when making a route request.
Finally, the function takes a callback
argument. This is a simple JavaScript function that does something with the
response (a simple JavaScript object).
The following code will get driving directions from (66.543333, 25.8475) to (59.437222, 24.745278) and print the response to the console.
simple_route(66.543333, 25.8475, 59.437222, 24.745278, "auto", function(response) {
console.log(response);
});
Tip
We won't go too deep into the all the response fields in this tutorial, but we encourage you to experiment
with a simple callback like the above to see what the data looks like. The API reference
covers what each field means (see the routeResponse
schema).
Polyline decoding¶
The API returns the shape of the route as an encoded polyline. To visualize this on a map, we need to decode this back into a set of coordinates. For this tutorial, we'll decode the polyline using the Mapbox polyline library. We opt to decode it as GeoJSON, since this the easiest to work with in MapLibre GL JS.
polyline.toGeoJSON(shape, 6)
Pulling it all together¶
Now that we have all the data we need, let's pull it all together into a web page! Click the button below to experiment with it in JSFiddle.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Vector Map Demo</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script type="text/javascript" src="//unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.js"></script>
<link href="//unpkg.com/maplibre-gl@2.4.0/dist/maplibre-gl.css" rel="stylesheet" />
<!-- We'll load the polyline library from unpkg for convenience in this tutorial for simplicity -->
<script type="text/javascript" src="https://unpkg.com/@mapbox/polyline"></script>
<style type="text/css">
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script type="text/javascript">
function simple_route(start_lat, start_lon, end_lat, end_lon, costing, callback) {
// Build a request body for the route request
var body = {
"locations": [
{
"lat": start_lat,
"lon": start_lon,
"type": "break"
},
{
"lat": end_lat,
"lon": end_lon,
"type": "break"
}
],
"costing": costing,
};
var oReq = new XMLHttpRequest();
oReq.open("POST", "https://api.stadiamaps.com/route/v1", true);
oReq.onload = function() {
var jsonData = JSON.parse(this.responseText);
callback(jsonData);
};
oReq.onerror = function(e) {
console.error(e);
}
oReq.onabort = function(e) {
console.error(e);
}
oReq.send(JSON.stringify(body));
}
var map = new maplibregl.Map({
container: "map",
style: "https://tiles.stadiamaps.com/styles/alidade_smooth.json", // Style URL; see our documentation for more options
center: [12, 53], // Initial focus coordinate
zoom: 4
});
// MapLibre GL JS does not handle RTL text by default,
// so we recommend adding this dependency to fully support RTL rendering.
maplibregl.setRTLTextPlugin("https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-rtl-text/v0.2.1/mapbox-gl-rtl-text.js");
// Add zoom and rotation controls to the map.
map.addControl(new maplibregl.NavigationControl());
// Find a route between Santa's Village and Tallinn,
// where a legend claims the first Christmas tree may
// have appeared: https://www.visitestonia.com/en/why-estonia/the-tale-of-tallinns-most-famous-christmas-tree.
// We'll assume that Santa's Reindeer are on strike,
// so he has to drive a truck. (In case you're wondering
// how he gets across the water, there is a ferry involved.)
simple_route(66.543333, 25.8475, 59.43995, 24.73715, "truck", function(response) {
// Construct a bounding box in the sw, ne format required by MapLibre. Note the lon, lat order.
var sw = [response.trip.summary.min_lon, response.trip.summary.min_lat];
var ne = [response.trip.summary.max_lon, response.trip.summary.max_lat];
// Zoom to the new bounding box to focus on the route,
// with a 50px padding around the edges. See https://maplibre.org/maplibre-gl-js-docs/api/map/#map#fitbounds.
map.fitBounds([sw, ne], {padding: 50});
// For each leg of the trip...
response.trip.legs.forEach(function(leg, idx) {
// Add a layer with the route polyline as an overlay on the map
var layerID = "leg-" + idx; // Unique ID with request ID and leg index
// Note: Our polylines have 6 digits of precision, not 5
var geometry = polyline.toGeoJSON(leg.shape, 6);
map.addLayer({
"id": layerID,
"type": "line",
"source": {
"type": "geojson",
"data": {
"type": "Feature",
"properties": {},
"geometry": geometry
}
},
"layout": {
"line-join": "round",
"line-cap": "round"
},
"paint": {
"line-color": "#0072ce",
"line-opacity": 0.3,
"line-width": 5
}
});
});
});
</script>
</body>
</html>
You're now able to use the Stadia Maps Geospatial APIs to get routes, parse summary information about the route, and visualize it on a map! This should give you a good foundation on which to build more complex routing applications for the web using the Stadia Maps Geospatial APIs.