Maps service
For models that require maps data, a maps service is part of our platform.
The maps service supports integrations with maps providers to calculate distance and travel matrices. Those matrices are used by some models (e.g. field-service-routing) to calculate the distance between locations, to optimize their routes accordingly.
The service includes the following features:
-
Pre-calculation and storage of matrices, to avoid calculating them on the fly while solving.
-
Incremental updates, so that the matrices do not have to be recalculated every time and the models can download only the matrix updates instead of the entire matrix.
-
Throttling based on the capacity of each maps provider, to avoid the provider being overloaded with requests.
-
Concurrency guarding, to prevent similar requests to the same provider to be done simultaneously.
Distance and Travel Matrices
The Maps Service is used to calculate a distance matrix and a travel matrix for a list of locations. The distance matrix is used to calculate the distance between two locations, while the travel matrix is used to calculate the travel time between two locations.
Each matrix is a 2D array of size n * n
, where n
is the number of locations in the list.
The matrices are calculated by sending requests to the maps provider with the coordinates of the locations.
The request is done during the SOLVING_STARTED
run status.
Available Map Providers
It’s possible to configure the map provider and map location in the configuration profiles or in the helm properties for self-hosted installations.
The maps service supports the following map providers:
-
haversine
: calculates the matrices using the Haversine formula. -
osrm
: calculates the matrices using an OSRM service for a specific location. -
external
: uses an external map provider to retrieve the matrices.
For users with a Trial plan, only the map provider haversine
is available.
Users using a self-hosted instance can also use the external
map provider, or their own OSRM service.
OSRM location management
When using the OSRM map provider, it’s necessary to deploy the OSRM map for the desired location.
For the Timefold Cloud Platform, there are already OSRM maps deployed. You can configure the location of the map in the configuration profiles. Not all map locations are loaded by default. If you want to use a map that is currently not available, you can contact us.
For self-hosted instances, the OSRM map can be configured and deployed using the self-hosted installations.
Implementing an external map provider
It’s possible to create an external map provider and configure the platform to use it.
The map provider must implement two endpoints:
-
POST
/v1/travelDistanceMatrix
to calculate the distance and travel time between locations. -
POST
/v1/waypoints
to calculate the waypoints for a list of locations.
A query parameter, options
, is also sent, with additional information about the request, namely the location, provider (external-provider
), tenant id, and model.
The OpenAPI specification can be found below.
Details
---
openapi: 3.0.3
info:
title: External Maps Provider API
description: External Maps Provider API
contact:
name: Timefold BV
url: https://timefold.ai
email: [email protected]
version: ""
servers:
- url: http://localhost:8480
description: Auto generated value
- url: http://0.0.0.0:8480
description: Auto generated value
paths:
/v1/travelDistanceMatrix:
post:
summary: Calculates travel time and distance matrix
parameters:
- name: options
in: query
schema:
type: string
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/LocationsDTO"
required: true
responses:
"400":
description: In case request given does not meet expectations
"500":
description: In case of processing errors
content:
application/json:
schema: {}
"200":
description: Travel and distance matrices
content:
application/octet-stream:
schema:
$ref: "#/components/schemas/TravelTimeAndDistanceDTO"
application/json:
schema:
$ref: "#/components/schemas/TravelTimeAndDistanceDTO"
tags:
- Test External Provider Resource
/v1/waypoints:
post:
summary: Calculates waypoints
parameters:
- name: options
in: query
schema:
type: string
requestBody:
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Location"
required: true
responses:
"400":
description: In case request given does not meet expectations
"500":
description: In case of processing errors
content:
application/json:
schema: {}
"200":
description: List of waypoints
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/Location"
tags:
- Test External Provider Resource
components:
schemas:
Location:
description: "Array of two elements: latitude and longitude, in that order."
maxItems: 2
minItems: 2
type: array
items:
format: double
type: number
example:
- 40.5044403760272
- -76.37894009358867
LocationsDTO:
type: object
properties:
source:
type: array
items:
$ref: "#/components/schemas/Location"
destination:
type: array
items:
$ref: "#/components/schemas/Location"
TravelTimeAndDistanceDTO:
type: object
properties:
travelTime:
type: array
items:
type: array
items:
format: double
type: number
distance:
type: array
items:
type: array
items:
format: double
type: number
A typical request and response for the travelDistanceMatrix
endpoint are shown below.
The source and destination locations to calculate the distance and travel time are sent as separate lists in the body of the request.
Each location is represented with an array with two elements, latitude and longitude, in that order
curl --location 'localhost:8480/v1/travelDistanceMatrix?options=provider:external-provider,tenantId:af7c1fe6-d669-414e-b066-e9733f0de7a8,location:us-northeast,model:employee-scheduling-v1' \
--header 'Content-Type: application/json' \
--data '{
"source": [
[
-71.1017,
42.3813
],
[
-89.6030,
41.5509
],
[
-2.1,
1.1
]
],
"destination": [
[
-71.1017,
42.3813
],
[
-89.6030,
41.5509
],
[
-2.1,
1.1
]
]
}'
The response includes two fields: travelTime
and distance
. Each field contains a list of lists, representing a matrix of the travel time (in seconds) and distances (in meters).
The outer list must be the size of the number of source locations, and each inner list must be the size of the number of destination locations.
The values must be represented in numerical format, with no negative numbers.
{
"travelTime": [
[
0.0,
148123.0,
591366.0
],
[
148123.0,
0.0,
701312.0
],
[
591366.0,
701312.0,
0.0
]
],
"distance": [
[
0.0,
2057259.0,
8213422.0
],
[
2057259.0,
0.0,
9740451.0
],
[
8213422.0,
9740451.0,
0.0
]
]
}
A typical request and response for the waypoints
endpoint are shown below.
The list of locations to calculate the waypoints is sent as the body of the request.
Request:
curl --location 'localhost:8480/v1/waypoints?options=provider:external-provider,tenantId:af7c1fe6-d669-414e-b066-e9733f0de7a8,location:us-northeast,model:employee-scheduling-v1' \
--header 'Content-Type: application/json' \
--data '
[
[
-71.1017,
42.3813
],
[
-89.6030,
41.5509
],
[
-2.1,
1.1
]
]'
The response contains a list with the location of the waypoints.
[
[
-71.1017,
42.3813
],
[
-89.603,
41.5509
],
[
-2.1,
1.1
]
]
Location Sets configuration
To avoid having to recalculate the distance matrix for the same locations, it’s possible to configure the precalculation of a location set. A location set is identified by its name and can be used by the models to avoid calculating an already cached distance matrix.
It’s possible to precalculate and cache a location set using the Location Sets Management API.
The API is available at /api/admin/v1/tenants/{tenantId}/maps/location-sets
, and it allows a user to configure location sets for a tenant.
Each location set, besides the name and the list of locations, must also be configured with a region (the region of the map used, eg. osrm-britain-and-ireland
)
and a map provider (eg. osrm
), so that it’s possible to create location sets for different regions and providers.
curl --location '{TIMEFOLD_PLATFORM_URL}/api/admin/v1/tenants/{TENANT_ID}/maps/location-sets' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {TOKEN}' \
--data '{
"name": "location-set-name",
"locations": [
[
40.5044403760272,
-76.37894009358867
],
[
41.5044403760272,
-75.37894009358867
]
],
"region": "{MAP_REGION}",
"provider": "{MAP_PROVIDER}"
}'
After the creation of a location set, its status will be PROCESSING
. After the matrix is calculated, the location set can be in one of two states: COMPLETED
or FAILED
.
If the status is COMPLETED
, the distance matrix of the location set was successfully calculated and cached.
Otherwise, when the status is FAILED
, the distance matrix was not stored in the cache.
curl --location '{TIMEFOLD_PLATFORM_URL}/api/admin/v1/tenants/{TENANT_ID}/maps/location-sets/location-set-name' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {TOKEN}'
{
"name": "location-set-name",
"locations": [
[
40.5044403760272,
-76.37894009358867
],
[
41.5044403760272,
-75.37894009358867
]
],
"region": "{MAP_REGION}",
"provider": "{MAP_PROVIDER}",
"status": "COMPLETED"
}
When the location set is deleted, the distance matrix is also deleted and removed from the cache.
curl --location --request DELETE '{TIMEFOLD_PLATFORM_URL}/api/admin/v1/tenants/{TENANT_ID}/maps/location-sets/location-set-name' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {TOKEN}' \
It’s also possible to add a list of locations to a location set, using the PATCH operation. In this case the new locations will be added at the end of the location set.
curl --location --request PATCH '{TIMEFOLD_PLATFORM_URL}/api/admin/v1/tenants/{TENANT_ID}/maps/location-sets/location-set-name' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {TOKEN}' \
--data '[
[
43.5044403760272,
-76.37894009358867
]
]'
All requests to the Location Sets Management API require a bearer token based on the oauth2 platform configuration.
For example, for the field-service-routing model, you can configure a location setting the field locationSetName
of the modelInput
with the name of the location set.
{
"modelInput": {
"locationSetName": "location-set-name",
...
},
...
}