ルーティング : 経路情報を取得

HERE SDK は 、 A から B までの最適な経路情報を計算するための本格的な機能のRoutingEngineを提供します。これには、複数のウェイポイント と、各ターンのローカライズ可能な操作手順が含まれます。

目的のルート タイプ (最速または最短) とさまざまなルート オプション (速度プロファイル、ルート制限、ビネット オプションなど) を適切な設定を指定し、エネルギーを最も節約する最適なルートを見つけます。先進的なルーティング技術と専用の EV ルートプランニングサポートにより、 HERE は 地球をよりクリーンで安全にするお手伝い をします。

フィーチャーの概要 :

  • ルートの計算: さまざまなトランスポートモードで複数のウェイポイントを使用してルートを計算します。
  • Isolineルーティング: 時間、距離、または燃料消費量に基づいて、特定のポイントからの到達範囲を表す Isolineポリゴンを計算します。
  • ルートに沿って検索: ルート全体に沿って場所を検索 します(このフィーチャーについては、「検索」セクションで説明します)。
  • ルートのインポート / ルートマッチング: 他の API からルートをインポートできます。
  • オフラインルーティング: インターネット接続が利用できない場合は、専用のオフラインルーティングエンジンに切り替えて、キャッシュ済みのマップ データまたは事前にロードされたオフラインマップデータのルートを計算できます。

ルートを取得

HERE SDK では、次のルートタイプがサポートされています。

  • 乗用車でのルート案内
  • タクシー乗り場への行き方。
  • 徒歩ルート案内
  • 自転車ルート案内
  • カスタマイズ性の高いトラックオプションを備えたトラックルートの案内。
  • スクーターのルート案内
  • バスのルート案内
  • 電気自動車が 最寄りの充電ステーションを見つけるためのルート案内(計算されたエネルギー消費量およびバッテリー仕様に基づく)。
  • 高度にカスタマイズ可能な交通手段を備えた公共交通機関のルート案内(TransitRoutingEngine経由 )。

すべてのトランスポートモードは、RoutingEngineでのオンラインルート計算に使用 できます。 一部のトランスポートモードは、キャッシュされたマップ データ でのオフラインルートの計算、またはOfflineRoutingEngineとともにダウンロードされたオフラインマップにも使用できます。 サポートされているオフラインモードの概要について は、 ここを参照してください。

各ルートタイプは 、CarOptionsまたは TruckOptionsなどの利用可能なルートオプションのいずれかによって決定されます。 ここ では、サポートされている各トランスポート モードで利用可能なすべてのルート オプションを見つけます。 これらのオプションは、ルートエンジン calculateRoute() のメソッドで使用可能なオーバーロードに設定できます。

ルートエンジンを次のように作成して、旅程を開始します。

try {
  _routingEngine = RoutingEngine();
} on InstantiationException {
  throw ("Initialization of RoutingEngine failed.");
}

新しい RoutingEngine インスタンスを作成すると、上の図のように処理する必要があるエラーがスローされることがあります。 たとえば、 HERE SDK の初期化が事前に失敗した場合に、このようなエラーが発生することがあります。

ApplicationonCreate() メソッド中にこのエンジンを初期化することはできません。 それ以外の時点では問題はありません。 たとえば、このエンジンを初期化するのに適した場所は、ActivityonCreate()メソッドに含まれている可能性があります。

次のステップとして、出発地と目的地 (どちらも GeoCoordinates インスタンスを保持する Waypointタイプ) という 2 つのウェイポイントに基づいてルートを計算できます。以下では、車両に最適化されたルートを計算するために CarOptions のデフォルトを設定します。

Future<void> addRoute() async {
  var startGeoCoordinates = _createRandomGeoCoordinatesInViewport();
  var destinationGeoCoordinates = _createRandomGeoCoordinatesInViewport();
  var startWaypoint = Waypoint.withDefaults(startGeoCoordinates);
  var destinationWaypoint = Waypoint.withDefaults(destinationGeoCoordinates);

  List<Waypoint> waypoints = [startWaypoint, destinationWaypoint];

  _routingEngine.calculateCarRoute(waypoints, CarOptions(),
      (RoutingError? routingError, List<here.Route>? routeList) async {
    if (routingError == null) {
      // When error is null, it is guaranteed that the list is not empty.
      here.Route route = routeList!.first;
      _showRouteDetails(route);
      _showRouteOnMap(route);
      _logRouteViolations(route);
    } else {
      var error = routingError.toString();
      _showDialog('Error', 'Error while calculating a route: $error');
    }
  });
}

複数の calculateRoute() をコールすることができます。たとえば、異なるルーティングオプションを持つルートを並行して計算するために、このルートを呼び出すことができます。

ヒント : ドライバーが走行している場合、方位値はルート計算の改善に役立つことがあります。startWaypoint.headingInDegrees = currentLocation.bearingInDegrees;

各ルート計算は非同期で実行されます。 完了すると、エラーの可能性があるRouteリストまたはRoutingErrorが表示されます。 すべて問題が解決した場合 RoutingError は、 null になります。 エラーが発生した場合、ルートリストはnull になります。 たとえば、指定したトランスポートモードでルートが実行できない場合、エンジンはルートを計算できません。

エラーがない場合 、ルートリストには 1 つの結果のみが含まれます。 ルートオプションを使用して代替ルートの数を指定することで 、追加 のルートバリアントを要求できます。 デフォルトでは、代替ルートなしでルートが計算されます。

上記のコード スニペットの _showRouteDetails() メソッドを使用して、操作指示を含むルートの詳細を表示します。 すべてのソースコードは、付属のサンプルアプリに記載されています。 操作手順については、以下で詳しく説明します。 _showRouteOnMap() メソッドには、マップ上でルートをレンダリングする方法の例が含まれています。 この点については、後述のセクションで簡単に説明します。

注 : 重要

ルートには 、ルートの計算後に発生する可能性のある問題を説明するNoticeCode値のリストが含まれている場合があります。 たとえば、ルートがトンネルを回避する必要があり、可能な唯一のルートがトンネルを通過する必要がある場合、Route には、要求されたトンネル回避の違反があったことを示す通知が含まれます。

  • 違反の可能性がないか、常に計算済みの Route を確認することをお勧めします。
  • NoticeCodeNoticeオブジェクトの一部です。 可能な Notice オブジェクトのリストには、RouteSection ごとにアクセスでき ます。
  • 違反が発生しなかった場合、リストは空になります。
  • 違反の可能性 がある場合は、少なくとも 1 つの違反を含むルートをスキップすることをお勧めします。

ただし、要求されたルートオプションおよび実際の NoticeCode 値のリストによって、実装はケースバイケースに判断します。 ルートオプションの詳細については、次のセクションを参照してください。 重要 : わかりやすいよう に、このガイドのコードスニペットでは、通知の 列挙型 (enum) 値を評価しません

次の方法で、可能性のあるルート通知を検出できます。

// A route may contain several warnings, for example, when a certain route option could not be fulfilled.
// An implementation may decide to reject a route if one or more violations are detected.
void _logRouteViolations(here.Route route) {
  for (var section in route.sections) {
    for (var notice in section.sectionNotices) {
      print("This route contains the following warning: " + notice.code.toString());
    }
  }
}

ヒント : すべてのルートにルート沿いの標高値が含まれています。 たとえば、予定されている自転車旅程の高度プロファイルを作成します。

各トランスポートモードにルートオプションを使用

上の例では、自動車ルートを計算する新しいCarOptionsインスタンスを設定しました。 各トランスポートモードに専用のルートオプションを使用すると、他のトランスポートモードのルートを計算できます。 次のルートオプションがあります。

  • CarOptions 車のルートを計算する: route.requestedTransportModeTransportMode.carです。
  • TruckOptions トラックルートを計算する : route.requestedTransportModeTransportMode.truckです。
  • PedestrianOptions 歩行者のルートを計算する: route.requestedTransportModeTransportMode.pedestrianです。
  • EVCarOptionsEVTruckOptions で電気自動車のルートを計算する: route.requestedTransportMode は、TransportMode.car またはTransportMode.truckです 。
  • ScooterOptions スクーターのルートを計算する: route.requestedTransportModeTransportMode.scooterです。
  • BicycleOptions 自転車のルートを計算する: route.requestedTransportModeTransportMode.bicycleです 。
  • TaxiOptions タクシーのルートを計算する : route.requestedTransportModeTransportMode.taxiです。
  • BusOptions バスのルートを計算する : route.requestedTransportModeTransportMode.busです。
  • TransitRouteOptions 公共交通機関のルートを計算するには ( TransitRoutingEngine経由でのみ利用可能 ) : route.requestedTransportModeTransportMode.publicTransitです。

TransportMode は、ルート計算が完了した後にルーティング エンジンによって設定されます。getRequestedTransportMode()はルート オプションからトランスポート モードを決定しますが、Routeの各 Sectionは異なるトランスポート モードを持つことができます。route.getSectionTransportMode()は、ルート計算に使用する必要がある実際の SectionTransportModeを提供します。 特定のセクション - 上記のトランスポート モードに加えて、ferrycarShuttleTrainなどのトランスポート モードもリストされています。

デフォルトでは、始点と終点のウェイポイントのみを通過する場合、導かれたルートには 1 つのルートSectionのみが含まれます。 各 route オブジェクトには、設定されているウェイポイントモードおよびトランスポートモードの数に応じて、より多くのルートセクションを含めることができます。 セクションは、ルートを複数の論理パーツに分割するルートレッグとして機能します。 ここで詳細情報を参照できます。

ルートを計算する前に、メイントランスポートモードがユーザーによって指定されますが、最終的なトランスポートモードは、Sectionごとにルーティングエンジンによって設定されます。

Routeには複数のSectionTransportModeを含めることができます。 このような場合、ルートは Section 別のルートに分割され、トランスポートモードの変更が示されます。 基本的に、トランスポートモードを変更するには 、たとえばフェリーに乗るために車を出るときに、旅程の停止が必要です。 ただし、マルチモーダルルーティング (または インターモーダルルーティング)はサポートされていません。 目的地として公園内の観光スポットが含まれている場合、最後のウェイポイントは、車で到達可能な公園の前が最後の場所としてマップマッチングされ、ルートには歩行者セクションは含まれません。

このようなギャップは 、RoutePlaceオブジェクトのmapMatchedCoordinatesoriginalCoordinatesを比較することで検出できます。 フォールバックとして、適切なトランスポートモードを使用して、これら 2 つの座標間の距離を新しいルート計算で埋めることをアプリケーションで決定できます。- 一部のユーザーは徒歩ではなくタクシーや公共交通機関を利用することを好む場合があるため、このようなモーダル ルートはさまざまなオプションで構成できます。HERE SDK は、このようなモーダルルートを個別の要求としてのみサポートするため、アプリケーションはフォールバックロジックを実装する必要があります。 代わり に、 Intermodal Routing API の使用を検討してください。

ルートに沿ったすべての地理座標がマップマッチングされることに注意してください (スナップイン道路とも呼ばれます)。 Waypoints を追加すると、マップマッチングも実行され、元の座標は Section の始点と終点を示す RoutePlace 内のマップマッチングした場所と比較できます。

