Skip to content

Custom routing profiles

FastVRP uses OpenStreetMap road data to calculate travel distances and durations between locations. Custom profiles let you provide your own travel distances and durations via custom routing profiles, which are useful when you have data from a different routing engine or need to model non-standard vehicle types that FastVRP does not know about.

The profiles field on the request can be used to provide custom profiles. Each profile must have the following attributes:

  • id: a unique identifier that vehicle types reference.
  • distances: a square \(N \times N\) matrix of travel distances in metres, where \(N\) is the number of locations.
  • durations: a square \(N \times N\) matrix of travel durations in seconds, where \(N\) is the number of locations.

Both matrices must have a zero diagonal (distance and duration from a location to itself is zero) and all values must be non-negative. The row and column order matches the order of locations in the request.

Example

A delivery company in Amsterdam uses cargo bikes to make deliveries. The depot is in Centrum, with deliveries to Vondelpark, De Pijp, Jordaan, and Oost. Cargo bikes can take shortcuts through parks and pedestrian areas, so we provide a custom cargo_bike profile with its own distances and durations between locations. We then reference that profile on the vehicle type, so FastVRP knows to apply it.

In this example, the cargo bike distances are shorter than typical car routes because bikes can cut through Vondelpark and the narrow streets of Jordaan. For instance, the cargo bike distance from Centrum to Jordaan is 1,600 metres (about 8 minutes), while Centrum to Oost is 2,800 metres (about 14 minutes).

request.json
{
  "locations": [
    {
      "id": "loc-Centrum",
      "latitude": 52.3676,
      "longitude": 4.9041
    },
    {
      "id": "loc-Vondelpark",
      "latitude": 52.3580,
      "longitude": 4.8686
    },
    {
      "id": "loc-De Pijp",
      "latitude": 52.3510,
      "longitude": 4.8952
    },
    {
      "id": "loc-Jordaan",
      "latitude": 52.3738,
      "longitude": 4.8810
    },
    {
      "id": "loc-Oost",
      "latitude": 52.3612,
      "longitude": 4.9392
    }
  ],
  "tasks": [
    {
      "id": "task-Vondelpark",
      "location": "loc-Vondelpark",
      "service_duration": "PT600S"
    },
    {
      "id": "task-De Pijp",
      "location": "loc-De Pijp",
      "service_duration": "PT600S"
    },
    {
      "id": "task-Jordaan",
      "location": "loc-Jordaan",
      "service_duration": "PT600S"
    },
    {
      "id": "task-Oost",
      "location": "loc-Oost",
      "service_duration": "PT600S"
    }
  ],
  "depots": [
    {
      "id": "depot-Centrum",
      "location": "loc-Centrum"
    }
  ],
  "vehicle_types": [
    {
      "id": "cargo_bike",
      "start_depot": "depot-Centrum",
      "end_depot": "depot-Centrum",
      "num_available": 2,
      "profile": "cargo_bike",
      "shift": {
        "earliest_start": "2025-01-01T08:00:00",
        "latest_end": "2025-01-01T18:00:00"
      }
    }
  ],
  "profiles": [
    {
      "id": "cargo_bike",
      "distances": [
        [0, 2400, 1800, 1600, 2800],
        [2400, 0, 1200, 2000, 4200],
        [1800, 1200, 0, 2200, 3200],
        [1600, 2000, 2200, 0, 3600],
        [2800, 4200, 3200, 3600, 0]
      ],
      "durations": [
        [0, 720, 540, 480, 840],
        [720, 0, 360, 600, 1260],
        [540, 360, 0, 660, 960],
        [480, 600, 660, 0, 1080],
        [840, 1260, 960, 1080, 0]
      ]
    }
  ],
  "options": {
    "stop": {
      "seconds": 1,
      "type": "max_runtime"
    }
  }
}

FastVRP uses the custom profile's distances and durations to compute the best route order, travel times, and costs.

The map visualisation shows as-the-crow-flies lines because the route geometry depends on whatever routing engine produced the custom profile. Thus, FastVRP cannot produce detailed geometries for routes using custom profiles.

Conclusion

In this tutorial you learned how to provide custom routing profiles to bring your own travel distance and duration data. This is useful when you have routing data from a different source or need to model custom vehicle types that do not follow road networks FastVRP already knows about.