ガイド変更履歴API references
ガイド

交通情報を更新する

最新の交通状況に基づいて、ルートを最新の状態に保ちます。このセクションでは、既存のルートの交通データを更新する方法と、交通状況が変化した際により適した代替ルートを見つけるために、ナビゲーション中に動的ルーティングを活用する方法について説明します。

ルート上の交通状況を更新する

ルートの交通情報は、calculateTrafficOnRoute()またはrefreshRoute()を呼び出すことで更新できます。

  • refreshRoute()メソッドは、出発地またはルートメタデータの更新が必要な場合に使用できます。
  • 交通情報のみを更新する必要があるシナリオでは、calculateTrafficOnRoute()メソッドを使用してTrafficOnRouteオブジェクトを提供できます。現在の交通流と交通障害に関する詳細情報がTrafficOnSectionごとに記載されています。TrafficOnSectionには、TrafficOnSpanオブジェクトのリストとして、スパンごとの詳細な交通情報が記載されています。

どちらのメソッドでも、ルート距離とジオメトリーは変更されません。

注 (Navigateにのみ適用)

または、DynamicRoutingEngineを使用してナビゲーション中によりよいルートを検索することもできます。これらのルートは現在の交通流に基づいて最適化されます。その結果、交通量の多い道路を迂回するための新しいルートジオメトリーも含まれる場合があります。DynamicRoutingEngineの詳細については、「ナビゲーション」セクションを参照してください。

TrafficOnRouteを使用してルートプレビュー中に交通状況を更新する

routingEngine.calculateTrafficOnRoute(..)メソッドは、作成後に特定のセクションまたはルート全体の交通状況を更新します。ナビゲーション中またはルートプレビューコンテキストでこれを計算できます。

インデックスと最後にアクセスした位置からのオフセット (メートル単位) を使用して、最後に移動したルートセクションからの交通状況を再計算することで、これを行います。ルートプレビューコンテキストでは、ルート全体の交通情報を更新するために、lastTraveledSectionIndex traveledDistanceOnLastSectionInMetersを0に設定できます。

このメソッドは、主にルートプレビュー用に設計された画面で次のように利用できます。

func updateTrafficOnRoute(route: Route?) {
    // Since traffic is being calculated for the entire route, lastTraveledSectionIndex and traveledDistanceOnLastSectionInMeters are set to 0.
    let lastTraveledSectionIndex = 0
    let traveledDistanceOnLastSectionInMeters = 0

    // Note: calculateTrafficOnRoute requires a route with routeHandle.
    // Enable it by setting routeOptions.enableRouteHandle to true when creating the route.
    routingEngine.calculateTrafficOnRoute(
        route: route!,
        lastTraveledSectionIndex: Int32(lastTraveledSectionIndex),
        traveledDistanceOnLastSectionInMeters: Int32(traveledDistanceOnLastSectionInMeters)
    ) { routingError, trafficOnRoute in
        if let error = routingError {
            print("CalculateTrafficOnRoute error: \(error)")
        } else if let trafficOnRoute = trafficOnRoute {
            self.showUpdatedETA(trafficOnRoute: trafficOnRoute)
        }
    }
}

TrafficOnRouteからの最新のETAはTrafficOnSpanから確認できます。各TrafficOnSpanはルート沿いの交通情報を提供します。次のメソッドを使用して更新されたETAを抽出できます。

private func showUpdatedETA(trafficOnRoute: TrafficOnRoute) {
    for section in trafficOnRoute.trafficSections {
        var updatedETAInSeconds = 0.0;
        section.trafficSpans.forEach{ updatedETAInSeconds = updatedETAInSeconds + Double($0.duration)}
        var updatedTrafficDelayInSeconds = 0.0;
        section.trafficSpans.forEach{ updatedTrafficDelayInSeconds = updatedTrafficDelayInSeconds + Double($0.trafficDelay)}
        let updatedETAString = String(format: "Updated travel duration %@\nUpdated traffic delay %@",
                                      timeUtils.formatTime(sec: updatedETAInSeconds),
                                      timeUtils.formatTime(sec: updatedTrafficDelayInSeconds))
        showDialog(title: "Updated traffic", message: updatedETAString)
    }
}

交通状況の更新では、予測モデルを使用してルートに沿った状況を予測しますが、マップレイヤーに表示されるリアルタイムの交通状況とは異なる場合があります。これらの違いの詳細については、「トラフィック」を参照してください。

ターン・バイ・ターンナビの実行中に交通状況を更新する (Navigateでのみ使用可能)

ターン・バイ・ターンナビの実行中は、calculateTrafficOnRoute()を呼び出して専用のTrafficOnRouteオブジェクトを計算することをお勧めします。交通状況は走行中に頻繁に変化する可能性があるため、アプリケーションはこの呼び出しを定期的に繰り返します。

以下の実装例では、設定可能な間隔で交通状況の更新が実行されます。

calculateTrafficOnRoute()が完了すると、VisualNavigatorを新しいTrafficOnRouteオブジェクトで更新することができます。これによりRouteProgressオブジェクトが提供する所要時間に関する情報が調整されます。

func updateTrafficOnRoute(routeProgress: RouteProgress) {
    guard let currentRoute = visualNavigator.route else {
        // Should never happen.
        return
    }

    // Below, we use 10 minutes. A common range is between 5 and 15 minutes.
    let trafficUpdateIntervalInMilliseconds = 10 * 60000 // 10 minutes
    let now = Int(Date().timeIntervalSince1970 * 1000) // Current time in milliseconds
    if (now - lastTrafficUpdateInMilliseconds) < trafficUpdateIntervalInMilliseconds {
        return
    }
    // Store the current time when we update trafficOnRoute.
    lastTrafficUpdateInMilliseconds = now

    let sectionProgressList = routeProgress.sectionProgress
    guard let lastSectionProgress = sectionProgressList.last else {
        // Should never happen if the list is valid.
        return
    }
    let traveledDistanceOnLastSectionInMeters =
    currentRoute.lengthInMeters - lastSectionProgress.remainingDistanceInMeters
    let lastTraveledSectionIndex = routeProgress.routeMatchedLocation.sectionIndex

    routeCalculator.calculateTrafficOnRoute(
        currentRoute: currentRoute,
        lastTraveledSectionIndex: Int(lastTraveledSectionIndex),
        traveledDistanceOnLastSectionInMeters: Int(traveledDistanceOnLastSectionInMeters)
    ) { routingError, trafficOnRoute in
        if let routingError = routingError {
            print("CalculateTrafficOnRoute error: \(routingError)")
            return
        }

        // Sets traffic data for the current route, affecting RouteProgress duration in SectionProgress,
        // while preserving route distance and geometry.
        self.visualNavigator.trafficOnRoute = trafficOnRoute
        print("Updated traffic on route.")
    }
}

このコードはHERE Routingバックエンドへの定期的な呼び出しを開始します。契約に応じて、 通話ごとに個別に課金される場合があります。このコードの実行方法および実行頻度は、 アプリケーション側が決定します。

visualNavigator.setTrafficOnRoute()メソッドはすぐには有効になりません。その代わりに、更新された所要時間 (ETA) は次のRouteProgressイベントに反映されます。ETAをRouteProgressイベントから抽出する方法の詳細については、ETAのセクションを参照してください。