利用可能なすべてのルートオプションを使用して、必要に応じてルート計算を最適化するための複数のパラメータをさらに指定できます。

上記の各オプションには、共通のオブジェクト RouteOptions を保持するフィールドが含まれています。 このオプションを使用すると、代替ルートの数などの一般的なオプションを指定できます。また、OptimizationModeで移動時間とルートの長さに基づいて最適なルートを検索することもできます。

デフォルトでは、ルートは ルートモードfastestを使用して計算されます。

または、アルゴリズムを変更することもできます。 たとえば、目的地にすばやく到達したい場合に、ルートの長さが自分にとってそれほど重要ではない場合は、RouteOptionsを経由するfastestのルートモードを選択します。 ルートを短くして、時間がそれほど重要でない場合にshortest を選択します。

最適なルートを見つけるために、ルーティングアルゴリズムでは多数の異なるパラメータが考慮されます。 これは、アルゴリズムが常に 最短 ルートまたは最速ルートを提供することを意味するものではありません。 たとえば、次の道路ネットワークについて考えてみます。

図 : どのルートを選択しますか?

A から B への旅程を計画する場合 、 4 つの異なる道路から選択できます。 緑のルートが高速道路を表しているとし ます。このルートは最速のルートですが、都市を案内する他のルートよりも長くなっています。

最短ルートを使用する場合は、黄色と赤色のルートが短くなりますが、アルゴリズムによって青色のルートが優先されることがあります。 その理由をお聞かせください。 黄色の道路は最短ルートですが、フェリーが発着する川を渡る必要があります。 このアルゴリズムでは、時間のかかるものと見なすことができます。 その結果、黄色のルートではなく、赤または青のルートを優先することができますが、どちらのルートも少し長くなります。

他の 2 つのオプションを確認してみましょう。 青と赤のルートを比較する場合、ルーティングアルゴリズムは、青のルートが赤のルートよりもわずかに長くても最短ルートとして推奨することがあります。通常、複数のターンはドライバーにとって有益ではありません。 この場合、赤色のルートには青色のルートよりも多くのルートが含まれていますが、青色のルートはわずかに長いため、推奨ルートとなる場合があります。 ルート探索アルゴリズムは、ターンおよび交通信号やドライバーの減速を引き起こす可能性のある鉄道踏切など、他の多くの道路特性をペナルティで固定します。

HERE SDK では、一般的なルーティングオプションに加えて、トラックルーティングなど、サポートされているさまざまなトランスポートモードに特化したオプションを提供しています。このオプションでは、次のように指定できます。 トラックの寸法。道路幅やトンネルの高さなど、トラックが適したルートのみを検索できます。

結果のルートは特定の条件に基づいて最適化されますが、信頼したくない状況が生じることがあります。 ベルリン市内を巡る旅を想像してみてください。ベルリンの観光名所を巡りたい場合は、最短ルートまたは最短ルートを見つけることはできません。 このような場合は、追加のウェイポイントを設定することをお勧めします。 以下の例を参照してください。

トラックルートを取得

HERE SDK は、ルート計算のためにさまざまなトランスポートモード(上記を参照)をサポートしています。 車両に最適化されたルートの計算方法を示す上記の例と同様に、トラックなどの他の輸送タイプのルートを計算することもできます。

既定のオプションを設定することで、トラック用に最適化されたルートをすでに取得できますが、トラックに最適なルートを検索するためのオプションが数多く用意されています。

たとえば、TruckOptions には、トラックの寸法を指定する TruckSpecifications などの追加のフィールドが含まれています。これらのフィールドは、オプションで車両重量およびその他のパラメータを考慮に入れるように適用できます。

トラックの取り回しの詳細については、「トラックガイダンス」セクションを参照してください。

公共交通機関を利用

TransitRoutingEngine を使用して、 A から B への公共交通機関のルートを計算します。その間には複数のウェイポイントがあります。 GitHubPublicTransit のサンプルアプリを探し て、その方法を確認できます。

ウェイポイントを追加してルートを形成

デフォルトでは、出発および目的地のみを設定すると、結果のルートには1つのルート Section のみが含まれます。 各ルートオブジェクトには、設定されているウェイポイントの数に応じて、より多くのルートセクションを含めることができます。 セクションは、ルートを複数の論理パーツに分割するルートレッグとして機能します。

ウェイポイントは、より多くのセクションまたはルートの形状を決定するためにユーザーが設定できる座標です ( フェリーで川を横断する場合などに便利です ) 。

オンライン RoutingEngine でサポートされているウェイポイントの数は、最大で約 200 個に制限されています。

ウェイポイントには、次の 2 つのタイプがあります。

  • stopover: デフォルトのウェイポイントタイプ。 このポイントを通過することが保証されているため、操作指示のリストに表示され、ルートが別々のルートセクションに分割されます。
  • passThrough: 操作指示リストに表示されない場合があり、タッチ入力の結果など、ルートを形成するヒントとして扱われます。 このタイプ では、ルートは別々のセクションに分割されません

新しい Waypoint オブジェクトを作成する場合、stopover タイプはデフォルトで設定されます。このタイプは、最初と最後のウェイポイントで使用されるタイプである必要があります。 2 つのウェイポイントのみが始点および終点として機能する場合、ルートは次のようになります。

出発地点と目的地の間に 1 つのルートセクションがあります。

RoutingEngine は複数のウェイポイントを処理できます。 基本となるアルゴリズムは、提供された ListWaypointType の順序と同様に、すべてのウェイポイントを接続するための最適なパスを探します。 各 stopoverウェイポイントは、出発地と目的地の間に位置します。すなわち、ウェイポイントリストの一番最初と一番最後の項目の間に位置します。

var startWaypoint = Waypoint.withDefaults(_startGeoCoordinates);
var destinationWaypoint = Waypoint.withDefaults(_destinationGeoCoordinates);

// Additional waypoints.
var waypoint1 = Waypoint.withDefaults(_createRandomGeoCoordinatesInViewport());
var waypoint2 = Waypoint.withDefaults(_createRandomGeoCoordinatesInViewport());

List<Waypoint> waypoints = [startWaypoint, waypoint1, waypoint2, destinationWaypoint];

_routingEngine.calculateCarRoute(waypoints, CarOptions(),
    (RoutingError? routingError, List<here.Route>? routeList) async {
  if (routingError == null) {
    // When error is null, it is guaranteed that the list is not empty.
    here.Route route = routeList!.first;
    _showRouteDetails(route);
    _showRouteOnMap(route);
    _logRouteViolations(route);
  } else {
    var error = routingError.toString();
    _showDialog('Error', 'Error while calculating a route: $error');
  }
});

上の図に示すように、コード スニペットを使用してルートに 2 つの stopover ルートウェイポイントを追加することで、出発地と目的地の間に 3 つのルートセクションが作成されました。

ウェイポイントリストの順序は、ルートに沿って渡される順序を定義します。

図 : 2 つのウェイポイントを追加しています。

目的地までの移動にかかる推定時間やルートの全長(メートル単位)など、ルートに関する追加情報は、以下のように Route オブジェクトから取得できます。

// estimatedTravelTimeInSeconds includes traffic delay.
int estimatedTravelTimeInSeconds = route.duration.inSeconds;
int estimatedTrafficDelayInSeconds = route.trafficDelay.inSeconds;
int lengthInMeters = route.lengthInMeters;

移動時間と長さは、それぞれのSectionにも利用できます。

void _logRouteSectionDetails(here.Route route) {
  DateFormat dateFormat = DateFormat().add_Hm();

  for (int i = 0; i < route.sections.length; i++) {
    Section section = route.sections.elementAt(i);

    print("Route Section : " + (i + 1).toString());
    print("Route Section Departure Time : " + dateFormat.format(section.departureLocationTime!.localTime));
    print("Route Section Arrival Time : " + dateFormat.format(section.arrivalLocationTime!.localTime));
    print("Route Section length : " + section.lengthInMeters.toString() + " m");
    print("Route Section duration : " + section.duration.inSeconds.toString() + " s");
  }
}

追加のstopoverウェイポイントがない場合、ルートには 1 つのルート Sectionだけが含まれます。 追加のstopoverウェイポイントが指定されている場合、ルートは各ウェイポイント間、出発地から最初のウェイポイントまで、および最後のウェイポイントから目的地まで、複数のルートセクションに分割されます。

デフォルトでは、追加のウェイポイントによってルートが個別のセクションに分割され、ルートがこのポイントを通過し、そのポイントに対する操作指示が生成されます。

Section は、ルートのシェイプが GeoPolyline で表されています。この配列では、最初の座標が出発点を示し、最後の座標が目的地を示します。

これは、たとえば、マップポリラインをそれぞれのSectionで異なる色を使用して、マップ上にルートを表示する場合に役立ちます。 ただし、ポリラインを Route オブジェクトから直接取得することもできます。

以下のコード スニペットは、ルートの各座標(出発地点と目的地を含む)の間に描画されたMapPolyline を使用して、この設定を実装する方法を示しています。

_showRouteOnMap(here.Route route) {
  // Show route as polyline.
  GeoPolyline routeGeoPolyline = route.geometry;
  double widthInPixels = 20;
  MapPolyline routeMapPolyline = MapPolyline(routeGeoPolyline, widthInPixels, Color.fromARGB(160, 0, 144, 138));
  _hereMapController.mapScene.addMapPolyline(routeMapPolyline);
}

以下の最初のスクリーンショットは、追加のウェイポイントがないルートを示しています。そのため、ルートセクションは 1 つだけです。 出発地点と目的地は、緑で囲まれたマップ マーカーオブジェクトで示されます。 円で囲まれたオブジェクトを描画するコードはここではありませんが、必要に応じてサンプルのソースコードから参照できます。

スクリーンショット: マップにルートを表示。

2 つ目のスクリーンショットには、上記と同じルートが表示 stopoverされますが、 2 つのウェイポイントが追加され、赤い丸で囲まれたマップ マーカーオブジェクトで示されます。 このため、ルートには 3 つのルートセクションが含まれています。

スクリーンショット: 2 つのウェイポイントが追加されたルートを表示。

内部的には、MapPolyline のレンダリングは非常に長いルートに合わせて最適化されています。 たとえば、高いズーム レベルではすべての座標をレンダリングする必要はありませんが、低いズームレベルではルート全体が表示されません。 このアルゴリズムは公開されていませ んが、基本的な原理は HERE のフレキシブルポリラインのオープンソースプロジェクトで確認できます。

マップに一致するウェイポイントを取得

ルートの計算には 、 オフロードの場合でも、任意の地点を出発地、目的地、中間地点、stopoverまたはpassThroughウェイポイントとして使用できます。 ただし、導かれるルートは、指定されたウェイポイントを正確に通過するものではありません。 ルーティングアルゴリズムは、指定された座標にできるだけ近い位置に移動しようとします。 これを実現するために、 HERE SDK には、指定されたトランスポートモードなどのさまざまなパラメータを使用して、座標の各セットに最も近いルートセグメントを検索する高度な技術が組み込まれています。 このプロセスを マップマッチングと呼びます。

