オフラインマップを使用

オフラインマップがプリロードされているため、インターネット接続を使用したり OTA の帯域幅を消費したりすることなく、国や大陸全体にオフラインでアクセスできます。

オフラインマップ ( 永続的マップ または プリロードされたマップとも呼ばれます ) は、オンラインで利用できるマップ データ と同じ機能を提供します。 場所の検索、ルートの計算、ガイダンスの開始( Navigate Edition でのみ利用可能)を行うことができます。もちろん、オンラインのマップ データ と同じ方法でMapView と対話できます。

概要

MapViewに加えて 、オフライン マップデータをサポートするエンジンが 2 つあります。

  • 場所を検索するには、オンライン対応のSearchEngineと同等のOfflineSearchEngineを使用します。
  • ルートを計算するには、オンライン対応RoutingEngineと同等の OfflineRoutingEngineAS を使用します。

オフラインフィーチャーを使用するには、すでにダウンロードまたはキャッシュされているマップ データ で上記のエンジンを実行する必要があります。 オフラインデータが利用可能であっても、オフラインで実行された場合には、他のエンジンから結果が返されません。

さらに、 Navigator および VisualNavigator は、オフラインのターンバイターンガイダンスをサポートするためにオフライン マップ データと完全に連携します。 言及する価値あり : Navigatorはヘッドレスで動作しますが( MapViewがなくても)、イベントを配信するにはマップ データ も必要です。

RegionMapDownloader とともにダウンロードされた場合、 またはマップをパンしてエリアがキャッシュされた場合、MapViewはインターネットに接続せずにこのエリアで完全に動作します。 ただし、SearchEngineRoutingEngine などの他のエンジンでは、キャッシュまたはダウンロードされたマップ データは使用されません

以下では、MapDownloaderでオフライン マップ データをアプリケーションに統合する方法について説明します。

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

オフラインマップを使用する理由 インターネット接続が遅れたり、切断されたり、完全に切断されたりすることがあります。 特に、移動中に安定した接続が利用できるとは限りません。 ユーザーが帯域幅の節約を決定したために、モバイル機器がオフラインになっている可能性もあります。 つまり、次のことを意味 オフラインのマップを使用する理由は複数あり ますが、オフラインマップを使用すると、応答時間が大幅に短縮され、ユーザーの操作性が向上します。 ただし、ほとんどの場合、帯域幅やデータの使用量に限りがある場合は、オンラインのマップ データにアクセスすることで、より正確で最新のマップ データを利用できます。 また、オフラインマップで利用できない機能もあります。たとえば、検索結果にオンラインで利用できるすべてのデータが含まれているわけではありません。

マップキャッシュとオフラインマップの違いは何ですか:

オフラインでマップ データにアクセスするには、次の 2 つの方法があります。

  • キャッシュの割り当て: デフォルトでは、マップの使用中にすべてのマップ データ がデバイスにキャッシュされます。 このストレージはセッション間で永続化されますが、ストレージサイズには制限があり、古いキャッシュデータが新しいマップ データ に置き換えられる可能性があります。 注 : HERE SDK をプログラムで初期化するときに、SDKNativeEngineに渡すことができるSDKOptionsを使用して、既定のキャッシュパスおよびサイズを変更できます。 キャッシュされたマップ データ は、ローカル のマップキャッシュストレージに保存されます。 キャッシュの詳細 については、 HERE を参照してください。 RoutePrefetcherを使用して、キャッシュにデータをアクティブに入力できます ( 以下を参照 ) 。

  • オフラインマップ: オフラインマップを使用すると、リージョン全体または大陸をダウンロードして、オフラインで使用できるようにマップ データ をプリロードできます。これには、場所、経路、その他のデータが含まれます。 専用の MapDownloader を使用すると、このデータを取得および管理できます。 オフラインのマップデータはセッション間で保持され、ユーザーが削除しない限りデータは削除されません。 オフラインのマップは、ローカル の永続的なマップストレージに保存されます。 これは 2 つ目のマップストレージで、マップキャッシュから完全に分離されています。 通常、オフラインのマップのダウンロードは、何ギガバイトものデータがロードされるため、 Wi-Fi 経由で行われます。 オフライン マップ データは、オンラインサービスの完全な代替手段として使用され、接続がない場合はキャッシュされたマップとして使用されます。

オフラインマップは 、ベクターベースのすべてのマップスキームで機能します。 衛星ベースのマップスキームは、ダウンロードされたマップ データの一部ではありません。

オフライン マップ データを使用して無線機をサイレントで操作するようにアプリ を強制できますか ?

