オフラインマップの使用

オフラインマップがプリロードされているため、インターネット接続を使用したり 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() ユーザーが滞在できない場合は、ユーザーに通知するか、継続中のダウンロードに通知する必要があります。

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

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

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

MapDownloader インスタンスの作成

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

guard let sdkNativeEngine = SDKNativeEngine.sharedInstance else {
    fatalError("SDKNativeEngine not initialized.")
}

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

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

すべてのインスタンスの準備が完了するまで、ディスパッチグループなどの別のローダーメソッドまたはクラスを使用して待機することを検討してください。 必要に応じて、待機中にローディングインジケータを表示します。 このインスタンスは、 nil チェックなしでクラス内で使用できます。 通常 、 MapDownloaderMapUpdater ( 以下を参照 ) の作成は 1 秒以内に行われます。

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

// Note that the default storage path can be adapted when creating a new SDKNativeEngine.
let storagePath = sdkNativeEngine.options.cachePath
showMessage("This example allows to download the region Switzerland. StoragePath: \(storagePath).")

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

リージョンリストをダウンロードします

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

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

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

func onDownloadListClicked() {
    // Download a list of Region items that will tell us what map regions are available for later download.
    _ = mapDownloader.getDownloadableRegions(languageCode: LanguageCode.deDe,
                                             completion: onDownloadableRegionsCompleted)
}

// Completion handler to receive search results.
func onDownloadableRegionsCompleted(error: MapLoaderError?, regions: [Region]?) {
    if let mapLoaderError = error {
        self.showMessage("Downloadable regions error: \(mapLoaderError)")
        return
    }

    // If error is nil, it is guaranteed that the list will not be nil.
    downloadableRegions = regions!

    for region in downloadableRegions {
        print(region.name)
        guard let childRegions = region.childRegions else {
            continue
        }

        // Note that this code ignores to list the children of the children (and so on).
        for childRegion in childRegions {
            let sizeOnDiskinMB = childRegion.sizeOnDiskInBytes / (1024 * 1024)
            print("Child region: \(childRegion.name), ID: \(childRegion.regionId.id), Size: \(sizeOnDiskinMB) MB")
        }
    }

    self.showMessage("Found \(downloadableRegions.count) continents with various countries. Full list: \(downloadableRegions.description).")
}

レスポンスにはエラーまたは結果が含まれています。 また、 mapLoaderErrorregions list は同時にnil とすることも、 nil としないこともできません。

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

注 : getDownloadableRegions() メソッドは 、リクエストをキャンセルするための AS 戻り値のTaskHandleを提供します。 上記のコード スニペットでは、このタグを使用せず、代わりにアンダースコア( "_=..." )を使用して契約を履行します。

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

リージョンのダウンロード

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

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

// Finds a region in the downloaded region list.
// Note that we ignore children of children (and so on).
private func findRegion(localizedRegionName: String) -> Region? {
    var downloadableRegion: Region?
    for region in downloadableRegions {
        if region.name == localizedRegionName {
            downloadableRegion = region
            break
        }
        guard let childRegions = region.childRegions else {
            continue
        }
        for childRegion in childRegions {
            if childRegion.name == localizedRegionName {
                downloadableRegion = childRegion
                break
            }
        }
    }

    return downloadableRegion
}

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

func onDownloadMapClicked() {
    // Find region for Switzerland using the German name as identifier.
    // Note that we requested the list of regions in German above.
    let swizNameInGerman = "Schweiz"
    let swizRegion = findRegion(localizedRegionName: swizNameInGerman)

    guard let region = swizRegion else {
        showMessage("Error: The Swiz region was not found. Click 'Regions' first to download the list of regions.")
        return
    }

    // For this example we only download one country.
    let regionIDs = [region.regionId]
    let mapDownloaderTask = mapDownloader.downloadRegions(regions: regionIDs,
                                                          statusListener: self)
    mapDownloaderTasks.append(mapDownloaderTask)
}

// Conform to the DownloadRegionsStatusListener protocol.
func onDownloadRegionsComplete(error: MapLoaderError?, regions: [RegionId]?) {
    if let mapLoaderError = error {
        self.showMessage("Download regions completion error: \(mapLoaderError)")
        return
    }

    // If error is nil, it is guaranteed that the list will not be nil.
    // For this example we downloaded only one hardcoded region.
    showMessage("Map download completed 100% for Switzerland! ID: \(String(describing: regions!.first))")
}

// Conform to the DownloadRegionsStatusListener protocol.
func onProgress(region: RegionId, percentage: Int32) {
    showMessage("Map download progress for Switzerland. ID: \(region.id). Progress: \(percentage)%.")
}

// Conform to the DownloadRegionsStatusListener protocol.
func onPause(error: MapLoaderError?) {
    if (error == nil) {
        showMessage("The download was paused by the user calling mapDownloaderTask.pause().")
    } else {
        showMessage("Download regions onPause error. The task tried to often to retry the download: \(error.debugDescription)")
    }
}

// Conform to the DownloadRegionsStatusListener protocol.
func onResume() {
    showMessage("A previously paused download has been resumed.")
}

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

onDownloadRegionsComplete() に対するレスポンスには、エラーまたは結果が含まれています。 mapLoaderErrorregions リストは、同時に nil にすることも、 nil にしないこともできません。

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

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

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

