Back to Documentation Overview

Customize Routing Behavior

Map annotations enable you to add custom map attributes to the basemap of the rideOS routing engine. You can annotate areas, paths, and turns with additional information using the Map Annotation API. By assigning these annotations to routing profiles (through the Routing Profile API), they can be used in the Path API and ETA API to create operational and avoidable constraints.

In this guide, we will:

  1. Add a map annotation
  2. Get the current status of the annotation
  3. Add the annotation to a routing profile
  4. Use the routing profile in the Path API

Prerequisite: Get the API Key

To run this example, you will need a rideOS API Key. You can sign up for one here and view it on your profile page.

Once you have the API Key, you can set the environment variable with export RIDEOS_API_KEY="YOUR_API_KEY" and use RIDEOS_API_KEY in the cURL commands given below.

Step 1: Add a map annotation

Let's say that we want to restrict travel in central San Francisco in three ways, as shown below:

To achieve this, we will annotate these features through the AddOrReplaceAnnotation endpoint, assigning them all the same annotation ID:

curl --request POST https://api.rideos.ai/map-annotation/preview/AddOrReplaceAnnotation \
--header "Content-Type: application/json" \
--header "X-Api-Key: $RIDEOS_API_KEY" \
--data '{
  "annotation": {
    "id": "annotation-sf",
    "features": [
      {
        "area": {
          "positions": [
            { "latitude": 37.80536, "longitude": -122.42573 },
            { "latitude": 37.80720, "longitude": -122.41017 },
            { "latitude": 37.78602, "longitude": -122.40608 },
            { "latitude": 37.78394, "longitude": -122.42150 },
            { "latitude": 37.80536, "longitude": -122.42573 }
          ]
        }
      },
      {
        "bidirectionalPath": {
          "positions": [
            { "latitude": 37.79199, "longitude": -122.39492 },
            { "latitude": 37.77339, "longitude": -122.41844 }
          ]
        }
      },
      {
        "turn": {
          "positions": [
            { "latitude": 37.78704, "longitude": -122.40000 },
            { "latitude": 37.78623, "longitude": -122.39900 },
            { "latitude": 37.78548, "longitude": -122.39990 }
          ]
        }
      }
    ]
  }
}'

Step 2: Get current status of the annotation

Annotations require some processing time before they can be referenced. Thus, we will call the GetAnnotationStatus endpoint to check if our annotation has been processed:

curl --request POST https://api.rideos.ai/map-annotation/preview/GetAnnotationStatus \
--header "Content-Type: application/json" \
--header "X-Api-Key: $RIDEOS_API_KEY" \
--data '{ "annotationId": "annotation-sf" }'

We get the status as INACTIVE if the annotation has been added but not processed yet. We call this endpoint until the status is ACTIVE, which denotes that the annotation has been processed. This usually takes less than a minute.

{"status":"ACTIVE"}

Step 3: Add the annotation to a routing profile

To use this annotation in our various APIs, we add it to a routing profile using the AddOrReplaceRoutingProfile endpoint. By using avoidConstraintIds below, we configure the features as avoid areas. If we instead used operationalConstraintIds, we would achieve the opposite behavior: restrict routing to only the areas we defined.

curl --request POST https://api.rideos.ai/routing-profile/preview/AddOrReplaceRoutingProfile \
--header "Content-Type: application/json" \
--header "X-Api-Key: $RIDEOS_API_KEY" \
--data '{
  "id": "profile-sf-avoid",
  "routingProfile": {
    "avoidConstraintIds": [ "annotation-sf" ]
  }
}'

Step 4: Use the routing profile in the Path API

We can apply our new routing profile to any ETA, path API, or fleet planner call. As an example, let's route from the Transamerica Pyramid to Lafayette Park in San Francisco. First, let's see what this route looks like without any travel restrictions (no routing profile):

curl --request POST https://api.rideos.ai/path/v2/GetPath \
--header "Content-Type: application/json" \
--header "X-Api-Key: $RIDEOS_API_KEY" \
--data '{
  "waypoints": [
    { "position": { "latitude": 37.79561, "longitude": -122.40334 } },
    { "position": { "latitude": 37.79193, "longitude": -122.42596 } }
  ],
  "geometryFormat": "LINESTRING"
}'

Now let's repeat the routing call with our routing profile:

curl --request POST https://api.rideos.ai/path/v2/GetPath \
--header "Content-Type: application/json" \
--header "X-Api-Key: $RIDEOS_API_KEY" \
--data '{
  "waypoints": [
    { "position": { "latitude": 37.79561, "longitude": -122.40334 } },
    { "position": { "latitude": 37.79193, "longitude": -122.42596 } }
  ],
  "geometryFormat": "LINESTRING",
  "routingProfileId": "profile-sf-avoid"
}'

We can see that the route indeed avoids the area, street and turn that we defined:

To summarize, we have successfully used the Map Annotation API and Routing Profile API to add custom map attributes, and used them as constraints.