ガイドAPIリファレンス
ガイド

HERE Tour Planning APIの使用を開始する

このセクションでは、HEREプラットフォームでHERE Tour Planning APIを使用して実行する方法を概略的に説明します。

📘

このセクションでは、HERE Tour Planning APIの使用を開始するために必要な最小限の設定について説明します。HEREアカウントの設定、アプリの登録、認証の詳細については、Identity and Access Managementのガイドを参照してください。

HEREアカウントを取得する

組織管理者からの招待状を通じて、または無料で利用を開始して、HEREプラットフォームへのアクセスを入手します。

  • 会社がすでにHEREプラットフォーム組織を設立している場合は、組織への参加に招待できる管理者に連絡してください。
  • 会社がまだHEREプラットフォーム組織を設立していない場合は、無料で利用を開始できます。詳細については、「HEREプラットフォームの価格設定」を参照してください。

アプリを登録する

アプリを登録するには、次の手順を実行します。

  1. HEREアカウントを使用してHEREプラットフォームにサインインします。
  2. ランチャから[アクセスマネージャー]を開きます。
  3. [アプリ]タブで、[新しいアプリを登録]をクリックし、求められた情報を入力します。
  4. [登録]をクリックします。プラットフォームで、一意のアプリIDを持つ新しいアプリが作成されます。

OAuth 2.0資格情報を取得する

ベアラートークンのOAuth 2.0業界標準プロトコルに準拠するHERE Token Credentialsを作成します (クライアント資格情報フロー)。アプリは、最大24時間有効なアクセストークンを使用して、HEREプラットフォームへのリクエストを認証できます。

📘

  • OAuth 2.0トークンはHERE Tour Planning APIの主要な認証方法であり、有効期限の短いベアラートークンの形式でセキュリティ上の利点が強化されています。OAuth 2.0による追加のセキュリティ機能が不要なシンプルなユースケースでは、HERE Tour Planningは代替の認証方法として、APIキーもサポートしています。
  • 認証方法としてAPIキーを使用している場合は、リクエストから'Authorization: Bearer <TOKEN>'ヘッダーを削除し、リクエストURLにapikeyパラメーターを追加します (例:https://tourplanning.hereapi.com/v3/problems?apikey=<YOUR_HERE_API_KEY>)。このアプローチは、すべてのHERE Tour Planningエンドポイントで使用できます。

OAuth 2.0認証に必要な資格情報を取得するには、次の手順を実行します。

  1. HEREアカウントを使用してHEREプラットフォームにサインインします。

  2. ランチャから[アクセスマネージャー]を開きます。

  3. [アプリ]タブで、前のセクション (アプリの登録) で作成したアプリ、またはOAuth 2.0資格情報のセットを作成する既存のグループアプリをクリックします。

  4. [資格情報]タブで[OAuth 2.0]を選択し、[Create credentials](資格情報を作成) をクリックして、HEREプラットフォームでアプリケーションを認証するためのOAuth 2.0資格情報を最大2セット作成します。次の図を参照してください。 OAuth 2.0資格情報の作成

  5. [Your access key ID and secret were created](アクセスキーIDとシークレットが作成されました) ダイアログで[ダウンロード]をクリックして、credentials.propertiesファイルをダウンロードします。次の図を参照してください。 資格情報の表示とダウンロード ファイルには、次のアクセス資格情報が含まれています。

    • here.user.id
    • here.client.id
    • here.access.key.id
    • here.access.key.secret
    • here.token.endpoint.url
    📘

    • credentials.propertiesファイルは安全な場所に保存し、ユーザーやワークステーション間で共有しないでください。
    • ウィンドウを閉じた後は、HEREプラットフォームでcredentials.propertiesファイルの内容を再度ダウンロードまたは表示することはできません。
  6. ダイアログを閉じます。

  7. 前の手順を完了して取得した資格情報を使用して、ベアラートークンを作成します。たとえば、HERE OLP CLIを使用して、最大24時間有効なベアラートークンを生成できます。

リクエストを送信する

HERE Tour Planning APIは、同期と非同期の2種類のリクエストをサポートしています。同期リクエストと非同期リクエストの両方ですべての機能を使用できます。ただし、同期リクエストでは、ジョブと運行管理サイズの制限がより厳しくなっています。

詳細については、以下を参照してください。

📘

一部のフィーチャーを使用すると、車両ルート検索問題の解決がより困難になるため、アルゴリズムが「適切な」ソリューションを見つけるのにより多くの時間が必要になります。このようなフィーチャーには、ジョブの数と車両タイプ、マルチジョブ、集荷ジョブと配達ジョブ、制限時間枠、ジョブの総需要に対する車両の総容量の不足などがあります。HEREでは、このような場合は非同期リクエストを使用し、ポーリング間隔を長くすることを推奨しています。

問題の複雑さと解決に必要な時間

一部のフィーチャーを使用すると、車両ルート検索問題の解決がより困難になるため、アルゴリズムが 「適切な」ソリューションを見つけるのにより多くの時間が必要になります。このようなフィーチャーには以下のようなものがあります。

  • ジョブと車両タイプの数:数が多いほど問題が複雑になります
  • マルチジョブ
  • 集荷ジョブと配達ジョブ
  • 制限時間枠
  • ジョブの総需要に対する車両の総容量の不足

このような場合は、非同期リクエストを使用し、ポーリング間隔を長くすることを検討してください。

同期リクエスト

同期リクエストを使用する場合には、サーバーにリクエストを送信し、そのレスポンスを待ちます。同期リクエストは250件のジョブと35件の車両タイプに制限されています。より大きな問題の場合は、非同期リクエストを使用できます。

問題の定義を作成し、POSTメソッドを使用して、対応するエンドポイントにソリューション計算リクエストを送信します。リクエストが有効な場合、サービスは計算を開始し、計算が完了するとソリューションを返します。次のスニペットは、そのようなリクエストのcURLの例を示しています。

curl --location 'https://tourplanning.hereapi.com/v3/problems' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <TOKEN>' \
--data '{
  "plan": {
    "jobs": [
      {
        "id": "myJob",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {"lat": 52.46642, "lng": 13.28124},
                  "times": [["2020-07-04T10:00:00.000Z","2020-07-04T12:00:00.000Z"]],
                  "duration": 180
                }
              ],
              "demand": [1]
            }
          ]
        }
      }
    ]
  },
  "fleet": {
    "types": [
      {
        "id": "myVehicleType",
        "profile": "car",
        "costs": {
          "distance": 0.0002,
          "time": 0.005,
          "fixed": 22
        },
        "shifts": [{
          "start": {
            "time": "2020-07-04T09:00:00Z",
            "location": {"lat": 52.52568, "lng": 13.45345}
          },
          "end": {
            "time": "2020-07-04T18:00:00Z",
            "location": {"lat": 52.52568, "lng": 13.45345}
          }
        }],
        "limits": {
          "maxDistance": 300000,
          "shiftTime": 28800
        },
        "capacity": [10],
        "amount": 1
      }
    ],
    "profiles": [{
      "name": "car",
      "type": "car",
      "departureTime": "2020-07-04T09:15:00Z"
    }]
  },
  "configuration": {
    "termination": {
      "maxTime": 2,
      "stagnationTime": 1
    }
  }
}'

