Directions
Directions functionality allows you to find an optimal route between multiple points (up to ten) and draw it on the map.
This plugin uses Directions API. To start using the plugin, get an API key for Directions API: see the instruction on obtaining API keys.
Next, you need to include the Directions plugin in your project. To do this, add the following line after the main MapGL script:
<script src="https://unpkg.com/@2gis/mapgl-directions@^2/dist/directions.js"></script>
Or you can install the needed package using npm:
npm install @2gis/mapgl-directions
This plugin calls Directions API under the hood to find a route. If you want, you can use your Directions API key to call the API directly instead of (or in addition to) using the plugin.
Usage
To draw routes on the map, first you need to initialize the Directions object:
const directions = new mapgl.Directions(map, {
directionsApiKey: 'Your Directions API key',
});
Or, if you are using npm:
// Import either as an ES module...
import { Directions } from '@2gis/mapgl-directions';
// ...or as a CommonJS module
const { Directions } = require('@2gis/mapgl-directions');
const directions = new Directions(map, {
directionsApiKey: 'Your Directions API key',
});
Then you can call the carRoute() method to display a car route or the pedestrianRoute() method to display a pedestrian route. Both methods take an array of geographical coordinates as the points
parameter.
directions.carRoute({
points: [
[55.27887, 25.21001],
[55.30771, 25.20314],
],
});
directions.pedestrianRoute({
points: [
[55.27887, 25.21001],
[55.30771, 25.20314],
],
});
To clear the route, call the clear()
method:
directions.clear();
Car route demonstration
Try clicking on any two points on the map to display a car route between them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Urbi Map API</title>
<meta name="description" content="MapGL API directions example" />
<style>
html,
body,
#container {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
#reset {
padding: 4px 10px;
background: #00a81f;
border-radius: 4px;
box-shadow: 0 1px 3px 0 rgba(38, 38, 38, 0.5);
border: none;
color: #fff;
font-size: 12px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="https://mapgl.2gis.com/api/js/v1"></script>
<script src="https://unpkg.com/@2gis/mapgl-directions@^2/dist/directions.js"></script>
<script>
const map = new mapgl.Map('container', {
center: [55.31878, 25.23584],
zoom: 13,
key: 'Your API access key',
});
const directions = new mapgl.Directions(map, {
// This key can be used for demo purpose only!
// You can get your own key on https://urbi.ae/urbi-navigation#contact
directionsApiKey: 'Your directions API access key',
});
const markers = [];
let firstPoint;
let secondPoint;
// A current selecting point
let selecting = 'a';
const controlsHtml = `<button id="reset">Reset points</button> `;
new mapgl.Control(map, controlsHtml, {
position: 'topLeft',
});
const resetButton = document.getElementById('reset');
resetButton.addEventListener('click', function() {
selecting = 'a';
firstPoint = undefined;
secondPoint = undefined;
directions.clear();
});
map.on('click', (e) => {
const coords = e.lngLat;
if (selecting != 'end') {
// Just to visualize selected points, before the route is done
markers.push(
new mapgl.Marker(map, {
coordinates: coords,
icon: 'https://docs.2gis.com/img/dotMarker.svg',
}),
);
}
if (selecting === 'a') {
firstPoint = coords;
selecting = 'b';
} else if (selecting === 'b') {
secondPoint = coords;
selecting = 'end';
}
// If all points are selected — we can draw the route
if (firstPoint && secondPoint) {
directions.carRoute({
points: [firstPoint, secondPoint],
});
markers.forEach((m) => {
m.destroy();
});
}
});
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Urbi Map API</title>
<meta name="description" content="MapGL API directions example" />
<style>
html,
body,
#container {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
#reset {
padding: 4px 10px;
background: #00a81f;
border-radius: 4px;
box-shadow: 0 1px 3px 0 rgba(38, 38, 38, 0.5);
border: none;
color: #fff;
font-size: 12px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="https://mapgl.2gis.com/api/js/v1"></script>
<script src="https://unpkg.com/@2gis/mapgl-directions@^2/dist/directions.js"></script>
<script>
const map = new mapgl.Map('container', {
center: [55.31878, 25.23584],
zoom: 17,
key: 'Your API access key',
});
const directions = new mapgl.Directions(map, {
// This key can be used for demo purpose only!
// You can get your own key on https://urbi.ae/urbi-navigation#contact
directionsApiKey: 'Your directions API access key',
});
const markers = [];
let firstPoint;
let secondPoint;
// A current selecting point
let selecting = 'a';
const controlsHtml = `<button id="reset">Reset points</button> `;
new mapgl.Control(map, controlsHtml, {
position: 'topLeft',
});
const resetButton = document.getElementById('reset');
resetButton.addEventListener('click', function() {
selecting = 'a';
firstPoint = undefined;
secondPoint = undefined;
directions.clear();
});
map.on('click', (e) => {
const coords = e.lngLat;
if (selecting != 'end') {
// Just to visualize selected points, before the route is done
markers.push(
new mapgl.Marker(map, {
coordinates: coords,
icon: 'https://docs.2gis.com/img/dotMarker.svg',
}),
);
}
if (selecting === 'a') {
firstPoint = coords;
selecting = 'b';
} else if (selecting === 'b') {
secondPoint = coords;
selecting = 'end';
}
// If all points are selected — we can draw the route
if (firstPoint && secondPoint) {
directions.pedestrianRoute({
points: [firstPoint, secondPoint],
});
markers.forEach((m) => {
m.destroy();
});
}
});
</script>
</body>
</html>
Customization
Route is a line on a map that consists of three sub-lines drawn under each other: the main route line at the top (green), a "substrate" line in the middle (white), and a "halo" line at the bottom (red). You can change the width of any of these sublines using the style
parameter.
Width can be specified in pixels or as InterpolateExpression, in which case it will change depending on the current zoom level. To hide a subline, set its width to 0.
directions.carRoute({
points: [
[55.28273111108218, 25.234131928828333],
[55.35242563034581, 25.23925607042088],
],
style: {
routeLineWidth: [
'interpolate',
['linear'],
['zoom'],
10,
30, // width will change from 30 px at zoom level 10 and below...
14,
3, // ...to 3 px at zoom level 14 and above
],
substrateLineWidth: [
'interpolate',
['linear'],
['zoom'],
10,
3, // width will change from 3 px at zoom level 10 and below...
14,
50, // ...to 50 px at zoom level 14 and above
],
// Width will stay constant at all zoom levels
haloLineWidth: 60,
},
});
Try zooming in and out to see the width interpolation in action.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Urbi Map API</title>
<meta name="description" content="MapGL API directions example" />
<style>
html,
body,
#container {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
#reset {
padding: 4px 10px;
background: #00a81f;
border-radius: 4px;
box-shadow: 0 1px 3px 0 rgba(38, 38, 38, 0.5);
border: none;
color: #fff;
font-size: 12px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="https://mapgl.2gis.com/api/js/v1"></script>
<script src="https://unpkg.com/@2gis/mapgl-directions@^2/dist/directions.js"></script>
<script>
const map = new mapgl.Map('container', {
center: [55.31878, 25.23584],
zoom: 13,
key: 'Your API access key',
});
const directions = new mapgl.Directions(map, {
// This key can be used for demo purpose only!
// You can get your own key on https://urbi.ae/urbi-navigation#contact
directionsApiKey: 'Your directions API access key',
});
directions.carRoute({
points: [
[55.28273111108218, 25.234131928828333],
[55.35242563034581, 25.23925607042088]
],
style: {
routeLineWidth: ['interpolate', ['linear'], ['zoom'],
10, 30, // zoom - width
14, 3 // zoom - width
],
substrateLineWidth: ['interpolate', ['linear'], ['zoom'],
10, 3, // zoom - width
14, 50 // zoom - width
],
// Or just static width value
haloLineWidth: 60,
}
});
</script>
</body>
</html>