Skip to main content

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:

src/index.js
//...

/**
* 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

src/index.js
//...
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.

src/index.js
//...
apiClient.subscribe("RECEIVED", (request) => {
console.log("received solution", request.job.solution);
});
Note

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.

src/index.js
//...
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);
});
Note

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.

src/index.js
//...

/**
* 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.

src/index.js
//...

/**
* 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

src/index.js
//...

/**
* 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.

src/index.js
apiClient.subscribe("LOADING", (request) => {
console.log(
`Job Progress: ${request.job.status} ${
request.job.percent ? `(${request.job.percent}/100)` : ""
}`
);
});
Note

All status do not have a percent value.