func onCancelMapDownloadClicked() {
    for mapDownloaderTask in mapDownloaderTasks {
        mapDownloaderTask.cancel()
    }
    showMessage("Cancelled \(mapDownloaderTasks.count) download tasks in list.")
    mapDownloaderTasks.removeAll()
}

キャンセルされたMapDownloaderTaskは再開できません。 ただし、新しいダウンロードリクエストを再度開始することはできます。

OfflineMaps Example アプリは 、 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が提供 されます。

private func checkForMapUpdates() {
    guard let mapUpdater = mapUpdater else {
        showMessage("MapUpdater instance not ready. Try again.")
        return
    }

    _ = mapUpdater.retrieveCatalogsUpdateInfo(callback: onCatalogUpdateCompleted)
}

// Completion handler to get notified whether a catalog update is available or not.
private func onCatalogUpdateCompleted(mapLoaderError: MapLoaderError?, catalogList: [CatalogUpdateInfo]?) {
    if let error = mapLoaderError {
        print("CatalogUpdateCheck Error: \(error)")
        return
    }

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

    logCurrentMapVersion();

    for catalogUpdateInfo in catalogList! {
        print("CatalogUpdateCheck - Catalog name:" + catalogUpdateInfo.installedCatalog.catalogIdentifier.hrn);
        print("CatalogUpdateCheck - Installed map version: \(String(describing: catalogUpdateInfo.installedCatalog.catalogIdentifier.version))");
        print("CatalogUpdateCheck - Latest available map version: \(catalogUpdateInfo.latestVersion)");
        performMapUpdate(catalogUpdateInfo: catalogUpdateInfo);
    }
}

// Downloads and installs map updates for any of the already downloaded regions.
// Note that this example only shows how to download one region.
private func performMapUpdate(catalogUpdateInfo: CatalogUpdateInfo) {
    guard let mapUpdater = mapUpdater else {
        showMessage("MapUpdater instance not ready. Try again.")
        return
    }

    // This method conveniently updates all installed regions if an update is available.
    // Optionally, you can use the returned CatalogUpdateTask to pause / resume or cancel the update.
    _ = mapUpdater.updateCatalog(catalogInfo: catalogUpdateInfo, completion: catalogUpdateListenerImpl)
}

private let catalogUpdateListenerImpl = CatalogUpdateListenerImpl()

private class CatalogUpdateListenerImpl : CatalogUpdateProgressListener {
    // Conform to the CatalogUpdateProgressListener protocol.
    func onPause(error: heresdk.MapLoaderError?) {
        if let mapLoaderError = error {
            print("Catalog update onPause error. The task tried to often to retry the update: \(mapLoaderError).")
        } else {
            print("CatalogUpdate: The map update was paused by the user calling catalogUpdateTask.pause().")
        }
    }

    // Conform to the CatalogUpdateProgressListener protocol.
    func onProgress(region: RegionId, percentage: Int32) {
        print("CatalogUpdate: Downloading and installing a map update. Progress for \(region.id): \(percentage)%.")
    }

    // Conform to the CatalogUpdateProgressListener protocol.
    func onComplete(error: MapLoaderError?) {
        if let mapLoaderError = error {
            print("CatalogUpdate completion error: \(mapLoaderError)")
            return
        }
        print("CatalogUpdate: One or more map update has been successfully installed.")

        // 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.
    }

    // Conform to the CatalogUpdateProgressListener protocol.
    func onResume() {
        print("MapUpdate: 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 データを把握すると便利な場合があります。 次のコード スニペット を使用して、現在使用されているマップバージョンをログに記録できます。

guard let sdkNativeEngine = SDKNativeEngine.sharedInstance else {
    fatalError("SDKNativeEngine not initialized.")
}

// Create MapUpdater in background to not block the UI thread.
MapUpdater.fromEngineAsync(sdkNativeEngine, { mapUpdater in
    let mapUpdaterInstance = mapUpdater

    do {
        let mapVersionHandle = try mapUpdaterInstance.getCurrentMapVersion()
        let versionInfo = mapVersionHandle.stringRepresentation(separator: ",")
        print("Info: \(String(describing: versionInfo))")
    } catch let mapLoaderException {
        fatalError("Get current map version failed: \(mapLoaderException.localizedDescription)")
    }
})

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

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

壊れたマップを修復

アプリ がバックグラウンドで実行されている間は、マップ データ のダウンロードまたは更新を続行しないことをお勧めします。

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

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

private func checkInstallationStatus() {
    // Note that this value will not change during the lifetime of an app.
    let 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(completion: onMapRepairCompleted)
    }
}

// Completion handler to get notified whether map reparation was successful or not.
private func onMapRepairCompleted(persistentMapRepairError: PersistentMapRepairError?) {
    if persistentMapRepairError == nil {
        print("RepairPersistentMap: Repair operation completed successfully!")
        return
    }
    print("RepairPersistentMap: Repair operation failed: \(String(describing: persistentMapRepairError))")
}

いずれの場合も、ダウンロードしたマップ データ に問題がある可能性があることをユーザーに通知することをお勧めします。 これは、修理作業を行う前に行う必要があります。

最悪の場合、修理操作が失敗した場合は、マップ データ を削除して再度ダウンロードする必要があります。 SDKCache 経由で clearCache​() を呼び出して、プログラムによって deleteRegions() を呼び出すこと、およびマップキャッシュを消去することができます。

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

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

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

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

質問と回答

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

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

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

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

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

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