New Feature: Work shifts

This feature allows you to easily model several driver shifts. Just add a “shifts” field to your vehicles with any number of shifts as follows:

{
      "vehicle_id": "fieldworker-1",
      "type_id": "car_type",
      "shifts": [
        {
          "shift_id": "monday",
          "start_address": {
            "location_id": "your_home",
            "lon": 13.39238003043599,
            "lat": 52.50385692772726
          },
          "earliest_start": 28800,
          "latest_end": 57600
        },
        {
          "shift_id": "tuesday",
          "start_address": {
            "location_id": "your_home",
            "lon": 13.39238003043599,
            "lat": 52.50385692772726
          },
          "earliest_start": 115200,
          "latest_end": 144000
        }
      ]
}

Please note that this is still a beta feature. If you notice anything unexpected or strange, please let us know.

Here you can find a tutorial about how to model a traveling salesman problem with a week-planning horizon and driver shifts.

Happy Routing!

2 Likes

You can also specify "end_address" for your shifts and whether your driver should return to the “depot” or not ("return_to_depot": true).

Hi Stefan, this is great feature and critical for our use cases. Are there any plans to advance this on from beta?

It is now possible to add breaks to your shifts. Here is an example (you can copy it and paste it to our api explorer):

{
  "objectives": [
    {
      "type": "min",
      "value": "completion_time"
    }
  ],
  "vehicles": [
    {
      "vehicle_id": "vehicle1",
      "shifts": [
        {
          "shift_id": "shift-1",
          "start_address": {
            "location_id": "gera",
            "lon": 12.076721,
            "lat": 50.877044
          },
          "break": {
            "earliest": 43200,
            "latest": 50400,
            "duration": 3600
          },
          "earliest_start": 28800,
          "latest_end": 64800
        },
        {
          "shift_id": "shift-2",
          "start_address": {
            "location_id": "gera",
            "lon": 12.076721,
            "lat": 50.877044
          },
          "break": {
            "earliest": 129600,
            "latest": 136800,
            "duration": 3600
          },
          "earliest_start": 115200,
          "latest_end": 151200
        },
        {
          "shift_id": "shift-3",
          "start_address": {
            "location_id": "gera",
            "lon": 12.076721,
            "lat": 50.877044
          },
          "break": {
            "earliest": 216000,
            "latest": 223200,
            "duration": 3600
          },
          "earliest_start": 201600,
          "latest_end": 252000
        }
      ],
      "type_id": "vehicle_type_1"
    },
    {
      "vehicle_id": "vehicle2",
      "shifts": [
        {
          "shift_id":"shift-1",
          "start_address": {
            "location_id": "gera",
            "lon": 12.076721,
            "lat": 50.877044
          },
          "break": {
            "earliest": 43200,
            "latest": 50400,
            "duration": 3600
          },
          "earliest_start": 28800,
          "latest_end": 64800
        }
      ],
      "type_id": "vehicle_type_1"
    }
  ],
  "vehicle_types": [
    {
      "type_id": "vehicle_type_1",
      "profile": "car",
      "capacity": [
        6
      ]
    }
  ],
  "services": [
    {
      "id": "rostock",
      "name": "drink_bionade_in_rostock",
      "address": {
        "location_id": "rostock",
        "lon": 12.1333333,
        "lat": 54.0833333
      },
      "size": [
        1
      ]
    },
    {
      "id": "berlin",
      "name": "drink_cola_in_berlin",
      "address": {
        "location_id": "berlin",
        "lon": 13.354568,
        "lat": 52.514549
      },
      "size": [
        1
      ],
      "time_windows": [
        {
          "earliest": null,
          "latest": null
        }
      ],
      "preferred_vehicles": [
        {
          "vehicle_id": "vehicle1",
          "priority": 1
        }
      ]
    },
    {
      "id": "ulm",
      "name": "drink_juice_in_ulm",
      "address": {
        "location_id": "ulm",
        "lon": 9.990692,
        "lat": 48.398209
      },
      "size": [
        1
      ],
      "time_windows": null
    },
    {
      "id": "dresden",
      "name": "drink_nothing_in_dresden",
      "address": {
        "location_id": "dresden",
        "lon": 13.738403,
        "lat": 51.050028
      },
      "size": [
        1
      ]
    },
    {
      "id": "kassel",
      "name": "drink_wine_in_kassel",
      "address": {
        "location_id": "kassel",
        "lon": 9.486694,
        "lat": 51.31173
      },
      "size": [
        1
      ]
    },
    {
      "id": "dortmund",
      "name": "drink_beer_in_dortmund",
      "address": {
        "location_id": "dortmund",
        "lon": 7.500916,
        "lat": 51.508742
      },
      "size": [
        1
      ]
    },
    {
      "id": "karlsruhe",
      "name": "drink_water_in_karlsruhe",
      "address": {
        "location_id": "karlsruhe",
        "lon": 8.3858333,
        "lat": 49.0047222
      },
      "size": [
        1
      ]
    },
    {
      "id": "bremen",
      "name": "drink_fish_in_bremen",
      "address": {
        "location_id": "bremen",
        "lon": 8.822021,
        "lat": 53.041213
      },
      "size": [
        1
      ],
      "preferred_vehicles": [
        {
          "vehicle_id": "vehicle1",
          "priority": 1
        }
      ]
    },
    {
      "id": "hof",
      "name": "drink_somethingelse_in_hof",
      "address": {
        "location_id": "hof",
        "lon": 11.8927,
        "lat": 50.310392
      },
      "size": [
        1
      ]
    }
  ],
  "shipments": [
    {
      "id": "shipment1",
      "name": "ship_fish_from_rostock_to_karlsruhe",
      "pickup": {
        "address": {
          "location_id": "rostock",
          "lon": 12.1333333,
          "lat": 54.0833333
        }
      },
      "delivery": {
        "address": {
          "location_id": "karlsruhe",
          "lon": 8.3858333,
          "lat": 49.0047222
        }
      },
      "size": [
        1
      ]
    },
    {
      "id": "shipment2",
      "name": "ship_smthbig_from_karlsruhe_to_rostock",
      "pickup": {
        "address": {
          "location_id": "karlsruhe",
          "lon": 8.3858333,
          "lat": 49.0047222
        }
      },
      "delivery": {
        "address": {
          "location_id": "rostock",
          "lon": 12.1333333,
          "lat": 54.0833333
        }
      },
      "size": [
        1
      ]
    }
  ]
}
2 Likes

You will now also find the shift specification in our doc: Documentation - GraphHopper Directions API

2 Likes

Does shifts work with infinite fleet?