Compute and display an itinerary
In this guide we will
- create an MCI Problem (Axioroute service for itinerary computation)
- send an MCI Problem to the Axioroute API
- listen to Axioroute API progress
- display the resulting itinerary on a map
- customize the itinerary display
- tune the itinerary computation
- listen to Axioroute API progress and log it
Follow common setup steps
If not done already, follow common setup and requirements
Create a list of site points
An MCI Problem is mainly defined by
Site points
: waypoints your
itinerary will pass by.
Let's make a minimal one:
//...
/**
* an MCI Problem with 2 site points, its start and end
*/
const myMCIProblem = {
sitePoints: [
{
id: "START",
longitude: -0.561642,
latitude: 47.462544,
},
{
id: "END",
longitude: -0.345602,
latitude: 48.597481,
},
],
};
Before sending our problem, we will set up a listener to the Axioroute API.
This will allow us to display the itinerary on a map as soon as it is computed.
Send the Problem
//...
const job = await ARRequestClient.instance().sendMCIProblem(myMCIProblem);
Once you send a problem, you won't get back the solution right away.
You need to listen the resolution progress and wait for the solution to be ready.
Listen to the resolution progress
We will only listen to the RECEIVED
event, which is triggered when the solution is ready.
If we want to display a progress bar we would also listen to LOADING
event.
//...
apiClient.subscribe("RECEIVED", (request) => {
console.log("received solution", request.job.solution);
});
receiving the solution may take a few seconds to some minutes, depending on the problem complexity and Axioroute Service traffic.
Sending the solution to the Map
Now let's replace the console.log by a function that will display the solution on a map.
//...
const displayItinerary = (job) => {
ARMessage.send({
type: "SET_WEBVIEW_ENTITIES",
payload: {
/**
* The Map Webview handle natively MCI jobs and will display the
* corresponding itinerary if the job has a solution
*/
mciIndependantJobs: [job],
},
});
};
apiClient.subscribe("RECEIVED", (request) => {
/**
* Upon solution reception, we display the itinerary
*/
displayItinerary(request.job);
});
By default, on itinerary rollover a tooltip will be displayed with the MCI job id matching the itinerary.
Customize the itinerary display
We can customize default itinerary display by sending an updated MapConfig
to the Map.
Let's change the default itinerary color to red.
//...
/**
* We wait the Map to be ready before sending the config
*/
ARMessage.on("MAP_READY", (event) => {
ARMessage.send({
type: "SET_CONFIG",
payload: {
itineraryColorDefault: [255, 0, 0, 1],
},
});
});
Tune itinerary computation
Tuning computation will take various informations into account to compute the best itinerary.
One of them is the start time of each sitePoints (except last obviously).
So let's add a start date for our initial site point.
//...
/**
* an MCI Problem with 2 site points, its start and end
*/
const myMCIProblem = {
sitePoints: [
{
id: "START",
longitude: -0.561642,
latitude: 47.462544,
},
{
id: "END",
longitude: -0.345602,
latitude: 48.597481,
},
],
/**
* we add start date for our initial site point (repeat for all except last one)
*/
itineraryStartDates: ["2023-10-09T08:30:00.000Z"],
};
//...
Then we add a trip profile that will add some constraint to itinerary computation.
For an exhaustive list of TripProfile parameterers and their usage, see the TripProfile schema in the MCI API documentation
//...
/**
* an MCI Problem with 2 site points, its start and end
*/
const myMCIProblem = {
sitePoints: [
{
id: "START",
longitude: -0.561642,
latitude: 47.462544,
},
{
id: "END",
longitude: -0.345602,
latitude: 48.597481,
},
],
/**
* we add start date for our initial site point (repeat for all except last one)
*/
itineraryStartDates: ["2023-10-09T08:30:00.000Z"],
/**
* we add a trip profile to add some constraints to the itinerary computation
*/
tripProfile: {
name: "DEMO",
speedPreferences: [
{
category: "PENALIZED_LOCAL_ROAD_SPEED",
speed: 15,
preferenceIndicator: -2,
},
{
category: "LOCAL_ROAD_SPEED",
speed: 20,
preferenceIndicator: -1,
},
{
category: "PENALIZED_SECONDARY_ROAD_SPEED",
speed: 25,
preferenceIndicator: -1,
},
{
category: "SECONDARY_ROAD_SPEED",
speed: 45,
preferenceIndicator: 0,
},
{
category: "PENALIZED_MAJOR_ROAD_SPEED",
speed: 55,
preferenceIndicator: 1,
},
{
category: "MAJOR_ROAD_SPEED",
speed: 60,
preferenceIndicator: 1,
},
{
category: "EXPRESSWAY_SPEED",
speed: 65,
preferenceIndicator: 0,
},
{
category: "MOTORWAY_SPEED",
speed: 70,
preferenceIndicator: -1,
},
],
},
};
//...
The more complex the problem is, the longer it can take to compute the solution.
We can monitor the current progress by listening to the LOADING
event.
apiClient.subscribe("LOADING", (request) => {
console.log(
`Job Progress: ${request.job.status} ${
request.job.percent ? `(${request.job.percent}/100)` : ""
}`
);
});
All status do not have a percent value.