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

UIビルディングブロックを追加する

このセクションでは、HERE SDKのサービスの一部としてすでに利用可能なさまざまなUI要素と関連するコードスニペットについて説明します。運転操作手順や運転操作アイコンアセットから、視覚的なルート表現まで、これらの要素をアプリケーションインターフェースに統合する方法を確認します。今後、再利用可能なUIビルディングブロックの追加が計画されています。

運転指示を取得する

Routeオブジェクトの各Sectionには、目的地に到達するためにユーザーが従う必要がある運転指示が含まれています。それぞれの右左折では、Maneuverオブジェクトに運転操作を実行する必要がある場所とアクションが含まれます。アクションは、「出発」などのアクションや「左折」などの指示を示す場合があります。

// Log maneuver instructions per route section.
List<Section> sections = route.getSections();
for (Section section : sections) {
    logManeuverInstructions(section);
}
// Log maneuver instructions per route section.
val sections: List<Section> = route.sections
for (section in sections) {
    logManeuverInstructions(section)
}

セクションごとの運転指示にアクセスするコードは次のとおりです。

private void logManeuverInstructions(Section section) {
    Log.d(TAG, "Log maneuver instructions per route section:");
    List<Maneuver> maneuverInstructions = section.getManeuvers();
    for (Maneuver maneuverInstruction : maneuverInstructions) {
        ManeuverAction maneuverAction = maneuverInstruction.getAction();
        GeoCoordinates maneuverLocation = maneuverInstruction.getCoordinates();
        String maneuverInfo = maneuverInstruction.getText()
                + ", Action: " + maneuverAction.name()
                + ", Location: " + maneuverLocation.toString();
        Log.d(TAG, maneuverInfo);
    }
}
private fun logManeuverInstructions(section: Section) {
    Log.d(TAG, "Log maneuver instructions per route section:")
    val maneuverInstructions: List<Maneuver> = section.maneuvers
    for (maneuverInstruction in maneuverInstructions) {
        val maneuverAction: ManeuverAction = maneuverInstruction.action
        val maneuverLocation: GeoCoordinates = maneuverInstruction.coordinates
        val maneuverInfo: String = (maneuverInstruction.text
                + ", Action: " + maneuverAction.name
                + ", Location: " + maneuverLocation.toString())
        Log.d(TAG, maneuverInfo)
    }
}

これは、ルート全体を書面で説明する運転指示リストを簡単に作成するのに役立ちます。たとえば、ManeuverAction列挙型を使用して、独自のルート検索エクスペリエンスを構築できます。

Screenshot: An example screen showing a route preview with maneuver instructions.

注 (HERE SDK for Android Navigate)

ナビゲーション中のManeuver指示テキスト (maneuverInstruction.getText()) は、NavigatorまたはVisualNavigatorから取得された場合は空になります。これには、Routeインスタンスから取得された場合のローカライズされた指示のみが含まれます。ManeuverAction列挙型は、ナビゲーション中に視覚的なインジケーターを表示するために使用されることが想定されており、テキストによる指示は、移動を開始する前に運転指示をプレビューするリストに適しています。

反対に、maneuverInstruction.getRoadTexts()maneuverInstruction.getNextRoadTexts()maneuverInstruction.getExitSignTexts() は、ナビゲーション中に経路誘導運転操作の一部として表示されることを意図しているため、ManeuverNavigator または VisualNavigator から取得された場合には空になりません。Routeインスタンスから取得した場合は、これらの属性は常に空になります。

注 (HERE SDK for Android Explore)

属性maneuverInstruction.getRoadTexts()maneuverInstruction.getNextRoadTexts()maneuverInstruction.getExitSignTexts()はナビゲーション中に経路誘導運転操作の一部として表示されることを目的としているため、Navigateなどのライセンスを持つユーザーのみが使用できます。Routeインスタンスから取得した場合は、これらの属性は常に空になります。

「APIリファレンス」では利用可能な運転操作アクションの概要を確認できます。