ルーティング検索などの機能には自動切り替えロジックがないため、どのマップストレージを使用するかは、アプリケーションが決定する必要があります。 ただし、マップ ビュー を表示する場合、アプリ は オフラインスイッチを使用してオフライン マップ の使用を強制でき ます。このモードでは、デバイスが接続の有無に関係なく動作しているかどうかは問題ありません。 オフラインスイッチがアクティブ化されると、 HERE SDK はインターネット接続を開始しません。

既定では、マップ ビュー と対話するときに、 HERE SDK はオンラインデータ、ローカルマップキャッシュ、および永続的なマップストレージを自動的に利用して、最良のユーザーエクスペリエンスを提供します。

  1. HERE SDK は、まず、現在のビューポイント領域のマップキャッシュストレージからマップ データが表示されるかどうかを確認します。これは、デバイスがオンラインの場合でも同様です。
  2. 現在のビューポイントでキャッシュされたデータが利用できない場合、HERE SDK は、デバイスがオンラインであっても、永続的なマップストレージでオフラインのマップデータを探します。 オフラインのマップデータが見つからない場合 :
    • デバイス がオフラインの場合: マップの詳細情報が少なくなったり、詳細情報が表示されなくなります。
    • デバイス がオンラインの場合: オフラインスイッチがアクティブでない限り、新しいマップ データ が表示され、キャッシュにダウンロードされます。 キャッシュがいっぱいになると、 LRU ( Least Recently Used )方式が適用されます。

たとえば、ベルリンリージョンがデバイスにインストールされていて、デバイスがオンラインの場合、ベルリンマップ領域をパンするときにマップ データがマップキャッシュにダウンロードされず、インストールされているリージョンデータが代わりに使用されます。

HERE SDK が検索やルーティングなどのバックエンドサービスを使用する場合 、キャッシュされたオフライン マップ データまたは事前にダウンロードされたデータにアクセスするには、専用のオフラインエンジンを使用する必要があります。 オフラインで マップ データ にアクセスするには、OfflineSearchEngineOfflineRoutingEngine を使用します。 対応する SearchEngine および RoutingEngine は、オンライン接続が利用可能な場合にのみ結果を提供します。利用できない場合は、エラーが発生します。 そのため、使用するエンジンを決定する必要があります。

専用のオフラインエンジン(OfflineRoutingEngineなど )は、デバイスまたはグローバルオフラインスイッチの接続に関係なく、オンラインデータをダウンロードすることはありません。

HERE SDK では専用のオンラインおよびオフラインフィーチャーエンジンを提供していますが、ターン・バイ・ターンナビ (矢印ナビ)ではこのような違いはありません。 Navigator および VisualNavigator エンジンには、マップキャッシュまたは 永続的なマップストレージ内のオフラインのマップデータのいずれか ( 存在する場合 ) からのマップ データ が必要です。 データが見つからない場合、グローバルオフラインスイッチがアクティブでない限り、データは自動的にキャッシュにダウンロードされます。

利用開始

オフラインマップをダウンロードして使用するには、 2 つの簡単な手順を実行します。

1) Region オブジェクトのリストをダウンロードします。 オプションで、この一覧表をローカルリージョン名でローカライズできます。 この一覧表が表示されたら 、ダウンロードするRegionIdを選択し、ダウンロード要求としてMapDownloaderに渡す ことができます。

2) MapDownloaderを使用して、 1 つRegionまたは複数のリージョンリストをダウンロードします。 複数のリージョンを並行してダウンロードすることもできます。 DownloadRegionsStatusListenerを設定して、ダウンロードの進行状況をユーザーに表示 します。

3) MapUpdater を使用して、すでにダウンロードされているリージョンとマップキャッシュを新しいバージョンのマップに更新します。

ダウンロードが完了すると、マップを使用できるようになります。 デバイスがオフラインの場合、カメラのターゲットがそのリージョンを指しているときに、ダウンロードされたリージョンが自動的に表示されます。

ダウンロードに失敗した場合でも、HERE SDKは完全に動作可能な状態になります。 進捗状況が100%に達し、ステータスが最終的に操作が完了したことを示すまで、もう一度ダウンロードしてみてください。 問題がより深刻な場合は 、以下の修復を試みることができます。 詳細については、下記の修理セクションを参照してください。

アプリ がバックグラウンドで実行されている間は、マップ データ のダウンロードまたは更新を続行しないことをお勧めします。 ベストプラクティス として、ユーザーには、アクセスできなくなったときにpause()通知が送られたり、cancel()ダウンロードが進行中であることが通知されます。 ベストプラクティスとして resume() 、アプリ が再開されたときにオプションを提供することを検討してください。

また、デバイス(特にGPUとCPU)を存続させ、アプリがアイドル状態にならないようにするために、プラットフォームコードを作成することも検討する必要があります。少なくとも、ユーザーに画面をオンにしておくように通知するために。

