Routing with Estimated Time of Arrival
This use-case focus on real-time driving and notification. It describes how to compute and update a using the PTV xRoute service. The goal of calculation is the real-time route-related information update of a driving .
Benefits
- Using the ETA calculation will ensure a more precise real-time vehicle navigation than conventional routing.
- Faster calculation than multiple conventional routes requests.
Prerequisites
Please ensure following prerequisites are fulfilled before you start with the use case:
- Installed and licensed PTV xRoute service
Programming Guide
This sample simulates the principal use case of this module : update the time of arrival depending of the position of the vehicle.
-
A first route request is sent, simulating an itinerary prevision. Both encodedPath and are requested in the resultFields. Polyline is for map dislay and encodedPath will be needed to build a PathWaypoint.
The result of this first request is the blue route on the map.
-
The second route request stands for a route recalculation according to a simulated vehiclePosition.
A vehiclePosition of type PositionEnRoute is sent. It simulates a truck with a driver driving to the next destination.
It contains 3 information:
-
A simulated vehicle position (ex: GPS coordinates).
-
A simulated heading (ex: In-board Accelerometer).
-
The next to serve. Here, there are only two waypoints.
var A = {
"$type": "OnRoadWaypoint",
"location": {
"coordinate": {
"x": 6.1561739444732675,
"y": 49.581704333851874
}
}
};
var B = {
"$type": "OnRoadWaypoint",
"location": {
"coordinate": {
"x": 6.1256572,
"y": 49.4816576
}
}
};
var map = new L.Map('map', {
center: [49.531769, 6.113249],
zoom: 18
});
// Add tile layer to map
var tileUrl = xServerUrl + '/services/rest/XMap/tile/{z}/{x}/{y}';
var tileLayer = new L.TileLayer(tileUrl, {
minZoom: 3,
maxZoom: 17,
noWrap: true
}).addTo(map);
new L.Marker([A.location.coordinate.y, A.location.coordinate.x]).addTo(map);
new L.Marker([B.location.coordinate.y, B.location.coordinate.x]).addTo(map);
xroute.calculateRoute({
"waypoints": [A, B],
"resultFields": {
"polyline": true,
"encodedPath": true
},
"routeOptions": {
"polylineOptions": {
"elevations": true
}
}
}, routingFinished);
function displayPolyline(poly, colorCode) {
var polyline = [];
for (var i = 0; i < poly.length; ++i) {
polyline.push(L.latLng(poly[i].y, poly[i].x));
}
polylineLayer = L.polyline(polyline, {
color: colorCode,
weight: 8
});
polylineLayer.addTo(map);
};
function routingETAFinished(route, exception) {
var polyline = route.polyline.plain.polyline;
displayPolyline(polyline, "#cc0000");
new L.Marker([polyline[0].y, polyline[0].x]).addTo(map);
print(route.distance + 'm in ' + route.travelTime + 's');
}
function routingFinished(route, exception) {
var polyline = route.polyline.plain.polyline;
displayPolyline(polyline, "#2882C8");
xroute.calculateRoute({
"waypoints": [{
"$type": "PathWaypoint",
"encodedPath": route.encodedPath
}],
"resultFields": {
"polyline": true
},
"routeOptions": {
"etaCalculationOptions": {
"vehiclePosition": {
"$type": "PositionEnRoute",
"currentLocation": {
x: 6.113701,
y: 49.531414
},
"indexOfNextWaypoint": 1,
"heading": 10
}
}
}
}, routingETAFinished);
}
Here is the same route with the same vehiclePosition, with a different heading. Due to this new heading, the linking to the road network is different.
var A = {
"$type": "OnRoadWaypoint",
"location": {
"coordinate": {
"x": 6.1561739444732675,
"y": 49.581704333851874
}
}
};
var B = {
"$type": "OnRoadWaypoint",
"location": {
"coordinate": {
"x": 6.1256572,
"y": 49.4816576
}
}
};
var map = new L.Map('map', {
center: [49.531769, 6.113249],
zoom: 18
});
// Add tile layer to map
var tileUrl = xServerUrl + '/services/rest/XMap/tile/{z}/{x}/{y}';
var tileLayer = new L.TileLayer(tileUrl, {
minZoom: 3,
maxZoom: 17,
noWrap: true
}).addTo(map);
new L.Marker([A.location.coordinate.y, A.location.coordinate.x]).addTo(map);
new L.Marker([B.location.coordinate.y, B.location.coordinate.x]).addTo(map);
xroute.calculateRoute({
"waypoints": [A, B],
"resultFields": {
"polyline": true,
"encodedPath": true
},
"routeOptions": {
"polylineOptions": {
"elevations": true
}
}
}, routingFinished);
function displayPolyline(poly, colorCode) {
var polyline = [];
for (var i = 0; i < poly.length; ++i) {
polyline.push(L.latLng(poly[i].y, poly[i].x));
}
polylineLayer = L.polyline(polyline, {
color: colorCode,
weight: 8
});
polylineLayer.addTo(map);
};
function routingETAFinished(route, exception) {
var polyline = route.polyline.plain.polyline;
displayPolyline(polyline, "#cc0000");
new L.Marker([polyline[0].y, polyline[0].x]).addTo(map);
print(route.distance + 'm in ' + route.travelTime + 's');
}
function routingFinished(route, exception) {
var polyline = route.polyline.plain.polyline;
displayPolyline(polyline, "#2882C8");
xroute.calculateRoute({
"waypoints": [{
"$type": "PathWaypoint",
"encodedPath": route.encodedPath
}],
"resultFields": {
"polyline": true
},
"routeOptions": {
"etaCalculationOptions": {
"vehiclePosition": {
"$type": "PositionEnRoute",
"currentLocation": {
x: 6.113701,
y: 49.531414
},
"indexOfNextWaypoint": 1,
"heading": 180
}
}
}
}, routingETAFinished);
}
Related Topics
The following topics might be relevant for this use case.
- Technical Concepts
- Showcases