ただし、ルートのシェイプは、マップが一致したウェイポイントだけで構成されます。

RouteSectionについて 、セクションの最初(出発地)および最後(到着地)にあるRoutePlaceにアクセスできます。 Routeplace パラメーター として渡された内容mapMatchedCoordinatesoriginalCoordinatesが含まれています。 両方を同じにすることも、異なる値にすることもできます それらが異なっていれば、 originalCoordinates は道にないことを意味します。

RoutePlace には、旅程の支援に役立つ詳細情報が含まれています。 たとえば、電気自動車に便利な chargeInKilowattHours(以下を参照) および元のウェイポイントの sideOfDestination とともにchargingStation 情報にアクセスできます。

図 : 元のウェイポイントとマップが一致した。

ルート沿いを走行中で、立ち寄り地として、オフロードにある観光スポットを指定したとします。 対応するマップに一致するウェイポイントに到着すると、道路上に留まり、ルートに沿って目的地に向かっていますが、sideOfDestinationフィールドには、観光スポット (または上図のレストラン) が、あなたが現在走行している道路の左側か右側に表示されます。

場合によっては、指定さた立ち寄り地が目の前、現在地の上または下にある場合もあります。そのような場合、sideOfDestinationフィールドにはその場所が undefined として表示されます。たとえば、湖に到着しようとしている場合、 道は目の前で終わります。

placesをウェイポイントに設定

SearchEngineから取得したPlace には、 1つ以上の アクセスポイントが含まれている場合があります。 たとえば、大規模な倉庫には複数の入口があり、倉庫の中心部には直接到達できない場合があります。 アクセスポイントは車両から到達できるように設計されていることに注意してください。

ルートの場合は、利用可能なアクセスポイントのいずれかにナビゲートすることをお勧めしますが、sideOfStreetHint はその場所の地理座標に設定する必要があります。 アクセスポイントが認識されていない場合、またはplacesに直接到達できる場合、リストは空になります。

List<GeoCoordinates> accessPoints = place.accessPoints;
// A Place always contains coordinates unless it is a suggestion.
Waypoint destinationWaypoint = Waypoint(place.geoCoordinates!);
if (!accessPoints.isEmpty) {
  // Set the first access point of a place as route destination.
  destinationWaypoint.coordinates = accessPoints.first;
  // When reaching destination provide a hint on the actual location of the place.
  destinationWaypoint.sideOfStreetHint = place.geoCoordinates;
  // Always prefer the given side of street hint, even if the street has no lane dividers.
  destinationWaypoint.matchSideOfStreet = MatchSideOfStreet.always;
}

結果として得られる Routeオブジェクトの RoutePlace には、ウェイポイントがアクセス ポイントに設定されたときにaccessPointに設定される RoutePlaceType が含まれます。

上の図を参照して、sideOfStreetHintRoutePlaceSideOfDestinationに与える影響を確認してください。

場所に複数のアクセスポイントが含まれている場合、ユーザーが適切なアクセスポイントを選択する必要があります。

出発地としてウェイポイントを設定

旅程を開始する際 RoutingEngine に、適切な開始方向を選択するための追加のヒントを提供することができます。たとえば、必要な U ターンを実施するためです。

たとえば、次のように最初の見出し方向を指定できます。

startWaypoint.headingInDegrees = location.bearingInDegrees;

ユーザーが移動している場合、方位の値を使用してルートの計算を改善できます。 Location オブジェクトがポジショニングソースから取得され、ユーザーがすでに移動している場合、そのオブジェクトにはベアリング値が含まれていることに注意してください。 そうでない場合、設定されていない可能性があります。 このようなシナリオは、ガイダンス中により一般的になります。たとえば、ユーザーが提示されたパスから逸脱した後でルートを再計算する必要がある場合などです。

ルートを拡大表示

一部の使用例では、計算されたルートをズームすると便利です。 Camera クラスを使用すると、ルートが収まるようにビューポイントを簡単に調整できます。

GeoBox routeGeoBox = route!.boundingBox;
// Keep default orientation for bearing and tilt.
_hereMapController.camera.lookAtAreaWithGeoOrientation(routeGeoBox, GeoOrientationUpdate(null, null));

ここでルートオブジェクトの外側のバウンディング ボックスを使用します。 これを使用すると、カメラを即座に更新できます。 ズーム レベルとカメラのターゲットポイントが変更され、指定された境界矩形がビューポイントに正確に収まるようになります。 さらに、方向を指定して、より多くのカメラパラメーターを指定できます。 ここではデフォルトの値を使用します。 lookAtAreaWithOrientation() の呼び出しによってビューが即座に変更されます。

ほとんどの使用例では、アニメーションを使用してルートを拡大縮小する方がユーザーの操作性が向上します。 次の例では、GeoBoxに 50ピクセルのパディングを加えてズームしています。

void _animateToRoute(here.Route route) {
  // The animation results in an untilted and unrotated map.
  double bearing = 0;
  double tilt = 0;
  // We want to show the route fitting in the map view with an additional padding of 50 pixels.
  Point2D origin = Point2D(50, 50);
  Size2D sizeInPixels = Size2D(_hereMapController.viewportSize.width - 100, _hereMapController.viewportSize.height - 100);
  Rectangle2D mapViewport = Rectangle2D(origin, sizeInPixels);

  // Animate to the route within a duration of 3 seconds.
  MapCameraUpdate update = MapCameraUpdateFactory.lookAtAreaWithGeoOrientationAndViewRectangle(route!.boundingBox,
      GeoOrientationUpdate(bearing, tilt),
      mapViewport);
  MapCameraAnimation animation = MapCameraAnimationFactory.createAnimationFromUpdate(
      update, const Duration(milliseconds: 3000), EasingFunction.inCubic);
  _hereMapController.camera.startAnimation(animation);
}

The `CameraKeyframeTracks` example app shows how this can look like.

操作手順を取得

Sectionには、目的地に到着するためにユーザーが従う必要がある操作手順が含まれています。 1 つの Maneuver オブジェクトには、曲がるたびに操作と操作が必要な場所が含まれています。 このアクションは、「出発」や「左折」などの道順を示す場合があります。

List<Section> sections = route.sections;
for (Section section in sections) {
  _logManeuverInstructions(section);
}

ここには、セクションごとの操作指示にアクセスするためのコードがあります。

void _logManeuverInstructions(Section section) {
  print("Log maneuver instructions per route section:");
  List<Maneuver> maneuverInstructions = section.maneuvers;
  for (Maneuver maneuverInstruction in maneuverInstructions) {
    ManeuverAction maneuverAction = maneuverInstruction.action;
    GeoCoordinates maneuverLocation = maneuverInstruction.coordinates;
    String maneuverInfo = maneuverInstruction.text +
        ", Action: " +
        maneuverAction.toString() +
        ", Location: " +
        maneuverLocation.toString();
    print(maneuverInfo);
  }
}

これは、経路全体を記述する操作指示リストを書面で簡単に作成する場合に役立ちます。 たとえば 、 列挙型 (enum)の ManeuverActionを使用して独自のルーティングエクスペリエンスを構築できます。

スクリーンショット: 操作手順を含むルートプレビューを示す画面の例。

Navigator または VisualNavigator から取得した場合、ナビゲーション中に Maneuver 説明テキスト(maneuverInstruction.text)はになります。 Route インスタンスから取得した場合にのみ、ローカライズされた命令が含まれます。 ManeuverAction 列挙型(enum)はナビゲーション中に視覚的なインジケータを表示するために使用され、テキストによる指示は、旅程を開始する前に操縦をプレビューするために、より多くのリストに入ることになっています。

反対に、maneuverInstruction.roadTextsmaneuverInstruction.nextRoadTexts および maneuverInstruction.exitSignTexts は、ナビゲーション中のターンバイターン操作の一部として表示されることを意味します。したがって、これらの操作は、ManeuverNavigator または VisualNavigator から取得された場合にのみ空ではありません。 Route インスタンスから取得した場合、これらの属性は常に空になります。

API リファレンス では、利用可能な 操作の概要を確認できます。

次の表は、プレビューの説明とアセットの例を含むすべてのアイテムManeuverAction を示しています。 HERE SDK自体には、操作アイコンは付属していません。 アセットは、オープンソース のHERE Icon Libraryの一部として、さまざまな密度のSVGまたはソリッドPNGとして利用できます。

使用可能な操作アクションは 、APIリファレンスに表示される順序でソートされます。