地域、国、または大陸全体のマップ データには数百メガバイトのデータが含まれている可能性があるため、利用可能な帯域幅などの要因によっては、ダウンロードに時間がかかることがあります。 接続がタイムアウトになり復旧できない場合、ダウンロードも失敗することがあります。 最適なユーザー体験を 提供するには、ユーザーが進行中の操作をキャンセルし、地図のダウンロードが成功するまで進行状況を監視できるようにすることをお勧めします。

このすべての動作の概要を確認するには、 offline_maps_app クラスを参照してください。 以下に示すすべてのコードスニペットが含まれています。このコードスニペットは、 GitHub にある offline_maps_app のサンプルアプリの一部です。

MapDownloader インスタンスを作成

MapDownloaderSDKNativeEngineごとに 1 回作成できます。

SDKNativeEngine? sdkNativeEngine = SDKNativeEngine.sharedInstance;
if (sdkNativeEngine == null) {
  throw ("SDKNativeEngine not initialized.");
}

// Create MapDownloader in background to not block the UI thread.
MapDownloader.fromSdkEngineAsync(sdkNativeEngine, (mapDownloader) {
  _mapDownloader = mapDownloader;
});

通常、アプリを起動するとSDKNativeEngineが自動的に初期化され、MapViewが表示されます。 そのため、実行時にインスタンスにアクセスし MapDownloader 、そこからを取得できます。

すべて Futures のインスタンスの準備が完了するまで待機するには、別のローダメソッドまたはクラスを使用して ( 例 : multiple ) 、複数のインスタンスを使用することを検討してください。 必要に応じて、待機中にローディングインジケータを表示します。 そのため、 null チェックを行わずに、クラス内のインスタンスを使用できます。 通常 MapDownloader 、 AND ( MapUpdater 以下を参照 ) の作成は 1 秒以内に行われます。

既定では、ダウンロードされたマップ データは既定の場所に保存されます。

// Note that the default storage path can be adapted when creating a new SDKNativeEngine.
String storagePath = sdkNativeEngine.options.cachePath;
_showDialog("This example allows to download the region Switzerland.", "Storage path: $storagePath");

コメントに記載 されているように、必要に応じてストレージの場所を変更できますが、 [ 重要な概念 ] セクションに示されているように新しいSDKNativeEngineインスタンスを作成し、SDKOptionsの一部として資格情報とともに新しいキャッシュパスを設定する必要があります。 ストレージパスは資格情報キーに固有であることに注意してください。

地域のリストをダウンロード

ダウンロード可能な各 Region ファイルは、一意 RegionIdのによって識別されます。 利用可能なリージョンと RegionID 所属するリージョンを確認する Regionには、利用可能なすべてのオフラインマップのリストをダウンロードする必要があります。 これには、世界中の地域が含まれています。

それぞれのRegionには複数の子を含めることができ、各子は親Regionのサブセットを表します- 親をダウンロードすると、子のリージョンが自動的に含まれます。エリアの小さい部分にのみ関心がある場合は、子リージョンを横断できます。 通常、トップレベルのリージョンは大陸を表し、国は子供です。 簡単にするために、以下ではダウンロード可能な国のみを検索し、子供とその子供の子はすべて無視します ( 以下同様 ) 。

次のコードでは、ダウンロード可能なリージョンのリストがダウンロードされ 、後で使用できるように利用可能な要素 Regionがリストに保存されます。

// Download a list of Region items that will tell us what map regions are available for later download.
_mapDownloader.getDownloadableRegionsWithLanguageCode(LanguageCode.deDe,
    (MapLoaderError? mapLoaderError, List<Region>? list) {
  if (mapLoaderError != null) {
    _showDialog("Error", "Downloadable regions error: $mapLoaderError");
    return;
  }

  // If error is null, it is guaranteed that the list will not be null.
  _downloadableRegions = list!;

  for (Region region in _downloadableRegions) {
    print("RegionsCallback: " + region.name);
    List<Region>? childRegions = region.childRegions;
    if (childRegions == null) {
      continue;
    }

    // Note that this code ignores to list the children of the children (and so on).
    for (Region childRegion in childRegions) {
      var sizeOnDiskInMB = childRegion.sizeOnDiskInBytes / (1024 * 1024);
      String logMessage = "Child region: " +
          childRegion.name +
          ", ID: " +
          childRegion.regionId.id.toString() +
          ", Size: " +
          sizeOnDiskInMB.toString() +
          " MB";
      print("RegionsCallback: " + logMessage);
    }
  }

  var listLenght = _downloadableRegions.length;
  _showDialog("Contintents found: $listLenght", "Each continent contains various countries. See log for details.");
});

応答にエラーまたは結果が含まれています。MapLoaderErrorまたList<Region>、同時にヌルにしたり、同時にヌルにしないこともできません。

