Routing#

The MOIA Fleet API contains a routing service tailored to the specific vehicles managed through the API. It is accessible in the Fleet API through the RoutingService. This service allows computing routes between two (or more) waypoints, similar to common public routing products such as Google/Apple/Bing Maps. When dispatching missions via the Fleet API, MOIA internally uses this service to compute appropriate routes for the vehicles to drive. Note that in the current state of Fleet API, routes obtained through the API are purely informative. They provide an indication of estimated travel times and route feasibility. However, getting a specific route through the routing service does not guarantee that this exact route will be taken by a successive mission assignment with the same waypoints (due to the volatility of traffic).

Routing Objects#

Request#

A ComputeRouteRequest primarily consists of an origin and a destination waypoint (represented by geographical coordinates and an optional heading). Additionally, the request must contain a VehicleConfiguration specifying what kind of vehicle should be routed. Further, up to 100 intermediate waypoints may be provided as via points.

{
  "origin": {
    "latitude": 30.273393,
    "longitude": -97.743473
  },
  "destination": {
    "latitude": 30.272680,
    "longitude": -97.741016,
    "heading": 20.0
  },
  "via": [
    {
      "latitude": 30.273080,
      "longitude": -97.742339
    }
  ],
  "vehicle_configuration": { "self_driving": true }
}

Route#

A Route is a suggested path to drive. It goes from the origin of a routing request over all via waypoints (in the specified order) to the destination. A route consists of a sequence of route legs where each leg contains the route between two successive waypoints.

{
  "legs": [
    {
      "leg": {
        "travelTimeSeconds": 15,
        "lengthMeters": 111,
        "geometry": [
          {
            "latitude": 30.273390,
            "longitude": -97.74348
          },
          {
            "latitude": 30.27328,
            "longitude": -97.74308
          },
          {
            "latitude": 30.27321,
            "longitude": -97.74283
          },
          {
            "latitude": 30.27309,
            "longitude": -97.742380
          }
        ]
      }
    },
    {
      "leg": {
        "travelTimeSeconds": 124,
        "lengthMeters": 571,
        "geometry": [
          {
            "latitude": 30.27309,
            "longitude": -97.742380
          },
          {
            "latitude": 30.27291,
            "longitude": -97.74245
          },
          ...
          {
            "latitude": 30.272710,
            "longitude": -97.74104
          }
        ]
      }
    }
  ]
}

Leg#

A Leg describes the length, predicted travel time and route geometry of a route section. For example:

{
  "travelTimeSeconds": 15,
  "lengthMeters": 111,
  "geometry": [
    {
      "latitude": 30.273390,
      "longitude": -97.74348
    },
    {
      "latitude": 30.27328,
      "longitude": -97.74308
    },
    {
      "latitude": 30.27321,
      "longitude": -97.74283
    },
    {
      "latitude": 30.27309,
      "longitude": -97.742380
    }
  ]
}

A leg may be accompanied by so called Violations. If there are violations, the service was able to compute a route but that route is dangerous, illegal or even impossible to drive. The service only responds with a leg with violations if no alternative route without violations exists according to the routing data. However, routing data is never perfect, therefore the route is provided regardless. Nevertheless, for any use case which involves driving a route, routes with violations should be discarded (for example, mission dispatch will reject routes with violations).

To ensure that callers explicitly handle violations, legs are wrapped in a message of type LegOrLegWithViolations which has different variants for regular legs and legs with violations. A leg without violations may look like this:

{
  "leg": {
    "travelTimeSeconds": 15,
    "lengthMeters": 111,
    "geometry": [
      {
        "latitude": 30.273390,
        "longitude": -97.74348
      },
      {
        "latitude": 30.27328,
        "longitude": -97.74308
      },
      {
        "latitude": 30.27321,
        "longitude": -97.74283
      },
      {
        "latitude": 30.27309,
        "longitude": -97.742380
      }
    ]
  }
}

A leg with violations may look like this:

{
  "legWithViolation": {
    "leg": {
      "travelTimeSeconds": 5,
      "lengthMeters": 38,
      "geometry": [
        {
          "latitude": 53.55654,
          "longitude": 10.002183
        },
        {
          "latitude": 53.5565,
          "longitude": 10.0021
        },
        {
          "latitude": 53.55639,
          "longitude": 10.0019
        },
        {
          "latitude": 53.55632,
          "longitude": 10.00175
        }
      ]
    },
    "violations": [
      {
        "violationType": "VIOLATION_TYPE_BLOCKED_ROAD_USED",
        "startIndex": 1,
        "coordinatesCount": 4
      }
    ]
  }
}

Violation#

A violation indicates an issue with a route leg. While a route could be computed, a leg violates a routing restriction. The part of a leg which is affected by the violation is provided as an index into the geometry array of the associated leg. For example:

{
  "violationType": "VIOLATION_TYPE_BLOCKED_ROAD_USED",
  "startIndex": 1,
  "coordinatesCount": 4
}

The service only responds with a leg with violations if no alternative route without violations exists according to the routing data. This may happen for example when the origin or destination of the route request lies on a blocked segment. Consider the specific violation type to assess the severity of a violation.

Routing Functionality#

Point-to-Point Routing#

Point-to-point routing is a straightforward use case for the routing service. Build a ComputeRouteRequest with your desired origin and destination waypoints and supply an appropriate VehicleConfiguration. Make sure to provide a heading to achieve good matching quality and to disambiguate the direction in which a vehicle should leave/arrive. Call the ComputeRoute procedure with the request. Given a ComputeRouteRequest, the procedure will produce a ComputeRouteResponse. In the case of successful computation, the response will consist of a route which you can then use for your purposes. If the requested waypoints necessarily lead into an impossible or illegal situation (according to the routing data), you will get back a route with violations. In this case you have to carefully consider if the route is usable in the context of your use case. Route computation may also fail entirely if the service could not match any of the waypoints to the MOIA map data, or if the map data contains no route between a pair of waypoints. This should only happen if you request routes for locations outside the area covered by MOIAs service.