以下の表は、すべてのManeuverActionアイテムとプレビューの説明およびアセットの例をまとめたものです。HERE SDK 自体には運転操作アイコンが付属していないことに注意してください。アセットは、オープンソースのHERE Icon Libraryの一部として、さまざまな密度のSVGまたはソリッドPNGとして利用できます。

利用可能な運転操作アクションは、「APIリファレンス」に記載されている順序で並べ替えられています。

運転操作アクション説明の例アイコンの例
到着「~に到着」などの到着運転操作。中間の経由地の説明の例:「<道路名 | 経由地> に到着」。ルートの目的地の場合:「<道路名 | 目的地名 | 目的地> に到着」。到着
そのまま走行「<道路名>をそのまま走行」などの運転操作を続行します。そのまま走行
出発「<道路名>を出発」などの出発運転操作。出発
左側から高速道路に合流左側から高速道路に合流します。これは、ドライバーが右に移動して高速道路に入る必要があることを意味します。このような運転操作は、一般道路の左側 (左側通行) を走行する国でのみ実行されます。左側から高速道路に合流
右側から高速道路に合流右側から高速道路に合流します。これは、ドライバーが左に移動して高速道路に入る必要があることを意味します。このような運転操作は、一般道路の右側 (右側通行) を走行する国でのみ実行されます。右側から高速道路に合流
左側出口「左側の出口から出て<次の道路名>に合流」などの左側出口運転操作。左側出口
左車線「左車線を走行して<次の道路名>に合流」などの左車線運転操作。左車線
左ランプ「左ランプを走行」などの左ランプ運転操作。左ランプ
左ロータリーに入る「ロータリーに入る」などのロータリー運転操作 (左側通行)。
左ロータリー出口 1「ロータリーの最初の出口を出る」などのロータリー運転操作 (左側通行)。左ロータリー出口1アイコン
左ロータリー出口 10「ロータリーの10番目の出口を出る」などのロータリー運転操作 (左側通行)。左ロータリー出口10アイコン
左ロータリー出口 11「ロータリーの11番目の出口を出る」などのロータリー運転操作 (左側通行)。左ロータリー出口11アイコン
左ロータリー出口 12「ロータリーの12番目の出口を出る」などのロータリー運転操作 (左側通行)。左ロータリー出口12アイコン
左ロータリー出口 2「ロータリーの2番目の出口を出る」などのロータリー運転操作 (左側通行)。左ロータリー出口2アイコン
左ロータリー出口 3「ロータリーの3番目の出口を出る」などのロータリー運転操作 (左側通行)。左ロータリー出口3アイコン
左ロータリー出口 4「ロータリーの4番目の出口を出る」などのロータリー運転操作 (左側通行)。左ロータリー出口4アイコン
左ロータリー出口 5「ロータリーの5番目の出口を出る」などのロータリー運転操作 (左側通行)。左ロータリー出口5アイコン
左ロータリー出口 6「ロータリーの6番目の出口を出る」などのロータリー運転操作 (左側通行)。左ロータリー出口6アイコン
左ロータリー出口 7「ロータリーの7番目の出口を出る」などのロータリー運転操作 (左側通行)。左ロータリー出口7アイコン
左ロータリー出口 8「ロータリーの8番目の出口を出る」などのロータリー運転操作 (左側通行)。左ロータリー出口8アイコン
左ロータリー出口 9「ロータリーの9番目の出口を出る」などのロータリー運転操作 (左側通行)。左ロータリー出口9アイコン
左ロータリーを通過「ロータリーを通過する」などのロータリー運転操作 (左側通行)。左ロータリーを通過アイコン
左折「<次の道路名>を左折」などの左折運転操作。左折アイコン
左 U ターン「<次の道路名>でUターン」などの左Uターン運転操作。左Uターンアイコン
中央車線「中央車線を走行して<次の道路名>に合流」などの中央車線運転操作。中央車線アイコン
右側出口「右側の出口から出て<次の道路名>に合流」などの右側出口運転操作。右側出口アイコン
右車線「右車線を走行して<次の道路名>に合流」などの右車線運転操作。右車線アイコン
右ランプ「右ランプを走行」などの右ランプ運転操作。右ランプアイコン
右ロータリーに入る「ロータリーに入る」などのロータリー運転操作 (右側通行)。右側ロータリー進入アイコン
右ロータリー出口 1「ロータリーの最初の出口を出る」などのロータリー運転操作 (右側通行)。右側ロータリー出口1アイコン
右ロータリー出口 10「ロータリーの10番目の出口を出る」などのロータリー運転操作 (右側通行)。右側ロータリー出口10アイコン
右ロータリー出口 11「ロータリーの11番目の出口を出る」などのロータリー運転操作 (右側通行)。右側ロータリー出口11アイコン
右ロータリー出口 12「ロータリーの12番目の出口を出る」などのロータリー運転操作 (右側通行)。右ロータリー出口12アイコン
右ロータリー出口 2「ロータリーの2番目の出口を出る」などのロータリー運転操作 (右側通行)。右ロータリー出口2アイコン
右ロータリー出口 3「ロータリーの3番目の出口を出る」などのロータリー運転操作 (右側通行)。右ロータリー出口3アイコン
右ロータリー出口 4「ロータリーの4番目の出口を出る」などのロータリー運転操作 (右側通行)。右ロータリー出口4アイコン
右ロータリー出口 5「ロータリーの5番目の出口を出る」などのロータリー運転操作 (右側通行)。右ロータリー出口5アイコン
右ロータリー出口 6「ロータリーの6番目の出口を出る」などのロータリー運転操作 (右側通行)。右ロータリー出口6アイコン
右ロータリー出口 7「ロータリーの7番目の出口を出る」などのロータリー運転操作 (右側通行)。右ロータリー出口7アイコン
右ロータリー出口 8「ロータリーの8番目の出口を出る」などのロータリー運転操作 (右側通行)。右ロータリー出口8アイコン
右ロータリー出口 9「ロータリーの9番目の出口を出る」などのロータリー運転操作 (右側通行)。右ロータリー出口9アイコン
右側ロータリー通過「ロータリーを通過する」などのロータリー運転操作 (右側通行)。右側ロータリー通過アイコン
右折「<次の道路名>を右折」などの右折運転操作。右折アイコン
右 U ターン「<次の道路名>で右Uターン」などの右Uターン運転操作。右Uターンアイコン
急な左折「左に急旋回して<次の道路名>に合流」などの左急旋回運転操作。急な左折アイコン
急な右折「右に急旋回して<次の道路名>に合流」などの右急旋回運転操作。急な右折アイコン
わずかに左折「道なりに左側を進んで<次の道路名>に合流」などの道なり左側走行運転操作。わずかに左折アイコン
わずかに右折「道なりに右側を進んで<次の道路名>に合流」などの道なり右側走行運転操作。わずかに右折アイコン