操作アクション 説明の例 アイコンの例
出発 「出発 <road name>」などの出発操作。 DEPART
到着 「到着」などの到着操作。 中間ウェイポイントの説明例: 」に到着 <road name | waypoint>。 ルートの目的地の場合: 」に到着 <road name | destination name | destination>。 ARRIVE (到着)
左転回をする 「左転回を行う <next road name>」などの左転回操作。 Left_U_Turnアイコン
鋭角に左に曲がる 「鋭角に左に曲がる <next road name>」などの鋭角な左折操作。 SHARP_LEFT_TURN icon(鋭角に左折する icon)
左折する 「左折」などの左折操作 <next road name>。 左旋回アイコン
少し左に曲がる 「左折してください <next road name>」など、少し左に曲がる操作。 SLETT_LEFT_TURNアイコン
継続オン 「続行」などの操作を続行 <road name>します。 continue_on
少し右に曲がる 「右折してください <next road name>」など、少し右に曲がる操作。 
SLIGHT_RIGHT_TURN icon(ライト右ターンアイコン)
右折する 「右折」などの右折操作 <next road name>。 右折アイコン
鋭角に右に曲がる 「鋭角に右に曲がる <next road name>」などの鋭角な右折操作。 SHARP_RIGHT_TURN icon (鋭角に右折するicon)
右転回する 右転回操作(「右転回する <next road name>」)。 RIGHT_U_TURNアイコン
左側の出口を出る 「左側の出口から出て <next road name>」(左側の出口で出る)などの左出口の操作。 LEFT_EXIT (出口から出る)
右側の出口を出る 「右側の出口から出て <next road name>」(右側の出口で出る)などの右出口の操作。 右の終了アイコン
左ランプを出る 「左ランプを出る」などの左ランプ出口操作。 左ランプを出る
右ランプを出る 「右ランプを出る」などの右ランプ出口操作。 右ランプアイコン
左車線を進む操作 左車線を進む操作(「左車線を進んで <next road name>」など)。 Left_fork(左車線を進む)
中央の車線を進む 「中央の車線を進む <next road name>」などの中央車線の進行操作。 中央の車線を進むアイコン
右の車線を進む 右車線を進む操作(「右車線を進んで <next road name>」など)。 右フォークアイコン
左側から高速道路に合流する 「左側から高速道路に合流する」など、左側からの操作で高速道路に合流します。 「_Highway_from_left」と入力します
右側から高速道路に合流する 「右側から高速道路に合流する」など、右側からの操作で高速道路に入ります。 「_Highway_From_right」と入力します
左ロータリー(環状交差点)に入る 「左ロータリー(環状交差点)に入る」など、右ロータリーを操作します ( 左側通行 ) 。
右ロータリー(環状交差点)に入る 「右ロータリー(環状交差点)に入る」など、右ロータリーを操作します ( 右側通行 ) 。 右環状交差点の入力アイコン
左ロータリー(環状交差点)を通過する 「左ロータリー(環状交差点)を通過する」など、ロータリーを操作します ( 左側通行 ) 。 LEFT_ROUNDABOUT_PASSアイコン LEFT_ROUNDABOUT_PASSアイコン
右ロータリー(環状交差点)を通過する 「右ロータリー(環状交差点)を通過する」など、ロータリーを操作します ( 右の交通量 ) 。 right_roundabout_passアイコン
左ロータリー(環状交差点)の最初の出口を出る 「左ロータリー(環状交差点)の最初の出口を出る」などのロータリー操作(左側通行)。 LEFT_ROUNDABOUT_EXIT1アイコン
左ロータリー(環状交差点)の2番目の出口を出る 「左ロータリー(環状交差点)の2番目の出口を出る」などのロータリー操作(左側通行)。 LEFT_ROUNDABOUT_EXIT2アイコン
左ロータリー(環状交差点)の3番目の出口を出る 「左ロータリー(環状交差点)の3番目の出口を出る」などのロータリー操作(左側通行)。 LEFT_ROUNDABOUT_EXIT3アイコン
左ロータリー(環状交差点)の4番目の出口を出る 「左ロータリー(環状交差点)の4番目の出口を出る」などのロータリー操作(左側通行)。 LEFT_ROUNDABOUT_EXIT4アイコン
左ロータリー(環状交差点)の5番目の出口を出る 「左ロータリー(環状交差点)の5番目の出口を出る」などのロータリー操作(左側通行)。 LEFT_ROUNDABOUT_EXIT5アイコン
左ロータリー(環状交差点)の6番目の出口を出る 「左ロータリー(環状交差点)の6番目の出口を出る」などのロータリー操作(左側通行)。 LEFT_ROUNDABOUT_EXIT6アイコン
左ロータリー(環状交差点)の7番目の出口を出る 「左ロータリー(環状交差点)の7番目の出口を出る」などのロータリー操作(左側通行)。 LEFT_ROUNDABOUT_EXIT7アイコン
左ロータリー(環状交差点)8番目の出口を出る 「左ロータリー(環状交差点)8番目の出口を出る」などのロータリー操作(左側通行)。 LEFT_ROUNDABOUT_EXIT8アイコン
左ロータリー(環状交差点)の9番目の出口を出る 「左ロータリー(環状交差点)の9番目の出口を出てる」などのロータリー操作(左側通行)。 LEFT_ROUNDABOUT_EXIT9アイコン
左ロータリー(環状交差点)の10番目の出口を出る 「左ロータリー(環状交差点)の10番目の出口を出る」などのロータリー操作(左側通行)。 LEFT_ROUNDABOUT_EXIT10アイコン
左ロータリー(環状交差点)の11番目の 出口を出る 「左ロータリー(環状交差点)の11番目の 出口を出る」などのロータリー操作(左側通行)。 LEFT_ROUNDABOUT_EXIT11アイコン
左ロータリー(環状交差点)の12番目の出口を出る 「左ロータリー(環状交差点)の12番目の出口を出る」などのロータリー操作(左側通行)。 LEFT_ROUNDABOUT_EXIT12アイコン
右ロータリー(環状交差点)の最初の出口を出る 「右ロータリー(環状交差点)の最初の出口を出る」などのロータリー操作(右側通行)。 右ロータリー(環状交差点)の[終了1(終了)]アイコン
右ロータリー(環状交差点)の2番目の出口を出る 「右ロータリー(環状交差点)の2番目の出口を出る」などのロータリー操作(右側通行)。 RIGHT_ROUNDABOUT_EXIT2アイコン
右ロータリー(環状交差点)の3番目の出口を出る 「右ロータリー(環状交差点)の3番目の出口を出る」などのロータリー操作(右側通行)。 RIGHT_ROUNDABOUT_EXIT3アイコン
右ロータリー(環状交差点)の4番目の出口を出る 「右ロータリー(環状交差点)の4番目の出口を出る」などのロータリー操作(右側通行)。 RIGHT_ROUNDABOUT_EXIT4アイコン
右ロータリー(環状交差点)の5番目の出口を出る 「右ロータリー(環状交差点)の5番目の出口を出る」などのロータリー操作(右側通行)。 RIGHT_ROUNDABOUT_EXIT5アイコン
右ロータリー(環状交差点)の6番目の出口を出る 「右ロータリー(環状交差点)の6番目の出口を出る」などのロータリー操作(右側通行)。 RIGHT_ROUNDABOUT_EXIT6アイコン
右ロータリー(環状交差点)の7番目の出口を出る 「右ロータリー(環状交差点)の7番目の出口を出る」などのロータリー操作(右側通行)。 RIGHT_ROUNDABOUT_EXIT7アイコン
右ロータリー(環状交差点)8番目の出口を出る 「右ロータリー(環状交差点)8番目の出口を出る」などのロータリー操作(右側通行)。 RIGHT_ROUNDABOUT_EXIT8アイコン
右ロータリー(環状交差点)9番目の出口を出る 「右ロータリー(環状交差点)9番目の出口を出る」などの右ロータリー操作(右側通行)。 RIGHT_ROUNDABOUT_EXIT9アイコン
右ロータリー(環状交差点)の10番出口を出る 「右ロータリー(環状交差点)の10番出口を出る」などのロータリー操作(右側通行)。 右ロータリー(環状交差点)の[終了10(終了)]アイコン
右ロータリー(環状交差点)の11番出口を出る 「右ロータリー(環状交差点)の11番出口を出る」などのロータリー操作(右側通行)。 右ロータリー(環状交差点)の[終了11(終了)]アイコン
右ロータリー(環状交差点)の12番目の出口を出る 「右ロータリー(環状交差点)の12番目の出口を出る」などのロータリー操作(右側通行)。 RIGHT_ROUNDABOUT_EXIT12アイコン

現時点では、leftRoundaboutPass および rightRoundaboutPassのHEREアセットは SVGとしてのみ使用でき、一部の操作アセットはサブフォルダ"wego-fallback-roundabout"でのみ使用できます。 PNG表現の場合、 MSDKUI オープンソースプロジェクトもフォールバックとして使用できます。

ルートに沿って交通状況を検索

渋滞に巻き込まれた場合の総時間を取得するには、次のいずれかの操作を行います。

int estimatedTrafficDelayInSeconds = route.trafficDelay.inSeconds;

ルートの個々のセクションでは、交通状況に関するより詳細な情報を利用できます。 操作に加えて(上記を参照)、各SectionRouteには、ルートが計算された時点のトラフィックフローの状況に関する情報が含まれています。

各インスタンス Section には、さまざまな量 のインスタンスTrafficSpeed を含めることができます。 これらの値は 、Spanに沿って次のSpanまでの間有効です。 各 Span ジオメトリは、ルート全体のポリライン 形状の一部であるポリラインによって表されます。

次のコード スニペットは Section の最初の SpanTrafficSpeed 要素を取得する方法を示しています。

Section firstSection = route.sections.first;
TrafficSpeed firstTrafficSpeed = firstSection.spans.first.trafficSpeed;

TrafficSpeed にはbaseSpeedInMetersPerSecondが含まれています。これは、予想されるデフォルトの走行速度です。 これは、道路の現在の制限速度とは異なる場合があります。道路状況が悪いと、走行速度が遅くなる可能性があります。 さらに、trafficSpeedInMetersPerSecondで現在の交通状況に基づく、実際の推定走行速度を取得できます。

トラフィックフローレイヤで使用されるカラーエンコーディングと同様 に、 0 (トラフィックなし) ~ 10 (道路がブロックされている)の範囲のjamFactorを使用して、ルートに沿ったトラフィックを指定できます。 HERE SDK のトラフィックフィーチャーの詳細については、「トラフィック」セクションを参照してください。

この値を適切な色にマップする方法の例を次に示します。

図 : 交通渋滞の要因。

通常、 jamFactor は次のように解釈されます。

  • 0 <=<4 jamFactor : 渋滞なし、または少しの渋滞。
  • 4 <= jamFactor <8 : 中程度または低速のトラフィック。
  • 8 <=<10 jamFactor : 渋滞しています。
  • jamFactor = 10 : 通行できない、例:道路が閉鎖されている。

TrafficSpeedを示す jamFactorは、道路の種類やその他のパラメーターを考慮せずに、 trafficSpeedInMetersPerSecond / baseSpeedInMetersPerSecond- の比率から線形的に計算されることに注意してください。したがって、提供された jamFactor は、マップ ビュー のトラフィックフローの表示と正確に一致するとは限りません(有効な場合)。 さらに、RoutingEngine予測位置情報サービスを使用 して、ルートを通過する間に今後のトラフィックを予測します。一方、トラフィックフローの視覚化は現在の時点のみを表します。

スクリーンショット: 渋滞係数を使用してルート上のトラフィックを視覚化。

ルートに沿ったトラフィックを表示する場合は 、セクションの各スパンに複数の色付きのMapPolylineオブジェクトをレンダリングすることを検討してください。

// This renders the traffic jam factor on top of the route as multiple MapPolylines per span.
_showTrafficOnRoute(here.Route route) {
  if (route.lengthInMeters / 1000 > 5000) {
    print("Skip showing traffic-on-route for longer routes.");
    return;
  }

  for (var section in route.sections) {
    for (var span in section.spans) {
      TrafficSpeed trafficSpeed = span.trafficSpeed;
      Color? lineColor = _getTrafficColor(trafficSpeed.jamFactor);
      if (lineColor == null) {
        // We skip rendering low traffic.
        continue;
      }
      double widthInPixels = 10;
      MapPolyline trafficSpanMapPolyline = new MapPolyline(span.geometry, widthInPixels, lineColor);
      _hereMapController.mapScene.addMapPolyline(trafficSpanMapPolyline);
      _mapPolylines.add(trafficSpanMapPolyline);
    }
  }
}

// Define a traffic color scheme based on the route's jam factor.
// 0 <= jamFactor < 4: No or light traffic.
// 4 <= jamFactor < 8: Moderate or slow traffic.
// 8 <= jamFactor < 10: Severe traffic.
// jamFactor = 10: No traffic, ie. the road is blocked.
// Returns null in case of no or light traffic.
Color? _getTrafficColor(double? jamFactor) {
  if (jamFactor == null || jamFactor < 4) {
    return null;
  } else if (jamFactor >= 4 && jamFactor < 8) {
    return Color.fromARGB(160, 255, 255, 0); // Yellow
  } else if (jamFactor >= 8 && jamFactor < 10) {
    return Color.fromARGB(160, 255, 0, 0); // Red
  }
  return Color.fromARGB(160, 0, 0, 0); // Black
}

パフォーマンス上の理由から、長いルートのトラフィックレンダリングはスキップします。この例では、トラフィックを持つ各スパンが個別の折れ線としてレンダリングされるためです。