各リージョンには子リージョンを含めることができます。 たとえば、ヨーロッパにはドイツ、フランス、スイスなどの子リージョンが多数含まれています。 sizeOnDiskInBytes このパラメータでは、ダウンロードが完了した後に圧縮解除されたときに、ダウンロードされたマップがデバイスのファイルシステムで使用する領域を指定します。 ダウンロードを開始する前に、デバイスの空き容量が制限されている可能性があるため、ユーザーに表示することをお勧めします。

スクリーンショット: ダウンロード可能なまっぷをユーザーに表示する方法の例。

地域をダウンロード

RegionIdがわかったら、それを使用してマップ データのダウンロードを開始できます。 各 Region インスタンスには、ダウンロードしたマップのサイズなど、ローカライズされた name その他のデータが含まれています。 マップ データをダウンロードすると、すべてのデータが圧縮され、ダウンロードが完了すると自動的にデバイスのディスクに展開されます。

以下 Region では、ダウンロードしたリージョンリストを検索して、スイスの要素を探しています。 上記の手順では、リージョンリストをドイツ語にローカライズするようリクエストしています。

// Finds a region in the downloaded region list.
// Note that we ignore children of children (and so on): For example, a country may contain downloadable sub regions.
// For this example, we just download the country including possible sub regions.
Region? _findRegion(String localizedRegionName) {
  Region? downloadableRegion;
  for (Region region in _downloadableRegions) {
    if (region.name == localizedRegionName) {
      downloadableRegion = region;
      break;
    }

    List<Region>? childRegions = region.childRegions;
    if (childRegions == null) {
      continue;
    }

    for (Region childRegion in childRegions) {
      if (childRegion.name == localizedRegionName) {
        downloadableRegion = childRegion;
        break;
      }
    }
  }

  return downloadableRegion;
}

Regionがわかったら、それ RegionIdを使用し てダウンロードを開始できます。 一意の ID がリストに渡されるので、同じリクエストで複数のリージョンをダウンロードできます。 HERE では、 1 つの地域のみをダウンロードします。

// Find region for Switzerland using the German name as identifier.
// Note that we requested the list of regions in German above.
String swizNameInGerman = "Schweiz";
Region? region = _findRegion(swizNameInGerman);

if (region == null) {
  _showDialog("Error", "Error: The Swiz region was not found. Click 'Get Regions' first.");
  return;
}

// For this example we download only one country.
List<RegionId> regionIDs = [region.regionId];

MapDownloaderTask mapDownloaderTask = _mapDownloader.downloadRegions(
    regionIDs,
    DownloadRegionsStatusListener((MapLoaderError? mapLoaderError, List<RegionId>? list) {
      // Handle events from onDownloadRegionsComplete().
      if (mapLoaderError != null) {
        _showDialog("Error", "Download regions completion error: $mapLoaderError");
        return;
      }

      // If error is null, it is guaranteed that the list will not be null.
      // For this example we downloaded only one hardcoded region.
      String message = "Download Regions Status: Completed 100% for Switzerland! ID: " + list!.first.id.toString();
      print(message);
    }, (RegionId regionId, int percentage) {
      // Handle events from onProgress().
      String message =
          "Download of Switzerland. ID: " + regionId.id.toString() + ". Progress: " + percentage.toString() + "%.";
      print(message);
    }, (MapLoaderError? mapLoaderError) {
      // Handle events from onPause().
      if (mapLoaderError == null) {
        _showDialog("Info", "The download was paused by the user calling mapDownloaderTask.pause().");
      } else {
        _showDialog("Error",
            "Download regions onPause error. The task tried to often to retry the download: $mapLoaderError");
      }
    }, () {
      // Hnadle events from onResume().
      _showDialog("Info", "A previously paused download has been resumed.");
    }));

_mapDownloaderTasks.add(mapDownloaderTask);

DownloadRegionsStatusListener は 4 つのイベントを提供します。 2 つ目のメッセージは、ダウンロードが進行中である間の進行状況を示し、 1 つ目のメッセージはダウンロードが完了すると通知します。 ダウンロードは MapLoaderErrorで完了することもあるので、問題が発生したかどうかを確認することをお勧めします。

lambda_onDownloadRegionsComplete()の応答には、エラーまたは結果が含まれています。MapLoaderErrorまたList<RegionId>、同時にヌルにすることも、同時にヌルにしないこともできます。