現時点では、LEFT_ROUNDABOUT_PASSRIGHT_ROUNDABOUT_PASSのHEREアセットはSVGとしてのみ利用可能であり、一部の運転操作アセットはサブフォルダー「wego-fallback-roundabout」でのみ利用できます。

道路標識アイコンを取得する

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

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

Examples of road shield icons.

使用例はGitHubの「Rerouting」サンプルアプリの一部で確認できます。このアプリにはHERE SDK (Navigate) が必要ですが、IconProviderのコードは他のエディションでも使用でき、たとえば、ルートプレビューの一部として道路標識アイコンを表示できます。IconProviderの詳細については、「道路標識アイコンを取得する」の章を参照してください。

地図にルートを表示する

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

GeoPolyline routeGeoPolyline = route.getGeometry();
float widthInPixels = 20;
Color polylineColor = Color.valueOf(0, 0.56f, 0.54f, 0.63f);
MapPolyline routeMapPolyline = null;

try {
    routeMapPolyline = new MapPolyline(routeGeoPolyline, new MapPolyline.SolidRepresentation(
            new MapMeasureDependentRenderSize(RenderSize.Unit.PIXELS, widthInPixels),
            polylineColor,
            LineCap.ROUND));
} catch (MapPolyline.Representation.InstantiationException e) {
    Log.e("MapPolyline Representation Exception:", e.error.name());
} catch (MapMeasureDependentRenderSize.InstantiationException e) {
    Log.e("MapMeasureDependentRenderSize Exception:", e.error.name());
}