あるいは、マップ上にルートのポリラインと並べて交通量スキームを表示可能です。ルートがトラフィックフローラインをカバーしていないことを確認するには 、現在のズーム レベル MapPolylineおよびMapArrowに基づいて、測定に依存する幅を設定します。

  • さらに、 TrafficEngineを使用して、ルートに沿った交通障害を照会できます。 このためには、Route の座標から GeoCorridor を作成する必要があります。 また、halfWidthInMetersを設定して、コリドーの半径も指定してください 。 GeoCorridor の長さと幅には制限があります。 Traffic Example アプリ を確認して、TrafficEngineの使用方法を確認してください。 このガイドの 交通状況を確認のセクションも確認してください。

  • ルート上の基本的な交通障害情報にのみ関心がある場合は、Section.getTrafficIncidents()を呼び出して、Route インスタンスから Section ごとに交通状況の概要を直接取得できます。 結果 TrafficIncidentOnRoute のオブジェクトには、TrafficEngineで使用できるデータの小さなサブセットが含ま れていますが、概要を最初に示すと便利です。

ルート上のトラフィックをレンダリングするだけでなく、 TrafficIncidentTypeに基づいてトラフィックインシデントをアイコンとして表示することもできます。 次のカテゴリは、オブジェクトRouteの一部として重複しています。

  • accident: 交通事故。
  • congestion: 交通渋滞。
  • construction: 建設工事。
  • disabledVehicle: 道路上の車両の転覆または故障。
  • laneRestriction: 車線規制。
  • massTransit: 鉄道や地下鉄などの大量輸送機関を含む事故。
  • plannedEvent: スポーツイベントやフェスティバルなどの活動に関する事故。
  • roadClosure: 道路閉鎖。
  • roadHazard: 倒木や信号が消えたりするなど、道路上の危険な障害。
  • weather: 悪天候。
  • other: 他のどのカテゴリーにも当てはまらない既知の事故。
  • unknown: 特定の障害に分類されない事象。

HERE SDKではこのようなアイコンアセットは公開されませんが 、マップフィーチャレイヤtrafficIncidentsを有効にして、すべてのインシデントをマップ上にアイコン付きで表示できます。 同様に 、trafficFlowレイヤを有効にして、道路上の一般的なトラフィックフローを表示することもできます。 詳細 については、交通状況を確認セクションをご覧ください。

refreshRoute() 経由でルートを更新すると、ルートの交通情報を更新できます。 以下のセクションを参照してください。 または、ガイダンスの最中にDynamicRoutingEngineを使用することも検討してください。

この先の制限速度などを確認可能

このオブジェクトRoute は、Routeに沿って詳細な情報を公開 し、今後の制限速度、道路の属性と道路名、動的な交通情報などを把握します。

次の属性を確認してください: Span.sectionPolylineOffsetSpan.dynamicSpeedInfoSpan.streetAttributesSpan.carAttributesSpan.truckAttributesSpan.scooterAttributesSpan.walkAttributesSpan.durationInSecondsSpan.streetNamesSpan.routeNumbersSpan.speedLimitInMetersPerSecondSpan.consumptionInKilowattHoursSpan.functionalRoadClassSpan.durationSpan.baseDuration。 属性の完全なリストについては、 API リファレンス を参照してください。

各属性はスパンごとに指定され、スパンの全長にわたって有効です。 また、 2 つの交差点の間にある道路ネットワーク の一部を示すセグメント ID も検索されることがあります。 Spanは 、ルート関連の概念です。ルートの一部で、同じ属性を持ちます。 同じセグメントに複数のスパンを含める ことができ、通常、各セグメントには開始オフセット終了オフセット があります。

Spanは、ルートセグメントの最小の部分を定義し、その曲率がのリストGeoCoordinatesとして公開されます。

ルートに沿って通行料金を取得

ルートの個々のセクションに沿って、通行料金を計算できます。

これはこのフィーチャーのベータ版です。このため、いくつかのバグや予期しない動作が発生する可能性があります。 関連する API は、非推奨プロセスなしで新しいリリースで変更されることがあります。

通行料金を取得するには、フラグrouteOptions.enableTollsを設定する必要があります。 デフォルトでは、false に設定されています。 このフラグを有効にすると 、API リファレンス で定義されているように、通行料金の該当するトランスポートモードの通行料金データが要求されます。

PaymentMethodTollFare、および一般的なToll情報を提供する section.tolls経由で通行料金を取得します。

void _logTollDetails(here.Route route) {
  for (Section section in route.sections) {
    // The spans that make up the polyline along which tolls are required or
    // where toll booths are located.
    List<Span> spans = section.spans;
    List<Toll> tolls = section.tolls;
    if (!tolls.isEmpty) {
      print("Attention: This route may require tolls to be paid.");
    }
    for (Toll toll in tolls) {
      print("Toll information valid for this list of spans:");
      print("Toll system: " + toll.tollSystem);
      print("Toll country code (ISO-3166-1 alpha-3): " + toll.countryCode);
      print("Toll fare information: ");
      for (TollFare tollFare in toll.fares) {
        // A list of possible toll fares which may depend on time of day, payment method and
        // vehicle characteristics. For further details please consult the local
        // authorities.
        print("Toll price: " + tollFare.price.toString() + " " + tollFare.currency);
        for (PaymentMethod paymentMethod in tollFare.paymentMethods) {
          print("Accepted payment methods for this price: " + paymentMethod.toString());
        }
      }
    }
  }
}

ナビゲーション中 - ルートを走行中 - isTollwayを含む新しい道路属性を通知する RoadAttributesListenerを使用して、現在の道路で料金を支払う必要があるかどうかを知ることができます。加えて、 TollStopWarningListenerにより、この先の料金所でのイベントも通知されます。

道路の特徴による回避

トンネル、高速道路、低排出ガス地帯(LEZ)、地域、フェリー、料金、その他の道路の特徴(急カーブなど)を除外するためにAvoidanceOptions を使用します。 RoadFeatures, ZoneCategory, GeoBox, CountryCode エレメントなどのリストを渡すことができます

RoadFeaturesには、 トンネルや有料道路などの道路固有のフィーチャーが含まれています。 たとえば、すべての高速道路を走行から除外するには、フィーチャーリストに controlledAccessHighway を追加します。

AvoidanceOptions は、ローカリゼーションや単位オプションなど、他のルートオプションと組み合わせて、目的のトランスポートモードのオプションに設定できます。 たとえば、車では、 CarOptions、トラックでは TruckOptions を使用するなどです。 これらのオプションは、ルートの計算時に読み取られ、AvoidanceOptionsの場合 、エンジンは一覧表示されているフィーチャーを回避しようとします。

スクリーンショット: 回避エリアのない2つのルートと回避エリアのある2つのルート。

ルートがブロックされたエリアで開始されたときなど、設定されたオプションを回避できない場合 SectionNotice は、提供された要素でこのような違反を検査できます。 これらのルートが設定されている場合は、そのようなルートを拒否できます。

ルートを更新

Route オブジェクトに含まれているトラフィックフロー情報は、ルートが計算された時間帯に有効です。上記を参照してください。 この情報を後で更新する場合は、ルートを更新できます。

ルートのルートオプションを更新することもできます。

RefreshRouteOptions refreshRouteOptions = RefreshRouteOptions.withTaxiOptions(taxiOptions);

// Update the route options and set a new start point on the route.
// The new starting point must be on or very close to the original route, preferrably, use a map-matched waypoint if possible.
// Note: A routeHandle is only available, when RouteOptions.enableRouteHandle was set to true when the original route was calculated.
routingEngine.refreshRoute(route.routeHandle, mapMatchedWaypoint, refreshRouteOptions, (routingError, routes) {
    if (routingError == null) {
        HERE.Route newRoute = routes.first;
        // ...
    } else {
        // Handle error.
    }
});

このためには、ルートが計算される前にRouteOptions.enableRouteHandle経由で要求されるRouteHandleを把握しておく必要があります。

また、ルートの更新は、ルートオプションをあるトランスポートタイプから別のトランスポートタイプに変換したり、特定のオプションを更新したりする場合に役立ちます。 たとえば、徒歩ルートがトラックルートに変換されたなど、変換ができない場合、 routingErrorが発生します。

新しい出発地点を指定して、ルートを短縮することもできます。 新しいルートは計算されないため、新しい出発地点は元のルートに非常に近い位置にある必要があります。 新しい出発地点が遠すぎると、routingErrorが発生します。

進行中のターン・バイ・ターンナビ (矢印ナビ)中にドライバーがルートから逸脱した場合、迂回路の計算を新たに行う必要があるため、ルートを更新するだけでは不十分です。 このような場合 returnToRoute() は、新しい出発地点を設定してルート全体を再計算するか、または元の代替ルートを保持できる方法を使用すると便利です。

ターン・バイ・ターンナビ (矢印ナビ) 中 にルートを更新して、最新の交通渋滞遅れアップデートを先に取得できます。 更新されたルートをNavigatorに設定する前に、ルートの最後の場所を新しい出発地点として設定する必要があります。 ただし、更新処理中にドライバーがすでに進行している場合、予期しない結果が生じる可能性があります。 いずれの場合も、 ETA を更新するだけで、新しい出発地点が既存のルートにある 場合、必ずしも新しいルートを設定する必要はありません。 代わりに、交通遅延時間を含む更新済みの ETA を使用できます。前方ルートの REST は 変更されません。 ガイダンス中に新しいルートを設定すると、新しいナビゲーションセッションが効果的に開始されます。

代わりに、最後の場所 現在のセクションインデックスを設定する必要がある DynamicRoutingEngine を使用することを検討してください。 この情報は、次 dynamicRoutingEngineOptions.pollInterval の到達時に使用されます。 トレードオフとして、これは即時の更新にはつながりません。また、現在の交通障害物を迂回するより適切なルートが見つかった場合、ルートの形状が変更される可能性があります。 ここでも、 refreshRoute()と同様に、新しいルートを設定するかどうかを決定する必要があります。

ルートの更新は OfflineRoutingEngineではサポートされていません - 現在の交通状況をクエリするにはオンライン接続が必要です。同様 に、DynamicRoutingEngine にもオンライン接続が必要です。

ルートに戻る。

RoutingEngineは、現在の交通状況に基づいて既存のルート(上記を参照)を更新できます。 結果として、前のルートよりも高速な新しいルートが作成されることがあります。 ただし、新しい startingPoint は元のルートに非常に近いものにする必要があります。

startingPointがルートから離れている場合に対処する必要がある場合は、RoutingEnginereturnToRoute()機能を使用することを検討してください。 たとえば、ローカルの交通状況により、ドライバーが迂回路を選択する場合があります。 また、 returnToRoute()のコール によって新しいルートが作成されますが、可能であれば、コストのかかるルートの再計算を行わずに、元のルートからできるだけ類似したルートが作成されます。

  • ストップオーバーウェイポイントの通過が保証。
  • パススルーウェイポイントは、ルートの形成のみを目的としているため、新しいルートがそれらのルートを受け入れるか、または廃棄するかは保証されない。
  • 現在の交通状況が考慮され、ルートが再形成される可能性がある。

ターン・バイ・ターンナビ (矢印ナビ)は Navigate Edition でのみ使用可能。