一時停止イベントは、ユーザー または タスク自身がダウンロードを一時停止したときに記録されます。 内部的には、ネットワーク接続の不良などにより、中断されたリージョンのダウンロードが HERE SDK によって再試行されます。 この状況が頻繁に発生する場合は、lambda_onPause()MapLoaderErrorに入力され、ダウンロードが一時停止します。 一時停止した MapDownloaderTask はユーザーのみが再開でき、関連するイベントによっても示されます。 特に大きいリージョンの場合は、接続が改善されるまでダウンロードを一時停止すると便利です 。 例 : 再開すると、ダウンロードは停止した時点から続行され、ダウンロード済みのマップデータは失われません。 一時停止したリージョンに対してdownloadRegions()をコールすると 、元のタスクに対して resume()を呼び出す場合と同じ効果があり、そのタスクが中断した時点から進行状況が継続されることに注意してください。

ダウンロードを開始すると、ただちに戻り値が返され、進行中の非同期ダウンロード操作をキャンセルできます。 上の例 MapDownloaderTask では、ユーザーが上記のコードを複数回トリガする可能性があるため、を一覧表に格納しています。

進行中のすべてのダウンロードをキャンセルするには、次のコード スニペットを使用できます。

for (MapDownloaderTask mapDownloaderTask in _mapDownloaderTasks) {
  mapDownloaderTask.cancel();
}
int taskLength = _mapDownloaderTasks.length;
_showDialog("Note", "Cancelled $taskLength download tasks in list.");
_mapDownloaderTasks.clear();

キャンセルされたMapDownloaderTaskは再開できませんが、新しいダウンロード要求を再度開始できます。

使用例は 、offline_maps_app サンプルアプリの一部として GitHub で利用できます。

マップ データおよびマップのバージョンを更新

MapUpdater このクラスを使用すると、新しいマップバージョンが利用可能かどうかを確認できます。また、利用可能な場合は、すでにインストールされているリージョンを更新できます。 各 HERE SDK バージョンには、特定のマップバージョンがハードコードされています。 キャッシュ内のマップ データおよびダウンロードされたリージョン(存在する場合)を定義します。

一部の HERE SDK 機能では、関連 する API リファレンス のマニュアルまたはこのガイドに示されているように、特定のマップバージョンが必要になる場合があります。

新しい HERE SDK バージョンを統合するアプリ 更新プログラムがインストールされると、多くの場合、新しいマップバージョンも含まれます。 ただし、このタスクの実行にMapUpdater が使用されない限り、マップ データ は自動的に更新されません。 もちろん、古い HERE SDK バージョンのマップ更新をインストールすることもできます。

  • mapUpdater.getCurrentMapVersion()を呼び出して、現在使用されているマップのバージョンを確認してください。
  • mapUpdater.retrieveCatalogsUpdateInfo()を呼び出して、更新プログラムが利用可能かどうかを確認してください。

mapUpdater.updateCatalog()をコールすると 、最新のマップ データ をダウンロードしてインストールできます。 この例について は、 GitHuboffline_maps_app サンプルアプリ を参照してください。

オフラインマップがインストールされていない場合、 mapUpdater.updateCatalog()を呼び出すと キャッシュのみが消去され、利用可能な最新のマップバージョンの新しいデータがキャッシュに入力されます。

キャッシュは常にオフラインマップと同じマップバージョンを使用します。 オフラインマップが更新されると、キャッシュも更新されます。 キャッシュのバージョンがオフラインマップのバージョンよりも古いことはありません。

mapUpdater.updateCatalog()が完了したら、getDownloadableRegions()を呼び出して、既存の Regionデータのダウンロード、更新、または削除に必要な内部カタログデータを更新する必要があります。

deleteRegions() 経由でダウンロードされたすべてのリージョンをアンインストールしてから、目的のリージョンを再度ダウンロードすることで、マップの更新を強制することはできません。 この場合、同じマップバージョンがダウンロードされます。 ただし 、updateCatalog() が事前に実行されている場合は、マップの更新が示され、インストールできます。

進行中のマップ更新および関連する操作中に、すべての MapDownloader および MapUpdater 機能にアクセスできるわけではありません。 多くの操作を並行して実行できますが、場合によっては、エラーメッセージによってエラーが示されることがあります。 この問題が発生した場合は、現在の操作が成功するまで待ってから、もう一度試してください。

deleteRegions() をコール中 に再試行可能 なエラーが発生した場合は、インターネット接続の問題が発生した可能性があります。 この場合、DownloadRegionsStatusListeneronPause() イベントを起動し、影響を受けるダウンロードが一時停止状態になります。 一時停止状態のダウンロードがある場合、ストレージが整合性のない状態にある可能性があるため、リージョンを削除できません。 この問題を解決 するには、ダウンロードを一時停止解除するか、キャンセルしてからもう一度お試しください。

マップ更新を実行するタイミングと方法

マップ更新の確認は、各アプリケーションの開始時に実行できます。 ただし、リージョンデータがインストールされている場合、この操作に時間がかかることがあるため、ユーザーに通知する必要があります。 通常は、まずretrieveCatalogsUpdateInfo() を呼び出して更新プログラムを確認します。これにより 、updateCatalog()の呼び出しに使用できる 1 つ以上のアイテムCatalogUpdateInfoが提供 されます。