mapView.getMapScene().addMapPolyline(routeMapPolyline);
val routeGeoPolyline: GeoPolyline = route.geometry
val widthInPixels = 20f
val polylineColor = Color(0f, 0.56.toFloat(), 0.54.toFloat(), 0.63.toFloat())
var routeMapPolyline: MapPolyline? = null

try {
    routeMapPolyline = MapPolyline(
        routeGeoPolyline, MapPolyline.SolidRepresentation(
            MapMeasureDependentRenderSize(RenderSize.Unit.PIXELS, widthInPixels.toDouble()),
            polylineColor,
            LineCap.ROUND
        )
    )
} catch (e: MapPolyline.Representation.InstantiationException) {
    Log.e("MapPolyline Representation Exception:", e.error.name)
} catch (e: MapMeasureDependentRenderSize.InstantiationException) {
    Log.e("MapMeasureDependentRenderSize Exception:", e.error.name)
}

mapView.mapScene.addMapPolyline(routeMapPolyline)

以下の最初のスクリーンショットは、追加の経由地のないルート、つまりルートセクションが1つだけのルートを示しています。出発地と目的地は、丸で囲まれた緑色のマップ マーカー オブジェクトで示されています。円で囲まれたオブジェクトを描画するコードはここには示されていませんが、興味があればサンプルのソースコードから確認できます。

Screenshot: Showing a route on the map.

2 番目のスクリーンショットは上記と同じルートを示していますが、赤丸で囲まれたマップ マーカー オブジェクトで示される 2 つの追加の STOPOVER 経由地があります。このため、ルートには3つのルートセクションが含まれています。

Screenshot: Showing a route with two additional waypoints.

stopoverで経由地を追加すると、ルートが複数のセクションに分割され、ルートはこれらのポイントを通過して、各ポイントで運転操作指示を生成するように強制されます。

内部的には、MapPolylineのレンダリングが非常に長いルート向けに最適化されていることに注意してください。たとえば、ズームレベルが高ければすべての座標をレンダリングする必要はありませんが、ズームレベルが低いとルート全体が表示されません。このためのアルゴリズムは公開されていませんが、基本原理はHEREのflexible-polylineオープンソースプロジェクトで見ることができます。

ルートにズームする

ユースケースによっては、計算されたルートにズームすると便利な場合があります。カメラクラスには、ルートが収まるようにビューポートを調整する便利なメソッドが用意されています。

GeoBox routeGeoBox = route.getBoundingBox();
// Set null values to keep the default map orientation.
camera.lookAt(routeGeoBox, new GeoOrientationUpdate(null, null));

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

ほとんどのユースケースでは、アニメーションを使用してルートにズームすると、ユーザーエクスペリエンスが向上します。以下に、GeoBoxに50ピクセルの追加のパディングを加えてズームする例を示します。

private void animateToRoute(Route route) {
    // The animation should result 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 = new Point2D(50, 50);
    Size2D sizeInPixels = new Size2D(mapView.getWidth() - 100, mapView.getHeight() - 100);
    Rectangle2D mapViewport = new Rectangle2D(origin, sizeInPixels);

    // Animate to the route within a duration of 3 seconds.
    MapCameraUpdate update = MapCameraUpdateFactory.lookAt(
            route.getBoundingBox(),
            new GeoOrientationUpdate(bearing, tilt),
            mapViewport);
    MapCameraAnimation animation =
            MapCameraAnimationFactory.createAnimation(update, Duration.ofMillis(3000), new Easing(EasingFunction.IN_CUBIC));
    mapView.getCamera().startAnimation(animation);
}

CameraKeyframeTracksサンプルアプリでは、これがどのように見えるかを示しています。

ルートに交通情報を表示する

ルート上に交通状況を視覚化する方法については、交通流に沿ってポリラインをレンダリングする方法やカスタムの交通情報オーバーレイなど、「ルート上の交通状況を視覚化する」参照してください。


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); })();