Map with driving route from A to B
- Last UpdatedJun 4, 2025
- 5 minute read
Request a driving route from A to B and display it on the map
This example calculates the fastest car route from the Brandenburg Gate in the centre of Berlin (52.51605°N, 13.37787°E) to Friedrichstraße Railway Station (52.52058°N, 13.38615°E), and displays it on the map.
Pariser Platz - Reichstagufer
- Head southeast on Pariser Platz. Go for 85 m.
- Continue on Unter den Linden. Go for 91 m.
- Turn left onto Wilhelmstraße (B2). Go for 192 m.
- Continue on Wilhelmstraße. Go for 94 m.
- Turn right onto Reichstagufer. Go for 449 m.
- Arrive at Reichstagufer. Your destination is on the right.
Total distance: 911m.
Travel Time: 2 minutes 53 seconds. (in current traffic)
Code
Access to the routing service is obtained from the H.service.Platform by calling getRoutingService(null, 8). The calculateRoute() method is used to calculate the fastest car route by passing in the relevant parameters as defined in Routing API. The styling and display of the response is under the control of the developer.
/**
* Boilerplate map initialization code starts below:
*/
// set up containers for the map + panel
var mapContainer = document.getElementById("map"),
routeInstructionsContainer = document.getElementById("panel");
// Step 1: initialize communication with the platform
// In your own code, replace variable window.apikey with your own apikey
var platform = new H.service.Platform({
apikey: "rVczblKDUJs-XSyUkLooaPkP4wcqHPaOB3oFvO1on3M",
});
var defaultLayers = platform.createDefaultLayers();
// Step 2: initialize a map - this map is centered over Berlin
var map = new H.Map(mapContainer, defaultLayers.vector.normal.map, {
center: { lat: 52.516, lng: 13.3779 },
zoom: 13,
pixelRatio: window.devicePixelRatio || 1,
});
// add a resize listener to make sure that the map occupies the whole container
window.addEventListener("resize", () => map.getViewPort().resize());
// Step 3: make the map interactive
// MapEvents enables the event system
// Behavior implements default interactions for pan/zoom (also on mobile touch environments)
var behavior = new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// Create the default UI components
var ui = H.ui.UI.createDefault(map, defaultLayers);
// Hold a reference to any infobubble opened
var bubble;
/**
* Opens/Closes a infobubble
* @param {H.geo.Point} position The location on the map.
* @param {String} text The contents of the infobubble.
*/
function openBubble(position, text) {
if (!bubble) {
bubble = new H.ui.InfoBubble(
position,
// The FO property holds the province name.
{ content: text }
);
ui.addBubble(bubble);
} else {
bubble.setPosition(position);
bubble.setContent(text);
bubble.open();
}
}
/**
* Creates a H.map.Polyline from the shape of the route and adds it to the map.
* @param {Object} route A route as received from the H.service.RoutingService
*/
function addRouteShapeToMap(route) {
route.sections.forEach((section) => {
// decode LineString from the flexible polyline
let linestring = H.geo.LineString.fromFlexiblePolyline(section.polyline);
// Create a polyline to display the route:
let polyline = new H.map.Polyline(linestring, {
style: {
lineWidth: 4,
strokeColor: "rgba(0, 128, 255, 0.7)",
},
});
// Add the polyline to the map
map.addObject(polyline);
// And zoom to its bounding rectangle
map.getViewModel().setLookAtData({
bounds: polyline.getBoundingBox(),
});
});
}
/**
* Creates a series of H.map.Marker points from the route and adds them to the map.
* @param {Object} route A route as received from the H.service.RoutingService
*/
function addManueversToMap(route) {
var svgMarkup =
'<svg width="18" height="18" ' +
'xmlns="http://www.w3.org/2000/svg">' +
'<circle cx="8" cy="8" r="8" ' +
'fill="#1b468d" stroke="white" stroke-width="1" />' +
"</svg>",
dotIcon = new H.map.Icon(svgMarkup, { anchor: { x: 8, y: 8 } }),
group = new H.map.Group(),
i,
j;
route.sections.forEach((section) => {
let poly = H.geo.LineString.fromFlexiblePolyline(
section.polyline
).getLatLngAltArray();
let actions = section.actions;
// Add a marker for each maneuver
for (i = 0; i < actions.length; i += 1) {
let action = actions[i];
var marker = new H.map.Marker(
{
lat: poly[action.offset * 3],
lng: poly[action.offset * 3 + 1],
},
{ icon: dotIcon }
);
marker.instruction = action.instruction;
group.addObject(marker);
}
group.addEventListener(
"tap",
function (evt) {
map.setCenter(evt.target.getGeometry());
openBubble(evt.target.getGeometry(), evt.target.instruction);
},
false
);
// Add the maneuvers group to the map
map.addObject(group);
});
}
/**
* Creates a series of H.map.Marker points from the route and adds them to the map.
* @param {Object} route A route as received from the H.service.RoutingService
*/
function addWaypointsToPanel(route) {
var nodeH3 = document.createElement("h3"),
labels = [];
route.sections.forEach((section) => {
labels.push(section.turnByTurnActions[0].nextRoad.name[0].value);
labels.push(
section.turnByTurnActions[section.turnByTurnActions.length - 1]
.currentRoad.name[0].value
);
});
nodeH3.textContent = labels.join(" - ");
routeInstructionsContainer.innerHTML = "";
routeInstructionsContainer.appendChild(nodeH3);
}
/**
* Creates a series of H.map.Marker points from the route and adds them to the map.
* @param {Object} route A route as received from the H.service.RoutingService
*/
function addSummaryToPanel(route) {
let duration = 0,
distance = 0;
route.sections.forEach((section) => {
distance += section.travelSummary.length;
duration += section.travelSummary.duration;
});
var summaryDiv = document.createElement("div"),
content =
"<b>Total distance</b>: " +
distance +
"m. <br />" +
"<b>Travel Time</b>: " +
toMMSS(duration) +
" (in current traffic)";
summaryDiv.style.fontSize = "small";
summaryDiv.style.marginLeft = "5%";
summaryDiv.style.marginRight = "5%";
summaryDiv.innerHTML = content;
routeInstructionsContainer.appendChild(summaryDiv);
}
/**
* Creates a series of H.map.Marker points from the route and adds them to the map.
* @param {Object} route A route as received from the H.service.RoutingService
*/
function addManueversToPanel(route) {
var nodeOL = document.createElement("ol");
nodeOL.style.fontSize = "small";
nodeOL.style.marginLeft = "5%";
nodeOL.style.marginRight = "5%";
nodeOL.className = "directions";
route.sections.forEach((section) => {
section.actions.forEach((action, idx) => {
var li = document.createElement("li"),
spanArrow = document.createElement("span"),
spanInstruction = document.createElement("span");
spanArrow.className = "arrow " + (action.direction || "") + action.action;
spanInstruction.innerHTML = section.actions[idx].instruction;
li.appendChild(spanArrow);
li.appendChild(spanInstruction);
nodeOL.appendChild(li);
});
});
routeInstructionsContainer.appendChild(nodeOL);
}
function toMMSS(duration) {
return (
Math.floor(duration / 60) + " minutes " + (duration % 60) + " seconds."
);
}
// Now use the map as required...
calculateRouteFromAtoB(platform);
/**
* Calculates and displays a car route from the Brandenburg Gate in the centre of Berlin
* to Friedrichstraße Railway Station.
*
* A full list of available request parameters can be found in the Routing API documentation.
* see: https://www.here.com/docs/bundle/routing-api-v8-api-reference/page/index.html
*
* @param {H.service.Platform} platform A stub class to access HERE services
*/
function calculateRouteFromAtoB(platform) {
var router = platform.getRoutingService(null, 8),
routeRequestParams = {
routingMode: "fast",
transportMode: "car",
origin: "52.5160,13.3779", // Brandenburg Gate
destination: "52.5206,13.3862", // Friedrichstraße Railway Station
return: "polyline,turnByTurnActions,actions,instructions,travelSummary",
};
router.calculateRoute(routeRequestParams, onSuccess, onError);
}
/**
* This function will be called once the Routing REST API provides a response
* @param {Object} result A JSON object representing the calculated route.
* See: https://www.here.com/docs/bundle/routing-api-v8-api-reference/page/index.html
*/
function onSuccess(result) {
var route = result.routes[0];
/*
* The styling of the route response on the map is entirely under the developer's control.
* A representative styling can be found the full JS + HTML code of this example
* in the functions below:
*/
addRouteShapeToMap(route);
addManueversToMap(route);
addWaypointsToPanel(route);
addManueversToPanel(route);
addSummaryToPanel(route);
// ... etc.
}
/**
* This function will be called if a communication error occurs during the JSON-P request
* @param {Object} error The error message received.
*/
function onError(error) {
alert("Can't reach the remote server");
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes">
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Map with Driving Route from A to B</title>
<link rel="stylesheet" type="text/css" href="https://js.api.here.com/v3/3.1/mapsjs-ui.css" />
<link rel="stylesheet" type="text/css" href="demo.css" />
<link rel="stylesheet" type="text/css" href="styles.css" />
<link rel="stylesheet" type="text/css" href="../template.css" />
<script type="text/javascript" src='../test-credentials.js'></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-core.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-service.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-ui.js"></script>
<script type="text/javascript" src="https://js.api.here.com/v3/3.1/mapsjs-mapevents.js"></script>
<style type="text/css">
.directions li span.arrow {
display:inline-block;
min-width:28px;
min-height:28px;
background-position:0px;
background-image: url("https://heremaps.github.io/maps-api-for-javascript-examples/map-with-route-from-a-to-b/img/arrows.png");
position:relative;
top:8px;
}
.directions li span.depart {
background-position:-28px;
}
.directions li span.rightturn {
background-position:-224px;
}
.directions li span.leftturn{
background-position:-252px;
}
.directions li span.arrive {
background-position:-1288px;
}
</style>
</head>
<body id="markers-on-the-map">
<div class="page-header">
<h1>Map with Driving Route from A to B</h1>
<p>Request a driving route from A to B and display it on the map</p>
</div>
<p>This example calculates the fastest car route from the <b>Brandenburg Gate</b>
in the centre of Berlin <i>(52.51605°N, 13.37787°E)</i> to <b>Friedrichstraße Railway Station</b>
<i>(52.52058°N, 13.38615°E)</i>, and displays it on the map.</p>
<div id="map"></div>
<div id="panel"></div>
<h3>Code</h3>
<p>Access to the routing service is obtained from the <code>H.service.Platform</code> by calling
<code>getRoutingService(null, 8)</code>. The <code>calculateRoute()</code> method is used to calculate the fastest
car route by passing in the relevant parameters as defined in
<a href="https://www.here.com/docs/bundle/routing-api-v8-api-reference/page/index.html" target="_blank">Routing API</a>.
The styling and display of the response is under the control of the developer.</p>
<script type="text/javascript" src='demo.js'></script>
</body>
</html>