Assign jobs to groups
Job grouping in the HERE Tour Planning API offers a versatile solution for optimizing logistics operations, especially in scenarios where efficient route planning and resource allocation are crucial. Consider a delivery service tasked with transporting goods to various destinations within a city. By utilizing job grouping, the delivery company can strategically organize deliveries based on specific criteria, such as geographic proximity, delivery windows, or product types.
Potential applications for job grouping
The following examples illustrate various practical scenarios where job grouping enhances operational efficiency and streamlines logistical processes:
-
Postal deliveries: Postmen often carry sets of house keys corresponding to specific areas. Each set represents a distinct delivery zone. Therefore, they typically complete all deliveries within one area before moving on to the next, optimizing their route efficiency.
-
Restricted access areas: In scenarios where drivers must register at a gate to access a specific area, job grouping becomes essential. Once inside, drivers aim to complete all deliveries before signing out, maximizing efficiency and minimizing disruptions caused by repeated entries and exits.
-
Driver efficiency in urban deliveries: In urban settings, drivers prioritize completing deliveries within specific city quarters, treating each quarter as a distinct entity. Despite potential route optimizations, such as serving a single job in a neighboring quarter, drivers often opt for this structured approach to maintain consistency, minimize disruptions, and uphold efficient delivery operations.
How job grouping works
The HERE Tour Planning API enables job grouping through an optional groupId parameter. By assigning the same groupId to a set of jobs within a problem, you instruct the optimization algorithm to generate a routing solution where a vehicle can visit all jobs within that particular group, while ensuring that each job within a group is assigned to a single vehicle only (that is, a single vehicle can serve multiple groups, but it cannot be assigned to share a group with another vehicle).
You can select one of the following modes for job grouping to adjust the grouping mechanism to your needs:
-
strict(default): All jobs from the same group are completed before other jobs, or jobs from a different group, can commence. In this mode, the optimization algorithm avoids mixing stand-alone jobs with group assignments but allows for stand-alone jobs to be slotted in between subsequent group assignments.In this more, the algorithm keeps operations such as reloads and breaks with specific locations separate from group jobs, except for breaks without specific locations. This means that a break with location or a reload can only be scheduled after or before a vehicle completes all assignments within a particular group.
For a practical demonstration, see Use case: Grouping delivery jobs by area.
-
flexible: In this mode, jobs with different group IDs can be mixed together as the tour progresses, with the emphasis put on finding the most efficient route, if possible.In this mode, the optimization algorithm prioritizes efficiency by allowing to schedule a break (with or without location) or reload anywhere within the tour.
For a practical demonstration, see Use case: Ensure safe school transportation of students.
Job clustering is permitted in job groups, with the constraint that jobs from different groups are not clustered together. Additionally, the algorithm supports global usage of tour order with groups and allows for priority assignment with group jobs, providing the flexibility to unassign lower priority tasks.
Use case: Grouping delivery jobs by area
Consider a delivery company aiming to streamline its operations by grouping jobs according to distinct delivery areas. In this scenario, each area represents a designated set of delivery tasks that must be completed before moving to the next one. For instance, a vehicle can only transition to a new area once all delivery tasks within the current area have been fulfilled.
Problem
The following problem consists of a set of jobs with distinct GroupId values representing neighborhood names in a city in the USA. One job does not have a GroupId assigned.
Click to expand/collapse the sample JSON
{
"fleet": {
"types": [
{
"id": "Vehicle_1",
"profile": "car",
"costs": {
"fixed": 2,
"distance": 0.0001,
"time": 0.0005
},
"shifts": [
{
"start": {
"time": "2021-10-23T08:00:00Z",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
}
},
"end": {
"time": "2021-10-23T21:00:00Z",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
}
}
}
],
"capacity": [
10
],
"amount": 1
}
],
"profiles": [
{
"type": "car",
"name": "car"
}
]
},
"plan": {
"jobs": [
{
"id": "Job_1",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"duration": 1500,
"groupId": "Bradley"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_2",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"duration": 1500,
"groupId": "Bradley"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_3",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"duration": 1500,
"groupId": "Bradley"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_4",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"duration": 1500,
"groupId": "Audubon"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_5",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"duration": 1500,
"groupId": "Audubon"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_6",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"duration": 1500,
"groupId": "Audubon"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_7",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"duration": 1500
}
],
"demand": [
1
]
}
]
}
}
]
}
}Solution
The following snippet shows the solution that the optimization algorithm provided, based on the preceding problem:
Click to expand/collapse the sample JSON
{
"statistic": {
"cost": 8.8008,
"distance": 9823,
"duration": 11637,
"times": {
"driving": 1137,
"serving": 10500,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "Vehicle_1_1",
"typeId": "Vehicle_1",
"stops": [
{
"time": {
"arrival": "2021-10-23T08:00:00Z",
"departure": "2021-10-23T08:00:00Z"
},
"load": [
7
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"time": {
"start": "2021-10-23T08:00:00Z",
"end": "2021-10-23T08:00:00Z"
}
}
],
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"distance": 0
},
{
"time": {
"arrival": "2021-10-23T08:03:01Z",
"departure": "2021-10-23T08:28:01Z"
},
"load": [
6
],
"activities": [
{
"jobId": "Job_1",
"type": "delivery",
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"time": {
"start": "2021-10-23T08:03:01Z",
"end": "2021-10-23T08:28:01Z"
}
}
],
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"distance": 1614
},
{
"time": {
"arrival": "2021-10-23T08:31:02Z",
"departure": "2021-10-23T08:56:02Z"
},
"load": [
5
],
"activities": [
{
"jobId": "Job_2",
"type": "delivery",
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"time": {
"start": "2021-10-23T08:31:02Z",
"end": "2021-10-23T08:56:02Z"
}
}
],
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"distance": 2865
},
{
"time": {
"arrival": "2021-10-23T08:57:33Z",
"departure": "2021-10-23T09:22:33Z"
},
"load": [
4
],
"activities": [
{
"jobId": "Job_3",
"type": "delivery",
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"time": {
"start": "2021-10-23T08:57:33Z",
"end": "2021-10-23T09:22:33Z"
}
}
],
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"distance": 3516
},
{
"time": {
"arrival": "2021-10-23T09:25:40Z",
"departure": "2021-10-23T09:50:40Z"
},
"load": [
3
],
"activities": [
{
"jobId": "Job_7",
"type": "delivery",
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"time": {
"start": "2021-10-23T09:25:40Z",
"end": "2021-10-23T09:50:40Z"
}
}
],
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"distance": 5774
},
{
"time": {
"arrival": "2021-10-23T09:52:50Z",
"departure": "2021-10-23T10:17:50Z"
},
"load": [
2
],
"activities": [
{
"jobId": "Job_5",
"type": "delivery",
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"time": {
"start": "2021-10-23T09:52:50Z",
"end": "2021-10-23T10:17:50Z"
}
}
],
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"distance": 6778
},
{
"time": {
"arrival": "2021-10-23T10:18:51Z",
"departure": "2021-10-23T10:43:51Z"
},
"load": [
1
],
"activities": [
{
"jobId": "Job_6",
"type": "delivery",
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"time": {
"start": "2021-10-23T10:18:51Z",
"end": "2021-10-23T10:43:51Z"
}
}
],
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"distance": 7239
},
{
"time": {
"arrival": "2021-10-23T10:45:33Z",
"departure": "2021-10-23T11:10:33Z"
},
"load": [
0
],
"activities": [
{
"jobId": "Job_4",
"type": "delivery",
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"time": {
"start": "2021-10-23T10:45:33Z",
"end": "2021-10-23T11:10:33Z"
}
}
],
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"distance": 7861
},
{
"time": {
"arrival": "2021-10-23T11:13:57Z",
"departure": "2021-10-23T11:13:57Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"time": {
"start": "2021-10-23T11:13:57Z",
"end": "2021-10-23T11:13:57Z"
}
}
],
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"distance": 9823
}
],
"statistic": {
"cost": 8.8008,
"distance": 9823,
"duration": 11637,
"times": {
"driving": 1137,
"serving": 10500,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}As the solution demonstrates, the optimization algorithm ensured that jobs with the same GroupID parameter are grouped together in the sequence of stops:
GroupId:Bradley-Job_1(stop 1),Job_2(stop 2),Job_3(stop 3)- No group:
Job_7(stop 4) GroupId:Audubon-Job_4(stop 5),Job_5(stop 6),Job_6(stop 7)
Note
In optimizing the solution for a problem with group jobs, the algorithm may choose various sequences of groups or individual tasks. However, the algorithm is designed not to interleave standalone jobs before completing all jobs from a specific group.
The following figure provides a color-coded representation of the sequence of stops from the preceding solution. The figure shows how jobs related to a specific neighborhood are planned sequentially, based on their GroupId (or lack thereof):
Note
While the preceding example demonstrates a simplified problem for the purpose of explanation, the following figure depicts a more realistic use case for job groups with 80 jobs divided into 4 groups, each containing an equal number of jobs:
This example further illustrates how organizing jobs into groups helps in managing the jobs more efficiently, especially in contexts such task allocation, or workload distribution.
By contrast, the following snippet provides a solution for the preceding sample problem, except with group assignments for jobs removed:
Click to expand/collapse the sample JSON
{
"statistic": {
"cost": 8.7913,
"distance": 9823,
"duration": 11618,
"times": {
"driving": 1118,
"serving": 10500,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "Vehicle_1_1",
"typeId": "Vehicle_1",
"stops": [
{
"time": {
"arrival": "2021-10-23T08:00:00Z",
"departure": "2021-10-23T08:00:00Z"
},
"load": [
7
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"time": {
"start": "2021-10-23T08:00:00Z",
"end": "2021-10-23T08:00:00Z"
}
}
],
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"distance": 0
},
{
"time": {
"arrival": "2021-10-23T08:04:35Z",
"departure": "2021-10-23T08:29:35Z"
},
"load": [
6
],
"activities": [
{
"jobId": "Job_2",
"type": "delivery",
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"time": {
"start": "2021-10-23T08:04:35Z",
"end": "2021-10-23T08:29:35Z"
}
}
],
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"distance": 2407
},
{
"time": {
"arrival": "2021-10-23T08:31:06Z",
"departure": "2021-10-23T08:56:06Z"
},
"load": [
5
],
"activities": [
{
"jobId": "Job_3",
"type": "delivery",
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"time": {
"start": "2021-10-23T08:31:06Z",
"end": "2021-10-23T08:56:06Z"
}
}
],
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"distance": 3058
},
{
"time": {
"arrival": "2021-10-23T08:59:13Z",
"departure": "2021-10-23T09:24:13Z"
},
"load": [
4
],
"activities": [
{
"jobId": "Job_7",
"type": "delivery",
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"time": {
"start": "2021-10-23T08:59:13Z",
"end": "2021-10-23T09:24:13Z"
}
}
],
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"distance": 5316
},
{
"time": {
"arrival": "2021-10-23T09:26:23Z",
"departure": "2021-10-23T09:51:23Z"
},
"load": [
3
],
"activities": [
{
"jobId": "Job_5",
"type": "delivery",
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"time": {
"start": "2021-10-23T09:26:23Z",
"end": "2021-10-23T09:51:23Z"
}
}
],
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"distance": 6320
},
{
"time": {
"arrival": "2021-10-23T09:52:24Z",
"departure": "2021-10-23T10:17:24Z"
},
"load": [
2
],
"activities": [
{
"jobId": "Job_6",
"type": "delivery",
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"time": {
"start": "2021-10-23T09:52:24Z",
"end": "2021-10-23T10:17:24Z"
}
}
],
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"distance": 6781
},
{
"time": {
"arrival": "2021-10-23T10:19:06Z",
"departure": "2021-10-23T10:44:06Z"
},
"load": [
1
],
"activities": [
{
"jobId": "Job_4",
"type": "delivery",
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"time": {
"start": "2021-10-23T10:19:06Z",
"end": "2021-10-23T10:44:06Z"
}
}
],
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"distance": 7403
},
{
"time": {
"arrival": "2021-10-23T10:45:50Z",
"departure": "2021-10-23T11:10:50Z"
},
"load": [
0
],
"activities": [
{
"jobId": "Job_1",
"type": "delivery",
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"time": {
"start": "2021-10-23T10:45:50Z",
"end": "2021-10-23T11:10:50Z"
}
}
],
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"distance": 8209
},
{
"time": {
"arrival": "2021-10-23T11:13:38Z",
"departure": "2021-10-23T11:13:38Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"time": {
"start": "2021-10-23T11:13:38Z",
"end": "2021-10-23T11:13:38Z"
}
}
],
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"distance": 9823
}
],
"statistic": {
"cost": 8.7913,
"distance": 9823,
"duration": 11618,
"times": {
"driving": 1118,
"serving": 10500,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}In the preceding solution, the optimization algorithm determines the fastest route possible between subsequent stops, with no additional constraints, as visualized in the following figure:
As demonstrated in the preceding solution, the optimization algorithm allows including jobs with and without a GroupId within a single problem. At the same time, the algorithm prevents jobs without a GroupID from intermixing with jobs belonging to a group. This segregation ensures that jobs within a group are handled consecutively, optimizing workflow and preventing any potential disruption.
Job groups with PUDOs
"PUDO" is the abbreviation for "Pick-Up and Drop-Off" point, serving as a location where goods are either collected for distribution or dropped off for further processing. Within the context of group jobs, PUDOs function as the initial or final stops, facilitating the collection or delivery of goods or passengers.
Note
This feature is currently in BETA. BETA features are in end-stage development and have no major bugs but their coverage, quality, performance, or test coverage may not yet be final. The feature's data model and problem definition remain stable and unchanged from previous versions. You can use BETA features in your applications, understanding that minor behavior refinements may occur as the feature approaches full production readiness.
Use case: Designating parcel pickup and delivery points
Consider a sample courier service, which places their PUDOs strategically to serve as pick-up or delivery points that facilitate efficient operations at the beginning or end of a job group in the HERE Tour Planning API. In the context of this example, the service can classify PUDOs into two categories:
-
First PUDO: Positioned as the first stop in a chain of jobs belonging to a specific group, it represents stores, post offices, or dedicated pickup lockers where customers can drop off their packages for later delivery by a courier.
-
Last PUDO: Positioned as the final stop in a job group, it represents delivery lockers located strategically in key areas of the city. Customers who might be unavailable to receive packages during regular delivery hours can choose to have their parcels delivered to these lockers instead of their homes or offices.
To ensure that a vehicle starts and/or ends with a PUDO, in the problem JSON, within the plan object, add the group array of objects, as shown in the following snippet:
"plan": {
"fleet": {...},
"groups": [
{
"id": "Bradley",
"pudos": [
{
"id": "pudoBradleyFirst",
"assignAt": "first",
"places": [
{
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"duration": 300,
"tag": "groupBradleyFirstPudo"
}
]
},
{
"id": "pudoBradleyLast",
"assignAt": "last",
"places": [
{
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"duration": 300,
"tag": "groupBradleyLastPudo"
}
]
}
]
}
],
"jobs": {...}
}This JSON snippet describes a data structure for organizing parcel delivery tasks within job groups, specifically focusing on the "Bradley" group from the previous example.
"id": "Bradley": This identifies the group to which PUDOs apply by its unique identifier,"Bradley"."pudos": This array contains information about the PUDOs (Pick Up Drop Off points) associated with the Bradley group. A single group can have two PUDOs at most, each with a differentassignAtvalue."id": "pudoBradleyFirst"and"id": "pudoBradleyLast": These are identifiers for the first and last PUDOs within the Bradley group, respectively."assignAt": Indicates whether the PUDO is assigned at the beginning ("first") or end ("last") of the group's sequence of delivery tasks."places": Contains details about the location, duration, and tag associated with each PUDO."location": Specifies the latitude and longitude coordinates of the PUDO."duration": Represents the estimated duration of time spent at the PUDO, in seconds."tag": Provides a descriptive tag for the PUDO, such as"groupBradleyFirstPudo"or"groupBradleyLastPudo".
For more information, see the API Reference.
Problem
The following problem builds on top of the one previously shown by incorporating PUDOs for both groups. In this updated problem, the Bradley group is assigned with first and last PUDOs, while the Audubon group has a last PUDO only:
Click to expand/collapse the sample JSON
{
"configuration": {
"experimentalFeatures":
["pudos"]
},
"fleet": {
"types": [
{
"id": "Vehicle_1",
"profile": "car",
"costs": {
"fixed": 2,
"distance": 0.0001,
"time": 0.0005
},
"shifts": [
{
"start": {
"time": "2021-10-23T08:00:00Z",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
}
},
"end": {
"time": "2021-10-23T21:00:00Z",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
}
}
}
],
"capacity": [
10
],
"amount": 1
}
],
"profiles": [
{
"type": "car",
"name": "car"
}
]
},
"plan": {
"groups": [
{
"id": "Audubon",
"pudos": [
{
"id": "pudoAudubonLast",
"assignAt": "last",
"places": [
{
"location": {
"lat": 38.21394813756292,
"lng": -85.72935333995113
},
"duration": 300,
"tag": "groupAudubonLastPudo"
}
]
}
]
},
{
"id": "Bradley",
"pudos": [
{
"id": "pudoBradleyFirst",
"assignAt": "first",
"places": [
{
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"duration": 300,
"tag": "groupBradleyFirstPudo"
}
]
},
{
"id": "pudoBradleyLast",
"assignAt": "last",
"places": [
{
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"duration": 300,
"tag": "groupBradleyLastPudo"
}
]
}
]
}
],
"jobs": [
{
"id": "Job_1_Bradley",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"duration": 1500,
"groupId": "Bradley"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_2_Bradley",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"duration": 1500,
"groupId": "Bradley"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_3_Bradley",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"duration": 1500,
"groupId": "Bradley"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_4_Audobon",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"duration": 1500,
"groupId": "Audubon"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_5_Audobon",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"duration": 1500,
"groupId": "Audubon"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_6_Audobon",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"duration": 1500,
"groupId": "Audubon"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "Job_7_No_Group",
"tasks": {
"deliveries": [
{
"places": [
{
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"duration": 1500
}
],
"demand": [
1
]
}
]
}
}
]
}
}Solution
As the updated solution demonstrates, the introduction of PUDOs for both groups significantly affects the group and job order:
Click to expand/collapse the sample JSON
{
"statistic": {
"cost": 10.2287,
"distance": 16177,
"duration": 13222,
"times": {
"driving": 1822,
"serving": 11400,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "Vehicle_1_1",
"typeId": "Vehicle_1",
"stops": [
{
"time": {
"arrival": "2021-10-23T08:00:00Z",
"departure": "2021-10-23T08:00:00Z"
},
"load": [
7
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"time": {
"start": "2021-10-23T08:00:00Z",
"end": "2021-10-23T08:00:00Z"
}
}
],
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"distance": 0
},
{
"time": {
"arrival": "2021-10-23T08:03:14Z",
"departure": "2021-10-23T08:28:14Z"
},
"load": [
6
],
"activities": [
{
"jobId": "Job_4_Audobon",
"type": "delivery",
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"time": {
"start": "2021-10-23T08:03:14Z",
"end": "2021-10-23T08:28:14Z"
}
}
],
"location": {
"lat": 38.20944898657478,
"lng": -85.73618600023076
},
"distance": 1962
},
{
"time": {
"arrival": "2021-10-23T08:29:55Z",
"departure": "2021-10-23T08:54:55Z"
},
"load": [
5
],
"activities": [
{
"jobId": "Job_6_Audobon",
"type": "delivery",
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"time": {
"start": "2021-10-23T08:29:55Z",
"end": "2021-10-23T08:54:55Z"
}
}
],
"location": {
"lat": 38.213713845866266,
"lng": -85.73778517460907
},
"distance": 2584
},
{
"time": {
"arrival": "2021-10-23T08:55:56Z",
"departure": "2021-10-23T09:20:56Z"
},
"load": [
4
],
"activities": [
{
"jobId": "Job_5_Audobon",
"type": "delivery",
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"time": {
"start": "2021-10-23T08:55:56Z",
"end": "2021-10-23T09:20:56Z"
}
}
],
"location": {
"lat": 38.216043801819936,
"lng": -85.73340726603497
},
"distance": 3045
},
{
"time": {
"arrival": "2021-10-23T09:22:16Z",
"departure": "2021-10-23T09:27:16Z"
},
"load": [
4
],
"activities": [
{
"jobId": "pudoAudubonLast",
"type": "pudo",
"jobTag": "groupAudubonLastPudo",
"location": {
"lat": 38.21394813756292,
"lng": -85.72935333995113
},
"time": {
"start": "2021-10-23T09:22:16Z",
"end": "2021-10-23T09:27:16Z"
}
}
],
"location": {
"lat": 38.21394813756292,
"lng": -85.72935333995113
},
"distance": 3627
},
{
"time": {
"arrival": "2021-10-23T09:30:01Z",
"departure": "2021-10-23T09:55:01Z"
},
"load": [
3
],
"activities": [
{
"jobId": "Job_7_No_Group",
"type": "delivery",
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"time": {
"start": "2021-10-23T09:30:01Z",
"end": "2021-10-23T09:55:01Z"
}
}
],
"location": {
"lat": 38.22218511622605,
"lng": -85.72979048849281
},
"distance": 4879
},
{
"time": {
"arrival": "2021-10-23T09:59:54Z",
"departure": "2021-10-23T10:04:54Z"
},
"load": [
3
],
"activities": [
{
"jobId": "pudoBradleyFirst",
"type": "pudo",
"jobTag": "groupBradleyFirstPudo",
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"time": {
"start": "2021-10-23T09:59:54Z",
"end": "2021-10-23T10:04:54Z"
}
}
],
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"distance": 7887
},
{
"time": {
"arrival": "2021-10-23T10:07:28Z",
"departure": "2021-10-23T10:32:28Z"
},
"load": [
2
],
"activities": [
{
"jobId": "Job_3_Bradley",
"type": "delivery",
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"time": {
"start": "2021-10-23T10:07:28Z",
"end": "2021-10-23T10:32:28Z"
}
}
],
"location": {
"lat": 38.21284881354167,
"lng": -85.74417903223404
},
"distance": 9022
},
{
"time": {
"arrival": "2021-10-23T10:34:31Z",
"departure": "2021-10-23T10:59:31Z"
},
"load": [
1
],
"activities": [
{
"jobId": "Job_1_Bradley",
"type": "delivery",
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"time": {
"start": "2021-10-23T10:34:31Z",
"end": "2021-10-23T10:59:31Z"
}
}
],
"location": {
"lat": 38.20500739379202,
"lng": -85.73925425866145
},
"distance": 10444
},
{
"time": {
"arrival": "2021-10-23T11:02:32Z",
"departure": "2021-10-23T11:27:32Z"
},
"load": [
0
],
"activities": [
{
"jobId": "Job_2_Bradley",
"type": "delivery",
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"time": {
"start": "2021-10-23T11:02:32Z",
"end": "2021-10-23T11:27:32Z"
}
}
],
"location": {
"lat": 38.20849490396401,
"lng": -85.74557648589085
},
"distance": 11695
},
{
"time": {
"arrival": "2021-10-23T11:29:43Z",
"departure": "2021-10-23T11:34:43Z"
},
"load": [
0
],
"activities": [
{
"jobId": "pudoBradleyLast",
"type": "pudo",
"jobTag": "groupBradleyLastPudo",
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"time": {
"start": "2021-10-23T11:29:43Z",
"end": "2021-10-23T11:34:43Z"
}
}
],
"location": {
"lat": 38.210124321431536,
"lng": -85.75204292373883
},
"distance": 12487
},
{
"time": {
"arrival": "2021-10-23T11:40:22Z",
"departure": "2021-10-23T11:40:22Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"time": {
"start": "2021-10-23T11:40:22Z",
"end": "2021-10-23T11:40:22Z"
}
}
],
"location": {
"lat": 38.1948557378452,
"lng": -85.73165933623139
},
"distance": 16177
}
],
"statistic": {
"cost": 10.2287,
"distance": 16177,
"duration": 13222,
"times": {
"driving": 1822,
"serving": 11400,
"waiting": 0,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}The following figure visualizes the previous solution, highlighting the order of stops for each group, as well as the PUDOs assigned to each group:
As the solution demonstrates, the Bradley group now includes both first and last PUDOs at the same location. Consequently, any vehicle serving this group must visit that location as the initial and final stop before proceeding to other jobs outside the Bradley group. This approach ensures that the vehicle picks up all parcels related to the group and then drops off undelivered packages at the same spot after completing all jobs within the group. These undelivered packages can then be picked up on another tour.
On the other hand, the Audubon group has a last PUDO only. This implies that this stop will consistently be the last one while serving this specific group, with the sequence of preceding stops dynamically determined by the optimization algorithm.
Flexible groups
The flexibleGroups feature allows related jobs to be linked together, providing benefits for various use cases. Leveraging the constraint that only a single vehicle can complete jobs within a given group, vehicles can also optimize their routes by interleaving jobs from different groups (for example, A1 -> B1 -> A2 -> B2). This approach is in contrast to more strict original job grouping, where vehicles would need to complete all jobs in one group before moving on to jobs from another group (for example, A1 -> A2 -> B1 -> B2).
For example, a postman can be assigned with specific sets of keys for accessing to specific buildings, mailboxes, communities, and so on. With the strict approach, a postman would be required to complete all assignments corresponding to a specific set of keys before moving to the next group, which might not always be efficient.
With the flexible approach, a postman can deliver a few items that require "key set A", then a few that require "key set B", and return to the ones requiring "key set A", if that’s the most efficient route.
You set the group placement as part of the plan.groups.placement object, as shown in the following example:
{ ...
"groups": [
{
"id": "group_A",
"placement": "flexible"
},
{
"id": "group_B",
"placement": "flexible"
},
{
"id": "Group_C",
"placement": "strict"
},
]
...
}The strict value means that a vehicle can proceed to serving another group only after completing all the assignments withing this group, as described in previous sections of this document.
For more information, see API Reference.
Note
This is an ALPHA feature, which means it is new or experimental and under active development. Alpha features are provided for testing and feedback purposes. They may change significantly or might not become generally available. For more information, see Explore experimental features.
To enable this feature, add the
flexibleGroupsflag to theexperimentalFeaturesarray.Flexible groups are compatible with the PUDO functionality.
Use case: Ensure safe school transportation of students
Another practical example to demonstrate the usefulness of this feature can be a school bus scenario where students have two journeys: one from home to school and another from school back to home. In this context, parents often require that each student is driven to and from school by the same driver, ensuring the students' safety.
Using flexible groups ensures designing optimal tours for school buses, in which students are transported by the same driver during both their morning and afternoon commutes.
The following list summarizes the main events that occur during a typical student's daily commute:
- Morning pickup: The student is picked up from their home to begin their day.
- Dropoff at school: The student arrives at school, marking the start of their educational activities.
- Afternoon pickup: The student is picked up from school to continue with their daily routine or head back home.
- Evening dropoff: The student's day concludes with a dropoff at their home.
In the HERE Tour Planning API, you can model these student commute events as two separate multi-jobs per student, one for the morning commute and one for the afternoon commute. Each multi-job necessitates the use of two tasks: a pickup task and a delivery task. The following example illustrates this concept:
[Job 1: Pickup A → Delivery A] → [Job 2: Pickup B → Delivery B]
To ensure the link between the morning and afternoon jobs in the problem, you must include the following configuration items in the problem:
- In the
groupsobject, create a unique groupidfor each student. Set each group's placement asflexible. - In each job pair representing the drives to and from school, assign the morning dropoff (delivery) task and the afternoon pickup task with the same
groupId.
By grouping related jobs together by using the flexibleGroups feature, you can not only optimize routes but also ensure that each student is transported by the same driver (or bus) for both their morning and afternoon journeys. This provides an added layer of safety and security, as students are less likely to be left unattended or mismatched with a different driver.
The following diagram shows a visual summary of this use case:
Problem
The following problem JSON file emulates the school bus use case as previously discussed, with the following settings:
- The fleet consists of two vehicles, each having the capacity to carry up to four students at any point during the tour.
- There are seven students that the drivers require to pick up in the morning, drop off at school, and then drive back home in the afternoon.
- Each student (represented by a student code) is assigned with their own, unique
groupId. - Each group's
placementsetting is set toflexible. - For each student code, the tasks representing the morning dropoff at school and the afternoon pickup are assigned with
groupIdto ensure that a student is assigned to the same driver for both commutes and that a driver can carry multiple students at the same time in the bus, increasing the tour efficiency.
Click to expand/collapse the sample JSON
{
"configuration": {
"experimentalFeatures":
["flexibleGroups"]
},
"fleet": {
"types": [
{
"id": "bus",
"profile": "bus",
"costs": {
"fixed": 20,
"distance": 0,
"time": 0.005
},
"shifts": [
{
"start": {
"time": "2023-05-28T06:00:00Z",
"location": {
"lat": 52.50935,
"lng": 13.41997
}
},
"end": {
"time": "2023-05-28T18:00:00Z",
"location": {
"lat": 52.50935,
"lng": 13.41997
}
}
}
],
"capacity": [
4
],
"amount": 2
}
],
"profiles": [
{
"type": "bus",
"name": "bus"
}
]
},
"plan": {
"groups": [
{
"id": "Student_Code_1",
"placement": "flexible"
},
{
"id": "Student_Code_2",
"placement": "flexible"
},
{
"id": "Student_Code_3",
"placement": "flexible"
},
{
"id": "Student_Code_4",
"placement": "flexible"
},
{
"id": "Student_Code_5",
"placement": "flexible"
},
{
"id": "Student_Code_6",
"placement": "flexible"
},
{
"id": "Student_Code_7",
"placement": "flexible"
}
],
"jobs": [
{
"id": "PickupEvent_1",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.50829,
"lng": 13.409382
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_1"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "PickupEvent_2",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.510099,
"lng": 13.390205
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_2"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "PickupEvent_3",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.519549,
"lng": 13.456663
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_3"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "PickupEvent_4",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.483268,
"lng": 13.394395
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_4"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "PickupEvent_5",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.500151,
"lng": 13.458333
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_5"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "PickupEvent_6",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.516855,
"lng": 13.497785
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_6"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "PickupEvent_7",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T06:00:00Z",
"2023-05-28T07:30:00Z"
]
],
"location": {
"lat": 52.50005,
"lng": 13.400365
},
"duration": 5
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T07:50:00Z",
"2023-05-28T09:10:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_7"
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_1",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_1"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.50829,
"lng": 13.409382
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_2",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_2"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.510099,
"lng": 13.390205
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_3",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_3"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.519549,
"lng": 13.456663
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_4",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_4"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.483268,
"lng": 13.394395
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_5",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_5"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.500151,
"lng": 13.458333
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_6",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_6"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.516855,
"lng": 13.497785
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
},
{
"id": "DropoffEvent_7",
"tasks": {
"pickups": [
{
"places": [
{
"times": [
[
"2023-05-28T14:00:00Z",
"2023-05-28T14:30:00Z"
]
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"duration": 5,
"groupId": "Student_Code_7"
}
],
"demand": [
1
]
}
],
"deliveries": [
{
"places": [
{
"times": [
[
"2023-05-28T15:00:00Z",
"2023-05-28T16:00:00Z"
]
],
"location": {
"lat": 52.50005,
"lng": 13.400365
},
"duration": 5
}
],
"demand": [
1
]
}
]
}
}
]
}
}Solution
The following figure provides a visualized solution of the previous problem, with the key elements highlighted:
As presented in the visualization, two vehicles were assigned to complete the jobs, with each vehicle taking the same students on their morning and afternoon commutes, for example, highlighted by PickupEvent_6, and DropoffEvent_6 instances at home (stops 3 and 5) and school (stop 4). The flexible placement of all groups allowed the drivers to serve jobs one after another in an efficient manner, rather than picking up and then dropping off each student separately.
The following section contains the full solution JSON for this use case:
Click to expand/collapse the sample JSON
{
"statistic": {
"cost": 338.235,
"distance": 63391,
"duration": 59647,
"times": {
"driving": 8473,
"serving": 140,
"waiting": 51034,
"stopping": 0,
"break": 0
}
},
"tours": [
{
"vehicleId": "bus_2",
"typeId": "bus",
"stops": [
{
"time": {
"arrival": "2023-05-28T06:00:00Z",
"departure": "2023-05-28T07:07:57Z"
},
"load": [
0
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"time": {
"start": "2023-05-28T06:00:00Z",
"end": "2023-05-28T07:07:57Z"
}
}
],
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"distance": 0
},
{
"time": {
"arrival": "2023-05-28T07:12:00Z",
"departure": "2023-05-28T07:12:05Z"
},
"load": [
1
],
"activities": [
{
"jobId": "PickupEvent_1",
"type": "pickup",
"location": {
"lat": 52.50829,
"lng": 13.409382
},
"time": {
"start": "2023-05-28T07:12:00Z",
"end": "2023-05-28T07:12:05Z"
}
}
],
"location": {
"lat": 52.50829,
"lng": 13.409382
},
"distance": 1445
},
{
"time": {
"arrival": "2023-05-28T07:16:34Z",
"departure": "2023-05-28T07:16:39Z"
},
"load": [
2
],
"activities": [
{
"jobId": "PickupEvent_2",
"type": "pickup",
"location": {
"lat": 52.510099,
"lng": 13.390205
},
"time": {
"start": "2023-05-28T07:16:34Z",
"end": "2023-05-28T07:16:39Z"
}
}
],
"location": {
"lat": 52.510099,
"lng": 13.390205
},
"distance": 3411
},
{
"time": {
"arrival": "2023-05-28T07:21:30Z",
"departure": "2023-05-28T07:21:35Z"
},
"load": [
3
],
"activities": [
{
"jobId": "PickupEvent_7",
"type": "pickup",
"location": {
"lat": 52.50005,
"lng": 13.400365
},
"time": {
"start": "2023-05-28T07:21:30Z",
"end": "2023-05-28T07:21:35Z"
}
}
],
"location": {
"lat": 52.50005,
"lng": 13.400365
},
"distance": 5523
},
{
"time": {
"arrival": "2023-05-28T07:30:00Z",
"departure": "2023-05-28T07:30:05Z"
},
"load": [
4
],
"activities": [
{
"jobId": "PickupEvent_4",
"type": "pickup",
"location": {
"lat": 52.483268,
"lng": 13.394395
},
"time": {
"start": "2023-05-28T07:30:00Z",
"end": "2023-05-28T07:30:05Z"
}
}
],
"location": {
"lat": 52.483268,
"lng": 13.394395
},
"distance": 8722
},
{
"time": {
"arrival": "2023-05-28T07:36:15Z",
"departure": "2023-05-28T14:00:20Z"
},
"load": [
4
],
"activities": [
{
"jobId": "PickupEvent_1",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:00Z",
"end": "2023-05-28T07:50:05Z"
}
},
{
"jobId": "PickupEvent_2",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:05Z",
"end": "2023-05-28T07:50:10Z"
}
},
{
"jobId": "PickupEvent_7",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:10Z",
"end": "2023-05-28T07:50:15Z"
}
},
{
"jobId": "PickupEvent_4",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:15Z",
"end": "2023-05-28T07:50:20Z"
}
},
{
"jobId": "DropoffEvent_4",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:00Z",
"end": "2023-05-28T14:00:05Z"
}
},
{
"jobId": "DropoffEvent_7",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:05Z",
"end": "2023-05-28T14:00:10Z"
}
},
{
"jobId": "DropoffEvent_2",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:10Z",
"end": "2023-05-28T14:00:15Z"
}
},
{
"jobId": "DropoffEvent_1",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:15Z",
"end": "2023-05-28T14:00:20Z"
}
}
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"distance": 11767
},
{
"time": {
"arrival": "2023-05-28T14:08:47Z",
"departure": "2023-05-28T15:00:05Z"
},
"load": [
3
],
"activities": [
{
"jobId": "DropoffEvent_4",
"type": "delivery",
"location": {
"lat": 52.483268,
"lng": 13.394395
},
"time": {
"start": "2023-05-28T15:00:00Z",
"end": "2023-05-28T15:00:05Z"
}
}
],
"location": {
"lat": 52.483268,
"lng": 13.394395
},
"distance": 16119
},
{
"time": {
"arrival": "2023-05-28T15:11:42Z",
"departure": "2023-05-28T15:11:47Z"
},
"load": [
2
],
"activities": [
{
"jobId": "DropoffEvent_7",
"type": "delivery",
"location": {
"lat": 52.50005,
"lng": 13.400365
},
"time": {
"start": "2023-05-28T15:11:42Z",
"end": "2023-05-28T15:11:47Z"
}
}
],
"location": {
"lat": 52.50005,
"lng": 13.400365
},
"distance": 21927
},
{
"time": {
"arrival": "2023-05-28T15:16:58Z",
"departure": "2023-05-28T15:17:03Z"
},
"load": [
1
],
"activities": [
{
"jobId": "DropoffEvent_2",
"type": "delivery",
"location": {
"lat": 52.510099,
"lng": 13.390205
},
"time": {
"start": "2023-05-28T15:16:58Z",
"end": "2023-05-28T15:17:03Z"
}
}
],
"location": {
"lat": 52.510099,
"lng": 13.390205
},
"distance": 24039
},
{
"time": {
"arrival": "2023-05-28T15:21:02Z",
"departure": "2023-05-28T15:21:07Z"
},
"load": [
0
],
"activities": [
{
"jobId": "DropoffEvent_1",
"type": "delivery",
"location": {
"lat": 52.50829,
"lng": 13.409382
},
"time": {
"start": "2023-05-28T15:21:02Z",
"end": "2023-05-28T15:21:07Z"
}
}
],
"location": {
"lat": 52.50829,
"lng": 13.409382
},
"distance": 25734
},
{
"time": {
"arrival": "2023-05-28T15:25:04Z",
"departure": "2023-05-28T15:25:04Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"time": {
"start": "2023-05-28T15:25:04Z",
"end": "2023-05-28T15:25:04Z"
}
}
],
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"distance": 27179
}
],
"statistic": {
"cost": 169.13500000000002,
"distance": 27179,
"duration": 29827,
"times": {
"driving": 3669,
"serving": 80,
"waiting": 26078,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
},
{
"vehicleId": "bus_1",
"typeId": "bus",
"stops": [
{
"time": {
"arrival": "2023-05-28T06:00:00Z",
"departure": "2023-05-28T07:05:54Z"
},
"load": [
0
],
"activities": [
{
"jobId": "departure",
"type": "departure",
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"time": {
"start": "2023-05-28T06:00:00Z",
"end": "2023-05-28T07:05:54Z"
}
}
],
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"distance": 0
},
{
"time": {
"arrival": "2023-05-28T07:13:22Z",
"departure": "2023-05-28T07:13:27Z"
},
"load": [
1
],
"activities": [
{
"jobId": "PickupEvent_5",
"type": "pickup",
"location": {
"lat": 52.500151,
"lng": 13.458333
},
"time": {
"start": "2023-05-28T07:13:22Z",
"end": "2023-05-28T07:13:27Z"
}
}
],
"location": {
"lat": 52.500151,
"lng": 13.458333
},
"distance": 3861
},
{
"time": {
"arrival": "2023-05-28T07:21:26Z",
"departure": "2023-05-28T07:21:31Z"
},
"load": [
2
],
"activities": [
{
"jobId": "PickupEvent_3",
"type": "pickup",
"location": {
"lat": 52.519549,
"lng": 13.456663
},
"time": {
"start": "2023-05-28T07:21:26Z",
"end": "2023-05-28T07:21:31Z"
}
}
],
"location": {
"lat": 52.519549,
"lng": 13.456663
},
"distance": 7532
},
{
"time": {
"arrival": "2023-05-28T07:30:00Z",
"departure": "2023-05-28T07:30:05Z"
},
"load": [
3
],
"activities": [
{
"jobId": "PickupEvent_6",
"type": "pickup",
"location": {
"lat": 52.516855,
"lng": 13.497785
},
"time": {
"start": "2023-05-28T07:30:00Z",
"end": "2023-05-28T07:30:05Z"
}
}
],
"location": {
"lat": 52.516855,
"lng": 13.497785
},
"distance": 11071
},
{
"time": {
"arrival": "2023-05-28T07:46:23Z",
"departure": "2023-05-28T14:00:15Z"
},
"load": [
3
],
"activities": [
{
"jobId": "PickupEvent_5",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:00Z",
"end": "2023-05-28T07:50:05Z"
}
},
{
"jobId": "PickupEvent_3",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:05Z",
"end": "2023-05-28T07:50:10Z"
}
},
{
"jobId": "PickupEvent_6",
"type": "delivery",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T07:50:10Z",
"end": "2023-05-28T07:50:15Z"
}
},
{
"jobId": "DropoffEvent_3",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:00Z",
"end": "2023-05-28T14:00:05Z"
}
},
{
"jobId": "DropoffEvent_6",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:05Z",
"end": "2023-05-28T14:00:10Z"
}
},
{
"jobId": "DropoffEvent_5",
"type": "pickup",
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"time": {
"start": "2023-05-28T14:00:10Z",
"end": "2023-05-28T14:00:15Z"
}
}
],
"location": {
"lat": 52.480634,
"lng": 13.435993
},
"distance": 18116
},
{
"time": {
"arrival": "2023-05-28T14:17:26Z",
"departure": "2023-05-28T15:00:05Z"
},
"load": [
2
],
"activities": [
{
"jobId": "DropoffEvent_6",
"type": "delivery",
"location": {
"lat": 52.516855,
"lng": 13.497785
},
"time": {
"start": "2023-05-28T15:00:00Z",
"end": "2023-05-28T15:00:05Z"
}
}
],
"location": {
"lat": 52.516855,
"lng": 13.497785
},
"distance": 25234
},
{
"time": {
"arrival": "2023-05-28T15:08:03Z",
"departure": "2023-05-28T15:08:08Z"
},
"load": [
1
],
"activities": [
{
"jobId": "DropoffEvent_3",
"type": "delivery",
"location": {
"lat": 52.519549,
"lng": 13.456663
},
"time": {
"start": "2023-05-28T15:08:03Z",
"end": "2023-05-28T15:08:08Z"
}
}
],
"location": {
"lat": 52.519549,
"lng": 13.456663
},
"distance": 29002
},
{
"time": {
"arrival": "2023-05-28T15:15:52Z",
"departure": "2023-05-28T15:15:57Z"
},
"load": [
0
],
"activities": [
{
"jobId": "DropoffEvent_5",
"type": "delivery",
"location": {
"lat": 52.500151,
"lng": 13.458333
},
"time": {
"start": "2023-05-28T15:15:52Z",
"end": "2023-05-28T15:15:57Z"
}
}
],
"location": {
"lat": 52.500151,
"lng": 13.458333
},
"distance": 32699
},
{
"time": {
"arrival": "2023-05-28T15:22:54Z",
"departure": "2023-05-28T15:22:54Z"
},
"load": [
0
],
"activities": [
{
"jobId": "arrival",
"type": "arrival",
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"time": {
"start": "2023-05-28T15:22:54Z",
"end": "2023-05-28T15:22:54Z"
}
}
],
"location": {
"lat": 52.50935,
"lng": 13.41997
},
"distance": 36212
}
],
"statistic": {
"cost": 169.10000000000002,
"distance": 36212,
"duration": 29820,
"times": {
"driving": 4804,
"serving": 60,
"waiting": 24956,
"stopping": 0,
"break": 0
}
},
"shiftIndex": 0
}
]
}Next steps
- For more information about formulating problems in the HERE Tour Planning API, see Problem.
- For an in-depth exploration of the HERE Tour Planning API methods, endpoints, and parameters, see the API Reference.
Updated 29 days ago