このメソッドreturnToRoute()は 、キャッシュ、またはダウンロードされたマップ データでオフラインで動作するOfflineRoutingEngineで使用することもできます。 ただし、現在の交通状況は考慮されません。

returnToRoute()を 使用したコーディング例については、ナビゲーションの章を参照 してください。

他のサービスからルートをインポート

これはこのフィーチャーのベータ版です。このため、いくつかのバグや予期しない動作が発生する可能性があります。 関連する API は、非推奨プロセスなしで新しいリリースで変更されることがあります。

さまざまな多重定義されたメソッドroutingEngine.importRoute() のいずれかを使用して、他の API やベンダーからルートをインポートできます。 これは 1 対 1 のインポートフィーチャではなく 、再構築であることに注意してください。

次の場所から新しいRouteオブジェクトを作成できます。

  • オプション 1 : GeoCoordinates および RouteOptions のリスト。これは、ルートを別のベンダーからインポートする必要がある場合、またはルートを長期間保持する必要がある場合に役立ちます。 ルートシェイプは、指定されたものにできるだけ近い場所に保持されます。 オンライン接続が必要です。
  • オプション 2 : RouteHandle これは、他の HERE サービスからルートをインポートする場合に役立ちます。 ユースケース では 、 HERE Wego Web サイトまたは HERE REST API を使用する別の Web ページにルートを作成し、それをモバイル機器に転送して旅程を開始できます。 バックエンド側でのマップの更新、または実世界でのその他の変更によって、無効なハンドルが生じる可能性があります。 また、ハンドルの寿命は一般的に制限されています。 そのため、数時間のみハンドルを使用することをお勧めします。 RouteHandleは、特定の情報をエンコードしますが、バックエンドから完全なルートデータを取得するには、オンライン接続が必要です。

適用されたすべてのものAvoidanceOptionsは廃棄され、ルートSection.sectionNoticesを経由して違反として報告されます。 たとえば、高速道路の回避を要求しても、指定された座標が高速道路と一致する場合、導かれたルートは引き続き高速道路と一致しますが、目的の回避オプションに違反していることを示す通知が追加されます。

一般に、ルートをインポートすると、まったく同じ RouteOptions を使用したとしても、元のルートとまったく同じルートが再現されるとは限らないことに注意してください。新しい建設現場や関連する交通状況などにより、マップには常に変更がされる可能性があります。 また、マップ データ自体は、新しい道路が建設されたり道路の制限速度が変更された場合 、既存の道路が閉鎖された場合などにも変更されます。 また、特定の道路を利用できる場合、出発時刻が影響を受けることがあります。

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

オプション 1 : 地理座標のリストからルートをインポート

RouteOptionsGeoCoordinates のリストからルートをインポートする には、ルートシェイプを定義するGeoCoordinatesのリストが必要です。 このような座標は互いに非常に近い値にする必要があります。そうしないと、計算に失敗します。 このような座標のリストは、別のベンダーによって計算されたルートから抽出することも、 GPX トレースから抽出することもできます。

// Import a route from list of Location instances.
// Note that the geographic coordinates need to be close to each other.
List<Location> routeLocations = [
  Location.withCoordinates(GeoCoordinates(52.518032, 13.420632)),
  Location.withCoordinates(GeoCoordinates(52.51772, 13.42038)),
  Location.withCoordinates(GeoCoordinates(52.51764, 13.42062)),
  Location.withCoordinates(GeoCoordinates(52.51754, 13.42093)),
  Location.withCoordinates(GeoCoordinates(52.51735, 13.42155)),
  Location.withCoordinates(GeoCoordinates(52.51719, 13.42209)),
  Location.withCoordinates(GeoCoordinates(52.51707, 13.42248)),
  Location.withCoordinates(GeoCoordinates(52.51695, 13.42285)),
  Location.withCoordinates(GeoCoordinates(52.5168, 13.42331)),
  Location.withCoordinates(GeoCoordinates(52.51661, 13.42387)),
  Location.withCoordinates(GeoCoordinates(52.51648, 13.42429)),
  Location.withCoordinates(GeoCoordinates(52.51618, 13.42513)),
  Location.withCoordinates(GeoCoordinates(52.5161, 13.42537)),
  Location.withCoordinates(GeoCoordinates(52.51543, 13.42475)),
  Location.withCoordinates(GeoCoordinates(52.51514, 13.42449)),
  Location.withCoordinates(GeoCoordinates(52.515001, 13.424374))];

routingEngine.importCarRoute(routeLocations, CarOptions(), (routingError, routes) {
  if (routingError == null) {
    HERE.Route newRoute = routes!.first;
    // ...
  } else {
    // Handle error.
  }
});

このオプションでは、目的の転送タイプに一致するメソッド importRoute() の過負荷を選択できます。

GeoCoordinatesRouteOptionsのリストからルートをインポートすると、RoutingEngineは 提供された地理座標からできるだけ近いルートシェイプを作成します。

最適な結果を得るには、 1Hz の GPS データ、または数メートルの間隔を持つポイントを使用します。 データが極端に希薄な場合、エラーが発生する可能性があります。

座標のリスト に制限はありません。 サポートされているアイテムの最大数については、 API リファレンス を参照してください。 同様に、ウェイポイントのリスト には制限はありません

OfflineRoutingEngineを使用している場合 、ウェイポイントを設定する際に制限はありません。 詳細については、次のセクションを参照してください。

このフィーチャーを使用するには、すべての提供ポイントを道路にマップする必要があります。 そのため、RouteHandleから(より長い)ルートをインポートする場合よりも、かなり遅くなることがあります。

オプション 2 : RouteHandle からルートをインポートします

以下のオプションRouteHandle を参照してください。 RouteHandle​(String handle) コンストラクタを使用すると、指定した文字列ハンドルから RouteHandle を作成できます。 このような文字列は、利用可能な HERE REST API の 1 つなど、他のバックエンドソースから提供できます。 文字列は数時間のみ有効です。

次に、ルートハンドル文字列を使用してルートを作成する REST API コールの例を示します( YOUR_API_KEY を使用している実際のキーで置き換えます)。

https://router.hereapi.com/v8/routes?apikey=-YOUR_API_KEY&origin=52.524465%2C13.382334&destination=52.525301%2C13.399844&return=polyline%2Csummary%2Cactions%2Cinstructions%2CrouteHandle&transportMode=car

JSON レスポンスからルートハンドル文字列をコピーし、次のように HERE SDK で使用できます。

// Import a route from RouteHandle.
routingEngine.importRouteFromHandle(RouteHandle("routeHandleStringFromBackend"), RefreshRouteOptions.withCarOptions(CarOptions()), (routingError, routes) {
  if (routingError == null) {
    HERE.Route newRoute = routes!.first;
    // ...
  } else {
    // Handle error.
  }
});

RouteHandle この文字列は、すでに計算されたルートを示します。 正常にインポートされると、 新しいオブジェクトCalculateRouteCallbackが作成され、Routeの一部として提供され、 HERE SDK でさらに使用できます。

HERE SDK では、 オフラインでのルートのインポートはサポートされていません。少なくとも、RouteHandle経由、またはGeoCoordinatesのリストを直接渡すといった上記のような形ではありません。 これは 、オンライン接続が必要なRoutingEngine でのみ可能です。

ただし、回避策があります。 OfflineRoutingEngine に無制限の数の Waypoint アイテムを挿入すると、ルートは指定したストップオーバーウェイポイントでオフラインで計算されることがあり、元のルートにできるだけ近いルートが形成されます。 RoutingEngineでサポートされるウェイポイントの数は、最大で約 200 個 に制限されていることに注意してください。 OfflineRoutingEngineを使用する場合 、このような制限はありませんが、ただし、より長いルートではパフォーマンスのトレードオフが発生する可能性があります。 そのため、すべてのルート座標のサブセットのみを経由地 として渡すことをお勧めします。たとえば、距離のしきい値でフィルタリングします。

OfflineRoutingEngineについては、次の章のを参照 してください。 追加のウェイポイント は、オンラインですでに表示されているのと同じ方法 RoutingEngineで設定できます。

オフラインルーティング

RoutingEngineに加えて、オフラインの使用例にも相当するものがあります。 OfflineRoutingEngine :すでに上記で示したオンライン版と同じ方法で構築できます。

RoutingInterface _routingEngine;
RoutingEngine _onlineRoutingEngine;
OfflineRoutingEngine _offlineRoutingEngine;

...

try {
  _onlineRoutingEngine = RoutingEngine();
} on InstantiationException {
  throw ("Initialization of RoutingEngine failed.");
}

try {
  // Allows to calculate routes on already downloaded or cached map data.
  _offlineRoutingEngine = OfflineRoutingEngine();
} on InstantiationException {
  throw ("Initialization of OfflineRoutingEngine failed.");
}

トランジットルート(TransitRoutingEngine経由 )および EV ルート(EVCarOptions および EVTruckOptions) はまだサポートされておらず、オンラインでのみ動作します。 サポートされていないトランスポートモードの場合、OfflineRouteEngineRoutingError.invalidParameterで失敗します。

OfflineRoutingEngineRoutingEngine と同じインターフェイスを提供しますが、結果は、 HERE バックエンドサービスへの新しい要求を開始するのではなく、すでにダウンロードまたはキャッシュされているマップ データから取得されたものであるため、若干異なる場合があります。

この方法 では、たとえば、RoutingEngineを使用しているときに受信したデータよりも古いデータを使用できます。 一方、このクラスでは、オンライン接続が不要なため、より迅速に結果を提供します。

ただし、結果のルートには空の操作のリストのみが含まれます。 ガイダンス中に操作が必要な場合は、NavigatorまたはVisualNavigatorで提供されているnextManeuverIndexを経由して直接操作を行うことができます。 これは ナビゲーション セクションに表示されます。

すでにキャッシュされているか、または事前にロードされているオフライン地図データでのみルートを計算できます。 キャッシュされたマップ データのみを使用する場合、すべてのタイルが下のズームレベルでロードされているわけではありません。 この場合、マップが表示されていても、低いズームレベルもロードされるまでルートは見つかりません。 オフラインの地図では、この問題は発生しません。また、必要なマップ データがダウンロードした地域で利用可能であることが保証されます。 したがって、キャッシュされたマップ データに依存しないことをお勧めします。

の使用可能なすべてのインターフェイス OfflineRoutingEngine もで使用でき RoutingEngine 、両方のエンジンが同じインターフェイスを採用します。 これにより、以下に示すように、両方のエンジンインスタンスを簡単に切り替えることができます。

このすべての仕組みについて簡単に説明 RoutingExample するには、クラスを参照してください。 以下に示すすべてのコードスニペットが含まれています。このコードは、 GitHub にある routing_hybrid_app の例の一部です。

以下に、OfflineRoutingEngineRoutingEngineを切り替える方法を示します 。 たとえば、移動中に、接続が一時的に失われ可能性があります。 このような場合 は、OfflineRoutingEngineですでにキャッシュまたはダウンロードされているマップ データのルートで計算することが妥当です。

そのためには、まずデバイスの接続が失われていないかを確認する必要があります。 2 番目のステップとして、優先エンジンを使用できます。