void _checkForMapUpdates() {
  if (_mapUpdater == null) {
    _showDialog("Note", "MapUpdater instance not ready. Try again.");
    return;
  }

  _mapUpdater.retrieveCatalogsUpdateInfo((mapLoaderError, catalogList) {
    if (mapLoaderError != null) {
      print("CatalogUpdateCheck Error: " + mapLoaderError.toString());
      return;
    }

    // When error is null, then the list is guaranteed to be not null.
    if (catalogList!.isEmpty) {
      print("CatalogUpdateCheck: No map updates are available.");
    }

    _logCurrentMapVersion();

    for (CatalogUpdateInfo catalogUpdateInfo in catalogList) {
      print("CatalogUpdateCheck - Catalog name:" + catalogUpdateInfo.installedCatalog.catalogIdentifier.hrn);
      print("CatalogUpdateCheck - Installed map version:" +
          catalogUpdateInfo.installedCatalog.catalogIdentifier.version.toString());
      print("CatalogUpdateCheck - Latest available map version:" + catalogUpdateInfo.latestVersion.toString());
      _performMapUpdate(catalogUpdateInfo);
    }
  });
}

// Downloads and installs map updates for any of the already downloaded regions.
// Note that this example only shows how to download one region.
void _performMapUpdate(CatalogUpdateInfo catalogUpdateInfo) {
  if (_mapUpdater == null) {
    _showDialog("Note", "MapUpdater instance not ready. Try again.");
    return;
  }

  // This method conveniently updates all installed regions if an update is available.
  // Optionally, you can use the CatalogUpdateTask to pause / resume or cancel the update.
  CatalogUpdateTask catalogUpdateTask = _mapUpdater.updateCatalog(
      catalogUpdateInfo,
      CatalogUpdateProgressListener((RegionId regionId, int percentage) {
        // Handle events from onProgress().
        print("CatalogUpdate: Downloading and installing a map update. Progress for ${regionId.id}: $percentage%.");
      }, (MapLoaderError? mapLoaderError) {
        // Handle events from onPause().
        if (mapLoaderError == null) {
          print("CatalogUpdate:  The map update was paused by the user calling catalogUpdateTask.pause().");
        } else {
          print("CatalogUpdate: Map update onPause error. The task tried to often to retry the update: " +
              mapLoaderError.toString());
        }
      }, (MapLoaderError? mapLoaderError) {
        // Handle events from onComplete().
        if (mapLoaderError != null) {
          print("CatalogUpdate: Map update completion error: " + mapLoaderError.toString());
          return;
        }

        print("CatalogUpdate: One or more map update has been successfully installed.");
        _logCurrentMapVersion();

        // It is recommend to call now also `getDownloadableRegions()` to update
        // the internal catalog data that is needed to download, update or delete
        // existing `Region` data. It is required to do this at least once
        // before doing a new download, update or delete operation.
      }, () {
        // Handle events from onResume():
        print("CatalogUpdate: A previously paused map update has been resumed.");
      }));
}

updateCatalog() の呼び出しは内部的に最適化され、実際に変更されたRegion の一部のみが更新されます。 これは、ほとんどの場合、アップデートではユーザーがすべてのパッケージを再ダウンロードする必要がなく、各リージョンが複数 の内部バンドル に分割されていることを意味します。これらのバンドルは、マップ データ が変更されたときにのみ再度ダウンロードされます。

カタログとは

既定では、 1 つのグローバルカタログに世界中のリージョンが含まれています。 すべてのマップ データ が、カタログから参照されているダウンロード可能なリージョンの一部です。 したがって、カタログ自体にはマップ データ は含まれていませんが、データへのリンクのみが含まれています。 各カタログは、 HERE リソースネーム によって識別されます。 HERE リソースネーム は、カタログまたは他の HERE リソースを識別する一意の HERE リソースネーム です。 スコープの定義にも使用できます ( 「主な概念」を参照 ) 。 通常、 HERE SDK が次の 2 つのカタログを識別するために使用する HERE リソースネーム 値は 2 つだけです。

  • "hrn: here:data::OLP - here:OCM" - 世界中の利用可能なすべてのリージョンへの参照を含むカタログ。
  • "hrn: here:data::olp - here: ocm-Japan" - 日本のマップ データ の詳細についての追加情報を含むカタログ。 これはデフォルトでは有効になっていません。 有効にすると、ベース マップ for Japan の詳細情報が拡張されます。 詳細な日本のマップを使用することを HERE と契約している場合、この 2 つ目のカタログをインストールして使用できます。詳細については、「マップ」セクションを参照してください。

