Multiple courier routing
A request to this resource distributes orders between the couriers based on the number of vehicles. After the orders are distributed, the optimal delivery route is built.
Step 1. Send a request to build a route
Request:
curl -X POST "https://courier.yandex.ru/vrs/api/v1/add/mvrp?apikey=<your API key>" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"depot\":{\"id\":0,\"point\":{\"lat\":55.734157,\"lon\":37.589346},\"time_window\":\"07:00-18:00\"},\"vehicles\":[{\"id\":1}],\"locations\":[{\"id\":1,\"point\":{\"lat\":55.708272,\"lon\":37.46826},\"time_window\":\"07:00-18:00\"}],\"options\":{\"time_zone\":3,\"quality\":\"normal\"}}"
Copied to clipboard
The request must contain the API key you obtained. If you don't have a key, submit a connection request.
Response:
The server response contains information about the request processing status.
{ "id":"f74a0efc-f9a1-4643-b834-9769fabaee7b", "status":{ "queued":1534160155.189995 }, "message":"Task queued" }
Copied to clipboard
Save the resulting ID to use it in the next step.
You can send a request to build a route using the "requests" library:
#!/usr/bin/env python2.7 import requests import time import datetime API_KEY = '<your API key>' API_ROOT_ENDPOINT = 'https://courier.yandex.ru/vrs/api/v1' # Create the request body, including the depot, delivery points, vehicle, and settings. payload = { "depot": { "id": 0, "point": { "lat": 55.734157, "lon": 37.589346 }, "time_window": "07:00-18:00" }, "vehicles": [{ "id": 1 } ], "locations": [{ "id": 1, "point": { "lat": 55.708272, "lon": 37.46826 }, "time_window": "07:00-18:00" } ], "options": { "time_zone": 3, "quality": "normal" } } # Send the request and get the task ID. response = requests.post( API_ROOT_ENDPOINT + '/add/mvrp', params={'apikey': API_KEY}, json=payload)
Copied to clipboard
You can send the request using the "request" module:
var request = require('request'); // Creating the request body, including the depot, delivery points, vehicle, and settings. var payload = { "depot": { "id": 0, "point": { "lat": 55.734157, "lon": 37.589346 }, "time_window": "07:00-18:00" }, "vehicles": [{ "id": 1 } ], "locations": [{ "id": 1, "point": { "lat": 55.708272, "lon": 37.46826 }, "time_window": "07:00-18:00" } ], "options": { "time_zone": 3, "quality": "normal" } }; const API_KEY = '<your API key>'; const API_ROOT_ENDPOINT = 'https://courier.yandex.ru/vrs/api/v1' // Sending the request and getting the task ID. function sendRequest(payload) { var url = API_ROOT_ENDPOINT + '/add/mvrp?apikey=' + API_KEY; var options = { body: JSON.stringify(payload), headers: {'Content-Type': 'application/json'} } return new Promise(function(resolve, reject) { request.post(url, options, function(error, response, body) { if (error) { reject(error); } else { var code = response.statusCode; if (code == 201 || code == 202) { resolve(JSON.parse(body).id); } else { reject(body); } } }) }); } function handleError(error) { console.log('Error:', error); } // sendRequest(payload) // .catch(handleError);
Copied to clipboard
Information about the request body is available on the service page.
Step 2. Get the processing result
You can obtain the built route by sending a GET request to the service.
Request:
curl -X GET "https://courier.yandex.ru/vrs/api/v1/result/mvrp/task_ID"
Copied to clipboard
Response:
If the route was built, the response will contain information about the route. Otherwise, the response will contain information about the request processing status.
# Wait for the response. poll_stop_codes = { requests.codes.ok, requests.codes.gone, requests.codes.internal_server_error } # Poll the server about the readiness of the route optimization result using the previously received ID. if response.status_code == requests.codes.accepted: request_id = response.json()['id'] poll_url = '{}/result/mvrp/{}'.format(API_ROOT_ENDPOINT, request_id) response = requests.get(poll_url) while response.status_code not in poll_stop_codes: time.sleep(1) response = requests.get(poll_url) # Output the data in a custom format. if response.status_code != 200: print 'Error {}: {}'.format(response.text, response.status_code) else: print 'Route optimization completed' print '' for route in response.json()['result']['routes']: print 'Vehicle {} route: {:.2f}km'.format( route['vehicle_id'], route['metrics']['total_transit_distance_m'] / 1000) # Output the route in text format. for waypoint in route['route']: print ' {type} {id} at {eta}, {distance:.2f}km driving '.format( type=waypoint['node']['type'], id=waypoint['node']['value']['id'], eta=str(datetime.timedelta(seconds=waypoint['arrival_time_s'])), distance=waypoint['transit_distance_m'] / 1000) # Output the route as a Yandex Maps link. yamaps_url = 'https://yandex.ru/maps/?mode=routes&rtext=' for waypoint in route['route']: point = waypoint['node']['value']['point'] yamaps_url += '{}%2c{}~'.format(point['lat'], point['lon']) print '' print 'See route on Yandex Maps:' print yamaps_url
Copied to clipboard
// Poll the server about the readiness of the route optimization result using the previously received ID. function pollResponse(requestId) { function delay(t) { return new Promise(function(resolve) { setTimeout(resolve, t); }); } function poller(resolve, reject) { function run() { let url = API_ROOT_ENDPOINT + '/result/mvrp/' + requestId; request.get(url, function(error, response, body) { if (error) { reject(error); } else { let result = JSON.parse(body); let code = response.statusCode; if (code != 200 && code != 410 && code != 500) { delay(500).then(run); } else { if (code == 200) { resolve(JSON.parse(body)); } else { reject(body); } } } }); } run(); } return new Promise(poller); } // Output the data in a custom format. function printResponse(response) { console.log('Route optimization completed\n') for (route of response.result.routes) { let distance_km = (route.metrics.total_transit_distance_m / 1000).toFixed(2) console.log(`Vehicle ${route.vehicle_id} route: ${distance_km}km`); // Output the route in text format. for (waypoint of route.route) { let type = waypoint.node.type; let id = waypoint.node.value.id; let eta = new Date(waypoint.arrival_time_s * 1000).toISOString().substr(11, 8); let distance_km = (waypoint.transit_distance_m / 1000).toFixed(2); console.log(` ${type} ${id} at ${eta}, ${distance_km}km driving `); } // Output the route as a Yandex Maps link. let yamaps_url = 'https://yandex.ru/maps/?mode=routes&rtext=' for (waypoint of route.route) { let point = waypoint.node.value.point; yamaps_url += `${point.lat}%2c${point.lon}~`; } console.log('\nSee route on Yandex Maps:\n', yamaps_url) } } // Asynchronous execution of functions. sendRequest(payload) .then(pollResponse) .then(printResponse) .catch(handleError);
Copied to clipboard