void useOnlineRoutingEngine() {
  _routingEngine = _onlineRoutingEngine;
  _showDialog('Switched to RoutingEngine', 'Routes will be calculated online.');
}

void useOfflineRoutingEngine() {
  _routingEngine = _offlineRoutingEngine;
  // Note that this does not show how to download offline maps. For this, check the offline_maps_app example.
  _showDialog(
      'Switched to OfflineRoutingEngine', 'Routes will be calculated offline on cached or downloaded map data.');
}

現在 _routingEngine のインスタンスで同じコードを実行できるようになりました ( 前のセクションを参照 ) 。

デバイスがオフラインの場合、オンラインバリアントはルートを検索せず、エラーを報告します。 その逆も同様です。デバイスがオンラインで、使用したい領域にキャッシュまたはプリロードされたマップ データがない場合、オフラインバリアントもエラーを報告します。

デバイスがオンラインかどうかを確認するコードが HERE から削除されていることに注意してください。 この目的でサードパーティのプラグインを使用するか、実際の接続を試みることができます。その場合は OfflineRoutingEngine 、次のようにして - または別の方法に切り替えることができます。 まずオフラインルーティングを試して、ユーザーに高速なエクスペリエンスを提供できますが、マップ データが利用できない場合はオンラインで試すことができます。

_routing_hybrid_app のサンプルアプリは 、 GitHub にあります。

ウェイポイントの順番を最適化

OfflineEngine ( 上記を参照 ) では、オフラインのウェイポイントシーケンス を使用して、出張の営業担当者 のユースケース をサポートすることもできます。 このフィーチャーは、オンラインRoutingEngineではまだサポートされて いません。

Waypoint に含まれる複数のストップオーバーアイテム Route は、次の設定 RouteOptions.optimizeWaypointsOrderにより自動的に順番が決められます。 trueに設定さ れている場合、OfflineRoutingEngineは、目的地に高速に到達するようにウェイポイントの順序を最適化するか、またはルートを短縮するように試行します。また、すべてのタイプstopoverの設定されたウェイポイント に到達するようにします。

指定されたOptimizationMode による並べ替えの結果、ルートの速度が速くなるか、または短くなるかが決定されます。

ルート計算への影響を確認するには、少なくとも 5 つ以上のウェイポイント(出発地点と目的地を含む)を設定する必要があります。 必要に 応じて、 各RoutePlaceoriginalCoordinatesをユーザー定義の座標と比較することで、再シャッフルされたウェイポイントを特定できます。 ストップオーバーごとにルートがセクションに分割されるため、Routeオブジェクトの各RoutePlaceSectionオブジェクトに提供されます。 ナビゲーション中に 、ユーザー定義のウェイポイントに到達したかどうかがイベントMilestoneStatusによって通知されます。

図 : ウェイポイントシーケンスを使用するルートとしないルート。

これはこのフィーチャーのベータ版です。

到達可能領域を表示

 Isoline(等値線) ルーティングを使用すると、時間、距離、またはエネルギー消費量に基づいて、特定のポイントからの到達範囲を表すポリゴンを生成できます。 ポリゴンには、特定の時間、最長走行距離、電気自動車で利用できる充電レベルで到達できるすべての目的地が含まれます。

 Isoline(等値線) ルーティング では、リアルタイムおよび履歴のトラフィックが計算で考慮されます。

これがどのように役立つかの例を次に示します。

  • 現在地から徒歩2km以内のレストランを検索できます。
  • ユーザーは、観光地までの距離に基づいてホテルを検索 できます。たとえば、ディズニーワールドやユニバーサルスタジオなどの主な名所まで車で 20 分以内の距離にあるホテルを検索できます。

以下に、電気自動車シナリオの消費量ベースIsoline の例を示します。この例では、ドライバーが指定された制限値 400 Wh 以内に到達可能なポイントを確認したいと考えています。 そのため、目標は 400 Wh 以下を消費することです。問題は次のとおりです。 このエネルギー制限の範囲内で、ドライバーはどこに達することができますか?

電気自動車は、現在のバッテリー充電量と、道路の勾配や補助電源の使用状況などのエネルギー消費量に影響を与える要因に基づいて、到達可能エリアに限界があります。 そのため、適切な範囲を視覚化して、充電ポイントに到達する前のエネルギー不足を避けることができます。 車両には固有の燃費パラメータがあるため、正確な走行距離を計算するために、要求に応じてパラメータを指定する必要があります。 詳細については 、以下の電気自動車のセクションを参照してください。

結果は GeoPolygonマップに表示できる図形になり、ドライバーに視覚的な方向を提供します。

// This finds the area that an electric vehicle can reach by consuming 400 Wh or less,
// while trying to take the fastest possible route into any possible straight direction from start.
// Note: We have specified evCarOptions.routeOptions.optimizationMode = OptimizationMode.FASTEST for EV car options above.
List<int> rangeValues = [400];

// With null we choose the default option for the resulting polygon shape.
int? maxPoints;
IsolineOptionsCalculation calculationOptions = IsolineOptionsCalculation.withNoDefaults(
    IsolineRangeType.consumptionInWattHours, rangeValues, IsolineCalculationMode.balanced, maxPoints, RoutePlaceDirection.departure);
IsolineOptions isolineOptions = IsolineOptions.withEVCarOptions(calculationOptions, _getEVCarOptions());

_routingEngine.calculateIsoline(Waypoint(_startGeoCoordinates!), isolineOptions,
    (RoutingError? routingError, List<Isoline>? list) {
  if (routingError != null) {
    _showDialog("Error while calculating reachable area:", routingError.toString());
    return;
  }

  // When routingError is nil, the isolines list is guaranteed to contain at least one isoline.
  // The number of isolines matches the number of requested range values. Here we have used one range value,
  // so only one isoline object is expected.
  Isoline isoline = list!.first;

  // If there is more than one polygon, the other polygons indicate separate areas, for example, islands, that
  // can only be reached by a ferry.
  for (GeoPolygon geoPolygon in isoline.polygons) {
    // Show polygon on map.
    Color fillColor = Color.fromARGB(128, 0, 143, 138);
    MapPolygon mapPolygon = MapPolygon(geoPolygon, fillColor);
    _hereMapController.mapScene.addMapPolygon(mapPolygon);
    _mapPolygons.add(mapPolygon);
  }
});

これにより、電気自動車が 400Wh 以下の電力を消費して到達できるエリアが見つかります。その一方で、最短ルートを開始地点から任意の直進方向に走行しようとします。

最速の理由 これは、ルートの最適化モードによって異なります(前述のセクションで説明しました)。もちろん、任意のモードを指定できます。 各  Isoline(等値線) には、出発地点からちょうど 1 つのセンターポイントが必要です。

エネルギー消費に関心があるので、こちら EVCarOptionsも提供しました。 これらのオプションには 、以下の電気自動車の取り回しのセクションに示されているバッテリーの仕様が含まれている必要があります。 範囲タイプとして時間または距離の制限を指定する場合は、前述のように通常のルートオプションを指定できます。

IsolineRangeTypeは、提供範囲値のタイプを定義します。 ここでは、400を使用しています。 複数の値を指定できます。その結果、指定された範囲の値ごとに、複数の Isoline オブジェクトが取得されます。

一方、各オブジェクト Isoline には、到達範囲に島が含まれている場合など、特殊なケースで複数のポリゴンを含めることができます。 このような領域は、個別のポリゴンとして提供されます。

結果のポリゴンシェイプは、パラメーター maxPoints で定義できます。 GeoPolygon の頂点の数を指定します。 このパラメータは、ポリゴンの実際の計算には影響を与えず、その外観にのみ影響します。

スクリーンショット: 指定した制限での到達範囲を表示。

スクリーンショットには、大きな緑色の円で示されたポリゴンの中心位置が表示されます。 また、このエリアを超える可能性のあるルートが表示され、ルートに沿って 2 つの追加の充電ステーションが見つかります。 次のセクションでは、電気自動車のルートを計算する方法について説明します。

上記のコード スニペットは ev_routing_appGitHub の例の一部です。

操作プレビュー用のロードシールドアイコンを取得

iconProvider.createRoadShieldIcon(...)では「 A7 」や「 US-101 」などの道路番号がマップ ビューにすでに表示されているように、非同期で Bitmap を作成できます。

道路標識アイコンの作成はオフラインで行われ、インターネット接続は必要ありません。 アイコンの作成に必要なデータは、そのアイコン自体 Route からのみ取得されますが、手動で入力することもできます。

道路標識アイコンの例。

Navigate Edition開発者ガイドでは 、ターンバイターンの例で使用例をガイダンスセクションに記載しています。 ReroutingGitHub のアプリの例も参照してください。 naviate Edition が必要ですが、IconProviderのコードは 他のエディションでも使用できます。たとえば、ルートプレビューの一部としてロードシールドアイコンを表示する場合に使用できます。

電気自動車のルートを取得

電気自動車( EV )の使用数と販売量は世界中で増加し続けています。 HERE はどのように電気自動車に最適なルートを提供するのに役立ちますか?

  • HERE EV ルーティングは、 EV が A から B に到達できるように最適化されたルートを提供し、充電の停止回数を最小限に抑え、バッテリー充電時間を最適化します(車両の消費モデルに基づきます)。 また、地形、道路のジオメトリ、リアルタイムの交通情報、交通パターンなど、旅程を計画する際にもいくつかの要因が考慮されます。

  • HERE は、ルート沿いの充電ステーションを検索する代わりに、可能なすべてのステーションの充電時間を分析し、最短の運転時間と充電時間を提供する最適な組み合わせを選択します。

EV ルートの取得は簡単です。 自動車やトラックのルートを取得する場合と同様 に、電気自動車に固有のルートオプションを追加するだけで、 EV のルートを取得できます。 このようにして、電気自動車のルートを他のトランスポートモードと同じように取得できます。 EVRouteOptions を指定して メソッドcalculateRoute()に追加するだけです。

_routingEngine.calculateEVCarRoute(waypoints, _getEVCarOptions(),
    (RoutingError? routingError, List<here.Route>? routeList) {
  if (routingError == null) {
    // When error is null, then the list guaranteed to be not null.
    here.Route route = routeList!.first;
    // Use routes from list.
  } else {
    var error = routingError.toString();
    _showDialog('Error', 'Error while calculating a route: $error');
  }
});

デフォルトでは、EVRouteOptionsは、エネルギー不足なしで目的地に到達できるようにするために必要なパラメータを含んでいません

これを確実 に行うには、ルートにチャージステーションを追加するために必要なパラメータを設定する必要があります。また、全体的な移動時間の結果を最適化する必要があります。

以下に、このようなオプションの作成例を示します。

