Introduction
The WorkWave Routing Engine (WWRE) is a service that exposes routing, scheduling and routing-optimization functionalities via a REST Application Programming Interface (API) endpoints. This document is the official reference for that service.
Basic concepts
The API is entirely HTTP-based
Methods to retrieve data from the API require a GET request. Methods that submit or change data require a POST. Methods that destroy data require a DELETE. API Methods that require a particular HTTP method will return an error if you do not make your request with the correct one. HTTP Response Codes are meaningful.
The API is a RESTful resource
The API attempts to conform to the design principles of Representational State Transfer (REST).
Libraries to build REST-compatible API clients are readily available for several programming languages.
The format used for structured data exchange is JSON
The API supports the JSON (JavaScript Object Notation) format. Details on how JSON works can be found here and here. Libraries that convert to and from the JSON format are readily available for popular and lesspopular programming languages. A full index, sorted by language, can be found at the bottom of this page
SSL/TLS is supported (and highly recommended)
The API works with both plain HTTP and HTTP-within-SSL/TLS (HTTPS).
HTTPS is highly recommended to avoid passing both the authentication KEY and potentiallyconfidential data (e.g.: client's geocoded locations) in clear text over the web.
Parameters have certain expectations
Some API methods take optional or requisite parameters. Please keep in mind that allquery-string parameter values should be converted to UTF-8 and URL encoded.
There is one special parameter in the API, key, used for authentication, see section belowfor more details.
Authentication
Authentication is performed using an API key (also called as Account) provided by WorkWave. The API key must be included in the HTTP(S) request using one of the following two methods:
- via the key query-string parameter
- via the X-WorkWave-Key HTTP header
Where both are provided the query-string parameter takes precedence.
The API key is a string formatted as AAAA-AAAA-AAAA-AAAA.
Concurrency
There is a limit on the maximum number of API requests that can be concurrently submitted from the same key.
This limit is "1" for the Optimization resource, that is: each API account can run one optimization at a time.
Asynchronous Requests
Optimization requests are synchronous, by default, but they can be made as asynchronous.
All asynchronous requests return immediately with a RequestId, a string that identify a specific request, more specifically it is a UUID in its canonical form (e.g.: "123e4567-e89b-12d3-a456-426655440000").
The RequestId can be used for retriving an optimization result.
Notifications
The WorkWave Routing Engine API supports a notification mechanism based on HTTP callbacks (aka WebHooks).
A callback URL is defined on a optimization request basis to receive event notifications when optimization request ends. Notification messages are POSTed to the callback URL.
Queueing and Throttling
All requests are queued on a per-key (aka Account) basis and processed one by one in the order they have been queued (FIFO).
The queue has a maximum size of 25 items. Attempting to queue more than this number of requests will return a "Too Many Requests" error.
Throttling and rate-limiting schemes are applied on a per-key to both synchronous and asynchronous requests to prevent overloading the system with too many / too fast requests.
Versioning and evolution
WorkWave Routing Engine API is constantly evolving. Existing methods are being improved and extended and new functionalities are being added.
Backward-compatible changes are implemented as extensions to existing versions, while backward-incompatible changes are implemented by introducing entirely new versions.
While we are strongly committed to never introduce breaking changes to existing versions, integration code must be flexible enough to handle backward-compatible updates gracefully.
Here is a list of backward-compatible changes together with how integration code is supposed to deal with them.
Introducing a new REST resource
This is never a problem as existing integration code, not knowing about new endpoints, will not use them.
Adding properties to existing response objects
Existing integration code should ignore unmapped fields.
Note: Some JSON libraries, most notably Jackson, by default will throw an error in case an unmapped field is encountered during parsing. It is important that such libraries are configured to ignore (and possibly report) unmapped fields rather than fail.
Adding optional properties to existing request objects
This is never a problem as existing integration code, not knowing about the new fields, will not populate them.
Adding new values to existing enums in request objects
This is never a problem as existing integration code, not knowing about the new values, will not use them.
Adding new values to existing enums in response objects
This is trickier and we try to limit it only to cases where the change can be handled in a backward-compatible way. Existing integration code should ignore ExecutionEvents with an unknown type
and it is recommended to log these events to keep track of them.
HTTP Status Codes
The WorkWave Routing Engine API attempts to return appropriate HTTP status codes for every request.
Error Code |
Description |
---|---|
200 | OK -- Success |
400 | Bad Request -- The request cannot be accepted. The accompanying error message explains why. |
401 | Unauthorized -- Authentication credentials are missing or incorrect. |
403 | Forbidden -- The resource requested is hidden for administrators only. |
404 | Not Found -- The URI requested is invalid or the resource requested does not exists. |
405 | Method Not Allowed -- You tried to access a resource with an invalid method. |
406 | Not Acceptable -- You requested a format that is not available (e.g. xml). |
429 | Too Many Requests -- Rate limit exceeded. Wait before retrying and reduce the rate of requests. |
500 | Internal Server Error -- We had a problem with the service. The WorkWave Routing Engine support team is automatically alerted when this error happens but you may wish to contact them directly to provide additional details to help in the resolution. |
502 | Bad Gateway -- The WorkWave Routing Engine service could be overloaded with requests. Try again later. |
503 | Service Unavailable -- The WorkWave Routing Engine service is temporarily down or being upgraded. Try again later. |
504 | Gateway Timeout -- The WorkWave Routing Engine service is running. This issue could be because the service is temporary overloaded or a large/complex request hit the HTTP timeout (300 seconds) because it is executed synchronously. In the second case please refer to Asynchronous Optimizations for additional information and execute the request as asynchronous. |
Error Codes and Messages
{
"errorCode": -1000,
"errorDescription": "Failed parsing JSON source"
}
When the WorkWave Routing Engine API returns error messages, it does so in JSON format. See examples in the right panel.
Error codes, as found in the body of returned error messages, further define the scope of an error.
The following error codes may be returned:
Error Code |
Description |
---|---|
-100 | Internal Error -- An unexpected internal error happened that prevented the request to be fully completed. You may try again later but, in case you would like to investigate the issue please contact WWRE support. |
-200 | Unknown Key -- Wrong authentication key. |
-400 | License Limit Exceeded -- The request is formally correct but a licensing limit has been exceeded. One or more constraints associated with the authentication key, such as maximum number of Vehicles or Waypoints, have been exceeded. |
-401 | License Expired -- The authentication key is expired. Contact WWRE support for a renewal. |
-700 | Unknown Matrix -- The specified matrix does not exist. |
-701 | Matrix Already Exists -- The specified Matrix already exists. |
-900 | Too Many Requests -- The given key has submitted too many requests in too short a period of time. Insert a pause between requests to avoid getting this error. |
-1000 | Malformed Request -- Something is wrong with the request. It could be that the JSON data in the request body is malformed (typically due to a missing or overabundant parenthesis or comma) or a mandatory field is missing or a negative value has been set for a field that expects a positive integer, etc |
-1100 | Unknown Request -- No request exists for the specified request ID. |
-1102 | Invalid Request -- Invalid request, for example to delete a request that has already been completed. |
-1103 | Expired Request Result -- We keep the result of a request for a limited amount of time, this is set to a couple of days but it can be changed, so when a request's result is expired it will be removed from the cache. |
-1300 | Resource Not Found -- Trying to access a resource that not exists, for example and invalid endpoint. |
REST Client
To start experimenting with a few examples we recommend a REST client called Postman, an handy API client that facilitates testing and experimenting with RESTful endpoints.
Installing Postman
You can ownload the Postman App for Windows, OS X, or Linux or you can use Postman online:
API Overview
The WorkWave Routing Engine API, exposed from the domain wwre.workwave.com, includes the following RESTful resources to integrate with.
Each resource is further detailed later in its own chapter.
- Matrix API: set of endpoints for managing your distance/time matrices.
- Optimization API: for managing your single and multiple execution days.
- Schedules API: returns a time schedule for a given list of vehicles that respects the given order of waypoints, minimizing the number of constraints violations
Optimization Concepts
Optimizes a set of waypoints so that they are best allocated to a set of vehicles taking into account the following complex constraints:
- Vehicle limited capacity and working time-window;
- Waypoint service time, delivery time-window and priority;
- Custom exclusion/inclusion rules using tags;
- Pickup and drop-off relationship;
- Custom clustering rules.
Optimization Goals
The optimization goals are defined by the following list of priorities:
- Maximize the number of served waypoints, starting with the higher-priority ones and serving the waypoints with a lower priority only if all the ones with a higher priority cannot be served.
- Total routes cost, where the cost of a route is defined as follows:
activationCost + drivingTimeCostFactor × driving time seconds + serviceTimeCostFactor × service time seconds + idleTimeCostFactor × idle time seconds + breakTimeCostFactor × break time seconds + distanceCostFactor * meters + perStopCost × number of unique stops + clusters cost
.
The properties of the vehicle required to compute its route cost are: activationCost, drivingTimeCostFactor, serviceTimeCostFactor, idleTimeCostFactor, breakTimeCostFactor, distanceCostFactor and perStopCost
Some examples of how costs can be tweaked to model different scenarios:
- Set a very high activation cost: the algorithm will try to minimize the number of used vehicles
- Set activation cost to zero: the algorithm will tend to use more vehicles if doing that reduces the overall cost, as using many vehicles comes "free"
- Set high driving time or mileage cost: get more "compact" routes
- Set high idle time cost: vehicles will prefer driving to a more distant waypoint rather then waiting idle at a nearby waypoint for its time window to open
- Set high per-stop cost: when possible the algorithm will prefer sending one vehicle to serve a group of waypoints clustered at the same location rather then splitting them among multiple vehicles (or even different trips from the same vehicle)
Optimization and Matrix
The maximum allowed size of a single optimization (single day or multi day) request varies according to the size of the purchased plan.
The size of an optimization request cannot exceed the account fleet size and the route plan size (in terms of the number of vehicles and waypoints included in the request). Note that multiple waypoints sharing the same coordinates count as their number and not as one and the same applies to vehicles.
There is no limit on the number of optimization requests that can be submitted, if their size and vehicle usage is allowed by the purchased plan. Too many or too frequent requests may be temporarily rejected with error code -900 (see Error Codes and Messages for details).
Optimizations can be "one-shot" or bound to a specific Matrix (identified by its matrix id).
For a "one-shot" optimization the process is:
- compute full driving duration Matrix against road network
- optimize problem and discard Matrix
For an optimization bound to a Matrix the process changes as follows:
- compute delta driving duration Matrix against road network
- optimize problem
- save updated Matrix
Bounding to a Matrix is especially useful when multiple optimizations are performed against the same or similar set of vehicles/waypoints. In such scenarios, at every new optimization request only a delta-matrix has to be computed thus greatly speeding up the whole process for quicker response times.
Note that the Matrix data is implicitly and automatically updated at every optimization request bound to that Matrix. Matrices can be created, listed and deleted but cannot be manipulated in any other way if not by the result of an optimization. A Matrix should therefore be considered as a simple "named token" to be used with the Optimization resource.
Asynchronous Optimizations
An optimization request can take from a few seconds up to several minutes to complete, depending on its size, constraints complexity and on the average and maximum reciprocal distance between all involved locations.
For larger/more complex invocations where the expected processing time is longer than a few seconds it is recommended to use the asynchronous mode to avoid dropped TCP connection issues. Currently the TCP idle connection time is set to 300 seconds, so if a synchronous request required more than 300 seconds will be forcefully closed.
The asynchronous mode is activated by setting the async parameter to true in the input request, which is otherwise identical to the one described on the object definition for SingleDayOptimizationRequest and MultiDayOptimizationRequest.
Asynchronous requests return immediately providing just the request identification (called requestId or reqId), which can then be used to poll for status updates and to retrieve the result when the request is completed.
Asynchronous Optimization Response
An optimization response for an asynchronous request that is not yet compleated have the format of AsyncResponse.
The status field can be PROCESSING or QUEUED. A queued request means that the user has one or more requests that are already executing. These requests must be completed before executing a queued one.
The progress field is an integer value in the range 0-100 indicating the completion of the request in 1% percent steps.
The resultAvailable field states if an optimization result is available. In this way, if the optimization is cancelled with keepResult flag enabled, current result is provided as optimization result.
Matrix API
List Matrices
curl https://wwre.workwave.com/opt/v5/matrix?key=AUTH_KEY
GET https://wwre.workwave.com/opt/v5/matrix HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
The above command returns JSON structured like this:
{
"matrices": [
{
"id": 550,
"name": "myFirstMtx",
"creationDate": 1286446431000
},
{
"id": 551,
"name": "mySecondMtx",
"creationDate": 1286446437000
}
]
}
List available Matrices with their name and ID.
HTTP Request
GET https://wwre.workwave.com/opt/v5/matrix
Execution Type
Synchronous
Throttling
Rate-limit (5 call every 60 seconds)
Return Values
Property | Type | Description |
---|---|---|
matrices | List of Matrix | List of matrices available and created by user's key |
Create Matrix
curl –X POST https://wwre.workwave.com/opt/v5/matrix?key=AUTH_KEY&name=myMtx
POST https://wwre.workwave.com/opt/v5/matrix?&name=myMtx HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
The above command returns JSON structured like this:
{
"id":551,
"name":"myMtx",
"creationDate":1286455766735
}
Create an empty Matrix to be used with an optimization resource.
HTTP Request
POST https://wwre.workwave.com/opt/v5/matrix[?name=myMtx]
Execution Type
Synchronous
Throttling
Rate-limit (10 call every 60 seconds)
QueryString Parameters
Property | Type | Description |
---|---|---|
name | String | Optional. Name assigned to the matrix |
Return Values
Delete Matrix
curl -X DELETE https://wwre.workwave.com/opt/v5/matrix/id/551?key=AUTH_KEY
curl -X DELETE https://wwre.workwave.com/opt/v5/matrix/name/myMtx?key=AUTH_KEY
DELETE https://wwre.workwave.com/opt/v5/matrix/id/551 HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
DELETE https://wwre.workwave.com/opt/v5/matrix/name/myMtx HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
Delete a Matrix.
HTTP Request
A matrix can be referred by name or matrix identification:
DELETE https://wwre.workwave.com/opt/v5/matrix/id/:matrixId
DELETE https://wwre.workwave.com/opt/v5/matrix/name/:matrixName
Execution Type
Synchronous
Throttling
Rate-limit (10 call every 60 seconds)
Path Parameters
Property | Type | Description |
---|---|---|
matrixId | Integer | The matrix identification, mutually exclusive with matrixName |
matrixName | String | The matrix name, mutually exclusive with matrixId |
Return Values
[Empty Response Body]
Single-Day Optimization API
Optimization that works on a single execution day.
Compute Single-Day Optimization
curl -X POST https://wwre.workwave.com/opt/v5/optimization?key=AUTH_KEY \
"Content-Type: application/json" \
-d "@request.json"
curl -X POST https://wwre.workwave.com/opt/v5/optimization/id/551?key=AUTH_KEY \
"Content-Type: application/json" \
-d "@request.json"
curl -X POST https://wwre.workwave.com/opt/v5/optimization/name/myMtx?key=AUTH_KEY \
"Content-Type: application/json" \
-d "@request.json"
Where request.json is a file containing the JSON data to be posted
POST https://wwre.workwave.com/opt/v5/optimization HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
Content-Type: application/json
POST https://wwre.workwave.com/opt/v5/optimization/id/551?key=AUTH_KEY HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
Content-Type: application/json
POST https://wwre.workwave.com/opt/v5/optimization/name/myMtx?key=AUTH_KEY HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
Content-Type: application/json
{
"vehicles": [
{
"name": "Vehicle A",
"origin": {
"latitude": 42.35516,
"longitude": -71.76032
},
"timeCostModel": {
"drivingTimeCostFactor": 5000,
"serviceTimeCostFactor": 5000,
"idleTimeCostFactor": 5000,
"breakTimeCostFactor": 5000
},
"distanceCostFactor": 100,
"timeWindow": {
"startTimeSec": 40000,
"stopTimeSec": 80000
},
"destination": {
"latitude": 42.35516,
"longitude": -71.76032
}
}
],
"waypoints": [
{
"name": "wp 1",
"location": {
"latitude": 42.38246,
"longitude": -71.33345
},
"serviceTimeSec": 900
},
{
"name": "wp 2",
"location": {
"latitude": 42.4559,
"longitude": -71.52353
}
},
{
"name": "wp 3",
"location": {
"latitude": 42.53996,
"longitude": -71.41965
}
}
]
}
The above command returns JSON structured like this:
Asynchronous response
{
"reqID": "4e0e9137-8dc5-42ff-aa83-23e1865aeca2",
"status": "PROCESSING",
"progress": 33,
"resultAvailable": false,
"queuePosition": 0
}
Synchronous response
{
"reqID": "dd0ef471-6223-427b-9017-ffc6dd4688a1",
"status": "COMPLETED",
"matrixID": -1,
"elapsedSec": 0,
"routes": [
{
"vehicle": {
"number": 0,
"name": "Vehicle A"
},
"routeStats": {
"breakTimeSec": 0,
"driveTimeSec": 9495,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 10395,
"distanceMt": 135736,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cost": 65548600,
"steps": [
{
"stepNumber": 0,
"waypoint": {
"name": "origin",
"number": -1
},
"latitude": 42.35516,
"longitude": -71.76032,
"timeWindow": {
"startTimeSec": 40000,
"stopTimeSec": 80000
},
"arrivalTimeSec": 0,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 40000,
"nextStepDriveTimeSec": 2693,
"nextStepDistanceMt": 52553,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 0,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 0,
"distanceMt": 0,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 1,
"waypoint": {
"name": "wp 3",
"number": 2
},
"latitude": 42.53996,
"longitude": -71.41965,
"arrivalTimeSec": 42693,
"idleTimeSec": 0,
"serviceStartTimeSec": 42693,
"departureTimeSec": 42693,
"nextStepDriveTimeSec": 2436,
"nextStepDistanceMt": 26830,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 2693,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 2693,
"distanceMt": 52553,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 2,
"waypoint": {
"name": "wp 1",
"number": 0
},
"latitude": 42.38246,
"longitude": -71.33345,
"arrivalTimeSec": 45129,
"idleTimeSec": 0,
"serviceStartTimeSec": 45129,
"departureTimeSec": 46029,
"nextStepDriveTimeSec": 2447,
"nextStepDistanceMt": 22595,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 5129,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 6029,
"distanceMt": 79383,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 3,
"waypoint": {
"name": "wp 2",
"number": 1
},
"latitude": 42.4559,
"longitude": -71.52353,
"arrivalTimeSec": 48476,
"idleTimeSec": 0,
"serviceStartTimeSec": 48476,
"departureTimeSec": 48476,
"nextStepDriveTimeSec": 1919,
"nextStepDistanceMt": 33758,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 7576,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 8476,
"distanceMt": 101978,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 4,
"waypoint": {
"name": "destination",
"number": -2
},
"latitude": 42.35516,
"longitude": -71.76032,
"arrivalTimeSec": 50395,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 50395,
"nextStepDriveTimeSec": 0,
"nextStepDistanceMt": 0,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 9495,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 10395,
"distanceMt": 135736,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
}
]
}
],
"unreachedWaypoints": [],
"unreachableWaypoints": [],
"unneededVehicles": [],
"warnings": []
}
Perform a single day optimization request, that can refers or not a pre-generated matrix. If a request do not use a matrix (so called one-shot request), a distance/time matrix will be computed and, at the end of computation, deleted.
HTTP Request
One-Shot HTTP Request
POST https://wwre.workwave.com/opt/v5/optimization
Matrix Based HTTP Request
A matrix can be referred by name or matrix identification:
POST https://wwre.workwave.com/opt/v5/optimization/id/:matrixId
POST https://wwre.workwave.com/opt/v5/optimization/name/:matrixName
Execution Type
- Synchronous
- Asynchronous: this mode can be set on the request's body (see member async of SingleDayOptimizationRequest object).
Throttling
Leaky bucket (size: 60, refill: 5 per minute)
Path Parameters
Property | Type | Description |
---|---|---|
matrixId | Integer | Optional. The matrix identification, mutually exclusive with matrixName |
matrixName | String | Optional. The matrix name, mutually exclusive with matrixId |
Request Body
SingleDayOptimizationRequest (Request example)
Return Value (synchronous)
SingleDayOptimizationResponse (Response example)
Return Value (asynchronous)
Get Single-Day Optimization
curl https://wwre.workwave.com/opt/v5/optimization/96cb6dcb-3841-489a-bbdc-b95460290362?key=AUTH_KEY
GET https://wwre.workwave.com/opt/v5/optimization/96cb6dcb-3841-489a-bbdc-b95460290362 HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
The above command returns JSON structured like this:
Optimization not yet compleated response
{
"reqID": "96cb6dcb-3841-489a-bbdc-b95460290362",
"status": "PROCESSING",
"progress": 33,
"resultAvailable": false,
"queuePosition": 0
}
Optimization compleated response
{
"reqID": "96cb6dcb-3841-489a-bbdc-b95460290362",
"status": "COMPLETED",
"matrixID": -1,
"elapsedSec": 1,
"routes": [
{
"vehicle": {
"number": 0,
"name": "Vehicle A"
},
"routeStats": {
"breakTimeSec": 0,
"driveTimeSec": 9495,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 10395,
"distanceMt": 135736,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cost": 65548600,
"steps": [
{
"stepNumber": 0,
"waypoint": {
"name": "origin",
"number": -1
},
"latitude": 42.35516,
"longitude": -71.76032,
"timeWindow": {
"startTimeSec": 40000,
"stopTimeSec": 80000
},
"arrivalTimeSec": 0,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 40000,
"nextStepDriveTimeSec": 2693,
"nextStepDistanceMt": 52553,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 0,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 0,
"distanceMt": 0,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 1,
"waypoint": {
"name": "wp 3",
"number": 2
},
"latitude": 42.53996,
"longitude": -71.41965,
"arrivalTimeSec": 42693,
"idleTimeSec": 0,
"serviceStartTimeSec": 42693,
"departureTimeSec": 42693,
"nextStepDriveTimeSec": 2436,
"nextStepDistanceMt": 26830,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 2693,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 2693,
"distanceMt": 52553,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 2,
"waypoint": {
"name": "destination",
"number": -2
},
"latitude": 42.35516,
"longitude": -71.76032,
"arrivalTimeSec": 50395,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 50395,
"nextStepDriveTimeSec": 0,
"nextStepDistanceMt": 0,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 9495,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 10395,
"distanceMt": 135736,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
}
]
}
],
"unreachedWaypoints": [],
"unreachableWaypoints": [],
"unneededVehicles": [],
"warnings": []
}
Return the outcome or the status of a single-day optimization. The body returned by this invocation is identical to the one that would have been returned by a synchronous invocation, error responses included (in case the optimization failed for some reason).
If the optimization request is asynchronous and is not yet completed, the response is limited to the request identification and the status parameters.
HTTP Request
GET https://wwre.workwave.com/opt/v5/optimization/:reqId
Execution Type
Synchronous
Throttling
Leaky bucket (size: 60, refill: 5 per minute)
Path Parameters
Property | Type | Description |
---|---|---|
reqId | UUID | The request identification |
Return Value
- SingleDayOptimizationResponse: if the optimization has compleated this endpoint will retrieve the complete result of its execution (Response example)
- AsyncResponse: if the request is still queued or executing
Delete Single-Day Optimization
curl –X DELETE https://wwre.workwave.com/opt/v5/optimization/96cb6dcb-3841-489a-bbdc-b95460290362?key=AUTH_KEY
curl –X DELETE https://wwre.workwave.com/opt/v5/optimization/96cb6dcb-3841-489a-bbdc-b95460290362?key=AUTH_KEY&keepResult=true
DELETE https://wwre.workwave.com/opt/v5/optimization/96cb6dcb-3841-489a-bbdc-b95460290362 HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
DELETE https://wwre.workwave.com/opt/v5/optimization/96cb6dcb-3841-489a-bbdc-b95460290362?keepResult=true HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
If the request is already completed or canceled
{
"errorCode": -1102,
"errorDescription": "Can't abort request with ID [96cb6dcb-3841-489a-bbdc-b95460290362] that has already been completed"
}
Cancel an asynchronous single-day optimization request.
If the request is queued will be removed from the queue, if the request is already completed or canceled a cancel command will be ignored (caller will be informed with a warning message), while if the request is processing will be forcefully terminated.
HTTP Request
DELETE https://wwre.workwave.com/opt/v5/optimization/:reqId[?keepResult=<Boolean>]
Execution Type
Synchronous
Throttling
Leaky bucket (size: 60, refill: 5 per minute)
Path Parameters
Property | Type | Description |
---|---|---|
reqId | UUID | The request identification |
QueryString Parameters
Property | Type | Description |
---|---|---|
keepResult | Boolean | Default to false. If true, the optimization is cancelled but current result (if available) is provided as optimization result, this could be not the best possible result for the provided input. |
Return Value
[Empty Response Body]
Multi-Day Optimization API
Optimization spread on multiple execution days.
Compute Multi-Day Optimization
curl -X POST https://wwre.workwave.com/opt/v5/optimization/multiday?key=AUTH_KEY \
"Content-Type: application/json" \
-d "@request.json"
curl -X POST https://wwre.workwave.com/opt/v5/optimization/multiday/id/551?key=AUTH_KEY \
"Content-Type: application/json" \
-d "@request.json"
curl -X POST https://wwre.workwave.com/opt/v5/optimization/multiday/name/myMtx?key=AUTH_KEY \
"Content-Type: application/json" \
-d "@request.json"
Where request.json is a file containing the JSON data to be posted
POST https://wwre.workwave.com/opt/v5/optimization/multiday HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
Content-Type: application/json
POST https://wwre.workwave.com/opt/v5/optimization/multiday/id/551?key=AUTH_KEY HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
Content-Type: application/json
POST https://wwre.workwave.com/opt/v5/optimization/multiday/name/myMtx?key=AUTH_KEY HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
Content-Type: application/json
{
"vehicles": [
{
"name": "Vehicle A",
"daySettings": {
"20160602": {
"origin": {
"latitude": 42.35516,
"longitude": -71.76032
},
"timeCostModel": {
"drivingTimeCostFactor": 5000,
"serviceTimeCostFactor": 5000,
"idleTimeCostFactor": 5000,
"breakTimeCostFactor": 5000
},
"distanceCostFactor": 100,
"timeWindow": {
"startTimeSec": 40000,
"stopTimeSec": 80000
},
"destination": {
"latitude": 42.36324,
"longitude": -71.71916
}
},
"20160603": {
"origin": {
"latitude": 42.36324,
"longitude": -71.71916
},
"timeCostModel": {
"drivingTimeCostFactor": 5000,
"serviceTimeCostFactor": 5000,
"idleTimeCostFactor": 5000,
"breakTimeCostFactor": 5000
},
"distanceCostFactor": 100,
"timeWindow": {
"startTimeSec": 20000,
"stopTimeSec": 50000
},
"destination": {
"latitude": 42.35516,
"longitude": -71.76032
}
}
}
}
],
"waypoints": [
{
"name": "wp 1",
"location": {
"latitude": 42.38246,
"longitude": -71.33345
},
"serviceTimeSec": 900,
"eligibleDays": [
20160602,
20160603
]
},
{
"name": "wp 2",
"location": {
"latitude": 42.4559,
"longitude": -71.52353
},
"serviceTimeSec": 300,
"eligibleDays": [
20160602
]
},
{
"name": "wp 3",
"location": {
"latitude": 42.53996,
"longitude": -71.41965
},
"serviceTimeSec": 300,
"eligibleDays": [
20160603
]
}
]
}
The above command returns JSON structured like this:
Asynchronous response
{
"reqID": "a0ac2be6-fe69-40ed-aebf-68b3b5f416ca",
"status": "PROCESSING",
"progress": 65,
"resultAvailable": false,
"queuePosition": 0
}
Synchronous response
{
"reqID": "a0ac2be6-fe69-40ed-aebf-68b3b5f416ca",
"status": "COMPLETED",
"matrixID": -1,
"elapsedSec": 2,
"routes": [
{
"vehicle": {
"day": 20160602,
"number": 0,
"name": "Vehicle A"
},
"routeStats": {
"breakTimeSec": 0,
"driveTimeSec": 3344,
"idleTimeSec": 0,
"serviceTimeSec": 300,
"workTimeSec": 3644,
"distanceMt": 65063,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cost": 24726300,
"steps": [
{
"stepNumber": 0,
"waypoint": {
"name": "origin",
"number": -1
},
"latitude": 42.35516,
"longitude": -71.76032,
"timeWindow": {
"startTimeSec": 40000,
"stopTimeSec": 80000
},
"arrivalTimeSec": 0,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 40000,
"nextStepDriveTimeSec": 1762,
"nextStepDistanceMt": 35487,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 0,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 0,
"distanceMt": 0,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 1,
"waypoint": {
"name": "wp 2",
"number": 1
},
"latitude": 42.4559,
"longitude": -71.52353,
"arrivalTimeSec": 41762,
"idleTimeSec": 0,
"serviceStartTimeSec": 41762,
"departureTimeSec": 42062,
"nextStepDriveTimeSec": 1582,
"nextStepDistanceMt": 29576,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 1762,
"idleTimeSec": 0,
"serviceTimeSec": 300,
"workTimeSec": 2062,
"distanceMt": 35487,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 2,
"waypoint": {
"name": "destination",
"number": -2
},
"latitude": 42.36324,
"longitude": -71.71916,
"arrivalTimeSec": 43644,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 43644,
"nextStepDriveTimeSec": 0,
"nextStepDistanceMt": 0,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 3344,
"idleTimeSec": 0,
"serviceTimeSec": 300,
"workTimeSec": 3644,
"distanceMt": 65063,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
}
]
},
{
"vehicle": {
"day": 20160603,
"number": 0,
"name": "Vehicle A"
},
"routeStats": {
"breakTimeSec": 0,
"driveTimeSec": 7045,
"idleTimeSec": 0,
"serviceTimeSec": 1200,
"workTimeSec": 8245,
"distanceMt": 118174,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cost": 53042400,
"steps": [
{
"stepNumber": 0,
"waypoint": {
"name": "origin",
"number": -1
},
"latitude": 42.36324,
"longitude": -71.71916,
"timeWindow": {
"startTimeSec": 20000,
"stopTimeSec": 50000
},
"arrivalTimeSec": 0,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 20000,
"nextStepDriveTimeSec": 2809,
"nextStepDistanceMt": 40195,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 0,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 0,
"distanceMt": 0,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 1,
"waypoint": {
"name": "wp 1",
"number": 0
},
"latitude": 42.38246,
"longitude": -71.33345,
"arrivalTimeSec": 22809,
"idleTimeSec": 0,
"serviceStartTimeSec": 22809,
"departureTimeSec": 23709,
"nextStepDriveTimeSec": 1888,
"nextStepDistanceMt": 26766,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 2809,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 3709,
"distanceMt": 40195,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 2,
"waypoint": {
"name": "wp 3",
"number": 2
},
"latitude": 42.53996,
"longitude": -71.41965,
"arrivalTimeSec": 25597,
"idleTimeSec": 0,
"serviceStartTimeSec": 25597,
"departureTimeSec": 25897,
"nextStepDriveTimeSec": 2348,
"nextStepDistanceMt": 51213,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 4697,
"idleTimeSec": 0,
"serviceTimeSec": 1200,
"workTimeSec": 5897,
"distanceMt": 66961,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 3,
"waypoint": {
"name": "destination",
"number": -2
},
"latitude": 42.35516,
"longitude": -71.76032,
"arrivalTimeSec": 28245,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 28245,
"nextStepDriveTimeSec": 0,
"nextStepDistanceMt": 0,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 7045,
"idleTimeSec": 0,
"serviceTimeSec": 1200,
"workTimeSec": 8245,
"distanceMt": 118174,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
}
]
}
],
"unreachedWaypoints": [],
"unreachableWaypoints": [],
"unneededVehicles": [],
"warnings": []
}
Perform a multi day optimization request, that can refers or not a pre-generated matrix. If a request do not use a matrix (so called one-shot request), a distance/time matrix will be computed and, at the end of computation, deleted.
HTTP Request
One-Shot HTTP Request
POST https://wwre.workwave.com/opt/v5/optimization/multiday
Matrix Based HTTP Request
A matrix can be referred by name or matrix identification:
POST https://wwre.workwave.com/opt/v5/optimization/multiday/id/:matrixId
POST https://wwre.workwave.com/opt/v5/optimization/multiday/name/:matrixName
Execution Type
- Synchronous
- Asynchronous: this mode can be set on the request's body (see member async of MultiDayOptimizationRequest object).
Throttling
Leaky bucket (size: 60, refill: 5 per minute)
Path Parameters
Property | Type | Description |
---|---|---|
matrixId | Integer | Optional. The matrix identification, mutually exclusive with matrixName |
matrixName | String | Optional. The matrix name, mutually exclusive with matrixId |
Request Body
MultiDayOptimizationRequest (Request example)
Return Value (synchronous)
MultiDayOptimizationResponse (Response example)
Return Value (asynchronous)
Get Multi-Day Optimization
curl https://wwre.workwave.com/opt/v5/optimization/multiday/96cb6dcb-3841-489a-bbdc-b95460290362?key=AUTH_KEY
GET https://wwre.workwave.com/opt/v5/optimization/multiday/96cb6dcb-3841-489a-bbdc-b95460290362 HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
The above command returns JSON structured like this:
Optimization not yet compleated response
{
"reqID": "96cb6dcb-3841-489a-bbdc-b95460290362",
"status": "PROCESSING",
"progress": 33,
"resultAvailable": false,
"queuePosition": 0
}
Optimization compleated response
{
"reqID": "96cb6dcb-3841-489a-bbdc-b95460290362",
"status": "COMPLETED",
"matrixID": -1,
"elapsedSec": 1,
"routes": [
{
"vehicle": {
"number": 0,
"name": "Vehicle A"
},
"routeStats": {
"breakTimeSec": 0,
"driveTimeSec": 9495,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 10395,
"distanceMt": 135736,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cost": 65548600,
"steps": [
{
"stepNumber": 0,
"waypoint": {
"name": "origin",
"number": -1
},
"latitude": 42.35516,
"longitude": -71.76032,
"timeWindow": {
"startTimeSec": 40000,
"stopTimeSec": 80000
},
"arrivalTimeSec": 0,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 40000,
"nextStepDriveTimeSec": 2693,
"nextStepDistanceMt": 52553,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 0,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 0,
"distanceMt": 0,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 1,
"waypoint": {
"name": "wp 3",
"number": 2
},
"latitude": 42.53996,
"longitude": -71.41965,
"arrivalTimeSec": 42693,
"idleTimeSec": 0,
"serviceStartTimeSec": 42693,
"departureTimeSec": 42693,
"nextStepDriveTimeSec": 2436,
"nextStepDistanceMt": 26830,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 2693,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 2693,
"distanceMt": 52553,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 4,
"waypoint": {
"name": "destination",
"number": -2
},
"latitude": 42.35516,
"longitude": -71.76032,
"arrivalTimeSec": 50395,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 50395,
"nextStepDriveTimeSec": 0,
"nextStepDistanceMt": 0,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 9495,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 10395,
"distanceMt": 135736,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
}
]
}
],
"unreachedWaypoints": [],
"unreachableWaypoints": [],
"unneededVehicles": [],
"warnings": []
}
Return the outcome or the status of a multi-day optimization. The body returned by this invocation is identical to the one that would have been returned by a synchronous invocation, error responses included (in case the optimization failed for some reason).
If the optimization request is asynchronous and is not yet completed, the response is limited to the request identification and the status parameters.
HTTP Request
GET https://wwre.workwave.com/opt/v5/optimization/multiday/:reqId
Execution Type
Synchronous
Throttling
Leaky bucket (size: 60, refill: 5 per minute)
Path Parameters
Property | Type | Description |
---|---|---|
reqId | UUID | The request identification |
Return Value
- MultiDayOptimizationResponse: if the optimization has compleated this endpoint will retrieve the complete result of its execution (Response example)
- AsyncResponse: if the request is still queued or executing
Delete Multi-Day Optimization
curl –X DELETE https://wwre.workwave.com/opt/v5/optimization/multiday/96cb6dcb-3841-489a-bbdc-b95460290362?key=AUTH_KEY
curl –X DELETE https://wwre.workwave.com/opt/v5/optimization/multiday/96cb6dcb-3841-489a-bbdc-b95460290362?key=AUTH_KEY&keepResult=true
DELETE https://wwre.workwave.com/opt/v5/optimization/multiday/96cb6dcb-3841-489a-bbdc-b95460290362 HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
DELETE https://wwre.workwave.com/opt/v5/optimization/multiday/96cb6dcb-3841-489a-bbdc-b95460290362?keepResult=true HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
If the request is already completed or canceled
{
"errorCode": -1102,
"errorDescription": "Can't abort request with ID [96cb6dcb-3841-489a-bbdc-b95460290362] that has already been completed"
}
Cancel an asynchronous multi-day optimization request.
If the request is queued will be removed from the queue, if the request is already completed or canceled a cancel command will be ignored (caller will be informed with a warning message), while if the request is processing will be forcefully terminated.
HTTP Request
DELETE https://wwre.workwave.com/opt/v5/optimization/multiday/:reqId[?keepResult=<Boolean>]
Execution Type
Synchronous
Throttling
Leaky bucket (size: 60, refill: 5 per minute)
Path Parameters
Property | Type | Description |
---|---|---|
reqId | UUID | The request identification |
QueryString Parameters
Property | Type | Description |
---|---|---|
keepResult | Boolean | Default to false. If true, the optimization is cancelled but current result (if available) is provided as optimization result, this could be not the best possible result for the provided input. |
Return Value
[Empty Response Body]
Schedules API
Given a list of a sequence of waypoints and a vehicle the Schedules API returns the time schedule for the given list of vehicles that respect the given order of waypoints while minimizing the number of constraint violations if any and with the following list of priorities:
- minimize the violation of the vehicle time window;
- minimize the violation of the waypoint time windows;
- minimize the vehicle working time.
If the given sequence does violate some constraints, the secondary goal after minimizing their number is to minimize the entity of the violation, in terms of the sum of the amount of time in violation of some constraint.
Typical usage of this API consists of the three following steps for implementing a custom best-fit logic:
- optimize a plan, using the optimization API, with a given set of waypoints and vehicles. The optimizer find the best solution, that one with the minimum cost, among all the possible combination of waypoints and vehicles according to the given constraints;
- read the solution and try to change the position (reschedule) of some waypoints in the optimal routes, both within the same route and between two different routes (e.g. assign a waypoint from a position P1 in a route R1 to a position P2 in a route R2, where R1 and R2 could optionally be the same route);
- reschedule, using the schedule API, the new routes and check if exists a time schedule compliant with all the time windows using the new waypoints sequences.
Compute Schedules
curl -X POST ?key=AUTH_KEY \
"Content-Type: application/json" \
-d "@request.json"
curl -X POST /id/551?key=AUTH_KEY \
"Content-Type: application/json" \
-d "@request.json"
curl -X POST https://wwre.workwave.com/opt/v5/schedules/name/myMtx?key=AUTH_KEY \
"Content-Type: application/json" \
-d "@request.json"
Where request.json is a file containing the JSON data to be posted
POST https://wwre.workwave.com/opt/v5/schedules HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
Content-Type: application/json
POST https://wwre.workwave.com/opt/v5/schedules/id/551?key=AUTH_KEY HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
Content-Type: application/json
POST https://wwre.workwave.com/opt/v5/schedules/name/myMtx?key=AUTH_KEY HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
Content-Type: application/json
{
"schedules": [
{
"vehicle": {
"name": "Vehicle A",
"origin": {
"latitude": 42.35516,
"longitude": -71.76032
},
"timeCostModel": {
"drivingTimeCostFactor": 5000,
"serviceTimeCostFactor": 5000,
"idleTimeCostFactor": 5000,
"breakTimeCostFactor": 5000
},
"distanceCostFactor": 100,
"timeWindow": {
"startTimeSec": 40000,
"stopTimeSec": 80000
},
"destination": {
"latitude": 42.35516,
"longitude": -71.76032
}
},
"waypoints": [
{
"name": "wp 3",
"location": {
"latitude": 42.38246,
"longitude": -71.33345
},
"serviceTimeSec": 900
},
{
"name": "wp 2",
"location": {
"latitude": 42.4559,
"longitude": -71.52353
}
},
{
"name": "wp 1",
"location": {
"latitude": 42.53996,
"longitude": -71.41965
}
}
]
},
{
"vehicle": {
"name": "Vehicle B",
"origin": {
"latitude": 42.35516,
"longitude": -71.76032
},
"timeCostModel": {
"drivingTimeCostFactor": 5000,
"serviceTimeCostFactor": 5000,
"idleTimeCostFactor": 5000,
"breakTimeCostFactor": 5000
},
"distanceCostFactor": 100,
"timeWindow": {
"startTimeSec": 10000,
"stopTimeSec": 50000
},
"destination": {
"latitude": 42.35516,
"longitude": -71.76032
}
},
"waypoints": [
{
"name": "wp 7",
"location": {
"latitude": 42.32246,
"longitude": -71.31345
},
"serviceTimeSec": 900
},
{
"name": "wp 6",
"location": {
"latitude": 42.4159,
"longitude": -71.41353
}
},
{
"name": "wp 5",
"location": {
"latitude": 42.44996,
"longitude": -71.52965
}
},
{
"name": "wp 4",
"location": {
"latitude": 42.32516,
"longitude": -71.49032
}
}
]
}
]
}
The above command returns JSON structured like this:
Asynchronous response
{
"reqID": "a5bf25d3-8c00-4af6-af40-9c59532f5445",
"status": "PROCESSING",
"progress": 43,
"resultAvailable": false,
"queuePosition": 0
}
Synchronous response
{
"reqID": "a5bf25d3-8c00-4af6-af40-9c59532f5445",
"status": "COMPLETED",
"matrixID": -1,
"elapsedSec": 0,
"routes": [
{
"vehicle": {
"number": 0,
"name": "Vehicle A"
},
"routeStats": {
"breakTimeSec": 0,
"driveTimeSec": 8390,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 9290,
"distanceMt": 141991,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cost": 60649100,
"steps": [
{
"stepNumber": 0,
"waypoint": {
"name": "origin",
"number": -1
},
"latitude": 42.35516,
"longitude": -71.76032,
"timeWindow": {
"startTimeSec": 40000,
"stopTimeSec": 80000
},
"arrivalTimeSec": 0,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 40000,
"nextStepDriveTimeSec": 2961,
"nextStepDistanceMt": 45206,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 0,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 0,
"distanceMt": 0,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 1,
"waypoint": {
"name": "wp 3",
"number": 0
},
"latitude": 42.38246,
"longitude": -71.33345,
"arrivalTimeSec": 42961,
"idleTimeSec": 0,
"serviceStartTimeSec": 42961,
"departureTimeSec": 43861,
"nextStepDriveTimeSec": 1736,
"nextStepDistanceMt": 21809,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 2961,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 3861,
"distanceMt": 45206,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 2,
"waypoint": {
"name": "wp 2",
"number": 1
},
"latitude": 42.4559,
"longitude": -71.52353,
"arrivalTimeSec": 45597,
"idleTimeSec": 0,
"serviceStartTimeSec": 45597,
"departureTimeSec": 45597,
"nextStepDriveTimeSec": 1345,
"nextStepDistanceMt": 23763,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 4697,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 5597,
"distanceMt": 67015,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 3,
"waypoint": {
"name": "wp 1",
"number": 2
},
"latitude": 42.53996,
"longitude": -71.41965,
"arrivalTimeSec": 46942,
"idleTimeSec": 0,
"serviceStartTimeSec": 46942,
"departureTimeSec": 46942,
"nextStepDriveTimeSec": 2348,
"nextStepDistanceMt": 51213,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 6042,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 6942,
"distanceMt": 90778,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 4,
"waypoint": {
"name": "destination",
"number": -2
},
"latitude": 42.35516,
"longitude": -71.76032,
"arrivalTimeSec": 49290,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 49290,
"nextStepDriveTimeSec": 0,
"nextStepDistanceMt": 0,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 8390,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 9290,
"distanceMt": 141991,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
}
]
},
{
"vehicle": {
"number": 1,
"name": "Vehicle B"
},
"routeStats": {
"breakTimeSec": 0,
"driveTimeSec": 8969,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 9869,
"distanceMt": 159242,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cost": 65269200,
"steps": [
{
"stepNumber": 0,
"waypoint": {
"name": "origin",
"number": -1
},
"latitude": 42.35516,
"longitude": -71.76032,
"timeWindow": {
"startTimeSec": 10000,
"stopTimeSec": 50000
},
"arrivalTimeSec": 0,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 10000,
"nextStepDriveTimeSec": 2714,
"nextStepDistanceMt": 54840,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 0,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 0,
"distanceMt": 0,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 1,
"waypoint": {
"name": "wp 7",
"number": 0
},
"latitude": 42.32246,
"longitude": -71.31345,
"arrivalTimeSec": 12714,
"idleTimeSec": 0,
"serviceStartTimeSec": 12714,
"departureTimeSec": 13614,
"nextStepDriveTimeSec": 1357,
"nextStepDistanceMt": 18651,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 2714,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 3614,
"distanceMt": 54840,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 2,
"waypoint": {
"name": "wp 6",
"number": 1
},
"latitude": 42.4159,
"longitude": -71.41353,
"arrivalTimeSec": 14971,
"idleTimeSec": 0,
"serviceStartTimeSec": 14971,
"departureTimeSec": 14971,
"nextStepDriveTimeSec": 1177,
"nextStepDistanceMt": 13480,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 4071,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 4971,
"distanceMt": 73491,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 3,
"waypoint": {
"name": "wp 5",
"number": 2
},
"latitude": 42.44996,
"longitude": -71.52965,
"arrivalTimeSec": 16148,
"idleTimeSec": 0,
"serviceStartTimeSec": 16148,
"departureTimeSec": 16148,
"nextStepDriveTimeSec": 1888,
"nextStepDistanceMt": 35558,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 5248,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 6148,
"distanceMt": 86971,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 4,
"waypoint": {
"name": "wp 4",
"number": 3
},
"latitude": 42.32516,
"longitude": -71.49032,
"arrivalTimeSec": 18036,
"idleTimeSec": 0,
"serviceStartTimeSec": 18036,
"departureTimeSec": 18036,
"nextStepDriveTimeSec": 1833,
"nextStepDistanceMt": 36713,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 7136,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 8036,
"distanceMt": 122529,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 5,
"waypoint": {
"name": "destination",
"number": -2
},
"latitude": 42.35516,
"longitude": -71.76032,
"arrivalTimeSec": 19869,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 19869,
"nextStepDriveTimeSec": 0,
"nextStepDistanceMt": 0,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 8969,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 9869,
"distanceMt": 159242,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
}
]
}
],
"unreachedWaypoints": [],
"unreachableWaypoints": [],
"unneededVehicles": [],
"warnings": []
}
Perform a schedules request, that can refers or not a pre-generated matrix. If a request do not use a matrix (so called one-shot request), a distance/time matrix will be computed and, at the end of computation, deleted.
HTTP Request
One-Shot HTTP Request
POST https://wwre.workwave.com/opt/v5/schedules
Matrix Based HTTP Request
A matrix can be referred by name or matrix identification:
POST https://wwre.workwave.com/opt/v5/schedules/id/:matrixId
POST https://wwre.workwave.com/opt/v5/schedules/name/:matrixName
Execution Type
- Synchronous
- Asynchronous: this mode can be set on the request's body (see member async of SchedulesRequest.
Throttling
Leaky bucket (size: 60, refill: 5 per minute)
Path Parameters
Property | Type | Description |
---|---|---|
matrixId | Integer | Optional. The matrix identification, mutually exclusive with matrixName |
matrixName | String | Optional. The matrix name, mutually exclusive with matrixId |
Request Body
Return Value (synchronous)
Return Value (asynchronous)
Get Schedules
curl /12cqw4c1-8921-489a-azfc-b95460290362?key=AUTH_KEY
GET /12cqw4c1-8921-489a-azfc-b95460290362 HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
The above command returns JSON structured like this:
Schedules not yet compleated response
{
"reqID": "12cqw4c1-8921-489a-azfc-b95460290362",
"status": "PROCESSING",
"progress": 59,
"resultAvailable": false,
"queuePosition": 0
}
Schedules compleated response
{
"reqID": "12cqw4c1-8921-489a-azfc-b95460290362",
"status": "COMPLETED",
"matrixID": -1,
"elapsedSec": 0,
"routes": [
{
"vehicle": {
"number": 0,
"name": ""
},
"routeStats": {
"breakTimeSec": 0,
"driveTimeSec": 13275,
"idleTimeSec": 0,
"serviceTimeSec": 22500,
"workTimeSec": 35775,
"distanceMt": 97799,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cost": 35775,
"steps": [
{
"stepNumber": 0,
"waypoint": {
"name": "origin",
"number": -1
},
"latitude": 53.502015,
"longitude": -2.787013,
"timeWindow": {
"startTimeSec": 28800,
"stopTimeSec": 59400
},
"arrivalTimeSec": 0,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 28800,
"nextStepDriveTimeSec": 2731,
"nextStepDistanceMt": 26823,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 0,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 0,
"distanceMt": 0,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 1,
"waypoint": {
"name": "",
"number": 0
},
"latitude": 53.358782,
"longitude": -2.745783,
"timeWindow": {
"startTimeSec": 28800,
"stopTimeSec": 34200
},
"arrivalTimeSec": 31531,
"idleTimeSec": 0,
"serviceStartTimeSec": 31531,
"departureTimeSec": 32731,
"nextStepDriveTimeSec": 1388,
"nextStepDistanceMt": 3716,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 2731,
"idleTimeSec": 0,
"serviceTimeSec": 1200,
"workTimeSec": 3931,
"distanceMt": 26823,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 2,
"waypoint": {
"name": "",
"number": 1
},
"latitude": 53.377544,
"longitude": -2.764246,
"timeWindow": {
"startTimeSec": 32400,
"stopTimeSec": 39600
},
"arrivalTimeSec": 34119,
"idleTimeSec": 0,
"serviceStartTimeSec": 34119,
"departureTimeSec": 39819,
"nextStepDriveTimeSec": 700,
"nextStepDistanceMt": 1867,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 4119,
"idleTimeSec": 0,
"serviceTimeSec": 6900,
"workTimeSec": 11019,
"distanceMt": 30539,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 3,
"waypoint": {
"name": "",
"number": 2
},
"latitude": 53.373796,
"longitude": -2.758154,
"arrivalTimeSec": 40519,
"idleTimeSec": 0,
"serviceStartTimeSec": 40519,
"departureTimeSec": 41719,
"nextStepDriveTimeSec": 2904,
"nextStepDistanceMt": 23742,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 4819,
"idleTimeSec": 0,
"serviceTimeSec": 8100,
"workTimeSec": 12919,
"distanceMt": 32406,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
}
]
}
],
"unreachedWaypoints": [],
"unreachableWaypoints": [],
"unneededVehicles": [],
"warnings": []
}
Return the outcome or the status of a schedules request. The body returned by this invocation is identical to the one that would have been returned by a synchronous invocation, error responses included (in case the request failed for some reason).
If the schedules request is asynchronous and is not yet completed, the response is limited to the request identification and the status parameters.
HTTP Request
GET https://wwre.workwave.com/opt/v5/schedules/:reqId
Execution Type
Synchronous
Throttling
Leaky bucket (size: 60, refill: 5 per minute)
Path Parameters
Property | Type | Description |
---|---|---|
reqId | UUID | The request identification |
Return Value
- SchedulesResponse: if the schedules request has completed this endpoint will retrieve the complete result of its execution
- AsyncResponse: if the request is still queued or executing
Delete Schedules
curl –X DELETE https://wwre.workwave.com/opt/v5/optimization/96cb6dcb-3841-489a-bbdc-b95460290362?key=AUTH_KEY
curl –X DELETE https://wwre.workwave.com/opt/v5/optimization/96cb6dcb-3841-489a-bbdc-b95460290362?key=AUTH_KEY&keepResult=true
DELETE https://wwre.workwave.com/opt/v5/optimization/96cb6dcb-3841-489a-bbdc-b95460290362 HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
DELETE https://wwre.workwave.com/opt/v5/optimization/96cb6dcb-3841-489a-bbdc-b95460290362?keepResult=true HTTP/1.1
Accept: application/json
X-WorkWave-Key: AUTH_KEY
Host: wwre.workwave.com
If the request is already completed or canceled
{
"errorCode": -1102,
"errorDescription": "Can't abort request with ID [96cb6dcb-3841-489a-bbdc-b95460290362] that has already been completed"
}
Cancel an asynchronous schedules request.
If the request is queued will be removed from the queue, if the request is already completed or canceled a cancel command will be ignored (caller will be informed with a warning message), while if the request is processing will be forcefully terminated.
HTTP Request
DELETE https://wwre.workwave.com/opt/v5/schedules/:reqId[?keepResult=<Boolean>]
Execution Type
Synchronous
Throttling
Leaky bucket (size: 60, refill: 5 per minute)
Path Parameters
Property | Type | Description |
---|---|---|
reqId | UUID | The request identification |
QueryString Parameters
Property | Type | Description |
---|---|---|
keepResult | Boolean | Default to false. If true, the request is cancelled but current result (if available) is provided as a schedules result, this could be not the best possible result for the provided input. |
Return Value
[Empty Response Body]
Advanced Scenarios
Below few advanced scenarios and topics that can be model with the optimization API.
Flexibile Time-Windowed Traffic
A request example with the use of flexible traffic management. See Single-Day Optimization API and Multi-Day Optimization API for details.
{
"traffic": {
"trafficTimeWindows": [
{
"startTimeSec": 36000,
"stopTimeSec": 39600
},
{
"startTimeSec": 46000,
"stopTimeSec": 49600
}
],
"trafficProfiles": {
"holiday": {
"trafficRegions": [
{
"region": [
"..."
],
"trafficFactor": 1,
"twTrafficFactors": [
1.5,
2.0
]
}
],
"baseTrafficFactor": 1
},
"weekday": {
"trafficRegions": [
{
"region": [
"..."
],
"trafficFactor": 1.7,
"twTrafficFactors": [
2.8,
4.5
]
}
],
"baseTrafficFactor": 1.5
}
}
},
"vehicles": [
{
"name": "Vehicle A",
"daySettings": {
// a friday
"1": {
"trafficProfile": "weekday",
"// ...": null
},
// a saturday
"2": {
"trafficProfile": "holiday",
"// ...": null
}
}
}
],
"waypoints": [
"..."
]
}
The API allows multiple Traffic Profiles to be defined and individually assigned to vehicles or, when using the multiday endpoint, to vehicle-day pairs. This enables modeling multiday scenarios with horizons spanning both week days and holidays where traffic is shaped differently according to the day of the week. Take a look of the example on the right panel.
Minimum Requirements
A request example with that use Minimum Requirements. See Vehicle object for details.
{
"vehicles": [
{
"name": "Van #1",
"daySettings": {
"1": {
"minCapacityMap": {
"pounds": 10_000,
"visitedWaypoints": 15
},
"minWorkingTimeSec": 34000,
// more vehicle settings
...
}
}
},
// more vehicles
...
],
"waypoints": [...]
}
Minimum Requirements (MR) are a set of "best effort" minimum acceptable constraints that can be defined into a vehicle object for a route to be acceptable/valid:
- minimum delivered loads
- minimum number of visited waypoints
- minimum total time worked (from departure to arrival)
- minimum driven miles
These are not hard constraints but they are a "best effort", meaning that they can be violated if by doing so results if better optimization results (i.e.: less costly solution).
By their nature MR work at their best:
- in scenarios where resources are not saturated (leaving room to redistribute waypoints so as to comply with MR constraints)
- when only one category of MR is requested: either loads or time. Specifying both MRs must be pondered based on the scenario being optimized: more often than not specifying both leads to contradicting requirements (e.g.: complying with minimum loads would produce routes that violate the minimum working time, and vice versa).
Reloading at Depots
A request example with Pickups/Dropoffs and loads.
{
"vehicles": [
{
"name": "ve1",
"maxCapacityMap": {
"refrigerators": 3,
"ovens": 2
},
"origin": {
"latitude": 42.35516,
"longitude": -71.76032
},
"timeWindow": {
"startTimeSec": 27000,
"stopTimeSec": 121000
},
"destination": {
"latitude": 42.35516,
"longitude": -71.76032
}
}
],
"waypoints": [
{
"name": "dropoff1",
"location": {
"latitude": 42.38246,
"longitude": -71.33345
}
},
{
"name": "pickup1",
"location": {
"latitude": 42.53996,
"longitude": -71.41965
},
"dropoffNumber": 0,
"pickupMap": {
"refrigerators": 2
},
"serviceTimeSec": 300,
"timeWindows": [
{
"startTimeSec": 28800,
"stopTimeSec": 43200
},
{
"startTimeSec": 46800,
"stopTimeSec": 61200
}
]
},
{
"name": "dropoff1",
"location": {
"latitude": 42.38246,
"longitude": -71.33345
}
},
{
"name": "pickup2",
"location": {
"latitude": 42.44266,
"longitude": -71.52767
},
"dropoffNumber": 2,
"pickupMap": {
"refrigerators": 2
},
"serviceTimeSec": 900,
"timeWindows": [
{
"startTimeSec": 28800,
"stopTimeSec": 43200
},
{
"startTimeSec": 46800,
"stopTimeSec": 61200
}
]
},
{
"name": "dropoff2",
"location": {
"latitude": 42.48246,
"longitude": -71.23421
},
"deliveryMap": {
"refrigerators": 1,
"ovens": 1
}
},
{
"name": "pickup3",
"location": {
"latitude": 42.45829,
"longitude": -71.69517
},
"dropoffNumber": 4,
"pickupMap": {
"refrigerators": 1,
"oven": 1
},
"serviceTimeSec": 1200,
"timeWindows": [
{
"startTimeSec": 28800,
"stopTimeSec": 43200
},
{
"startTimeSec": 46800,
"stopTimeSec": 61200
}
]
}
]
}
Scenarios where vehicles have a limited load capacity but plenty of working time and may require returning to a depot one or more times through the course of their route to reload.
These scenarios can be modeled using the existing Pickup&Delivery (P&D) constraints. Multiple deliveries where all items to be delivered are stored at a central depot can model each delivery as two waypoints: one pickup waypoint located at the depot and one delivery waypoint, linked to its pickup, at the actual delivery destination.
Existing P&D heuristics have been extended to also handle reload scenarios where there is typically a multitude of waypoints sharing the same location (the depot or depots).
There are typically two Reload scenarios:
- pickups are at one or more depots, deliveries are spread out on the territory (e.g. food delivery)
- pickups are spread out on the territory, deliveries are at one or more depots (e.g. waste collection)
Clustering
Clusters may be used to model several situations in which the driving times and the costs associated with the vehicles are not enough to grasp all the complexities that occur in real-world logistic problems. Both waypoints (see Cluster object) and vehicle origin / destination depot (see members originClusters and destinationClusters in Vehicle object) can belong to one or more clusters.
Clustering Overview
When it needs to determine the driving times and the costs associated with the route from a point P (the vehicle origin depot or a waypoint) to another point Q (a waypoint or the vehicle destination depot) or the service time associated with Q when it is preceded by P, the Routing Engine applies the following rules:
- Determines KQ, the set of clusters to which Q belongs.
- Determines KP, the set of clusters to which P belongs.
- Defines the difference set O = KP \ KQ as the old clusters.
- Defines the difference set N = KQ \ KP as the new clusters.
- Sets OUTtime and OUTcost are defined by collecting respectively the values exitTimeSec and exitCost of the clusters contained in O.
- Sets INtime, INcost and INsetup are defined by collecting respectively the values enterTimeSec, enterTimeCost and setupTimeSec of clusters contained in N.
- The driving time associated with route P→Q is incremented by a value equal to TIN(INtime) + TOUT(OUTtime) where TIN and TOUT are equal to the sum function by default and can be modified by setting, respectively, the members enterTime and exitTime of the intersectionFunctions object (see Clustering).
- The cluster cost associated with route P→Q is incremented by a value equal to CIN(INcost) + COUT(OUTcost) where CIN and COUT are equal to the sum function by default and can be modified by setting, respectively, the member enterCost and enterTime of the intersectionFunctions object (see Clustering).
- The service time associated with Q, when P is its immediate predecessor in a route, is incremented by a value equal to S(INsetup) where S is equal to the sum function by default and can be modified by setting the member setupTime of the intersectionFunctions object (see Clustering).
- If at least one cluster in N has member requireVehicleStop equal to true the number of unique stops associated with the vehicle is incremented by one and the service time associated with Q, when P is its immediate predecessor in a route is incremented by the value of member perStopSetupTimeSec of the vehicle associated with the route (see Vehicle).
Note: in any case a vehicle will stop before serving each waypoint that doesn’t belong to any cluster.
Note that the increment in driving/service time related to the application of previous rules will not impact on computation of driving time and service time during the route cost computation described in section Optimization Goals (in order to modify route cost using clusters you need to correctly set the enterCost and exitCost members of your clusters, see objects Clustering and Vehicle).
Clustering scenario
A request example that models the problem using clusters
{
"clustering": {
"clusters": {
"cluster 1": {
"enterCost": 100,
"exitCost": 200,
"setupTimeSec": 60
},
"cluster 2": {
"setupCost": 100,
"setupTimeSec": 120,
"enterTimeSec": 100,
"exitTimeSec": 200
},
"cluster 3": {
"enterCost": 100,
"exitCost": 50,
"requireVehicleStop": true
}
},
"intersectionFunctions": {
"enterTime": "SUM",
"exitTime": "AVG",
"enterCost": "MIN",
"exitCost": "MAX"
}
},
"vehicles": [
{
"name": "Vehicle A",
"daySettings": {
"1": {
"originClusters": [
"cluster 1"
],
"destinationClusters": [
"cluster 2"
]
}
}
}
],
"waypoints": [
{
"name": "wp 1",
"clusters": [
"cluster 1"
],
// ...
},
{
"name": "wp 2",
"clusters": [
"cluster 2",
"cluster 3"
],
// ...
},
// ...
]
}
This feature allows clustering waypoints together and applying driving time and cost penalties for vehicles entering or exiting the cluster.
Entering a cluster means driving from a waypoint that does not belong to the cluster to a waypoint that belongs to the cluster. Vice versa for exiting a cluster.
Clusters are not (necessarily) geographical entities, they are abstract grouping entities.
A cluster defines the following properties:
- enter cost: cost to be factored in every time the vehicle "enters" the cluster
- exit cost: cost to be factored in every time the vehicle "exits" the cluster
- enter time: additional driving time to be factored in every time the vehicle "enters" the cluster
- exit time: additional driving time to be factored in every time the vehicle "exits" the cluster
- setup time: additional service time to be factored in every time the vehicle "enters" the cluster
Clustering helps model scenarios where it is desirable that a vehicle driving to a certain area stays there serving all nearby waypoints, possibly waiting for a time window to open rather then driving back and forth between different areas to avoid idle time because moving between areas is costly in terms of tolls or driving time.
Clustering also helps model Reload scenarios where reloading at depots incurs a fixed setup time & cost which is unrelated to the number/amount of goods that are loaded (e.g. fixed time required to dock a truck):
- Clustering needs not be geographic: e.g. 2 types of services (say "laying rat traps" and "spraying chemicals") where switching from one type of service to the other requires a setup time, so it's desirable to first do all "lay trap" services and then all the "spraying"
- Clusters can overlap, meaning that any given waypoint can belong to N clusters
- Vehicles' origins and end destinations can also be associated to one or more clusters
- Origin -> 1: no penalties
- 1 -> 2: no penalties
- 2 -> 3: B's enter time&cost
- 3 -> 4: A's exit time&cost
- 4 -> 5: B's exit time&cost
- 5 -> 6: C's enter time&cost
- 6 -> Destination: C's exit time&cost
- Origin -> Deposit : R's setup time&cost
- Deposit -> 1 : no penalties
- 1 -> 2 : no penalties
- 2 -> 3 : no penalties
- 3 -> Depot : R's setup time&cost
- Depot -> 4 : no penalties
- 4 -> 5 : no penalties
- 5 -> 6 : no penalties
- 6 -> Destination : no penalties
Road Segment Exceptions
Request format with segment exceptions
{
"routings": {
"default": {
"exceptions": [{
"start": {...},
"end": {...},
// specify either
"malus": 8, // valid range [-10, 10]
// or
"additionalDrivingTimeSec": 1800
},
//... more exceptions
]
}
},
// ...
}
Another example for blocking bridge crossing
{
"routings": {
"default": {
"exceptions": [
// ban Champlain bridge
{
"start": { "latitude": 45.471807, "longitude": -73.520317 },
"end": { "latitude": 45.464674, "longitude": -73.520103 },
"malus": 10
},
// crossing Victoria bridge incurs a 30mins driving time penalty
{
"start": { "latitude": 45.494071, "longitude": -73.533081 },
"end": { "latitude": 45.488531, "longitude": -73.528191 },
"additionalDrivingTimeSec": 1800
},
// strongly discourage using Tunnel Louis-Hippolyte
{
"start": { "latitude": 45.585302, "longitude": -73.500884 },
"end": { "latitude": 45.582266, "longitude": -73.501701 },
"malus": 8
}
]
}
},
"vehicles": [...],
"waypoints": [...],
// ... rest of the optimization request here
}
The exception segments drawn on the map by the exception above:
Directly affects routing (i.e.: how driving and mileage matrices are computed) and helps model the following scenarios:
- block one or more streets / bridges / tunnels
- encourage or discourage routing on some streets / bridges / tunnels
- e.g.: a user might prefer for his vehicles to cross the river using bridge A over bridge B
- e.g.: a user might prefer for his vehicles not to use a certain parkway
- factor in additional driving time when traveling on certain road segments
- (e.g.: add 20 minutes of driving time when crossing the Lincol Tunnel and/or Verrazano Bridge)
Each Exception object must have both start and end coordinates and either a malus or an additionalDrivingTimeSec parameter.
malus ranges from -10 to 10 where:
- negative values "encourage" routing on intersected road segments
- positive values "discourage" routing on intersected road segments
- setting malus to 10 bans/blocks intersected road segments
- additionalDrivingTimeSec and malus cannot work together. If "additionalDrivingTimeSec" is specified then "malus" is ignored.
Multiple Waypoint Choice
A request example with Multiple Waypoint Choice: one vehicle, one delivery and 4 multiple choice pickups that have different locations and time windows.
See field mcRefNumber at Waypoint object for details.
{
"vehicles": [
{
"name": "ve1",
"origin": {
"latitude": 42.35516,
"longitude": -71.76032
},
"destination": {
"latitude": 42.35516,
"longitude": -71.76032
}
}
],
"waypoints": [
{
"name": "delivery",
"location": {
"latitude": 42.38246,
"longitude": -71.33345
}
},
{
"name": "pickup-original",
"location": {
"latitude": 42.53996,
"longitude": -71.41965
},
"serviceTimeSec": 300,
"dropoffNumber": 0,
"timeWindows": [
{
"startTimeSec": 28800,
"stopTimeSec": 43200
},
{
"startTimeSec": 46800,
"stopTimeSec": 61200
}
]
},
{
"name": "pickup-mc1",
"location": {
"latitude": 42.53996,
"longitude": -71.41965
},
"serviceTimeSec": 100,
"dropoffNumber": 0,
"mcRefNumber": 1,
"timeWindows": [
{
"startTimeSec": 38800,
"stopTimeSec": 53200
}
]
},
{
"name": "pickup-mc2",
"location": {
"latitude": 42.44266,
"longitude": -71.52767
},
"serviceTimeSec": 500,
"dropoffNumber": 0,
"mcRefNumber": 1,
"timeWindows": [
{
"startTimeSec": 28800,
"stopTimeSec": 43200
},
{
"startTimeSec": 46800,
"stopTimeSec": 61200
}
]
},
{
"name": "pickup-mc3",
"location": {
"latitude": 42.48246,
"longitude": -71.23421
},
"serviceTimeSec": 300,
"dropoffNumber": 0,
"mcRefNumber": 1,
"timeWindows": [
{
"startTimeSec": 13800,
"stopTimeSec": 23200
},
{
"startTimeSec": 36800,
"stopTimeSec": 45200
},
{
"startTimeSec": 56800,
"stopTimeSec": 64200
}
]
}
]
}
The Multiple Waypoint Choice is a feature that allows creating multiple variants of a waypoint and let the solver choose the best (minimizing the solution cost) one to serve.
This feature can be used to model the following scenarios:
- Orders that can be served at certain times on certain days and at different times on other days
- e.g. a customer that can be served between 2pm and 4pm on Friday or between 10am and 11am on Saturday
- Reload scenarios where there are multiple equivalent depots and where it's best to let the algorithm pick the best one to go to to reload
- e.g. fuel delivery where the truck can refill from several depots and it's best to go reload from the one closest to the current location
- e.g. waste collection where the truck can empty at several landfills and it's best to pick the one closest to the current location
- A combination of the two scenarios above
- e.g a reload scenario with multiple equivalent pickup depots where the delivery can happen at different time windows on different days
Positional priorities
In a bus ride, with adults and children, there should be at least one adult when the ride starts and one adult when the ride ends.
See fields selectAmongFirst and selectAmongLast at Vehicle object for details.
See fields amongFirst and amongLast at Waypoint object for details.
{
"vehicles": [
{
"name": "Bus",
"origin": {
"latitude": 45.52745,
"longitude": 9.51652
},
"destination": {
"latitude": 45.52745,
"longitude": 9.51652
},
"selectAmongFirst": true,
"selectAmongLast": true
}
],
"waypoints": [
{
"name": "adult 1 dropoff",
"location": {
"latitude": 45.48246,
"longitude": 9.23345
},
"amongLast": true
},
{
"name": "adult 1 pickup",
"location": {
"latitude": 45.48246,
"longitude": 9.23345
},
"amongFirst": true,
"dropoffNumber": 0
},
{
"name": "adult 2 dropoff",
"location": {
"latitude": 45.48246,
"longitude": 9.23345
},
"amongLast": true
},
{
"name": "adult 2 pickup",
"location": {
"latitude": 45.5559,
"longitude": 9.02353
},
"amongFirst": true,
"dropoffNumber": 2
},
{
"name": "adult 3 dropoff",
"location": {
"latitude": 45.48246,
"longitude": 9.23345
},
"amongLast": true
},
{
"name": "adult 3 pickup",
"location": {
"latitude": 45.48246,
"longitude": 9.23345
},
"amongFirst": true,
"dropoffNumber": 4
},
{
"name": "child 1 dropoff",
"location": {
"latitude": 45.48246,
"longitude": 9.23345
}
},
{
"name": "child 1 pickup",
"location": {
"latitude": 45.7559,
"longitude": 9.12353
},
"dropoffNumber": 6
},
{
"name": "child 2 dropoff",
"location": {
"latitude": 45.48246,
"longitude": 9.23345
}
},
{
"name": "child 2 pickup",
"location": {
"latitude": 45.8559,
"longitude": 9.22353
},
"dropoffNumber": 8
},
{
"name": "child 3 dropoff",
"location": {
"latitude": 45.48246,
"longitude": 9.23345
}
},
{
"name": "child 3 pickup",
"location": {
"latitude": 45.5559,
"longitude": 9.02353
},
"dropoffNumber": 10
}
]
}
This feature allows a customer to have better management of the position within a route (sequence) that the algorithm computes for each waypoint.
- A waypoint can be forced to be the first or the last element of its route
- A vehicle can be forced to pick the first or the last waypoint of its route within a specific group of waypoints
- Each waypoint can be provided with a “priority value” (soft constraint) that states how much it is important to serve that waypoint near the beginning of the route
Manage cached matrices
The Routing Engine (RE), called using a matrix based HTTP request (see section Matrix Based HTTP Request for optimization and schedule requests), automatically caches, evolves and manages computed matrices transparently to users.
Matrix cache mechanism
Caching a distance/travel time matrix boosts performance because the RE does not need to recompute the whole matrix from scratch for a subsequent request in the same region; instead, the RE uses the cached version as-is, or simply extends it by adding only the missing locations, thus minimizing the computation time that each subsequent request would incur.
Typically, users do not need to manage the cached matrices or extend them by adding missing locations; this is done by the RE, determining which locations are missing, comparing them to the input request, and extending the cached matrix with those locations. So, when an optimization or a schedule request reference a cached matrix (e.g., calling URLs like /opt/v5/optimization/name/myMatrix
or /opt/v5/optimization/id/2412312
), the RE automatically adapts the cached matrix by adding or removing locations along with their travel times and distances.
Optimization and schedule requests use different logic for automatically evolving the underlying cached matrix:
- optimization: the matrix is always adapted to fit the available locations of the last request. Routing Engine will use those locations that are present in the request and not in the cached matrix to extend it, while locations present in the matrix that are not in the request will be removed;
- schedule: every time a schedule request uses a cached matrix the Routing Engine adds the missing locations and persists the matrix with the new locations. If new locations are added to a schedule request, that matrix will grow, as will the time needed to extend it. Schedule requests do not remove locations from stored matrices.
Advanced cache control
A simple example of a request with
mtxLocs
andephemeralLocs
:
{
"vehicles": [...],
"waypoints": [...],
"traffic": {...},
"mtxLocs": [
//[latitude, longitude]
[45.29824, -75.57652],
[45.43171, -75.6545],
[45.40042, -75.73016],
...
],
"ephemeralLocs": [
//[latitude, longitude]
[45.19224, -75.27221],
[45.21723, -75.8931],
...
],
(rest of the request)
}
Advanced users sometimes need more control over the matrix caching mechanism, to be sure that, for example, few locations are always available from the cached matrix and must not be removed or that, on the contrary, some locations do not need to be saved in the cached matrix. On optimizations and schedules API v5 we introduced the following parameters:
mtxLocs
: an optional list of couples of (latitude, longitude) that holds the locations that must not be removed from the referenced cached matrix;ephemeralLocs
: an optional list of couples (latitude, longitude) for the locations that must not be included when persisting a cached matrix
Their syntax is more succinct than the waypoint object format to avoid over bloating requests when many locations are involved. Both latitude and longitude values must be decimal and serialized with the decimal separator. For example -45.123450 is correct, whereas -45123450 is not.
If we have truncation logic that is only active for some parts of the request it might happen that, say, a latitude is passed as -45.120000 when embedded in a waypoint
object or a vehicle
object and as -45.1200000000000001 when passed inside mtxLocs
, because of floating-point math rules. Since they are treated as different values the truncated one (e.g. -45.120000) will be dropped from the cached matrix on subsequent requests. We always suggest truncate both latitude and longitude to 6-decimal digits (accuracy is down to centimeters, so that should be more than enough) before passing them to the Routing Engine.
Scenarios
The following are a list of scenarios that could be helpful to explain how the matrix management logic works and how we can use mtxLocs
and ephemeralLocs
to have granular control over the cached matrix mechanism.
The advanced cache control works only when optimization/schedules request reference matrices by name or by id from the URL parameter (e.g. POST /opt/v5/optimization/name/myMatrixName
or POST /opt/v5/schedules/id/2412312
).
Full Optimization
A full optimization is an optimization request that contains the whole plan, so all the locations from the list of waypoints that need to be served and the vehicles that can be used to serve them. In this case, the best approach is to let the Routing Engine adapt the matrix, extending or shrinking it as needed.
Schedule a single route
Use case: after an optimization we need to (re)schedule just a route adding, removing or changing the order of few waypoints using the /schedules
REST endpoint, leveraging the pre-computed and cached matrix but without trashing it, i.e. throwing away everything except the currently scheduled route’s waypoints.
In this case, we don’t need to do anything special besides invoking the schedules request passing the appropriate matrix, e.g. POST /schedules/id/{mtxId}
. The Routing Engine is smart enough not to trash the matrix and will also extend the cached matrix adding any missing location found in the schedule request. Please note that by reusing the same matrix for schedule requests where each request includes new locations the matrix will keep growing, ultimately slowing down matrix extensions.
Optimize a subset of the original problem (reschedule or partial optimization)
Suppose we have a simple optimization with 5 waypoints (wp1, wp2, wp3, wp4 and wp5) and 2 vehicles (ve1 and ve2). The optimization endpoint is called using a cached matrix with
POST https://wwre.workwave.com/opt/v5/optimization/name/cachematrixtest
, if the matrixcachematrixtest
does not exist the Routing Engine will create it and link it to the key used for calling the API.
{
"vehicles": [
{
"name": "ve1",
"origin": {
"latitude": 45.52745,
"longitude": 9.51652
},
"destination": {
"latitude": 45.52745,
"longitude": 9.51652
},
"timeWindow": {
"startTimeSec": 27000,
"stopTimeSec": 73800
}
},
{
"name": "ve2",
"origin": {
"latitude": 45.45516,
"longitude": 8.86032
},
"destination": {
"latitude": 45.45516,
"longitude": 8.86032
},
"timeWindow": {
"startTimeSec": 27000,
"stopTimeSec": 73800
}
}
],
"waypoints": [
{
"name": "wp1",
"location": {
"latitude": 45.48246,
"longitude": 9.23345
},
"serviceTimeSec": 900,
"timeWindows": [
{
"startTimeSec": 54000,
"stopTimeSec": 86400
}
]
},
{
"name": "wp2",
"location": {
"latitude": 45.5559,
"longitude": 9.02353
},
"serviceTimeSec": 900,
"timeWindows": [
{
"startTimeSec": 46800,
"stopTimeSec": 61200
}
]
},
{
"name": "wp3",
"location": {
"latitude": 45.63996,
"longitude": 9.11965
},
"serviceTimeSec": 900,
"timeWindows": [
{
"startTimeSec": 28800,
"stopTimeSec": 43200
}
]
},
{
"name": "wp4",
"location": {
"latitude": 45.54266,
"longitude": 9.02767
},
"serviceTimeSec": 900,
"timeWindows": [
{
"startTimeSec": 28800,
"stopTimeSec": 43200
},
{
"startTimeSec": 46800,
"stopTimeSec": 61200
}
]
},
{
"name": "wp5",
"location": {
"latitude": 45.55829,
"longitude": 8.99517
},
"serviceTimeSec": 900,
"timeWindows": [
{
"startTimeSec": 28800,
"stopTimeSec": 43200
},
{
"startTimeSec": 46800,
"stopTimeSec": 61200
}
]
}
]
}
The resulting distance and travel time matrix will contain locations for waypoints wp1, wp2, wp3, wp4 and wp5, and also origin/destination locations for vehicle ve1 and ve2, so the corresponding cached matrix contains 7 locations (origin and destination locations are the same). As you can see from the response here below waypoints wp3, wp2, wp5 and wp4 are assigned to vehicle ve2 and wp1 to ve1. Please note that the answer could be slightly different depending on the map release used to compute the distance/travel time matrix and the particular version of the solver used to solve it.
{
"reqID": "12345678-7ffd-41f7-bb93-087a7d923fac",
"status": "COMPLETED",
"matrixID": 1,
"elapsedSec": 0,
"routes": [
{
"vehicle": {
"number": 1,
"name": "ve2"
},
"routeStats": {
"breakTimeSec": 0,
"driveTimeSec": 6866,
"idleTimeSec": 1090,
"serviceTimeSec": 3600,
"workTimeSec": 11556,
"distanceMt": 103382,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cost": 11556,
"steps": [
{
"stepNumber": 0,
"waypoint": {
"name": "origin",
"number": -1
},
"latitude": 45.45516,
"longitude": 8.86032,
"timeWindow": {
"startTimeSec": 27000,
"stopTimeSec": 73800
},
"arrivalTimeSec": 0,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 40401,
"nextStepDriveTimeSec": 2799,
"nextStepDistanceMt": 47925,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 0,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 0,
"distanceMt": 0,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 1,
"waypoint": {
"name": "wp3",
"number": 2
},
"latitude": 45.63996,
"longitude": 9.11965,
"timeWindow": {
"startTimeSec": 28800,
"stopTimeSec": 43200
},
"arrivalTimeSec": 43200,
"idleTimeSec": 0,
"serviceStartTimeSec": 43200,
"departureTimeSec": 44100,
"nextStepDriveTimeSec": 1610,
"nextStepDistanceMt": 19954,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 2799,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 3699,
"distanceMt": 47925,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 2,
"waypoint": {
"name": "wp2",
"number": 1
},
"latitude": 45.5559,
"longitude": 9.02353,
"timeWindow": {
"startTimeSec": 46800,
"stopTimeSec": 61200
},
"arrivalTimeSec": 45710,
"idleTimeSec": 1090,
"serviceStartTimeSec": 46800,
"departureTimeSec": 47700,
"nextStepDriveTimeSec": 478,
"nextStepDistanceMt": 3267,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 4409,
"idleTimeSec": 1090,
"serviceTimeSec": 1800,
"workTimeSec": 7299,
"distanceMt": 67879,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 3,
"waypoint": {
"name": "wp5",
"number": 4
},
"latitude": 45.55829,
"longitude": 8.99517,
"timeWindow": {
"startTimeSec": 46800,
"stopTimeSec": 61200
},
"arrivalTimeSec": 48178,
"idleTimeSec": 0,
"serviceStartTimeSec": 48178,
"departureTimeSec": 49078,
"nextStepDriveTimeSec": 521,
"nextStepDistanceMt": 4692,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 4887,
"idleTimeSec": 1090,
"serviceTimeSec": 2700,
"workTimeSec": 8677,
"distanceMt": 71146,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 4,
"waypoint": {
"name": "wp4",
"number": 3
},
"latitude": 45.54266,
"longitude": 9.02767,
"timeWindow": {
"startTimeSec": 46800,
"stopTimeSec": 61200
},
"arrivalTimeSec": 49599,
"idleTimeSec": 0,
"serviceStartTimeSec": 49599,
"departureTimeSec": 50499,
"nextStepDriveTimeSec": 1458,
"nextStepDistanceMt": 27544,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 5408,
"idleTimeSec": 1090,
"serviceTimeSec": 3600,
"workTimeSec": 10098,
"distanceMt": 75838,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 5,
"waypoint": {
"name": "destination",
"number": -2
},
"latitude": 45.45516,
"longitude": 8.86032,
"arrivalTimeSec": 51957,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 51957,
"nextStepDriveTimeSec": 0,
"nextStepDistanceMt": 0,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 6866,
"idleTimeSec": 1090,
"serviceTimeSec": 3600,
"workTimeSec": 11556,
"distanceMt": 103382,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
}
]
},
{
"vehicle": {
"number": 0,
"name": "ve1"
},
"routeStats": {
"breakTimeSec": 0,
"driveTimeSec": 3450,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 4350,
"distanceMt": 52174,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cost": 4350,
"steps": [
{
"stepNumber": 0,
"waypoint": {
"name": "origin",
"number": -1
},
"latitude": 45.52745,
"longitude": 9.51652,
"timeWindow": {
"startTimeSec": 27000,
"stopTimeSec": 73800
},
"arrivalTimeSec": 0,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 52194,
"nextStepDriveTimeSec": 1806,
"nextStepDistanceMt": 26760,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 0,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 0,
"distanceMt": 0,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 1,
"waypoint": {
"name": "wp1",
"number": 0
},
"latitude": 45.48246,
"longitude": 9.23345,
"timeWindow": {
"startTimeSec": 54000,
"stopTimeSec": 86400
},
"arrivalTimeSec": 54000,
"idleTimeSec": 0,
"serviceStartTimeSec": 54000,
"departureTimeSec": 54900,
"nextStepDriveTimeSec": 1644,
"nextStepDistanceMt": 25414,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 1806,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 2706,
"distanceMt": 26760,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 2,
"waypoint": {
"name": "destination",
"number": -2
},
"latitude": 45.52745,
"longitude": 9.51652,
"arrivalTimeSec": 56544,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 56544,
"nextStepDriveTimeSec": 0,
"nextStepDistanceMt": 0,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 3450,
"idleTimeSec": 0,
"serviceTimeSec": 900,
"workTimeSec": 4350,
"distanceMt": 52174,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
}
]
}
],
"unreachedWaypoints": [],
"unreachableWaypoints": [],
"unneededVehicles": [],
"warnings": []
}
Suppose that now we have a new waypoint wp6 that we want to assign to vehicle ve1 (that has already the waypoint wp1). The vehicle has not started his trip so it does not matter if the new waypoint is placed before or after wp1, so an optimization request will contain just those waypoints that we need will be ok. To improve performance we want to reuse the cached matrix
cachematrixtest
, but doing the request considering just vehicle ve1, waypoints wp1 and wp6 calling the same endpoint as before (POST https://wwre.workwave.com/opt/v5/optimization/name/cachematrixtest
) means that the resulting matrix will be pruned from locations of waypoints wp2-wp5 and origin/destination of vehicle ve2.To keep all the locations in the matrix we need to use the parameter
mtxLocs
in the second optimization request, this will avoid losing locations from the matrix that instead we want to keep in it.
{
"vehicles": [
{
"name": "ve1",
"origin": {
"latitude": 45.52745,
"longitude": 9.51652
},
"destination": {
"latitude": 45.52745,
"longitude": 9.51652
},
"timeWindow": {
"startTimeSec": 27000,
"stopTimeSec": 73800
}
}
],
"waypoints": [
{
"name": "wp1",
"location": {
"latitude": 45.48246,
"longitude": 9.23345
},
"serviceTimeSec": 900,
"timeWindows": [
{
"startTimeSec": 54000,
"stopTimeSec": 86400
}
]
},
{
"name": "wp6",
"location": {
"latitude": 45.49921,
"longitude": 9.37854
},
"serviceTimeSec": 300,
"timeWindows": [
{
"startTimeSec": 28800,
"stopTimeSec": 43200
},
{
"startTimeSec": 46800,
"stopTimeSec": 61200
}
]
}
],
"mtxLocs": [
[45.52745,9.51652],//ve1
[45.45516,8.86032],//ve2
[45.48246,9.23345],//wp1
[45.5559,9.02353], //wp2
[45.63996,9.11965],//wp3
[45.54266,9.02767],//wp4
[45.55829,8.99517],//wp5
[45.49921,9.37854] //wp6
]
}
After this second optimization request the resulting matrix will contain locations for waypoints wp1, wp2, wp3, wp4, wp5 and wp6, and also origin/destination locations for vehicle ve1 and ve2, so the cached matrix contains 8 locations. While if we had not used the parameter
mtxLocs
the matrixcachematrixtest
would only contain location for wp1, wp6 ad origin/destination of vehicle ve1, removing all unnecessary locations.
Use case: after a full optimization (e.g. a full week of delivery/services) we need to (re)optimize a subset of the original problem (say, one single day of the initial full week, with 3000 locations from the original request) leveraging the pre-computed matrix but without trashing it or pruning locations from it (we do not want a 2 waypoints optimization to purge the remaining 2998 locations from our cached matrix).
In this case, we can use the mtxLocs
parameter providing hints about which locations we don’t want to be pruned from the cached matrix. The mtxLocs
list in the request tells the Routing Engine not to remove the listed locations from the cached matrix, even if they are not referenced by waypoints/vehicles in the optimization/schedule request.
Typically a customer starts with a week’s worth of orders, likely optimizes everything (the matrix is built based on the full optimization request), then they need to reoptimize, tweak, or reschedule only parts of the whole original problem (and the mtxLocs
is helpful in this case). Then a day goes by and all served waypoints (with their locations) are removed from the equation and new waypoints (locations) come in for the next 24 hours, and so on and so forth.
In this scenario, the user knows the complete list of locations they’re dealing with (making up the whole active problem) so it passes them in the mtxLocs
array to prevent damaging pruning of locations. The served waypoints and their locations will not be part of the active problem, thus not be added to mtxLocs and consequently removed from the cached matrix at the next optimization event (these are what we call “rolling” matrices, because are constantly adding new locations while keeping those that still to be served).
Ephemeral locations with schedule requests
Suppose we have a simple initial optimization with 4 waypoints (wp1, wp2, wp3, wp4 and wp5) and 2 vehicles (ve1 and ve2). For semplicity we use tags to forcibly assign waypoints wp1 and wp2 to vehicle ve1, and vehicle ve2 to serve wp3 and wp4. The optimization endpoint is called using a cached matrix with
POST https://wwre.workwave.com/opt/v5/optimization/name/cachematrixtest
, if the matrixcachematrixtest
does not exist the Routing Engine will create it and link it to the key used for calling the API.
{
"vehicles": [
{
"name": "ve1",
"origin": {
"latitude": 45.52745,
"longitude": 9.51652
},
"destination": {
"latitude": 45.52745,
"longitude": 9.51652
},
"timeWindow": {
"startTimeSec": 27000,
"stopTimeSec": 73800
},
"tags": ["ve1"]
},
{
"name": "ve2",
"origin": {
"latitude": 45.45516,
"longitude": 8.86032
},
"destination": {
"latitude": 45.45516,
"longitude": 8.86032
},
"timeWindow": {
"startTimeSec": 27000,
"stopTimeSec": 73800
},
"tags": ["ve2"]
}
],
"waypoints": [
{
"name": "wp1",
"location": {
"latitude": 45.48246,
"longitude": 9.23345
},
"timeWindows": [
{
"startTimeSec": 54000,
"stopTimeSec": 86400
}
],
"tagsIncludeAnd": ["ve1"]
},
{
"name": "wp2",
"location": {
"latitude": 45.5559,
"longitude": 9.02353
},
"timeWindows": [
{
"startTimeSec": 46800,
"stopTimeSec": 61200
}
],
"tagsIncludeAnd": ["ve1"]
},
{
"name": "wp3",
"location": {
"latitude": 45.63996,
"longitude": 9.11965
},
"timeWindows": [
{
"startTimeSec": 28800,
"stopTimeSec": 43200
}
],
"tagsIncludeAnd": ["ve2"]
},
{
"name": "wp4",
"location": {
"latitude": 45.54266,
"longitude": 9.02767
},
"timeWindows": [
{
"startTimeSec": 28800,
"stopTimeSec": 43200
}
],
"tagsIncludeAnd": ["ve2"]
}
]
}
The resulting distance and travel time matrix will contain locations for waypoints wp1, wp2, wp3 and wp4, and also origin/destination locations for vehicle ve1 and ve2, so the corresponding cached matrix contains 6 locations (origin and destination locations are the same). As you can see from the response here below waypoints wp1 and wp2 are served by vehicle ve1, while waypoint wp3 and wp4 by vehicle ve2. Please note that the answer could be slightly different depending on the map release used to compute the distance/travel time matrix and the particular version of the solver used to solve it, but the waypoint-vehicle assignment will remain.
{
"reqID": "12345678-fb16-448c-8d55-807ee65be6bf",
"status": "COMPLETED",
"matrixID": 1,
"elapsedSec": 0,
"routes": [
{
"vehicle": {
"number": 1,
"name": "ve2"
},
"routeStats": {
"breakTimeSec": 0,
"driveTimeSec": 5926,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 5926,
"distanceMt": 96810,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cost": 5926,
"steps": [
{
"stepNumber": 0,
"waypoint": {
"name": "origin",
"number": -1
},
"latitude": 45.45516,
"longitude": 8.86032,
"timeWindow": {
"startTimeSec": 27000,
"stopTimeSec": 73800
},
"arrivalTimeSec": 0,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 27000,
"nextStepDriveTimeSec": 2799,
"nextStepDistanceMt": 47925,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 0,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 0,
"distanceMt": 0,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 1,
"waypoint": {
"name": "wp3",
"number": 2
},
"latitude": 45.63996,
"longitude": 9.11965,
"timeWindow": {
"startTimeSec": 28800,
"stopTimeSec": 43200
},
"arrivalTimeSec": 29799,
"idleTimeSec": 0,
"serviceStartTimeSec": 29799,
"departureTimeSec": 29799,
"nextStepDriveTimeSec": 1669,
"nextStepDistanceMt": 21341,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 2799,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 2799,
"distanceMt": 47925,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 2,
"waypoint": {
"name": "wp4",
"number": 3
},
"latitude": 45.54266,
"longitude": 9.02767,
"timeWindow": {
"startTimeSec": 28800,
"stopTimeSec": 43200
},
"arrivalTimeSec": 31468,
"idleTimeSec": 0,
"serviceStartTimeSec": 31468,
"departureTimeSec": 31468,
"nextStepDriveTimeSec": 1458,
"nextStepDistanceMt": 27544,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 4468,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 4468,
"distanceMt": 69266,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 3,
"waypoint": {
"name": "destination",
"number": -2
},
"latitude": 45.45516,
"longitude": 8.86032,
"arrivalTimeSec": 32926,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 32926,
"nextStepDriveTimeSec": 0,
"nextStepDistanceMt": 0,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 5926,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 5926,
"distanceMt": 96810,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
}
]
},
{
"vehicle": {
"number": 0,
"name": "ve1"
},
"routeStats": {
"breakTimeSec": 0,
"driveTimeSec": 5737,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 5737,
"distanceMt": 95649,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cost": 5737,
"steps": [
{
"stepNumber": 0,
"waypoint": {
"name": "origin",
"number": -1
},
"latitude": 45.52745,
"longitude": 9.51652,
"timeWindow": {
"startTimeSec": 27000,
"stopTimeSec": 73800
},
"arrivalTimeSec": 0,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 52194,
"nextStepDriveTimeSec": 1806,
"nextStepDistanceMt": 26760,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 0,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 0,
"distanceMt": 0,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 1,
"waypoint": {
"name": "wp1",
"number": 0
},
"latitude": 45.48246,
"longitude": 9.23345,
"timeWindow": {
"startTimeSec": 54000,
"stopTimeSec": 86400
},
"arrivalTimeSec": 54000,
"idleTimeSec": 0,
"serviceStartTimeSec": 54000,
"departureTimeSec": 54000,
"nextStepDriveTimeSec": 1739,
"nextStepDistanceMt": 23396,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 1806,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 1806,
"distanceMt": 26760,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 2,
"waypoint": {
"name": "wp2",
"number": 1
},
"latitude": 45.5559,
"longitude": 9.02353,
"timeWindow": {
"startTimeSec": 46800,
"stopTimeSec": 61200
},
"arrivalTimeSec": 55739,
"idleTimeSec": 0,
"serviceStartTimeSec": 55739,
"departureTimeSec": 55739,
"nextStepDriveTimeSec": 2192,
"nextStepDistanceMt": 45493,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 3545,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 3545,
"distanceMt": 50156,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
},
{
"stepNumber": 3,
"waypoint": {
"name": "destination",
"number": -2
},
"latitude": 45.52745,
"longitude": 9.51652,
"arrivalTimeSec": 57931,
"idleTimeSec": 0,
"serviceStartTimeSec": 0,
"departureTimeSec": 57931,
"nextStepDriveTimeSec": 0,
"nextStepDistanceMt": 0,
"perStopSetupTimeSec": 0,
"cumulativeRouteStats": {
"breakTimeSec": 0,
"driveTimeSec": 5737,
"idleTimeSec": 0,
"serviceTimeSec": 0,
"workTimeSec": 5737,
"distanceMt": 95649,
"perStopSetupTimeSec": 0,
"perStopSetupCost": 0,
"clusterSetupTimeSec": 0,
"clusterEnterTimeSec": 0,
"clusterExitTimeSec": 0,
"clusterEnterCost": 0,
"clusterExitCost": 0
},
"cumulativeCapacityMap": {}
}
]
}
],
"unreachedWaypoints": [],
"unreachableWaypoints": [],
"unneededVehicles": [],
"warnings": []
}
Suppose that our vehicles start executing the assigned plan: the vehicle ve2 served the waypoint wp3 and need to serve wp4, while vehicle ve1 still need to serve both wp1 and wp2. Vehicles have GPS module on board and we can collect their latest GPS fixes, this could helps understading how the plan is going, extimating their ETAs as the plan goes on. To do that we can do a reschedule request using the remaining waypoints and vehicles’ locations (GPS fixes), but because GPS fixes are valid just for a small amount of time and we do not want that our matrix keeps growing with ephemeral GPS locations we need to use both
mtxLocs
(to keep locations in the cached matrix) andephemeralLocs
parameters (for those locations that we do not need to persist in the cached matrix). The request is invoked calling the endopointPOST https://wwre.workwave.com/opt/v5/schedules/name/cachematrixtest
.
{
"schedules": [
{
"vehicle": {
"name": "ve1",
"origin": {
"latitude": 45.48621,//origin updated with the latest gps location
"longitude": 9.24145
},
"destination": {
"latitude": 45.52745,
"longitude": 9.51652
},
"timeWindow": {
"startTimeSec": 27000,
"stopTimeSec": 73800
}
},
"waypoints": [
{
"name": "wp1",
"location": {
"latitude": 45.48246,
"longitude": 9.23345
},
"timeWindows": [
{
"startTimeSec": 54000,
"stopTimeSec": 86400
}
]
},
{
"name": "wp2",
"location": {
"latitude": 45.5559,
"longitude": 9.02353
},
"timeWindows": [
{
"startTimeSec": 46800,
"stopTimeSec": 61200
}
]
}
]
},
{
"vehicle": {
"name": "ve2",
"origin": {
"latitude": 45.61747,//origin updated with the latest gps location
"longitude": 9.06444
},
"destination": {
"latitude": 45.45516,
"longitude": 8.86032
},
"timeWindow": {
"startTimeSec": 27000,
"stopTimeSec": 73800
}
},
"waypoints": [
{
"name": "wp4",
"location": {
"latitude": 45.54266,
"longitude": 9.02767
},
"timeWindows": [
{
"startTimeSec": 28800,
"stopTimeSec": 43200
}
]
}
]
}
],
"mtxLocs": [
[45.52745,9.51652],//ve1
[45.45516,8.86032],//ve2
[45.48246,9.23345],//wp1
[45.5559,9.02353], //wp2
[45.54266,9.02767] //wp4
],
"ephemeralLocs": [
[45.48621,9.24145],//gps for ve1
[45.61747,9.06444] //gps for ve2
]
}
After this schedule request the resulting cached matrix will contain locations for waypoints wp1, wp2, wp4, and also origin/destination locations for vehicle ve1 and ve2. Becase before calling the schedules API the waypoint wp3 was in the cached matrix but not in the
mtxLocs
list of the schedule request, it is removed from the cached matrix. Ephemeral locations that contains gps locations for vehicles ve1 and ve2 are computed but not stored with the matrix.
Use case: after a full optimization that creates or updates the cached matrix with all the locations needed, we call the reschedule API to update the ETAs of the waypoints based on the vehicles’ locations (e.g. GPS fixes of their last location); in this case, locations in the schedule requests are valid for a single call and we do not want to keep them in the cached matrix.
Suppose that we have 200 waypoints and 10 vehicles. Every 5 minutes we have fresh GPS fixes from our vehicles and we need to check if our plan is on time using the new locations or, on the contrary, a vehicle is a bit late and we need to take action about that. This means that calling a new schedule every 5 minutes, we add to the cached matrix 10 new locations each time; so after the first request we have a 210x210 matrix, after the second one a 220x220 matrix, and so on. At each request, we are adding 10 ephemeral locations to our cached matrix gradually with an ever greater impact on the computation time required to extend the cached matrix.
In this example, mtxLocs
will be used for keeping the locations (e.g. waypoints to serve or depots to visit) that we need to keep in the matrix, while ephemeralLocs
parameter (e.g. vehicles’ GPS fixes) will contains locations needed for a single request so that they do not augment the cached matrix, keeping just those locations that we need.
Object Definitions
Matrix
Matrix Object
Property | Type | Description |
---|---|---|
id | Integer | Matrix identification |
name | String | Matrix name assigned during creation |
creationDate | Long | Creation date in milliseconds (Unix Epoch) |
Single Day Optimization
Single Day Optimization Request Object
Property | Type | Description |
---|---|---|
vehicles | List of Vehicle | Mandatory. List of objects defining vehicle properties like costs, working time window and capacity |
waypoints | List of Waypoint | Mandatory. List of objects defining waypoint properties like latitude, longitude and delivery time window |
altWaypointsGroups | List of List of Waypoint | Defines groups of alternative Waypoints. After the main optimization completes, and for each defined group of waypoints, an additional progressive optimization is performed after replacing the original waypoints with those in the alternative group (which is typically smaller than the original set). Each alternative waypoint object must define a "refNumber" property, setting it to the 0-based index of the waypoint in the "waypoints" list to replace. Results of the additional optimizations are stored separately from the main optimization result in the response property "altResults". Typical usage scenario: best-fit and next-best-fit simulations: compute multiple results testing the impact of having one single waypoint (or a small subset) served at different time windows and/or by different vehicles (via tag constraints). In this scenario altWaypointGroups would contain several 1-waypoint alternatives |
async | Boolean | Defaults to false. Determine if this request should be blocking or asynchronous |
balanced | Boolean | Default to true. Set to true to balance route duration, set to false to disable route duration balancing and minimize the overall duration of all routes |
callbackUrl | URL | URL to be notified about the completion of the optimization request. When the optimization completes an HTTP POST request is sent from the Routing Engine server to the specified URL, adding a "reqID" and a "success" parameters. For example, if callbackUrl is http://my.server.com/webhooks/opt?myID=1234 The request will be sent as: http://my.server.com/webhooks/opt?myID=1234&success=[true|false]&reqID=[uuid] The remote server is expected to accept the TCP connection and return an HTTP 200 OK code within 15 seconds. Failing that, the callbackUrl is invoked again up to 10 times according to the following retry strategy:
|
callbackHeaders | map[String]String | Optional, defaults to null. If set the headers are added to the callback request. |
clustering | Clustering | Defines routing behavior on predefined waypoint clusters. Clusters are defined based on the "clusters" property set on Waypoint. |
ephemeralLocs | List of [Double, Double] | List of locations (latitude and longitude) that must NOT be included and persisted into the saved matrix. This is useful for directly managing a cached matrix where a set of locations must be used just one time and not saved into the cached matrix, improving the performance for extending the matrix. See section Manage cached matrices from Advanced Scenarios for additional details. |
mtxLocs | List of [Double, Double] | List of locations (latitude and longitude) that must be keept and persisted into the saved matrix. This is useful for managing those locations that are available from the cached matrix referenced by two or more requests. See section Manage cached matrices from Advanced Scenarios for additional details. |
optimization | OptimizationParameters | Parameters that affects the behaviour of the optimization algorithm |
resultFields | ResultFields | Defines the optional result fields that will be added to the response |
routeHints | List of RouteHint | Defines a list of routes that are used as the starting point for further optimization. Route hints derived from a previous optimization request and used to "bootstrap" a further similar optimization, can provide a major boost in terms of response time. Note that in this case Route Hints cannot be used for including additional waypoints to a previous optimization (e.g "fit in"), because assigned waypoints on the previous optimization can be marked as unserved and replaced by waypoints that were not present in the previous optimization. Route hints are checked for errors and for constraint violations. Invalid routes are partially or fully dropped. Providing low-quality, partial, irrelevant, or invalid route hints may lead to sub-optimal results with respect to the same request submitted without route hints |
routings | map[String]RoutingParameters | Specific parameters for the routing module |
traffic | Traffic | Defines traffic patterns |
Single Day Optimization Response Object
Property | Type | Description |
---|---|---|
reqID | UUID | Globally unique request ID. Can be used with the "export" resource to get a link to a map showing the optimized routes |
status | String | One of:
QUEUED and PROCESSING statuses only apply to asynchronous requests |
matrixID | Integer | ID of the Matrix. -1 for one-shot optimizations that do not used a saved matrix |
elapsedSec | Integer | Duration of the optimization process in seconds |
routes | List of Route | List of computed routes, one for each used vehicle |
unreachableWaypoints | List of OutWaypoint | List of OutWaypoint objects defining the waypoints that cannot be served in any feasible solution. A waypoint belongs to this list if no vehicle can serve it, even if it is the only waypoint served by the vehicles (e.g. waypoint requires a tag that no vehicle has). Each element represents the name of a waypoint as provided in the input (or an empty string if not provided) |
unreachedWaypoints | List of OutWaypoint | List of OutWaypoint objects defining the waypoints that, with the given constraints, could not be reached/served. Is the difference between the waypoints in input and those in output that are not associated with any route. There are two consideration:
|
unneededVehicles | List of OutVehicle | List of OutVehicle objects defining the unneeded vehicles |
warnings | List of CodedMessage | List of warnings defined by a numeric code and a descriptive message. Warnings are issued when, for example, the optimization request completes successfully but some geodesic distances are used instead of actual driving durations because one or more coordinates cannot be linked to the road network |
altResults | List of AlternativeResult | List of optimization results performed on the alternative set of waypoints |
Multi Day Optimization
Multi Day Optimization Request Object
Basic format of a multi day request
{
"vehicles": [
{
"name": "Vehicle A",
"daySettings": {
"1": {
// settings for day 2020.06.01
},
"2": {
// settings for day 2016.06.02
},
"4": {
// settings for day 2016.06.04
},
// ... more days
}
},
{
"name": "Vehicle B",
"daySettings": {
"1": {
// settings for day 2016.06.01
},
"2": {
// settings for day 2016.06.02
},
// ... more days
}
},
// ... more vehicles
],
"waypoints": [
{
"name": "Waypoint #1",
"eligibleDays" : [1, 2],
// ... more waypoint constraints
},
// ... more waypoints
]
}
Property | Type | Description |
---|---|---|
vehicles | List of MultiDayVehicle | Mandatory. List of objects defining vehicle properties like costs, working time window and capacity |
waypoints | List of MultiDayWaypoint | Mandatory. List of objects defining waypoint properties like latitude, longitude and delivery time window |
altWaypointsGroups | List of List of MultiDayWaypoint | Defines groups of alternative Waypoints. After the main optimization completes, and for each defined group of waypoints, an additional progressive optimization is performed after replacing the original waypoints with those in the alternative group (which is typically smaller than the original set). Each alternative waypoint object must define a "refNumber" property, setting it to the 0-based index of the waypoint in the "waypoints" array to replace. Results of the additional optimizations are stored separately from the main optimization result in the response property "altResults". Typical usage scenario: best-fit and next-best-fit simulations: compute multiple results testing the impact of having one single waypoint (or a small subset) served at different time windows and/or by different vehicles (via tag constraints). In this scenario altWaypointGroups would contain several 1-waypoint alternatives |
async | Boolean | Defaul to false. Determine if this request should be blocking or asynchronous |
balanced | Boolean | Default to true. Set to true to balance route duration, set to false to disable route duration balancing and minimize the overall duration of all routes |
callbackUrl | URL | URL to be notified about the completion of the optimization request. When the optimization completes an HTTP POST request is sent from the Routing Engine server to the specified URL, adding a "reqID" and a "success" parameters. For example, if callbackUrl is http://my.server.com/webhooks/opt?myID=1234 The request will be sent as: http://my.server.com/webhooks/opt?myID=1234&success=[true|false]&reqID=[uuid] The remote server is expected to accept the TCP connection and return an HTTP 200 OK code within 15 seconds. Failing that, the callbackUrl is invoked again up to 10 times according to the following retry strategy:
|
callbackHeaders | map[String]String | Optional, defaults to null. If set the headers are added to the callback request. |
clustering | Clustering | Defines routing behavior on predefined waypoint clusters. Clusters are defined based on the "cluster" property set on Waypoint objects |
ephemeralLocs | List of [Double, Double] | List of locations (latitude and longitude) that must NOT be included and persisted into the saved matrix. This is useful for directly managing a cached matrix where a set of locations must be used just one time and not saved into the cached matrix, improving the performance for extending the matrix. See section Manage cached matrices from Advanced Scenarios for additional details. |
mtxLocs | List of [Double, Double] | List of locations (latitude and longitude) that must be keept and persisted into the saved matrix. This is useful for managing those locations that are available from the cached matrix referenced by two or more requests. See section Manage cached matrices from Advanced Scenarios for additional details. |
optimization | OptimizationParameters | Parameters that affects the behaviour of the optimization algorithm |
resultFields | ResultFields | Defines the optional result fields that will be added to the response |
routeHints | List of MultiDayRouteHint | Defines a list of routes that are used as the starting point for further optimization. Route hints derived from a previous optimization request and used to "bootstrap" a further similar optimization, can provide a major boost in terms of response time. Note that in this case Route Hints cannot be used for including additional waypoints to a previous optimization (e.g "fit in"), because assigned waypoints on the previous optimization can be marked as unserved and replaced by waypoints that were not present in the previous optimization. Route hints are checked for errors and for constraint violations. Invalid routes are partially or fully dropped. Providing low-quality, partial, irrelevant, or invalid route hints may lead to sub-optimal results with respect to the same request submitted without route hints |
routings | map[String]RoutingParameters | Specific parameters for the routing module |
traffic | Traffic | Defines traffic patterns |
Multi Day Optimization Response Object
Property | Type | Description |
---|---|---|
reqID | UUID | Globally unique request ID. Can be used with the "export" resource to get a link to a map showing the optimized routes |
status | String | One of:
QUEUED and PROCESSING statuses only apply to asynchronous requests |
matrixID | Integer | ID of the Matrix. -1 for one-shot optimizations |
elapsedSec | Integer | Duration of the optimization process in seconds |
routes | List of MultiDayRoute | List of computed routes, one for each day and for each vehicle that is used in that day |
unreachableWaypoints | List of OutWaypoint | List of OutWaypoint objects defining the waypoints that cannot be served in any feasible solution. A waypoint belongs to this list if no vehicle can serve it, even if it is the only waypoint served by the vehicles (e.g. waypoint requires a tag that no vehicle has). Each element represents the name of a waypoint as provided in the input (or an empty string if not provided) |
unreachedWaypoints | List of OutWaypoint | List of OutWaypoint objects defining the waypoints that, with the given constraints, could not be reached/served. Is the difference between the waypoints in input and those in output that are not associated with any route. There are two consideration:
|
warnings | List of CodedMessage | List of warnings defined by a numeric code and a descriptive message. Warnings are issued when, for example, the optimization request completes successfully but some geodesic distances are used instead of actual driving durations because one or more coordinates cannot be linked to the road network |
altResults | List of MultiDayAlternativeResult | List of optimization results performed on the alternative set of waypoints |
Schedules
Schedules Request Object
Property | Type | Description |
---|---|---|
schedules | List of Schedule | Mandatory. The set of schedule requests. |
async | Boolean | Defaults to false. Determine if this request should be blocking or asynchronous |
callbackUrl | URL | URL to be notified about the completion of the optimization request. When the optimization completes an HTTP POST request is sent from the Routing Engine server to the specified URL, adding a "reqID" and a "success" parameters. For example, if callbackUrl is http://my.server.com/webhooks/opt?myID=1234 The request will be sent as: http://my.server.com/webhooks/opt?myID=1234&success=[true|false]&reqID=[uuid] The remote server is expected to accept the TCP connection and return an HTTP 200 OK code within 15 seconds. Failing that, the callbackUrl is invoked again up to 10 times according to the following retry strategy:
|
callbackHeaders | map[String]String | Optional, defaults to null. If set the headers are added to the callback request. |
clustering | Clustering | Defines routing behavior on predefined waypoint clusters. Clusters are defined based on the "clusters" property set on Waypoint. |
ephemeralLocs | List of [Double, Double] | List of locations (latitude and longitude) that must NOT be included and persisted into the saved matrix. This is useful for directly managing a cached matrix where a set of locations must be used just one time and not saved into the cached matrix, improving the performance for extending the matrix. See section Manage cached matrices from Advanced Scenarios for additional details. |
mtxLocs | List of [Double, Double] | List of locations (latitude and longitude) that must be keept and persisted into the saved matrix. This is useful for managing those locations that are available from the cached matrix referenced by two or more requests. See section Manage cached matrices from Advanced Scenarios for additional details. |
routings | map[String]RoutingParameters | Specific parameters for the routing module |
scheduling | SchedulingParameters | Parameters that affects the behaviour of the schedule algorithm. |
traffic | Traffic | Defines traffic patterns |
Schedules Response Object
Property | Type | Description |
---|---|---|
reqID | UUID | Globally unique request ID. Can be used with the "export" resource to get a link to a map showing the optimized routes |
status | String | One of:
QUEUED and PROCESSING statuses only apply to asynchronous requests |
matrixID | Integer | ID of the Matrix. -1 for one-shot optimizations that do not used a saved matrix |
elapsedSec | Integer | Duration of the optimization process in seconds |
routes | List of Route | List of computed routes, one for each used vehicle |
unreachableWaypoints | List of OutWaypoint | List of OutWaypoint objects defining the waypoints that cannot be served in any feasible solution. A waypoint belongs to this list if no vehicle can serve it, even if it is the only waypoint served by the vehicles (e.g. waypoint requires a tag that no vehicle has). Each element represents the name of a waypoint as provided in the input (or an empty string if not provided) |
unreachedWaypoints | List of OutWaypoint | List of OutWaypoint objects defining the waypoints that, with the given constraints, could not be reached/served. Is the difference between the waypoints in input and those in output that are not associated with any route. There are two consideration:
|
unneededVehicles | List of OutVehicle | List of OutVehicle objects defining the unneeded vehicles |
warnings | List of CodedMessage | List of warnings defined by a numeric code and a descriptive message. Warnings are issued when, for example, the optimization request completes successfully but some geodesic distances are used instead of actual driving durations because one or more coordinates cannot be linked to the road network |
Async Response
Property | Type | Description |
---|---|---|
reqID | UUID | Globally unique request ID |
status | String | One of:
|
progress | Integer | The excetion request progress, in the range [0, 100]:
|
resultAvailable | Boolean | true if a partial result is available, false if a partial result is not |
queuePosition | Integer | The queue position, in the assigned server, of this request respect to all requests made by the same key and currently in QUEUED status |
Miscellaneous Objects
AlternativeResult Object
Property | Type | Description |
---|---|---|
routes | List of Route | List of computed routes, one for each used vehicle |
unreachableWaypoints | List of OutWaypoint | List of OutWaypoint objects defining the waypoints that cannot be served in any feasible solution. A waypoint belongs to this list if no vehicle can serve it, even if it is the only waypoint served by the vehicles (e.g. waypoint requires a tag that no vehicle has). Each element represents the name of a waypoint as provided in the input (or an empty string if not provided) |
unreachedWaypoints | List of OutWaypoint | List of OutWaypoint objects defining the waypoints that, with the given constraints, could not be reached/served. Is the difference between the waypoints in input and those in output that are not associated with any route. There are two consideration:
|
unneededVehicles | List of OutVehicle | List of OutVehicle objects defining the unneeded vehicles |
Break Object
Property | Type | Description |
---|---|---|
durationSec | Integer | Mandatory. Break duration in seconds. The break can be scheduled to start at any time between startTimeSec and stopTimeSec, and lasts for durationSec. |
startTimeSec | Integer | Mandatory. Minimum allowed break start time in seconds since midnight (00:00). The allowed range can span a maximum of a 7-days period [0 – 604800] |
stopTimeSec | Integer | Mandatory. Maximum allowed break stop time in seconds since midnight (00:00). Must be >= startTimeSec. The allowed range can span a maximum of a 7-days period [0 – 604800] |
Example: startTimeSec = 43200 (12:00), stopTimeSec = 45000 (12:30) and durationSec = 3600 (1 hour) means: schedule a 1-hour break starting at any time between 12:00 and 12:30.
Cluster Object
Property | Type | Description |
---|---|---|
enterCost | Integer | Default to 0. The cost penalty paid by the vehicle before arriving to the first waypoint of a sequence of waypoints that belong to this cluster |
enterTimeSec | Integer | Default to 0. The driving time penalty paid by the vehicle before arriving to the first waypoint of a sequence of waypoints that belong to this cluster |
exitCost | Integer | Default to 0. The cost paid by the vehicle before exiting from the last waypoint of a sequence of waypoints that belong to this cluster |
exitTimeSec | Integer | Default to 0. The driving time penalty paid by the vehicle before exiting from the last waypoint of a sequence of waypoints that belong to this cluster |
requireVehicleStop | Boolean | Default to false. If it’s equal to True the vehicle must stop before entering into a sequence of waypoints that belong to this cluster |
setupTimeSec | Integer | Default to 0. The setup time required to enter in a cluster, each time the vehicle enter in this cluster. It impacts on the service time of the first waypoint of a sequence of waypoints that belong to this cluster |
ClusterBehavior Object
Property | Type | Description |
---|---|---|
enterCost | String | Default to SUM. Describe the way in which multiple clusters enter costs (see enterCost member from Cluster object) will be combined (available functions are "SUM", "AVG", "MIN", "MAX"). |
enterTime | String | Default to SUM. Describe the way in which multiple clusters enter times (see enterTimeSec member from Cluster object) will be combined (available functions are "SUM", "AVG", "MIN", "MAX"). |
exitCost | String | Default to SUM. Describe the way in which multiple clusters exit costs (see exitCost member from Cluster object) will be combined (available functions are "SUM", "AVG", "MIN", "MAX"). |
exitTime | String | Default to SUM. Describe the way in which multiple clusters exit times (see exitTimeSec member from Cluster object) will be combined (available functions are "SUM", "AVG", "MIN", "MAX"). |
setupTime | String | Default to SUM. Describe the way in which multiple clusters setup times (see setup time member from Cluster object) will be combined (available functions are "SUM", "AVG", "MIN", "MAX"). |
Clustering Object
Property | Type | Description |
---|---|---|
clusters | map[String]Cluster | A map from cluster names to Cluster objects. Each cluster name must be defined in at least one of the following arrays:
|
intersectionFunctions | ClusterBehavior | Defines the way in which multiple clusters impact on solution times and costs |
parkAndWalk | map[String]ParkAndWalkCluster | A map from park & walk cluster names to ParkAndWalkCluster objects. br/> Each park & walk cluster name must be defined by at least one waypoint |
CodedMessage Object
Property | Type | Description |
---|---|---|
code | Integer | Integer code defining this type of message |
message | String | Message text |
Where code can be of the following:
code |
Description |
---|---|
-10000 | Unlinkable coordinates. Some coordinates (full list provided in message text) cannot be linked to the road network. Driving times to and from these locations are estimated using geodesic distances, which may lead to less optimal results and less accurate schedules |
-10100 | Unreachable coordinates. Some coordinates (full list provided in message text) are linked to restricted roads and cannot be reached. Driving times to these locations are estimated using geodesic distances, which may lead to less optimal results and less accurate schedules |
-11000 | Alternative Optimization failed. One of the optimization in the alternative group failed. |
-12000 | Solver not found. If the requested solver version has not been found. |
DateString Object
Date represented as a string formatted as yyyyMMddTHH:mm:ss+/-HH:mm. For example 20230831T12:34:00+02:00.
DynamicBreak Object
Property | Type | Description |
---|---|---|
durationSec | Integer | Mandatory. Break duration in seconds |
maxTimeFromPrevSec | Integer | Mandatory. Maximum time from the previous break that the algorithm has to add the dynamic break to the route. If this is the first dynamic break the “maxTimeFromPrevSec” refers to the start time of the vehicle’s time window |
ExceptionSegment Object
Property | Type | Description |
---|---|---|
end | Location | Mandatory. End point of the segment. Note: the segment length must be >= 5m and <= 200m. |
start | Location | Mandatory. Start point of the segment. Note: the segment length must be >= 5m and <= 200m. |
additionalDrivingTimeSec | Integer | Default to 0. If the computed route accross this segment this is the amount of time that will be added to the route computation. If additionalDrivingTimeSec is different from 0, the malus property will be ignored |
malus | Integer | Default to 0. A malus value in the range [-10, +10] where +10 is used for blocking the segment, while -10 is used to indicate the preference of using this segment |
Location Object
Property | Type | Description |
---|---|---|
latitude | Double | Mandatory. Latitude coordinate in decimal format specified using the WGS 84 reference frame (e.g.: 45.397204) |
longitude | Double | Mandatory. Longitude coordinate in decimal format specified using the WGS 84 reference frame (e.g.: 9.251765) |
MultiDayAlternativeResult Object
Property | Type | Description |
---|---|---|
routes | List of MultiDayRoute | List of computed routes, one for each day and for each vehicle that is used in that day |
unreachableWaypoints | List of OutWaypoint | List of OutWaypoint objects defining the waypoints that cannot be served in any feasible solution. A waypoint belongs to this list if no vehicle can serve it, even if it is the only waypoint served by the vehicles (e.g. waypoint requires a tag that no vehicle has). Each element represents the name of a waypoint as provided in the input (or an empty string if not provided) |
unreachedWaypoints | List of OutWaypoint | List of OutWaypoint objects defining the waypoints that, with the given constraints, could not be reached/served. Is the difference between the waypoints in input and those in output that are not associated with any route. There are two consideration:
|
MultiDayRoute Object
Property | Type | Description |
---|---|---|
vehicle | OutMultiDayVehicle | The vehicle associated with this route and the day in which the vehicle serves the route |
steps | List of RouteStep | Ordered list of route steps. Route steps include one origin, one or more waypoints, zero or one destination (route ends at the last visited waypoint if no destination is specified for the vehicle) |
routeStats | RouteStats | Cost and time statistics related to this route |
cost | Double | Total cost of the route: sum of total driving cost, total mileage cost, total idle time cost, total break time cost, total service time cost and total enter/exit cluster cost |
MultiDayRouteHint Object
Property | Type | Description |
---|---|---|
day | Integer | Mandatory. The day to which this hint applies |
sequence | List of Integers | [DEPRECATED] (replaced by waypointIndexes). The sequence of waypoints that defines the route. The values in the array represent the zero-based index of the sequence waypoints in the "waypoints" array. IMPORTANT: if the given sequence is not compatible with the input constraints, steps will be removed from the sequence in no particular order up to the point where either the sequence becomes compatible or it is completely discarded. When a step is discarded, so is any "lock" constraint it may have defined |
vehicleNumber | Integer | Mandatory. The Vehicle that this route hint applies to. The value represents the zero-based index of the vehicle in the "vehicles" array |
waypointIndexes | List of WaypointIndex | Mandatory The sequence of waypoints that defines the route. The values in the array represent the zero-based index of the sequence waypoints in the "waypoints" array. IMPORTANT: if the given sequence is not compatible with the input constraints, steps will be removed from the sequence in no particular order up to the point where either the sequence becomes compatible or it is completely discarded. When a step is discarded, so is any "lock" constraint it may have defined |
MultiDayVehicle Object
Property | Type | Description |
---|---|---|
daySettings | map[Integer]Vehicle | Mandatory. Maps each working day of the vehicle with its settings for that day |
name | String | Mandatory. Unique vehicle identifier. Note: The following substrings/characters are NOT allowed: '..', '/', '\', '&', '?', '#', '=' |
MultiDayWaypoint Object
Property | Type | Description |
---|---|---|
location | Location | Mandatory. Defines waypoint latitude/longitude coordinates |
clusters | List of Strings | The name of clusters associated with the waypoint |
dayLengthSec | Integer | Default value 86400 (seconds in a single day). The day length, for example the duration of a "day" can be artificially increased to fit both a "day" and a "night" shift into each "extended" day |
deliveryMap | map[String]Integer | Defines the size of the delivery in terms of load unit types (i.e.: consumed vehicle capacity). Mutually exclusive with pickupMap (each waypoint is either a delivery or a pickup, not both). 0 where not specified |
dropoffNumber | Integer | When defined marks this waypoint as a "pickup for dropoff". The value represents the zero-based index of the dropoff waypoint in the "waypoints" array. A waypoint defining a dropoffNumber is a pickup point and therefore its deliveryMap must be empty. Consequently, the referenced dropoff waypoint is a dropoff/delivery point and therefore its pickupMap must be empty |
eligibleDays | List of Integers | The index of days in which this waypoint can be served, all the working days |
mcRefNumber | Integer | References the waypoint for which this waypoint is a choice, this choice is mutually exclusive so this waypoint or that one that is referenced. The value represents the zero-based index of the referenced waypoint in the Waypoint list |
name | String | If provided, this name string can be used to identify this waypoint in the output |
pickupMap | map[String]Integer | Defines the size of the pickup in terms of load unit types (i.e.: consumed vehicle capacity). Mutually exclusive with deliveryMap (each waypoint is either a delivery or a pickup, not both). 0 where not specified |
priority | Integer | Default to 0. Defines the priority of this waypoint where 0 is the lowest possible priority. Priority is only taken into account when all Waypoints cannot be serviced by the given Vehicles: under such circumstances Waypoints with a higher priority are preferred over lower-priority ones. It can influence the solver behivour just for including/excluding waypoints in the resulting route, it cannot be used for defining their visiting order. |
refNumber | Integer | References the waypoint that will be replaced by this one when processing alternative waypoint groups. Mandatory for waypoints defined as part of an alternative waypoint group, ignored otherwise. The value represents the zero-based index of the referenced waypoint in the "waypoints" array |
serviceTimeSec | Integer | The default amount of time in seconds which a vehicle is expected to be stationary at this waypoint (i.e. the time required for the servicing to take place). 0 where not specified |
serviceTimeSecPerVehicle | map[Integer]Integer | Override the default service time for the specified vehicles. Each map pair is defined by the index (the map key) of the vehicle in the zero-indexed list "vehicles" and by the ad-hoc service time for the specified vehicle (the map value). This enables modeling scenarios where the time it takes to serve a waypoint can be different based on what vehicle actually serves it. Examples are landscaping scenarios where a vehicle carring a team of 4 techs can serve a waypoint in half the time it would take a vehicle with only 2 techs on board: vehicle Ve1, with only 1 tech on board, takes 20 mins to serve waypoint A while vehicle Ve2, with 3 techs on board, takes 7 mins to serve the same waypoint |
tagsExclude | List of String | Define tag-based vehicle exclusion constraints: all vehicles defining one or more tags in this list are not allowed to service this waypoint. Exclusion constraints take precedence over inclusion ones |
tagsIncludeAnd | List of String | Define tag-based vehicle inclusion constraints: only vehicles defining all tags in this list (AND-criteria) are allowed to service this waypoint |
tagsIncludeOr | List of String | Define tag-based vehicle inclusion constraints: all vehicles defining one or more tags in this list (OR-criteria) are allowed to service this waypoint |
timeWindows | List of TimeWindow | If provided, defines an array of arrival time window constraints for this waypoint. Each time window defines a time interval when the waypoint can start to be serviced. This interval does not include the service time (e.g.: if service time is 30 minutes and the time window is from 10:00 to 11:00, then it is ok for the vehicle to arrive and start servicing the waypoint at 10:59 and complete the service 30 minutes later at 11.29). If the time window must include the service time, just subtract the service time from the end time of the time window (e.g.: if service time is 30 minutes and the time window is from 10:00 to 11:00 and must include the service time, then change the time window to be from 10:00 to 10:30). Multiple time windows can be used, for example, to prevent the waypoint from being serviced in off-limits intervals (e.g.: defining the time windows: 8:00-12:00 and 14:00-18:00 would prevent the waypoint from being serviced between 12:00 and 14:00). Both start time and stop time of all the time window in the array must be in the single day interval [0s, 86400s]. If not specified, this waypoint will always be available to be serviced |
OptimizationParameters Object
Property | Type | Description |
---|---|---|
dynamicBreakPercentageThreshold | Integer | Default to 0. The maximum deviation percentage between one pause and the next that the optimizer can consider valid when it has to place breaks in a route. e.g. if set to 10% the solver consider valid a deviation until 10% between a pause and the next one. This parameter is mutually exclusive with dynamicBreakSecThreshold, they can’t be used both at the same time |
dynamicBreakSecThreshold | Integer | Default to 0. The maxium deviation in seconds between one pause and the next that the optimizer can consider valid when it has to place breaks in a route. e.g. if set to 600 seconds the solver consider valid a deviation at most of 600 seconds between a pause and the next one. This parameter is mutually exclusive with the parameter dynamicBreakPercentageThreshold, they can’t be used both at the same time |
version | Integer | The algoritm version for executing the request. If not defined or if the selected version is no more supported the routing engine will select the most appropriate algoritm based on the input. Note that if the request defines a specific algorithm version, but the input is not compatible with the input the routing engine will notify the caller with an error message. Also, considers that solving the same problem with different versions of the algorithm could lead to different solutions (with the same compatible input) and/or may take a different amount of time. Supported versions:
|
OutMultiDayVehicle Object
Property | Type | Description |
---|---|---|
name | String | The name of the referenced vehicle in the "vehicles" array |
number | Integer | The value represents the zero-based index of the referenced waypoint in the "vehicles" array |
day | Integer | The day in which the vehicle is working |
OutVehicle Object
Property | Type | Description |
---|---|---|
name | String | The name of the referenced vehicle in the "vehicles" array |
number | Integer | The value represents the zero-based index of the referenced vehicles in the "vehicles" array |
day | Integer | Always zero (0) for single-day optimizations |
OutWaypoint Object
Property | Type | Description |
---|---|---|
name | String | The name of the referenced waypoint in the "waypoints" array. In route steps that are not waypoints like origin and destination it is set to "origin" and "destination" respectively |
number | Integer | The value represents the zero-based index of the referenced waypoint in the "waypoints" array. In route steps that are not waypoints like origin and destination it is set to -1 and -2 respectively |
ParkAndWalkCluster Object
Property | Type | Description |
---|---|---|
parkingLocation | Location | Mandatory. The parking location. A vehicle visiting a Park&Walk cluster is supposed to drive to the parking location, and then the driver will walk to the waypoints belonging to the same cluster. In order to visit a waypoint outside of the current cluster the driver will return, walking, to the parking location and then drive to that waypoint (or, in case that waypoint belongs to a different Park&Walk cluster, to the parking location defined by that different cluster) |
routing | ParkAndWalkRouting | Mandatory. Defines the routing properties to be used within the cluster |
parkingTimeSec | Integer | Default to 0. The estimated time, in seconds, that the driver will spend parking at the parking location |
ParkAndWalkRouting Object
Property | Type | Description |
---|---|---|
mode | String | Mandatory. Default to GEODESIC. One of:
|
avgSpeedKmh | Integer | Default to 5. Ignored if mode is ROAD. The average walking speed in Km/h |
profile | String | Default to WALKING. Ignored if mode is GEODESIC, otherwise can be one of:
|
ResultFields Object
Property | Type | Description |
---|---|---|
polyline | Boolean | Default to false. Set to true to add list of [latitude, longitude], representing the route between a route step waypoint to the next one, to the optimization result |
RateCardDistanceCostModel Object
Property | Type | Description |
---|---|---|
fixedDistanceCost | Integer | Parameter for the "rate card" distance cost computation model. The fixed cost for the route traveled distance until distanceThresholdMt. The default value is 0 |
variableDistanceCostFactor | Double | Parameter for the "rate card" distance cost computation model. The variable cost factor for the route traveled distance starting from distanceThresholdMt. The default value is 0.0 |
distanceThresholdMt | Integer | Parameter for the "rate card" distance cost computation model. The distance, in meters starting from the route beginning, with a fixed cost (cost identified by fixedDistanceCostFactor). The default value is 0 |
RateCardOverdistanceCostModel Object
Property | Type | Description |
---|---|---|
variableOverdistanceCostFactor | Double | Parameter for the "rate card" distance cost computation model. The variable cost factor for the route traveled distance during overdistance. The default value is 0.0 |
RateCardOvertimeCostModel Object
Property | Type | Description |
---|---|---|
workingOvertimeVariableCostFactor | Double | Parameter for the "rate card" working time cost computation model. The variable cost factor for the route working time during overtime. The default value is 0.0 |
RateCardTimeCostModel Object
Property | Type | Description |
---|---|---|
workingTimeFixedCost | Integer | Parameter for the "rate card" working time cost computation model. The fixed cost for the route working time until workingTimeThresholdSec. The default value is 0 |
workingTimeVariableCostFactor | Double | Parameter for the "rate card" working time cost computation model. The variable cost factor for the route working time starting from workingTimeThresholdSec. The default value is 0.0 |
workingTimeThresholdSec | Integer | Parameter for the "rate card" working time cost computation model. The time, in seconds starting from the route beginning, with a fixed cost (cost identified by workingTimeFixedCostFactor). The default value is 0 |
Route Object
Property | Type | Description |
---|---|---|
vehicle | OutVehicle | The OutVehicle object representing the vehicle associated with this route |
steps | List of RouteStep | Ordered list of route steps. Route steps include one origin, one or more waypoints, zero or one destination (route ends at the last visited waypoint if no destination is specified for the vehicle) |
routeStats | RouteStats | Cost and time statistics related to this route |
cost | Double | Total cost of the route: sum of total driving cost, total mileage cost, total idle time cost, total break time cost, total service time cost and total enter/exit cluster cost. |
RouteHint Object
Property | Type | Description |
---|---|---|
vehicleNumber | Integer | Mandatory. The Vehicle that this route hint applies to. The value represents the zero-based index of the vehicle in the "vehicles" array. |
sequence | List of Integers | [DEPRECATED] (replaced by waypointIndexes). The sequence of waypoints that defines the route. The values in the array represent the zero-based index of the sequence waypoints in the "waypoints" array. IMPORTANT: if the given sequence is not compatible with the input constraints, steps will be removed from the sequence in no particular order up to the point where either the sequence becomes compatible or it is completely discarded. When a step is discarded, so is any "lock" constraint it may have defined |
waypointIndexes | List of WaypointIndex | Mandatory The sequence of waypoints that defines the route. The values in the array represent the zero-based index of the sequence waypoints in the "waypoints" array. IMPORTANT: if the given sequence is not compatible with the input constraints, steps will be removed from the sequence in no particular order up to the point where either the sequence becomes compatible or it is completely discarded. When a step is discarded, so is any "lock" constraint it may have defined |
RouteStats Object
Property | Type | Description |
---|---|---|
workTimeSec | Integer | Working time. computed as arrival time to destination - departure time |
breakTimeSec | Integer | Time in seconds elapsed during breaks |
driveTimeSec | Integer | Driving time in seconds. Includes clusterEnterTimeSec, clusterExitTimeSec and perStopSetupTimeSec |
distanceMt | Integer | Mileage in meters |
serviceTimeSec | Integer | Service time in seconds (i.e.: sum of all waypoint service times). Includes clusterSetupTimeSec |
idleTimeSec | Integer | Idle time in seconds (i.e.: sum of all idle times). Idle time happens when, as per schedule, the Vehicle arrives early at a waypoint and must wait, idle, for the waypoint time window to open. Idle time is computed according to this formula: idleTimeSec = workTimeSec - drivingTimeSec - serviceTimeSec - breakTimeSec |
perStopSetupTimeSec | Integer | Time in seconds elapsed during vehicle stops |
perStopSetupCost | Integer | Cost paid related to vehicle stops |
clusterEnterCost | Integer | Cost paid to enter in clusters |
clusterExitCost | Integer | Cost paid to exit from clusters |
clusterSetupTimeSec | Integer | Setup time in seconds spent to setup before entering in clusters |
clusterEnterTimeSec | Integer | Time in seconds spent to enter in clusters |
clusterExitTimeSec | Integer | Time in seconds spent to exit from clusters |
RouteStep Object
Property | Type | Description |
---|---|---|
stepNumber | Integer | A zero-based counter indicating the step number in this route |
waypoint | OutWaypoint | Identification of the waypoint associated with this step. If this step represents the origin or the destination depot this field assumes particular values |
latitude | Double | Latitude coordinate specified using the WGS 84 reference frame (e.g.: 45.397204) |
longitude | Double | Longitude coordinate specified using the WGS 84 reference frame (e.g.: 9.251765) |
timeWindow | TimeWindow | Delivery time window constraint for this route step (i.e.: the visited Waypoint’s matching time window). Set to the Vehicle’s working time window for origins and empty for the end destination |
arrivalTimeSec | String | Arrival time in seconds since midnight |
idleTimeSec | Integer | This field is > 0 if the arrival time is earlier than the time window start time (in which case the vehicle has to wait until the time window start time) |
serviceStartTimeSec | String | Time when the goods are delivered, in seconds since midnight |
departureTimeSec | String | Departure time in seconds since midnight |
nextStepDriveTimeSec | Integer | Time in seconds required to reach the next route step. Always set to 0 for the last step |
nextStepDistanceMt | Integer | Meters between the current and the next route step. Always set to 0 for the last step |
perStopSetupTimeSec | Integer | Time required to stop the vehicle in this step of the route |
driveBreakTimeSec | Integer | This field is > 0 if the driving time between the previous step and this step is interrupted by one or more Vehicle-defined Breaks (e.g.: lunch break) and amounts to the sum of the durationSec of all involved Breaks. Note that arrivalTimeSec and all related times already take Vehicle Breaks into account. This field is omitted if no Vehicle Breaks are defined in the input request |
driveBreaks | List of RouteStepBreak | Lists all breaks occurring during the driving time between the previous step and this step. This field is omitted if no Vehicle Breaks are defined in the input request |
serviceBreakTimeSec | Integer | This field is > 0 if the service time at this step is interrupted by one or more Vehicle-defined Breaks (e.g.: lunch break) and amounts to the sum of the durationSec of all involved Breaks. Note that departureTimeSec already take Vehicle Breaks into account. Note that the optimization engine will try to avoid placing Breaks during a service time if at all possible. This field is omitted if no Vehicle Breaks are defined in the input request |
serviceBreaks | List of RouteStepBreak | Lists all breaks interrupting the service time at this step. This field is omitted if no Vehicle Breaks are defined in the input request |
cumulativeCapacityMap | map[String]Integer | Vehicle capacities consumed up to this step |
cumulativeRouteStats | RouteStats | Cost and time statistics cumulated from route start to this step |
polyline | List of [latitude, longitude] | List of [latitude, longitude] representing the route between this route step waypoint to the next one |
vehicleServiceTime | VehicleServiceTime | Vehicle service time for this route. The initial service time will be included in the first step after origin. The final service time will be included in the route destination; if a vehicle defines a final service time but doesn't have a destination the optimization response will have a destination step that includes the final service time. |
RouteStepBreak Object
Property | Type | Description |
---|---|---|
breakTimeSec | Integer | Break start time in seconds since midnight |
durationSec | Integer | Break duration in seconds |
RoutingParameters Object
Property | Type | Description |
---|---|---|
exceptions | List of ExceptionSegment | List of segments that could affect route/matrix computation |
sameSideOfStreet | Boolean | Default to false. All the vehicles that use a traffic profile with this value set to true will arrive to a location on the same side of street where it's located |
trafficTimeReference | DateString | All the vehicles that use a traffic profile with this value set will use the historical traffic at the time specified in this field. |
Schedule Object
Property | Type | Description |
---|---|---|
vehicle | Vehicle | Mandatory. Object defining vehicle properties like costs, working time window and capacity |
waypoints | List of Waypoint | Mandatory. List of objects defining waypoint properties like latitude, longitude and delivery time window |
SchedulingParameters Object
Property | Type | Description |
---|---|---|
dynamicBreakPercentageThreshold | Integer | Default to 0. The maximum deviation percentage between one pause and the next that the optimizer can consider valid when it has to place breaks in a route. e.g. if set to 10% the solver consider valid a deviation until 10% between a pause and the next one. This parameter is mutually exclusive with dynamicBreakSecThreshold, they can’t be used both at the same time |
dynamicBreakSecThreshold | Integer | Default to 0. The maxium deviation in seconds between one pause and the next that the optimizer can consider valid when it has to place breaks in a route. e.g. if set to 600 seconds the solver consider valid a deviation at most of 600 seconds between a pause and the next one. This parameter is mutually exclusive with the parameter dynamicBreakPercentageThreshold, they can’t be used both at the same time |
version | Integer | The scheduler version for executing the request. If not defined or if the selected version is no more supported the routing engine will select the most appropriate algoritm based on the input. Note that if the request defines a specific version, but the input is not compatible with the input the routing engine will notify the caller with an error message. Supported versions:
|
TimeCostModel Object
Property | Type | Description |
---|---|---|
drivingTimeCostFactor | Double | Default to 1.0. A multiplicative factor applied internally to the vehicle driving time (the portion of working time in which the vehicle travels from the current waypoint location to the next one). Must be non-negative (drivingTimeCostFactor >= 0). Usage examples:
|
serviceTimeCostFactor | Double | Default to 1.0. A multiplicative factor applied internally to the vehicle service time (the portion of working time consumed by the vehicle stationary in a location in order to serve a waypoint). Must be non-negative (serviceTimeCostFactor >= 0). Usage examples:
Note: the value of this parameter does not modify the returned scheduled times, it is only considered internally by the optimization logic to determine the cost of a route |
idleTimeCostFactor | Double | Default to 1.0. A multiplicative factor applied internally to the vehicle idle time (the portion of working time consumed by the vehicle waiting the opening of a waypoint time window after its arrival to the waypoint location). Must be non-negative (idleTimeCostFactor >= 0). Usage examples: by increasing the idleTimeCostFactor without increasing other cost factors, the optimization logic will be forced towards solutions having a good matching between the arrival time of the vehicle in a waypoint location and the opening of one of the waypoint time windows, even if this implies an overall increase in the working time. Note: the value of this parameter does not modify the returned scheduled times, it is only considered internally by the optimization logic to determine the cost of a route |
breakTimeCostFactor | Double | Default to 1.0. A multiplicative factor applied internally to the vehicle break time (the portion of working time consumed during vehicle mandatory breaks). Must be non-negative (breakTimeCostFactor >= 0). Usage examples: by increasing the breakTimeCostFactor without increasing other cost factors, the optimization logic will be forced towards solutions that avoid mandatory breaks even if this implies an increase in the overall working time. Note: the value of this parameter does not modify the returned scheduled times, it is only considered internally by the optimization logic to determine the cost of a route |
TimeWindow Object
Property | Type | Description |
---|---|---|
startTimeSec | Integer | Mandatory. Default to 0. Time window start time in seconds since midnight (00:00). |
stopTimeSec | Integer | Mandatory. Default to 86400. Time window stop time in seconds since midnight (00:00), must be >= startTimeSec. |
Traffic Object
Property | Type | Description |
---|---|---|
trafficProfiles | map[String]TrafficProfile | Map associating the name of a traffic profile to its definition |
trafficTimeWindows | List of TimeWindow | An array of traffic time-windows. The given time windows must not overlap. The maximum number of time windows is currently limited to 2 |
TrafficProfile Object
Property | Type | Description |
---|---|---|
baseTrafficFactor | Double | Default to 1.0. Global route duration multiplier, ised to take into account a static and global traffic scenario (all driving times for vehicles using this profile are multiplied by baseTrafficFactor, regardless of area and time). Affects all routes. Allowed range is 0.5-5.0, out of range values are capped at range bounds. Set to 1.0 for normal traffic conditions. See also speedFactor parameter from Vehicle |
trafficRegions | List of TrafficRegion | If provided, defines an array of regions associated to time-dependent trafficFactors. Each region’s trafficFactor is proportionally applied to the percentage of each arc intersecting that region. NOTE: Regions are intended to cover a sufficiently wide area (e.g.: a city, a city center, a borough, a district, a suburban area, etc). Regions that strictly contour specific roads will not work as expected and should be avoided. NOTE: The maximum number of Locations (aka polygon vertices) that can be specified by all trafficRegions combined is limited to 100. NOTE: In case of overlapping regions, the region with the highest trafficFactor is considered for the overlapping area (for each defined traffic time-window). NOTE: the global baseTrafficFactor parameter and trafficRegions can both be specified and are both independently applied. E.g.: Assuming two non-overlapping regions R1 and R2 are defined: Driving time from A to B: baseTrafficFactor * AB * (1 + AB_%intersecting_R1 * (1 – R1_trafficFactor) + AB%_intersecting_R2 * (1 – R2_trafficFactor)) |
routing | String | The name of the routing profile used by this traffic profile. |
TrafficRegion Object
Property | Type | Description |
---|---|---|
region | List of Location | Mandatory. A list of 3 or more Locations (different and non-collinear) defining the shell of a simple closed polygon. Concave and convex polygons are supported; self-intersecting polygons are accepted but are internally converted to their convex hull (see http://en.wikipedia.org/wiki/Convex_hull) |
trafficFactor | Double | Default to 1.0. The region's default (non time-dependent) trafficFactor. Applies outside of the defined traffic time-windows.Allowed range is 0.5-5.0, out of range values are capped at range bounds. |
twTrafficFactors | List of Double | A list of time-dependent traffic factors that apply to this region. Allowed range for each value is 0.5-5.0, out of range values are capped at range bounds. The size of the array must match the size of the trafficTimeWindows array defined on the parent Traffic object. Each twTrafficFactor in the array will override "trafficFactor" during its traffic time window. For example, assuming we have two traffic time windows, one between 7am and 10am, and one between 4pm and 7pm and that this region's default trafficFactor is 1.5 and that twTrafficFactors are [2.1, 3.0], then traveling between any two locations within the region will incur in the following time-dependent penalty:
|
Vehicle Object
Property | Type | Description |
---|---|---|
name | String | Mandatory. Unique vehicle identifier. Note: The following substrings/characters are NOT allowed: '..', '/', '\', '&', '?', '#', '=' |
origin | Location | Mandatory. The location of the start point for this vehicle. |
activationCost | Integer | Defaul to 0. A cost, in terms of "seconds of working time", that is factored-in internally if the vehicle is used. Cannot be a negative value (activationCost >= 0). Usage example: In a multi-vehicle optimization where all waypoints can be served by a subset of vehicles (excess of resources), the optimization logic will prefer vehicles with a lower activationCost. Note: the value of this parameter does not modify the returned scheduled times, it is only considered internally by the optimization logic to determine whether to use the vehicle or not. Note: this parameter is only relevant in multi-vehicle optimizations. |
addOptionalFinalBreak | Boolean | Default to false. A final break is a break between the vehicle arrival time and the end of the vehicle time window. If this option is true , the solver will schedule a final break at the end of the route. Otherwise false will not include a final break at the end of the route.This option can be enabled only with normal breaks, dynamicBreaks is not supported. |
breaks | List of Break | Breaks defined for this vehicle. If multiple Breaks are specified, they must be non-overlapping. If a Time Window is specified for this vehicle then all defined breaks must be fully contained in the Time Window (i.e.: break's startTimeSec > timewindow's startTimeSec AND break's stopTimeSec + durationSec < timewindow's stopTimeSec). This parameter can be used alternatively with dynamicBreaks parameter, so they cannot use both at the same time. |
destination | Location | If provided, defines the location of the end-destination for this vehicle. If not specified, the route calculated for this vehicle terminates with the last visited waypoint |
destinationClusters | List of String | The name of clusters associated with the destination depot of the vehicle |
distanceCostFactor | Double | Default to 0.0. A multiplicative factor applied internally to the distance traveled by the vehicle. Must be non-negative (distanceCostFactor >= 0). Usage examples: By increasing the distanceCostFactor the optimization logic will be forced towards solutions in which waypoints that are geographically near are served consecutively even if this implies an increase in overall working time (this happens, as example, when two near waypoints have very different time windows). |
dynamicBreaks | List of DynamicBreak | List of dynamic breaks defined for this vehicles. It’s the solver that find the best (minimizing the whole route cost) allocation for each break. This parameter can be used alternatively with break parameter, so they cannot use both at the same time. |
finalServiceTimeSec | Integer | A non negative integer value, which defines a time in seconds that the vehicle must spend after arriving to its final destination, or after completing its service. If the parameter is missing the default value is 0. |
forceUse | Boolean | Default to false. It must be used just with the minimum requirements feature like minWorkingTimeSec and minCapacityMap. If true, force to use the vehicle even if it is not used by the optimizer for contrains on minimum requirements, this could result in an increased cost |
includeRegion | List of Location | A list of Locations (from 3 up to 50, different and non-collinear) specifying the shell of a simple closed polygon. Concave, convex and self-intersecting polygons are supported. If specified, only this vehicle will be allowed to serve waypoints falling inside the defined region (including edges). Note: all other constraints still apply (if, for example, a waypoint included in this vehicle’s region requires a tag defined by a different vehicle, that waypoint will not be served). Note: a vehicle defining an includeRegion is still allowed to serve other waypoints not included in its region. Note: defining a region does not make included waypoints more likely to be served than others nor does it force the vehicle to serve them before other waypoints. It just prevents them from being served by other vehicles (unless they are also included in overlapping regions defined by those other vehicles). |
initialServiceTimeSec | Integer | A non negative integer value, which defines a time in seconds that the vehicle must spend before leaving its initial location, or starting its service. If the parameter is missing the default value is 0. |
maxCapacityMap | map[String]Integer | List of maximum capacities for the vehicle. Each capacity is identified by a user-defined name (e.g.: "weight", "pounds", "seats", "volume_cm3", "crates", etc) and a non-negative (>=0) integer value representing the maximum allowed capacity. Waypoints loads, which are defined through the deliveryMap and pickupMap properties, and which are not set in the maxCapacityMap will have infinite capacity in those vehicles that do not define them. A vehicle for which we want to avoid serving a waypoint that defines a specific load (e.g. refrigerators, seats, weight etc.) must explicitly set the capacity for that load to 0. |
maxDistanceMt | Integer | Maximum allowed distance (meters) from departure to arrival at the end destination. |
maxDrivingTimeSec | Integer | Maximum allowed driving time from departure to arrival at the end destination. If not set or set to 0, the maximum driving time is limited by the timeWindow (or not limited at all if no timeWindow was specified). If specified together with maxWorkingTimeSec, then both constraints are enforced |
maxOrders | Integer | Maximum number of orders that can be assigned to this vehicle |
maxLocations | Integer | Maximum number of waypoint distinct locations that can be visited by this vehicle |
maxStops | Boolean | Maximum number of stops that can be performed by this vehicle; a stop is defined as a location change needed to reach a waypoint |
maxStopsCountOpenRouteOrigin | Boolean | Default to false. If true, in case the vehicle does not define an "origin", the "origin" route step is considered as a stop |
maxStopsClusterBasedCount | Integer | Default to false. If true, the definition of stop is different: a stop is counted if a waypoint is reached coming from a different set of clusters and the waypoint clusters define a vehicle stop or the waypoint does not define any cluster |
maxServiceStartTimeSec | Integer | Maximum allowed arrival time at the end destination. In case of conflict the strictest constraint between waypoint time windows and this value will be applied. |
maxWorkingTimeSec | Integer | Maximum allowed working time from departure to arrival at the end destination. "Working time" is the driving time + service time at each served waypoint + break time (if any). If not set or set to 0, the maximum working time is limited by the timeWindow (or not limited at all if no timeWindow was specified) |
minCapacityMap | map[String]Integer | List of minimum capacities for the vehicle. Each capacity is identified by a user-defined name (e.g.: "weight", "pounds", "seats", "volume_cm3", "crates", etc) and an integer value representing the minimum capacity. It is not an "hard constraints" but just a "best effort", meaning that it can be violated if by doing so results if better optimization results (i.e.: less costly solution) |
minServiceStartTimeSec | Integer | Minimum allowed arrival time at the first destination. In case of conflict the strictest constraint between waypoint time windows and this value will be applied. |
minWorkingTimeSec | Integer | Minimum working time from departure to arrival. Is not an "hard constraints" but is a "best effort", meaning that it can be violated if by doing so results if better optimization results (i.e.: less costly solution) |
originClusters | List of String | The name of clusters associated with the origin depot of the vehicle |
overdistanceStartMt | Integer | Meter after which the default distance cost factor (see distanceCostFactor above) is replaced by the over distance cost factor (see overdistanceCostFactor) |
overdistanceCostFactor | Double | Default to 0.0. A multiplicative factor applied internally to the meters traveled by the vehicle after the first overdistanceStartMt meters |
overtimeCostModel | TimeCostModel | Cost model for the time consumed by the vehicle during overtime. Cannot be set together with rateCardTimeCostModel or rateCardOvertimeCostModel. If set, one between overtimeStartTimeSec and overtimeThresholdSec must be set too. |
overtimeStartTimeSec | Integer | Time (in seconds), considered starting from instant 0, after which the time-cost model used for modeling cost is replaced by the overtime cost model parameter "overtimeCostModel". This parameter is mutually exclusive to the parameter "overtimeThresholdSec". From instant 0 to "overtimeStartTimeSec" (excluded) the Routing Engine uses the cost model describe in "timeCostModel", while after "overtimeStartTimeSec" the cost will be modeled with the "overtimeCostModel" parameter. |
overtimeThresholdSec | Integer | Defines the time relative to the start of the route after which the time-cost model used is defined by the "overtimeCostModel" parameter. While, before this time threshold, the Routing Engine uses the time-cost model defined in "timeCostModel". This value can be used in mutual exclusion and as an alternative to the "overtimeStartTimeSec" parameter. |
perStopCost | Integer | Default to 0. A cost that is factored-in internally every time the vehicle stops at a waypoint belonging to a different cluster along its route. NOTE: If none of the waypoints define the "cluster" property, waypoints are automatically clustered based on proximity, namely: waypoints that share the same location are considered part of the same cluster (i.e.: "perStopCost" is incurred only once when consecutively servicing multiple waypoints sharing the same location, multiple times if the waypoints' locations are different). |
perStopSetupTimeSec | Integer | Defaul to 0. The setup time in seconds incurred every time the vehicle has to stop at a different waypoint along its route (e.g.: parking time, per-stop equipment setup time, etc). Vehicle origin and destination are not considered. If for a set of waypoints the "perStopSetupTimeSec" should not be incurred along the route, you can associate those waypoints to a Cluster where the property "requireVehicleStop" is set to false, while if you set it to true also those waypoints will incur the "perStopSetupTimeSec" |
rateCardDistanceCostModel | RateCardDistanceCostModel | The "rate card" cost model for the vehicle traveled distance. Cannot be set together with distanceCostFactor or overdistanceCostFactor |
rateCardOverdistanceCostModel | RateCardOverdistanceCostModel | The "rate card" cost model for the vehicle traveled distance. Cannot be set together with overdistanceCostFactor. Must be set together with overdistanceStartMt |
rateCardOvertimeCostModel | RateCardOvertimeCostModel | The "rate card" cost model for the working time consumed by the vehicle during overtime. Cannot be set together with timeCostModel or overtimeCostModel. If set, one between overtimeStartTimeSec and overtimeThresholdSec must be set too. |
rateCardTimeCostModel | RateCardTimeCostModel | The "rate card" cost model for the working time consumed by the vehicle. Cannot be set together with timeCostModel or overtimeCostModel |
schedulingMode | String | Defaul to "FLEX_DEPARTURE". Used for selecting the mode that should be used for scheduling the vehicle. Allowed values are:
For example: given a working Time Window between 8am and 6pm, with schedulingMode set to FLEX_DEPARTURE the output schedule could be 9am-5pm. While if we use FIXED_DEPARTURE the output schedule could be 8am-4.30pm. Note: this parameter is only relevant when, in an optimization, the visited waypoints have time window constraints or the vehicle define one or more breaks. |
selectAmongFirst | Boolean | Default to false. A vehicle defining this flag must include in its route a waypoint that defines the corresponding flag amongFirst, serving it in the first position of the sequence. |
selectAmongLast | Boolean | Default to false. A vehicle defining this flag must include in its route a waypoint that defines the corresponding flag amongLast, serving it in the last position of the sequence. |
selectFirstPosition | Boolean | Default to false. A vehicle defining this flag must include in its route a waypoint that defines the corresponding flag firstPosition, serving it in the first position of the sequence. |
selectLastPosition | Boolean | Default to false. A vehicle defining this flag must include in its route a waypoint that defines the corresponding flag lastPosition, serving it in the last position of the sequence. |
speedFactor | Double | Defaul to 1.0. Vehicle's specific speed multiplier. Typically used in multi-vehicle optimizations when different vehicles have different average speeds. Allowed range is 0.2-4.0, out of range values are capped at range bounds. See also the global baseTrafficFactor parameter. |
tags | List of String | List of textual tags associated to this vehicle. Used together with waypoint's tagsExclude, tagsIncludeAnd and tagsIncludeOr fields, tags enable configuring complex vehicle-to-waypoint association constraints. |
timeCostModel | TimeCostModel | The cost model for the time consumed by the vehicle. Cannot be set together with rateCardTimeCostModel or rateCardOvertimeCostModel |
timeWindow | TimeWindow | If provided, defines the vehicle availability time range. If not specified, the vehicle will always be considered as available. The vehicle's time window will take into account the service time at the last visited waypoint and, if a destination is specified, the driving time to get there (that is, this API will never schedule a route so that the scheduled time of arrival at the last waypoint + the service time at that waypoint + the driving time to reach the destination exceeds the vehicle's time window). Note: both start time and stop time of this time window must be in the single day interval [0s, 86400s] |
trafficProfile | String | The name of the traffic profile used by this vehicle |
VehicleServiceTime Object
Property | Type | Description |
---|---|---|
startTimeSec | Integer | Vehicle service time start time in seconds since midnight (00:00). |
durationSec | Integer | Vehicle service time duration in seconds. |
Waypoint Object
Property | Type | Description |
---|---|---|
location | Location | Mandatory. Defines waypoint latitude/longitude coordinates |
amongFirst | Boolean | Default to false. A waypoint defining this flag must be served in the first position by a vehicle that defines the corresponding flag selectAmongFirst only if it is the first or the last element of its route; in other words, if the active vehicles honor their selectAmongFirst constraint, a waypoint flagged as amongFirst can be served by any vehicle in any position. |
amongLast | Boolean | Default to false. A waypoint defining this flag must be served in the last position by a vehicle that defines the corresponding flag selectAmongLast only if it is the last or the last element of its route; in other words, if the active vehicles honor their selectAmongLast constraint, a waypoint flagged as amongLast can be served by any vehicle in any position. |
clusters | List of String | The name of clusters associated with the waypoint. Note: if a waypoint is associated with a park & walk cluster, its name shouldn’t be inserted in this array (see the following parkAndWalkCluster parameter) |
deliveryMap | map[String]Integer | Defines the size of the delivery in terms of load unit types (i.e.: consumed vehicle capacity). Mutually exclusive with pickupMap (each waypoint is either a delivery or a pickup, not both). 0 where not specified |
dropoffNumber | Integer | When defined marks this waypoint as a "pickup for dropoff". The value represents the zero-based index of the dropoff waypoint in the "waypoints" array. A waypoint defining a dropoffNumber is a pickup point and therefore its deliveryMap must be empty. Consequently, the referenced dropoff waypoint is a dropoff/delivery point and therefore its pickupMap must be empty |
firstPosition | Boolean | Default to false. A waypoint defining this flag must be served (in the first position) by a vehicle that defines the corresponding flag selectFirstPosition. |
lastPosition | Boolean | Default to false. A waypoint defining this flag must be served (in the last position) by a vehicle that defines the corresponding flag seelctLastPosition. |
mcRefNumber | Integer | References the waypoint for which this waypoint is a choice, this choice is mutually exclusive so this waypoint or that one that is referenced. The value represents the zero-based index of the referenced waypoint in the Waypoint list |
name | String | If provided, this name string can be used to identify this waypoint in the output |
pickupMap | map[String]Integer | Defines the size of the pickup in terms of load unit types (i.e.: consumed vehicle capacity). Mutually exclusive with deliveryMap (each waypoint is either a delivery or a pickup, not both). 0 where not specified |
parkAndWalkCluster | String | Park & walk cluster associated with the waypoint |
positionPriority | Integer | Default to 0. The bigger is the value, the nearer to the beginning of the route the waypoint will be positioned. If the positionPriority value is 0, the waypoint can be served in any position. |
priority | Integer | Default to 0. Defines the priority of this waypoint where 0 is the lowest possible priority. Priority is only taken into account when all Waypoints cannot be serviced by the given Vehicles: under such circumstances Waypoints with a higher priority are preferred over lower-priority ones. It can influence the solver behivour just for including/excluding waypoints in the resulting route, it cannot be used for defining their visiting order. |
refNumber | Integer | References the waypoint that will be replaced by this one when processing alternative waypoint groups. Mandatory for waypoints defined as part of an alternative waypoint group, ignored otherwise. The value represents the zero-based index of the referenced waypoint in the Waypoint list. |
serviceTimeSec | Integer | The default amount of time in seconds which a vehicle is expected to be stationary at this waypoint (i.e. the time required for the servicing to take place). 0 where not specified |
serviceTimeSecPerVehicle | map[Integer]Integer | Override the default service time for the specified vehicles. Each map pair is defined by the index (the map key) of the vehicle in the zero-indexed list "vehicles" and by the ad-hoc service time for the specified vehicle (the map value). This enables modeling scenarios where the time it takes to serve a waypoint can be different based on what vehicle actually serves it. Examples are landscaping scenarios where a vehicle carring a team of 4 techs can serve a waypoint in half the time it would take a vehicle with only 2 techs on board: vehicle Ve1, with only 1 tech on board, takes 20 mins to serve waypoint A while vehicle Ve2, with 3 techs on board, takes 7 mins to serve the same waypoint |
tagsExclude | List of String | Define tag-based vehicle exclusion constraints: all vehicles defining one or more tags in this list are not allowed to service this waypoint. Exclusion constraints take precedence over inclusion ones |
tagsIncludeAnd | List of String | Define tag-based vehicle inclusion constraints: only vehicles defining all tags in this list (AND-criteria) are allowed to service this waypoint |
tagsIncludeOr | List of String | Define tag-based vehicle inclusion constraints: all vehicles defining one or more tags in this list (OR-criteria) are allowed to service this waypoint |
timeWindows | List of TimeWindow | If provided, defines an array of arrival time window constraints for this waypoint. Each time window defines a time interval when the waypoint can start to be serviced. This interval does not include the service time (e.g.: if service time is 30 minutes and the time window is from 10:00 to 11:00, then it is ok for the vehicle to arrive and start servicing the waypoint at 10:59 and complete the service 30 minutes later at 11.29). If the time window must include the service time, just subtract the service time from the end time of the time window (e.g.: if service time is 30 minutes and the time window is from 10:00 to 11:00 and must include the service time, then change the time window to be from 10:00 to 10:30). Multiple time windows can be used, for example, to prevent the waypoint from being serviced in off-limits intervals (e.g.: defining the time windows: 8:00-12:00 and 14:00-18:00 would prevent the waypoint from being serviced between 12:00 and 14:00). If not specified, this waypoint will always be available to be serviced |
WaypointIndex Object
Property | Type | Description |
---|---|---|
waypointNumber | Integer | The zero-based index of the waypoint in the "waypoints" array. |
locked | Boolean | Default to false. If true, the waypoint is locked to his relative position before or after other locked waypoints in the same route. |