詳細については、「問題」を参照してください。

リクエストが有効でない場合、次の例に示すように、対応するエラーが返されます。

{
  "title": "BAD_REQUEST",
  "status": 400,
  "code": "E613420",
  "cause": "Vehicle's arrival time is earlier than its departure time",
  "action": "Correct arrival time of 'vehicle' to be earlier than its departure",
  "correlationId": "<globally unique id>"
}

非同期リクエスト

非同期リクエストで問題のソリューションを受け取る場合、次の複数のステップを実行します。

📘

非同期リクエストフローは、6,000件のジョブと150件の車両タイプに制限されています。

問題のソリューションをリクエストする

問題の定義を作成し、POSTメソッドを使用して、対応するproblems/asyncエンドポイントにソリューション計算リクエストを送信します。次のスニペットは、cURLツールを使用したリクエスト例を示しています。

curl --location 'https://tourplanning.hereapi.com/v3/problems/async' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <TOKEN>' \
--data '{
  "plan": {
    "jobs": [
      {
        "id": "myJob",
        "tasks": {
          "deliveries": [
            {
              "places": [
                {
                  "location": {"lat": 52.46642, "lng": 13.28124},
                  "times": [["2020-07-04T10:00:00.000Z","2020-07-04T12:00:00.000Z"]],
                  "duration": 180
                }
              ],
              "demand": [1]
            }
          ]
        }
      }
    ]
  },
  "fleet": {
    "types": [
      {
        "id": "myVehicleType",
        "profile": "car",
        "costs": {
          "distance": 0.0002,
          "time": 0.005,
          "fixed": 22
        },
        "shifts": [{
          "start": {
            "time": "2020-07-04T09:00:00Z",
            "location": {"lat": 52.52568, "lng": 13.45345}
          },
          "end": {
            "time": "2020-07-04T18:00:00Z",
            "location": {"lat": 52.52568, "lng": 13.45345}
          }
        }],
        "limits": {
          "maxDistance": 300000,
          "shiftTime": 28800
        },
        "capacity": [10],
        "amount": 1
      }
    ],
    "profiles": [{
      "name": "car",
      "type": "car",
      "departureTime": "2020-07-04T09:15:00Z"
    }]
  },
  "configuration": {
    "termination": {
      "maxTime": 2,
      "stagnationTime": 1
    }
  }
}'

APIは次のレスポンス本文を返します。

{
  "statusId": "<globally unique id>",
  "href": "https://tourplanning.hereapi.com/v3/status/<statusId>"
}

レスポンスの要素は次のとおりです。

  • statusId - ステータスの一意の識別子。ソリューション計算ステータスのトラッキングやソリューション結果のダウンロードに使用します。
  • href - ステータスをポーリングするためのURL。

ソリューションのステータスを確認する

特定の問題IDのソリューション計算のステータスを取得するには、次のcURLスニペットに示すように、リクエストの送信時に取得したhrefパラメーターを使用してGETリクエストを送信します。