カタログには、使用可能なリージョンへの参照のみが含まれていることに注意してください。 リージョンのマップ データ は、使用されているカタログ、またはダウンロードおよびインストールされているバージョンによって異なる場合があります。 実際には、カタログ自体は更新せず、既存のカタログにリンクされているデータのみを更新します。

現在の地図バージョンを取得

マップキャッシュに使用されているマップのバージョンおよびインストールされている Region データを把握すると便利な場合があります。 次のコード スニペット を使用して、現在使用されているマップバージョンをログに記録できます。

SDKNativeEngine? sdkNativeEngine = SDKNativeEngine.sharedInstance;

if (sdkNativeEngine != null) {
  // Create MapUpdater in background to not block the UI thread.
  MapUpdater.fromSdkEngineAsync(sdkNativeEngine, (mapUpdaterConstructionCallback) {
    try {
      MapVersionHandle mapVersionHandle = mapUpdaterConstructionCallback.getCurrentMapVersion();
      String versionInfo = mapVersionHandle.stringRepresentation(",");
      print("Info: Current Map Version: " + versionInfo);
    } on MapLoaderExceptionException catch(e) {
      // Handle exception.  
      print("Get current map version failed: " + e.error.name.toString());
    }
  });
}
else {
  print("Error: SDKNativeEngine not initialized.");
}

この情報は、主にデバッグ目的で役立ちます。 マップ ビュー が初めて表示されたときに、マップのバージョンも HERE SDK によって記録されます。

形式が[cache-version].[offline-maps-version],[japan-cache-version].[japan-offline-maps-version]です。 例を挙げると、 "47.47,47.47" のように見えます。 マップキャッシュ オフラインマップの異なるバージョンを取得することはできません。

破損したマップを修復

アプリ がバックグラウンドで実行されている間は、マップ データ のダウンロードまたは更新を続行しないことをお勧めします。 HERE SDK は pause()および resume() ダウンロードのメソッドを提供していることに注意してください - たとえば、アプリがバックグラウンドに移行するとき、または再開されるときです。このような場合は、ユーザーに通知することをお勧めします。

ただし、クラッシュなどの理由で、マップの更新操作を完了する前にアプリ が閉じられることがあります。 したがって、最悪の場合、中間状態がデバイスのディスクで発生する可能性があります。

HERE SDK を使用すると、この方法 getInitialPersistentMapStatus() でこのような問題が発生していないかを簡単に確認できます。 また、可能であれば、破損したマップを修復することもできます。

_checkInstallationStatus() {
  // Note that this value will not change during the lifetime of an app.
  PersistentMapStatus persistentMapStatus = _mapDownloader.getInitialPersistentMapStatus();
  if (persistentMapStatus != PersistentMapStatus.ok) {
    // Something went wrong after the app was closed the last time. It seems the offline map data is
    // corrupted. This can eventually happen, when an ongoing map download was interrupted due to a crash.
    print("PersistentMapStatus: The persistent map data seems to be corrupted. Trying to repair.");

    // Let's try to repair.
    _mapDownloader.repairPersistentMap((PersistentMapRepairError? persistentMapRepairError) {
      if (persistentMapRepairError == null) {
        print("RepairPersistentMap: Repair operation completed successfully!");
        return;
      }

      // In this case, check the PersistentMapStatus and the recommended
      // healing option listed in the API Reference. For example, if the status
      // is "pendingUpdate", it cannot be repaired, but instead an update
      // should be executed. It is recommended to inform your users to
      // perform the recommended action.
      print("RepairPersistentMap: Repair operation failed: " + persistentMapRepairError.toString());
    });
  }
}

ダウンロードしたマップ データ に問題がある可能性があることをユーザーに通知することをお勧めします。 このようなダイアログは、修復操作を実行する前にアプリ 側に表示することも、修復操作が失敗した場合に必要になる可能性のあるその他のフォローアップアクションを実行する前に表示することもできます。 ただし、getInitialPersistentMapStatus()repairPersistentMap() を呼び出し てサイレントに実行すると、このような通知が必要かどうかを確認できます。

最悪の場合、修復操作が失敗した場合は、マップ データ を削除して再度ダウンロードする必要があります。 プログラムによってdeleteRegions()を呼び出し、そしてSDKCacheを使用してclearCache​()を呼び出してマップキャッシュを消去することができます。 この場合、ユーザーに通知してアプリケーションを再起動することをお勧めします。

または、手動でデータを削除することもできます。 ダウンロードされたリージョンおよびキャッシュのパスは、persistentMapStoragePath および cachePath プロパティを使用して SDKOptions から取得できます。

インデックスを作成

OfflineSearchEngine の検索結果を改善するために 、OfflineSearchIndex.Optionsを設定できます。 デフォルトでは、インデックス作成は無効になっています。

