Prerequisites
- JavaScript knowledge, including up-to-date knowledge of ES6 features.
- Basic knowledge of JavaScript asynchronous programming using Promises.
- HTML page for displaying PTVs Raster Map with Leaflet. For help, please visit this tutorial on Raster Maps.
How to use this tutorial
This tutorial is intended to introduce how to use the PTV Developer Route Optimization API with JavaScript.
Getting started
- Request an API key:
- Register and login at myptv.com
- Activate PTV Developer
- Create your API key
- Download an editor such as Visual Studio Code or Atom which work with HTML and JavaScript.
- You can find more details of requests and responses in the reference manual.
- Detailed information about the PTV Developer Route Optimization API is also available in the Quick Start.
- For more information, please visit the Leaflet reference documentation.
Create the JavaScript code
Create a new JavaScript file and reference it in the HTML page for display in the map.
Create an optimization plan
The first step is to add the code below and replace the string "YOUR_API_KEY" with your PTV Developer API key if this has not already been done.
The plan to be optimized consists of locations, transports and used vehicles.
Part of the result is the generated unique planId, which is used for all following API requests.
const api_key = "YOUR_API_KEY";
// Always add the API key to request headers
const applyAPIKey = (configuration) => ({
...configuration,
headers: {
"apiKey": api_key,
...configuration ? { ...configuration.headers } : {}
}
});
const createOptimizationPlan = () => {
const vehicles = [];
const numberOfVehicles = 2; // Set number of vehicles to use
const vehicleProfile = "EUR_CAR"; // Set profile for the vehicles
for (let i = 1; i <= numberOfVehicles; i++) {
vehicles.push({
id: "Vehicle " + i,
profile: vehicleProfile
});
}
const planToBeOptimized = {
locations: [...], // Specified locations
transports: [...], // Specified transports
vehicles
};
return fetch(
"https://api.myptv.com/routeoptimization/v1/plans",
applyAPIKey({
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(planToBeOptimized)
})
)
.then(response => response.ok ? response.json() : console.error(response))
};
You can use the PTV Developer Geocoding API to find locations by a given search text. For more information to this API, please visit the reference documentation.
const searchText = "Berlin";
fetch(
`https://api.myptv.com/geocoding/v1/locations/by-text?searchText=${searchText}`,
applyAPIKey()
)
.then(response => response.json())
.then({ locations } => console.log(locations));
Start the optimization process for that plan
After creating a plan, start the optimization based on the planId.
const startOptimization = (planId) =>
fetch(
`https://api.myptv.com/routeoptimization/v1/plans/${planId}/operation/optimization`,
applyAPIKey({
method: "POST",
headers: {
"Content-Type": "application/json"
}
})
).then(response => response.ok ? true : console.error(response));
Check the progress of the optimization process
Retrieve the optimization process status to check if the optimized plan is finished.
const getOptimizationProgress = (planId) =>
fetch(
`https://api.myptv.com/routeoptimization/v1/plans/${planId}/operation`,
applyAPIKey()
).then(response => response.ok ? response.json() : console.error(response));
Get the optimized plan
After the optimization process has been successfully completed (status = SUCCEEDED) the plan is updated internally and you can request the optimized plan.
const getOptimizedPlan = (planId) =>
fetch(
`https://api.myptv.com/routeoptimization/v1/plans/${planId}`,
applyAPIKey()
).then(response => response.ok ? response.json() : console.error(response));
Put the optimization process together
Now you can put the separate steps of the optimization process together to optimize specified transports.
const optimizeTransports = async () => {
const plan = await createOptimizationPlan(); // Create an optimization plan
if (!plan) return;
const startSuccessful = await startOptimization(plan.id); // Start the optimization
if (!startSuccessful) return;
const interval = setInterval( async () => {
const progress = await getOptimizationProgress(plan.id); // Get optimization progress
if (!progress) return clearInterval(interval);
// Only if the optimization has been finished and successful
if (progress.status === "SUCCEEDED") {
clearInterval(interval);
const optimizedPlan = await getOptimizedPlan(plan.id); // Get optimized plan
if (!optimizedPlan) return;
console.log(optimizedPlan);
}
}, 500);
};
Display optimized routes on the map
To display the routes given by the optimized plan as a Leaflet Polyline on the map, retrieve the optimized plan and add two more functions.
const map = new L.Map(...); // Your Leaflet map instance
const addPolylineToMap = (coordinates) => {
const randomColor = "#" + (Math.random() * 0xFFFFFF << 0).toString(16).padStart(6, "0"); // Choose a random color
const polyline = L.polyline(coordinates, {color: randomColor});
polyline.addTo(map);
map.fitBounds(polyline.getBounds()); // Fit map to added polyline
}
const drawRoutes = (optimizedPlan) => {
const { locations, routes } = optimizedPlan;
routes.forEach(route => {
const locationIds = route.stops.map(stop => stop.locationId);
// Extract the coordinates
const coordinates = locationIds.map(locationId => {
const location = locations.find(location => location.id === locationId)
return [location.latitude, location.longitude];
});
addPolylineToMap(coordinates);
});
};
// Adapt this existing function
const optimizeTransports = async () => {
...
const interval = setInterval( async () => {
...
if (progress.status === "SUCCEEDED") {
...
console.log(optimizedPlan);
drawRoutes(optimizedPlan); // Call the function to draw the routes
}
}, 500);
};