curl --location 'https://tourplanning.hereapi.com/v3/status/<statusId>' \
--header 'Authorization: Bearer <TOKEN>'

APIは、次のようなリクエストのステータスを含むレスポンスを返します。

{
  "status": "pending"
}

ステータスがpendingまたはinProgressになった場合は、計算が完了し、successtimeoutfailureのステータスが返されるまでポーリングを続行する必要があります。

successを持つレスポンスでは、次のスニペットに示すように、計算されたソリューションをダウンロードするためのリソースリンクが返されます。

{
    "status": "success",
    "resource": {
      "resourceId": "<globally unique id>",
      "href": "https://tourplanning.hereapi.com/v3/problems/<resourceId>/solution"
    }
}

failureを持つレスポンスでは、次のようなエラーオブジェクトが返されます。

{
    "status": "failure",
    "error": {
      "message": "There was an error solving the problem"
    }
}

statusIdを使用すると、solutionエンドポイントからエラーの詳細を取得できます。この方法は次のセクションで説明します。

ソリューションをダウンロードする

ソリューションの計算のステータスがsuccessの場合、計算されたソリューションはresourceId要素で指定されたID (実質的にはproblemId) を使用して取得できます。次のような形でGETリクエストを送信して、ソリューションを取得します。

curl --location 'https://tourplanning.hereapi.com/v3/problems/<resourceId>/solution' \
--header 'Authorization: Bearer <TOKEN>'

次の例に示すように、APIはレスポンスとしてソリューションのJSONを返します。

{
  "statistic": {
    "cost": 45.7042,
    "distance": 31921,
    "duration": 3464,
    "times": {
      "driving": 3284,
      "serving": 180,
      "waiting": 0,
      "stopping": 0,
      "break": 0,
      "intraStop": 0
    },
    "intraStopDistance": 0
  },
  "tours": [
    {
      "vehicleId": "myVehicleType_1",
      "typeId": "myVehicleType",
      "stops": [
        {
          "time": {
            "arrival": "2020-07-04T09:00:00Z",
            "departure": "2020-07-04T09:32:12Z"
          },
          "load": [1],
          "activities": [
            {
              "jobId": "departure",
              "type": "departure",
              "location": {
                "lat": 52.52568,
                "lng": 13.45345
              },
              "time": {
                "start": "2020-07-04T09:00:00Z",
                "end": "2020-07-04T09:32:12Z",
                "arrival": "2020-07-04T09:00:00Z"
              }
            }
          ],
          "location": {
            "lat": 52.52568,
            "lng": 13.45345
          },
          "distance": 0,
          "intraStopDistance": 0
        },
        {
          "time": {
            "arrival": "2020-07-04T10:00:00Z",
            "departure": "2020-07-04T10:03:00Z"
          },
          "load": [0],
          "activities": [
            {
              "jobId": "myJob",
              "type": "delivery",
              "location": {
                "lat": 52.46642,
                "lng": 13.28124
              },
              "time": {
                "start": "2020-07-04T10:00:00Z",
                "end": "2020-07-04T10:03:00Z",
                "arrival": "2020-07-04T10:00:00Z"
              }
            }
          ],
          "location": {
            "lat": 52.46642,
            "lng": 13.28124
          },
          "distance": 16020,
          "intraStopDistance": 0
        },
        {
          "time": {
            "arrival": "2020-07-04T10:29:56Z",
            "departure": "2020-07-04T10:29:56Z"
          },
          "load": [0],
          "activities": [
            {
              "jobId": "arrival",
              "type": "arrival",
              "location": {
                "lat": 52.52568,
                "lng": 13.45345
              },
              "time": {
                "start": "2020-07-04T10:29:56Z",
                "end": "2020-07-04T10:29:56Z",
                "arrival": "2020-07-04T10:29:56Z"
              }
            }
          ],
          "location": {
            "lat": 52.52568,
            "lng": 13.45345
          },
          "distance": 31921,
          "intraStopDistance": 0
        }
      ],
      "statistic": {
        "cost": 45.7042,
        "distance": 31921,
        "duration": 3464,
        "times": {
          "driving": 3284,
          "serving": 180,
          "waiting": 0,
          "stopping": 0,
          "break": 0,
          "intraStop": 0
        },
        "intraStopDistance": 0
      },
      "shiftIndex": 0
    }
  ]
}

詳細については、「ソリューション」を参照してください。

問題の解決中にエラーが発生した場合は、次のエラーレスポンスが返されます。

{
    "title": "Unprocessable entity",
    "status": 422,
    "code": "E613000",
    "cause": "E613420, 'Vehicle's arrival time is earlier than its departure time' 'Correct arrival time of 'vehicle' to be earlier than its departure'",
    "action": "",
    "correlationId": "REQ-497fdde4-048d-4db5-9d6e-8e44a952dede"
}
📘

未完了の計算のソリューションをリクエストすると、HTTPステータスコード404 Not Foundが返されます。

次のステップ

詳細については、「HERE Tour PlanningのAPIリファレンス」とさまざまな旅程計画のシナリオについて詳しく説明している本ガイドのユースケースを参照してください。