インデックスの作成プロセスを追跡するようにOfflineSearchIndexListenerを設定できます。

インデックス作成は、提供されている検索センターから離れている場合でも、インストールされているデータ Region の場所を検索するメカニズムを提供します。 これは、オンラインでのみ動作するため、検索インデックスを作成する必要がなく、デフォルトでこれを行う SearchEngine の動作と一致させるのに役立ちます。

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

内部的には、インデックス化によってデバイスに追加のデータが作成され、インストールされているすべてのマップコンテンツが検索可能になります。

インデックス作成が有効になっている場合、永続ストレージのコンテンツを変更するすべての操作に影響があります。

  • mapDownloader.downloadRegions(..)
  • mapDownloader.deleteRegions(..)
  • mapDownloader.clearPersistentMapStorage(..)
  • mapDownloader.repairPersistentMap(..)
  • mapDownloader.performMapUpdate(..)
  • mapDownloader.performFeatureUpdate(..)
  • mapDownloader.updateCatalog(..)

これらのメソッドを使用すると、インデックスが作成、削除、または更新され、永続ストレージにインストールされているデータRegion のエントリが含まれるようになります。

インデックスの作成には時間がかかるため、オフラインマップをダウンロードまたは更新するすべての操作にかかる時間は長くなりますが、通常は数秒以内から、最大で数分かかります ( インストールされているオフラインマップデータの量によって異なります ) 。 また、保存されているインデックスによって、オフラインマップが占めるスペースが約 5% 増加します。

プリフェッチマップ データ

RoutePrefetcher または PolygonPrefetcher を使用して、事前にマップ データをキャッシュにロードできます。たとえば、ターン・バイ・ターンナビ (矢印ナビ)エクスペリエンスを改善できます。

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

質問と回答

  • オフライン検索の仕組み:デフォルト では、OfflineSearchEngineは永続的なオフライン マップ データを検索しますが、Regionがロードされていない場合は、マップキャッシュの使用を試みます。 詳細については、ここを参照してください。

  • オフラインルーティングの仕組み: オフラインルーティングは、キャッシュされたマップ データ だけでなく、オフラインマップで使用することを目的としています。 オフライン マップ データが利用できない場合 、OfflineRoutingEngine はマップキャッシュ内の不足しているデータを探そうとします。 ルートの一部にマップ データ がない場合、ルートの計算は失敗します。 詳細については、ここを参照してください。

  • マップキャッシュとオフラインマップの違いは何ですか: マップ ビューがパンされると、キャッシュが自動的に実行されます。 また、RoutePrefetcher を使用 して、マップキャッシュへのデータのフェッチを要求することもできます。 マップキャッシュ内のデータは永続的に保存されるものではありません。また、キャッシュがいっぱいの場合などに、必要に応じて新しいデータに置き換えることができます。 キャッシュの詳細 については、 ここ を参照してください。 一方、オフラインマップは永続化され、デバイスの別のパスに保存されます。 MapDownloaderなどの専用 API を使用すると、世界中の特定の領域を恒久的にダウンロードしたり、ユーザーのリクエストに応じて更新または削除できます。

  • オンラインの RoutingEngine を使用しているときに、データの不一致が発生することがありますか : RoutingEngineを使用している場合 、計算されたルートは常に最新の利用可能なマップ データに基づいて作成されます。古いマップバージョンがデバイス自体で使用されている場合も同様です。 たとえば、古いバージョンのマップでは知られていない、新しく建設された橋をルートが通過する場合があります。 これは、主にマップの表示に影響します。 たとえば、橋が期待どおりにマップ ビューでレンダリングされない場合があります。 ただし、ナビゲーションエクスペリエンスは、デバイスが完全にオフラインで動作している場合でも、新しいルートに基づいています。また、そのリージョンのオフラインマップがすでにインストールされている(まだ更新はされていない)場合も同様です。 いずれの場合も、navigator はルートに基づいてガイダンスを提供し、橋をナビゲートします。 また、デバイスがオンラインの場合でも、既存のオフラインまたはキャッシュされたマップ データが検出されても、 navigator は新しいデータを要求しません。 ただし、不一致の可能性を回避 するために、トリップを開始する前に、MapUpdater を使用して最新のマップバージョンに更新することができます。 GPS ソースから提供された場所がルートに十分近くなると、リソースを節約するためのマップマッチングが行われないことに注意してください。 その場所がルートから離れている場合にのみ、 HERE SDK はその場所を道路にマップしようとします。

  • オフラインマップをデバイスにプレインストールできますか: リクエストに応じて、手動でこのようなパッケージを作成してマップ データをプリロードできます。 ただし、利用できる API はありません。詳細については、弊社にお問い合わせください。

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

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