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

オフラインのルート検索機能

オフラインマップはNavigateライセンスでのみ使用できます。

オンラインのみのRoutingEngineに加えて、オフラインのユースケースに相当するOfflineRoutingEngineも利用可能です。このオフライン バージョンは、オンライン版と同じ強固なルート検索機能を提供するように作られており、インターネット接続がなくてもシームレスにナビゲーションを実行します。

ルートを計算できるのは、すでにキャッシュに保存された、またはプリロードされたオフライン マップ データのルートのみです。キャッシュに保存されたマップ データのみを使用する場合、ズーム レベルが低いと一部のタイルが読み込まれない場合があります。その場合、地図が表示されても、より低いズーム レベルが読み込まれるまでルートは見つかりません。オフライン マップではこのようなことは起こり得ず、ダウンロードした地域で必要なマップ データが利用できることが保証されます。したがって、キャッシュに保存されたマップ データに依存しないことをお勧めします。

OfflineRoutingEngineRoutingEngine と同じ簡単な方法で構築できます。

private var routingEngine: RoutingProtocol
private var onlineRoutingEngine: RoutingEngine
private var offlineRoutingEngine: OfflineRoutingEngine

...

do {
    try onlineRoutingEngine = RoutingEngine()
} catch let engineInstantiationError {
    fatalError("Failed to initialize routing engine. Cause: \(engineInstantiationError)")
}

do {
    // Allows to calculate routes on already downloaded or cached map data.
    try offlineRoutingEngine = OfflineRoutingEngine()
} catch let engineInstantiationError {
    fatalError("Failed to initialize offline routing engine. Cause: \(engineInstantiationError)")
}

// By default, use online routing engine.
routingEngine = onlineRoutingEngine

// Detect whether we should search online or offline.
setNetworkUpdateHandler()

運送ルート (TransitRoutingEngine経由) とEVルート (RoutingOptionsElectricVehicleOptions経由) はまだサポートされておらず、オンラインでのみ機能します。サポートされていない移動モードの場合、OfflineRouteEngineRoutingError.invalidParameterで失敗します。

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

この方法では、たとえば、RoutingEngine の使用時に受信するデータと比較してデータが古い可能性があります。一方、このクラスではオンライン接続が必要ないため、より速く結果が得られます。

ただし、最終的なルートには空の運転操作のリストのみが含まれます。案内中に運転操作を取得する必要がある場合は、提供されているnextManeuverIndexを介してNavigatorまたはVisualNavigatorから直接取得できます。これは「ナビゲーション」セクションに示されています。

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

これらの機能について概要を簡単に確認するには、RoutingHybridExample.swiftクラスを参照してください。これには以下に示すすべてのコードスニペットが含まれており、GitHubにある「RoutingHybrid」サンプルアプリの一部です。

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

これを行うには、まずデバイスの接続が失われたかどうかを確認する必要があります。2番目のステップとして、自分の好きなエンジンを使用できます。

// Sets the OfflineRoutingEngine as main engine when the device is not connected, otherwise this will set the
// RoutingEngine that requires connectivity.
private func setRoutingEngine() {
    if isDeviceConnected {
        routingEngine = onlineRoutingEngine
    } else {
        routingEngine = offlineRoutingEngine
    }
}

ここではブール値 isDeviceConnected を使用して、デバイスが接続されているかどうかを保存します。

これで、上記の前のセクションで示したように、現在の routingEngine インスタンスで同じコードを実行できるようになります。

デバイスがオフラインの場合、オンライン バリエーションではルートが検索されず、エラーが報告されます。逆に、デバイスがオンラインであっても、使用するエリアで利用できるキャッシュまたはプリロードされたマップ データがない場合は、オフライン バリエーションでは、同様にエラーが報告されます。

デバイスがオンラインかどうかを確認するためのコードはここでは省略されていることに注意してください。これにはサード パーティ API を使用するか、実際の接続を試みることができます。これが失敗した場合は、OfflineRoutingEngine に切り替えるか、その逆を行うことができます。ユーザーに高速なエクスペリエンスを提供するために、最初にオフラインのルート検索を試すことができますが、マップ データが利用できない場合はオンラインで試すことができます。

「RoutingHybrid」のサンプル アプリは GitHub にあります。


EN 日本語

HERE documentation

Find answers to your product and technical questions

Documentation

What's new

Videos

EN 日本語

HERE ドキュメント

製品や技術に関する質問の答えを見つけましょう。より多くの内容と最新の情報については、英語版をご覧ください。

ドキュメント

ダイナミックマップ

動的コンテンツ関連のAPIをアプリやサービスに活用して、ドライバーが安全・快適かつ予定どおりに目的地へ到着できるよう支援します。

地図とデータ

世界中を走行する多数のマッピング車両から得られる最新の位置情報データを活用し、精度の高い地図やカスタムレイヤーを構築できます。

最新情報

動画

(function () { const input = document.querySelector('input[data-typeahead]'); if (!input) return; // Prevent the form from submitting/navigating input.closest('form')?.addEventListener('submit', e => e.preventDefault()); input.addEventListener('input', function () { const q = this.value.trim().toLowerCase(); document.querySelectorAll('.nav-group-name').forEach(group => { let anyVisible = false; group.querySelectorAll('.nav-group-task').forEach(task => { const text = task.textContent.trim().toLowerCase(); const show = !q || text.includes(q); task.style.display = show ? '' : 'none'; if (show) anyVisible = true; }); // Hide the whole group header if nothing matches group.style.display = anyVisible || !q ? '' : 'none'; }); }); })(); (function () { function onTokenClick(event) { var link = event.target.closest('.sdk-for-ios .item .token'); if (!link) return; event.preventDefault(); console.log('token clicked', link.textContent.trim()); var item = link.closest('.item'); if (!item) return; var content = item.querySelector('.height-container'); if (!content) { console.log('no .height-container found for item', item); return; } var isHidden = window.getComputedStyle(content).display === 'none'; content.style.display = isHidden ? 'block' : 'none'; link.classList.toggle('token-open', isHidden); var href = link.getAttribute('href'); if (href) { if (history.pushState) history.pushState({}, '', href); else location.hash = href; } } function openHashTarget() { var hash = window.location.hash.slice(1); if (!hash) return; var anchor = document.querySelector('.sdk-for-ios a[name="' + hash + '"]'); if (!anchor) return; var item = anchor.closest('.item'); if (!item) return; var link = item.querySelector('.token'); var content = item.querySelector('.height-container'); if (!link || !content) return; content.style.display = 'block'; link.classList.add('token-open'); } function init() { console.log('HERE SDK accordion init'); openHashTarget(); } document.removeEventListener('click', onTokenClick); document.addEventListener('click', onTokenClick); if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } window.addEventListener('hashchange', openHashTarget); window.addEventListener('pageLoad', init); })();