EVCarOptions _getEVCarOptions() {
  EVCarOptions evCarOptions = EVCarOptions();

  // The below three options are the minimum you must specify or routing will result in an error.
  evCarOptions.consumptionModel.ascentConsumptionInWattHoursPerMeter = 9;
  evCarOptions.consumptionModel.descentRecoveryInWattHoursPerMeter = 4.3;
  evCarOptions.consumptionModel.freeFlowSpeedTable = {0: 0.239, 27: 0.239, 60: 0.196, 90: 0.238};

  // Must be 0 for isoline calculation.   
  evCarOptions.routeOptions.alternatives = 0;

  // Ensure that the vehicle does not run out of energy along the way
  // and charging stations are added as additional waypoints.
  evCarOptions.ensureReachability = true;

  // The below options are required when setting the ensureReachability option to true
  // (AvoidanceOptions need to be empty).
  evCarOptions.avoidanceOptions = AvoidanceOptions();
  evCarOptions.routeOptions.speedCapInMetersPerSecond = null;
  evCarOptions.routeOptions.optimizationMode = OptimizationMode.fastest;
  evCarOptions.batterySpecifications.connectorTypes = [
    ChargingConnectorType.tesla,
    ChargingConnectorType.iec62196Type1Combo,
    ChargingConnectorType.iec62196Type2Combo
  ];
  evCarOptions.batterySpecifications.totalCapacityInKilowattHours = 80.0;
  evCarOptions.batterySpecifications.initialChargeInKilowattHours = 10.0;
  evCarOptions.batterySpecifications.targetChargeInKilowattHours = 72.0;
  evCarOptions.batterySpecifications.chargingCurve = {0.0: 239.0, 64.0: 111.0, 72.0: 1.0};

  // Note: More EV options are available, the above shows only the minimum viable options.
  return evCarOptions;
}

HERE では、 電気自動車のエネルギー消費モデルEVConsumptionModelを指定するようにを定義します。 また、BatterySpecifications を追加します 。 これらのオプションを使用すると、追加のストップオーバーとして追加のチャージステーションをルートに挿入できます。つまり、挿入されたチャージステーションの数に応じて、ルートがより多くのセクションに分割されます。

このように必要な充電ステーションを含める場合は、必ずOptimizationMode.FASTESTを使用してください。 また、ensureReachability を true に設定する必要があります。 ensureReachability がアクティブ化 されている場合、必要な充電ステーションが結果の経路に沿って移動し、必要な充電ステーションがrouteWayPointアイテムとして追加されるようにルートを調整できます。

すべてのオプションが、電気自動車のルートの計算にかかる時間に影響を与える可能性があります。 最も重要なのは、totalCapacityInKilowattHoursに設定されている大容量のバッテリーでは、充電の停止や、旅程開始時のフル充電のバッテリーの必要性が低減されることです。詳細については、以下のinitialChargeInKilowattHoursを参照してください。 比較的低い値は、ルートの先頭付近に充電ステーションが含まれている必要があることを意味します。 そうしないと、ルートの計算に失敗する可能性があります。

現在、エンジンには サービス中の充電ステーションのみが含まれています。 アウトオブサービスまたはメンテナンス中のチャージステーションは考慮されません。 ただし、チャージステーションは動的な状況のため、エンジンは、ステーションが現在使用中または予約済みであるかどうかは判断しません。 最悪の場合、充電ステーションに到着したときに、他の車を充電するために、現在使用されている可能性があります。

また、利用可能なバッテリーコネクタタイプも指定しているため、車両を充電するための互換性のあるコネクタを提供していない充電ステーションは除外されます。

通常、バッテリーの消費量とバッテリーの情報は車自体から取得するか、マニュアルまたは自動車メーカーに直接問い合わせることで取得可能です。すべての情報が利用できるわけではありません。また、一部の情報はメーカーのみが把握している場合があります。 いずれの場合も、ルート計算プロセスでは指定された仕様が考慮され、不足している値に適切なデフォルト値が入力されます。

特に電気自動車を使用した長距離ドライブの場合は、途中で充電の停止を計画することが重要です。 結局のところ、チャージステーションはガソリンスタンドよりもはるかに一般的ではありません。 上記のオプションを使用する と、RoutingEngine最速のルート(すなわち、目的地に到達するために消費された全体的な時間が最も短いルート)を探し、その間に車両のエネルギーが不足しないようにします。

この計算結果は、「 ルートに沿った検索 」セクションに示されているように、電気自動車向けに最適化されたルートです。経路に沿って見つかった充電ステーションを追加するだけではありません。

route が計算されると、より有用な情報を収集できます。 以下に示すコード スニペットには、Sectionごとの推定エネルギー消費量が記録さ れ、必要に応じてバッテリーを充電するために必要な処置が一覧表示されます。

void _logEVDetails(here.Route route) {
  // Find inserted charging stations that are required for this route.
  // Note that this example assumes only one start waypoint and one destination waypoint.
  // By default, each route has one section.
  int additionalSectionCount = route.sections.length - 1;
  if (additionalSectionCount > 0) {
    // Each additional waypoint splits the route into two sections.
    print("EVDetails: Number of required stops at charging stations: " + additionalSectionCount.toString());
  } else {
    print(
        "EVDetails: Based on the provided options, the destination can be reached without a stop at a charging station.");
  }

  int sectionIndex = 0;
  List<Section> sections = route.sections;
  for (Section section in sections) {
    EVDetails? evDetails = section.evDetails;
    if (evDetails == null) {
      print("No EVDetails found.");
      return;
    }
    print("EVDetails: Estimated net energy consumption in kWh for this section: " +
        evDetails.consumptionInKilowattHour.toString());
    for (PostAction postAction in section.postActions) {
      switch (postAction.action) {
        case PostActionType.chargingSetup:
          print("EVDetails: At the end of this section you need to setup charging for " +
              postAction.duration.inSeconds.toString() +
              " s.");
          break;
        case PostActionType.charging:
          print("EVDetails: At the end of this section you need to charge for " +
              postAction.duration.inSeconds.toString() +
              " s.");
          break;
        case PostActionType.wait:
          print("EVDetails: At the end of this section you need to wait for " +
              postAction.duration.inSeconds.toString() +
              " s.");
          break;
        default:
          throw ("Unknown post action type.");
      }
    }

    print("EVDetails: Section " +
        sectionIndex.toString() +
        ": Estimated battery charge in kWh when leaving the departure place: " +
        section.departurePlace.chargeInKilowattHours.toString());
    print("EVDetails: Section " +
        sectionIndex.toString() +
        ": Estimated battery charge in kWh when leaving the arrival place: " +
        section.arrivalPlace.chargeInKilowattHours.toString());

    // Only charging stations that are needed to reach the destination are listed below.
    ChargingStation? depStation = section.departurePlace.chargingStation;
    if (depStation != null && depStation.id != null && !chargingStationsIDs.contains(depStation.id)) {
      print("EVDetails: Section " + sectionIndex.toString() + ", name of charging station: " + depStation.name.toString());
      chargingStationsIDs.add(depStation.id.toString());
      _addCircleMapMarker(section.departurePlace.mapMatchedCoordinates, "assets/required_charging.png");
    }

    ChargingStation? arrStation = section.departurePlace.chargingStation;
    if (arrStation != null && arrStation.id != null && !chargingStationsIDs.contains(arrStation.id)) {
      print("EVDetails: Section " + sectionIndex.toString() + ", name of charging station: " + arrStation.name.toString());
      chargingStationsIDs.add(arrStation.id.toString());
      _addCircleMapMarker(section.arrivalPlace.mapMatchedCoordinates, "assets/required_charging.png");
    }

    sectionIndex += 1;
  }
}

postAction.duration.inSeconds には、バッテリの充電にかかる推定時間が記載されています。 この時間は、全体的なルート計算および到着予定時間( ETA )に含まれます。

以下は、導かれるルートのスクリーンショットです。

スクリーンショット: 電気自動車のルートを表示。

ここで、ルートには、充電スタンドで 2 つのウェイポイントが必要であることがわかります。赤色のマーカーで示されます。 ルートには、各充電スタンドがルートを分割するときに、追加のウェイポイントを挿入するときに 3 つのセクションが含まれています。

最初のセクションには 、充電の停止について説明する事後処理が含まれています。 これには、予想到着料金などの情報が含まれています。

特に指定のない限り、エネルギー消費量は Wh と見なされます。

充電ステーションを検索

オンラインSearchEngineで、 EVChargingPoolの一部であるEVChargingStationコネクターを検索できます 。 電気自動車用の充電プールは、 1 つ以上の充電ステーションを備えたエリアです。

PlaceCategory.businessAndServicesEVChargingStation をプールの検索に使用します。 結果PlaceDetailsで、ステーションを含む検出されたプールのリストがある場合は、そのリストを見つけることができます。

お使いの HERE SDK のエディションでこのエンジンがサポートされている場合は、OfflineSearchEngineでステーションを検索することもできます。

この検索フィーチャーを使用するには、オンライン SearchEngineで使用するためのライセンスが必要です。 OfflineSearchEngineで使用する場合、ライセンスは必要ありません。 アクセス権を取得するには、弊社に連絡してください。 資格情報が有効になっていない場合は、不足しているライセンスを示すエラー SearchError.FORBIDDENが表示されます。

これはこのフィーチャーのベータリリースであるため、バグがいくつか発生したり、予期しない動作が発生する可能性があります。 関連する API は、非推奨プロセスなしで新しいリリースで変更されることがあります。

消費モデルを定義

以下のパラメータは、電気自動車のより正確な結果を得るための消費モデルを定義します。

  • ascentConsumptionInWattHoursPerMeter: 1 メートルあたりのエネルギー消費量の上昇率。
  • PercentRecoveryInWattHoursPerMeter : 1 メートル降下する毎のエネルギー回収の割合。
  • freeFlowSpeedTable: 平坦な舗装路で、所定のフリーフロー速度での消費レートを指定する機能カーブ。
  • trafficSpeedTable: 平坦な道路での交通状況下で、所定の速度での消費レートを指定する機能カーブ。
  • auxiliaryConsumptionInWattHoursPerSecond : 車両の補助システム(エアコン、照明など)が 1 秒間に消費するエネルギーの割合。

消費速度表は、車両が km/時 で指定された速度で標高の変更を行うことなく直進路を走行するときのエネルギー消費量を定義する。 区分線形関数を表します。

HERE は、フリーフロー速度リストの例です。 左側には速度が、右側には燃費が表示されます。

  • 0 : 0.239.
  • 27 : 0.239.
  • 45 : 0.259.
  • 60 : 0.196.
  • 75 : 0.207.
  • 90 : 0.238.
  • 100 : 0.26
  • 110 : 0.296
  • 120 : 0.337
  • 130 : 0.351

グラフでは、次のようになります。

スクリーンショット: 燃費グラフの例。

2 つの異なる消費速度テーブル(フリーフロー速度テーブル トラフィック速度テーブル)を指定できます。

  • フリーフロー速度: 一定の速度で走行する場合のエネルギー消費量を示します。
  • 走行速度: 交通量の多い状況で走行する場合のエネルギー消費量を示します。たとえば、車両が特定の平均速度で走行速度を頻繁に変更すると予想される場合などです。

trafficSpeedTableが提供されていない場合 は、速度関連のエネルギー消費量の計算にのみfreeFlowSpeedTableが使用されます。

GitHubev_routing_appサンプルのアプリを見つける ことができます。

」に一致する結果は 件です

    」に一致する結果はありません