Placesを検索

HERE SDK for Android では、数億ものPOI( 施設情報 )、ストリート名、および世界中のポイントアドレスのグローバルデータセットを利用して、すばやく簡単に検索できます。 HERE SDK を使用すると、検索に関連するさまざまなタスクを 1つのSearchEngine内から解決できます。

  • Placesを検索: この巨大なデータベースのPlacesを、カテゴリ別、または検索語を定義して、世界中で検索して発見できます。
  • Autosuggestを生成: 検索条件を入力して検索を完了するときに、Placesを検索します。
  • 住所をリバースジオコード: 特定の地理座標に属する住所を検索します。
  • 住所をジオコード: 住所に関連付けられている地理座標を検索します。
  • ID で検索: HERE Places ID で特定されたPlacesを検索します。
  • ルートに沿って検索: ルート全体に沿ったPlacesを検索します。
  • ルートに沿ってカテゴリで検索: ルート全体のカテゴリに基づいてPlacesを検索します。 この機能はベータ版です。

すべての検索バリアントに共通するフィーチャーの1つは、検索する場所または領域を指定できることです。 領域の設定は、GeoBoxで指定された矩形領域 、またはGeoCircleで指定された円領域を通過することで行う ことができます。 指定した領域外にある潜在的な検索結果は、関連するグローバルな結果を除いて、優先度の低いものでランク付けされます。たとえば、ベルリンで「 Manhattan 」を検索する場合です。 基本となる検索アルゴリズムが最適化され、結果のリストを絞り込むことができるようになり、ユーザーに迅速でわかりやすい結果が提供されます。

注 : 各検索リクエストは非同期で実行されます。 SearchEngine を使用して HERE のバックエンドサービスから結果を取得する場合は、オンライン接続が必要です。

HERE Location Services が提供するPlacesの膨大なデータベースは、 HERE SDKのSearchEngineで簡単に見つけることができます。 例を見てみましょう。 まず、新しい SearchEngine インスタンスを作成します。

try {
    searchEngine = new SearchEngine();
} catch (InstantiationErrorException e) {
    throw new RuntimeException("Initialization of SearchEngine failed: " + e.error.name());
}

新しい SearchEngine インスタンスを作成すると、前述のように処理する必要のある InstantiationErrorException をスローできます。 ApplicationonCreate()ライフサイクル中にエンジンを初期化することはできません。 それ以外の任意の時点で問題はありません。 たとえば、エンジンを初期化する適切な場所が ActivityonCreate() メソッドに含まれている可能性があります。

Placesを検索

デバイスに表示されている現在のマップセンターの周りにあるすべての「pizza」のPlacesを探しているとします。 検索を開始する前に、詳細をいくつか指定する必要があります。

SearchOptions searchOptions = new SearchOptions();
searchOptions.languageCode = LanguageCode.EN_US;
searchOptions.maxItems = 30;

ここで SearchOptions は、目的のデータを保持する新しいオブジェクトを作成します。

  • LanguageCodeを設定することで、返される検索結果の言語を指定できます。
  • maxItems は、応答で配信する結果アイテムの最大数を定義するように設定されています。

上の例では、結果を 30 に制限しています。 リクエストよりも多くの検索結果が見つかった場合、最も関連性の高い 30 件の検索結果のみが返されます。

現在のビューポイント内のすべての結果を検索するために、エリア検索 (One-Box) を実行します。 SearchEngine では、次の 3 つの方法で検索場所を指定できます。

  • GeoCoordinates検索場所:指定した座標系を中心に非同期の検索リクエストを実行し、近隣で最も関連性の高い検索結果を提供します。
  • GeoCircle エリア内を検索 : 上記と似ていますが、指定した円の領域内で結果を検索します。この領域は、中心の地理座標およびメートル単位の半径で定義されます。
  • GeoBox エリア内を検索 : 上記と同様ですが、指定した矩形領域内で結果を検索します。この領域は、パラメーターとして渡された南西および北東の座標によって定義されます。

One-Box検索 は、近隣のPlacesを探すのに最適です。 入力すると、さまざまな言語 ( ラテン語、キリル語、アラビア語、ギリシャ語など ) で自由形式のテキストを提供できます。

検索する領域と用語を同時に指定できます。 たとえば、以下のように queryString 「 pizza 」に設定できます。

GeoBox viewportGeoBox = getMapViewGeoBox();
TextQuery.Area queryArea = new TextQuery.Area(viewportGeoBox);
TextQuery query = new TextQuery(queryString, queryArea);

ここでは、 getMapViewGeoBox()のコードを削除しました。 ユースケースに適した任意のGeoBoxを作成して渡すことができます。 実装の可能性については、付属のサンプルアプリを参照してください。

まず、指定したマップ範囲内の結果が返されます。 検索結果が見つからなかった場合は、グローバル検索結果が返されることがあります。 ただし、指定した検索場所に関係なく、主要都市や州などの関連するグローバルな結果が含まれる場合があります。

注 : クエリー文字列には、検索するコンテンツの任意のテキスト記述を含めることができます。 複数の検索語を使用して、コンマで区切って検索結果を絞り込むことができます。 「ピザショーシー通り」と「ピザ、ショーシー通り」は同じ結果をもたらします。通り「チャウゼー通り」にあるピザレストランのみが見つかります。 また、空のクエリ文字列を渡すとエラーになります。この場合、検索は失敗します。

最後に、非同期で検索を開始できます。

searchEngine.search(query, searchOptions, querySearchCallback);

...

private final SearchCallback querySearchCallback = new SearchCallback() {
    @Override
    public void onSearchCompleted(@Nullable SearchError searchError, @Nullable List<Place> list) {
        if (searchError != null) {
            showDialog("Search", "Error: " + searchError.toString());
            return;
        }

        // If error is null, list is guaranteed to be not empty.
        showDialog("Search", "Results: " + list.size());

        // Add new marker for each search result on map.
        for (Place searchResult : list) {
            // ...
        }
    }
};

結果を確認する前に、まずSearchErrorの可能性を確認する必要があります。 たとえば、デバイスがオフラインの場合、 list は null になり、エラー 列挙型 (enum) が原因を示します。 この場合、ヘルパーメソッドshowDialog() を呼び出して、エラーの説明をユーザーに表示します。 showDialog()の実装の可能性は、付随する「検索」の例のソースコードからアクセスできます。このコードには、 HERE SDK 固有のコードは含まれていません。

検索応答にエラーまたは結果が含まれています : SearchError および List<Place>。 両方とも同時にnullにすることも、また、同時にnull以外にすることもできません。

ここで、結果を確認しましょう。 一致する結果が見つからない場合は、事前にエラーが検出されている可能性があります。

// If error is null, list is guaranteed to be not empty.
showDialog("Search", "Results: " + list.size());

// Add new marker for each search result on map.
for (Place searchResult : list) {
    Metadata metadata = new Metadata();
    metadata.setCustomValue("key_search_result", new SearchResultMetadata(searchResult));
    // Note: getGeoCoordinates() may return null only for Suggestions.
    addPoiMapMarker(searchResult.getGeoCoordinates(), metadata);
}

...

// Class to store search results as Metadata.
private static class SearchResultMetadata implements CustomMetadataValue {

    public final Place searchResult;

    public SearchResultMetadata(Place searchResult) {
        this.searchResult = searchResult;
    }

    @NonNull
    @Override
    public String getTag() {
        return "SearchResult Metadata";
    }
}

最後に、結果のリストについて反復処理を行います。 各Placeには、検索結果を説明するさまざまなフィールドが含まれています。

この例では、マップにマーカーを追加するために、そのPlacesの場所に関心があります。 さらに、Metadata を保存できるオブジェクト SearchResultを作成します。

注 : Metadata オブジェクトには、の MapMarker 結果データとの関連付けを容易にするためのさまざまなデータ型を含めることができます。 このようにして、マップ マーカーに関連するすべての情報を 1 つのオブジェクトに保持できます。これは、ユーザーがマップ マーカーをタップした後などに、このデータを表示する場合に便利です。 上記 CustomMetadataValue のように、インターフェイスを実装することで、複雑なデータオブジェクトも保存できます。

addPoiMapMarker()の実装方法としては 、付随する「検索」のサンプルソースコードからアクセス できます。このガイドの「マップマーカーについて」も参照してください。 ピックしたマップ マーカーオブジェクトを手元に置いておくと Metadata 、前のステップで設定した情報を取得できます。

Metadata metadata = topmostMapMarker.getMetadata();
if (metadata != null) {
    CustomMetadataValue customMetadataValue = metadata.getCustomValue("key_search_result");
    if (customMetadataValue != null) {
        SearchResultMetadata searchResultMetadata = (SearchResultMetadata) customMetadataValue;
        String title = searchResultMetadata.searchResult.getTitle();
        String vicinity = searchResultMetadata.searchResult.getAddress().addressText;
        showDialog("Picked Search Result",title + ". Vicinity: " + vicinity);
        return;
    }
}

すべてのマップマーカーにMetadataが含まれているわけではありません 事前にMetadata を設定していない場合、 getMetadata()は null を返します。 この例では、 "key_search_result" のために保存されているデータが null でないかどうかを確認するだけで、データに検索データが含まれていることがわかります。 その後、 目的のPlaceを保持するカスタムタイプSearchResultMetadata にダウンキャストできます。

利用可能な nullを入力可能なフィールドの詳細については、 API リファレンス を参照してください。

スクリーンショット: 選択した検索結果をタイトルと近隣で表示。

このセクションおよび以降のセクションのすべてのコードは Search、 GitHubのサンプルアプリの一部として入手できます。

Placesにズーム

上記のコードでは、GeoBox を使用 して、表示されているマップビューポイント を直接検索します。そのため、検索結果をズームする必要はありません。 GeoBoxの代わり に、CountryCode値のリストを渡すことで、 GeoCircleの内側、 GeoCorridorに沿って、または内側の国を囲む位置を検索することもできます ( 「自分の周りを検索」 ) 。 サポートされているすべてのタイプについては、TextQuery.Area を参照

検索領域が表示されているマップビューポイントと異なる場合は、次のコードを使用してGeoCoordinatesの一覧からGeoBoxを作成し、結果を参照できます。 GeoBox からGeoBox.containing(geoCoordinatesList)を取得します。

// Set null values to keep the default map orientation.
mapCamera.lookAt(geoBox, new GeoOrientationUpdate(null, null));

これでカメラが即座に移動します。 必要に応じて、さまざまなアニメーションスタイルを適用して、カメラを目的の領域にフライすることもできます。 このMapCameraセクションを参照 して、 GitHubCameraKeyframeTracks サンプルアプリ を確認します。

追加のパディングを適用する場合は、viewRectangleを追加のパラメーターとして受け取るオーバーロードされたメソッドlookAt()を使用します。 矩形は、GeoBoxが表示されている内部のマップ ビュー を参照するピクセル単位で指定されます。

Point2D origin = new Point2D(5, 5);
Size2D sizeInPixels = new Size2D(mapView.getWidth() - 10, mapView.getHeight() - 10);
Rectangle2D paddedViewRectangle = new Rectangle2D(origin, sizeInPixels);

上記のコードでは、 GeoBox マップビューポイント に表示されている任意の周囲に 5 ピクセルのパディングを追加するために使用できる矩形を作成します。

Placesカテゴリを検索

上記のようにTextQueryをしてキーワード検索を行う代わりに、カテゴリを検索して結果を予想されるカテゴリPlaceに限定することもできます。

カテゴリ ID は特定の形式に従い、 HERE platform では 700 を超えるカテゴリを使用できます。 HERE SDK には、カテゴリ検索をより簡単に実行できるように定義済みの値のセットが用意されています。 必要に応じて、 xxx-xxxx-xxxx の形式でカスタムカテゴリ文字列を渡すこともできます。各グループは、 1 、 2 、 3 の各レベルのカテゴリを表します。 1 番目のレベルがメインカテゴリを表し、 2 番目と 3 番目のレベルが論理サブセットで編成されたサブカテゴリを表します。 各カテゴリレベルは 、placesカテゴリシステムで番号として定義されます。 例 : 100 - 「飲食」メイン カテゴリ このカテゴリでは、カテゴリ「 1000 」 ~ 「レストラン」があります。このレベル 2 のカテゴリには、カテゴリ「 0001 」のカジュアルダイニングがあります。カテゴリ ID は次のとおりです。 100-1000-0001

例として、「飲食」カテゴリまたは「ショッピングエレクトロニクス」カテゴリに属するすべての場所を以下から検索します。

private void searchForCategories() {
    List<PlaceCategory> categoryList = new ArrayList<>();
    categoryList.add(new PlaceCategory(PlaceCategory.EAT_AND_DRINK));
    categoryList.add(new PlaceCategory(PlaceCategory.SHOPPING_ELECTRONICS));

    CategoryQuery.Area queryArea = new CategoryQuery.Area(new GeoCoordinates(52.520798, 13.409408));
    CategoryQuery categoryQuery = new CategoryQuery(categoryList, queryArea);

    SearchOptions searchOptions = new SearchOptions();
    searchOptions.languageCode = LanguageCode.EN_US;
    searchOptions.maxItems = 30;

    searchEngine.search(categoryQuery, searchOptions, new SearchCallback() {
        @Override
        public void onSearchCompleted(SearchError searchError, List<Place> list) {
            if (searchError != null) {
                infoTextview.setText("Search Error: " + searchError.toString());
                return;
            }

            // If error is null, list is guaranteed to be not empty.
            String numberOfResults = "Search results: " + list.size() + ". See log for details.";
            infoTextview.setText(numberOfResults);

            for (Place searchResult : list) {
                String addressText = searchResult.getAddress().addressText;
                Log.d(TAG, addressText);
            }
        }
    });
}

PlaceCategory は、Stringを受け入れます。 HERE では、事前定義されたカテゴリ EAT_AND_DRINK および SHOPPING_ELECTRONICSを使用します。 この値String には、プレースカテゴリシステムで表されている ID が含まれています。 ここでも、SearchEngineのオーバーロードされたsearch()メソッドを使用して、カテゴリリストとPlacesを探す地理的座標を含むCategoryQueryオブジェクトを渡します。

Autosuggestを検索

ほとんどの場合、Places検索を提供するアプリケーションでは、ユーザーが希望する検索用語を編集可能なテキストフィールドコンポーネントに入力可能です。 入力中に、可能性のある用語の予測を取得できると便利です。

エンジンによって提示された提案がランク付けされ、最も関連性の高い用語が結果リストの一番上に表示されます。 たとえば、最初のリストアイテムを使用して、ユーザーが現在入力している検索語のAutosuggestを提供できます。 または、ユーザーの入力中に更新された一致候補のリストを表示できます。 ユーザーは、提案のリストから適切なキーワードを選択して、選択した用語の新しい検索を開始できます。または 、タイトル近隣などの結果の詳細情報をすでに取得し てユーザーに提示できます。

HERE SDKは 、UIや完全に統合されたAutosuggestソリューションを提供していません。 このようなソリューションは、必要に応じてアプリケーションによって実装できます。 このフィーチャーSuggestionを使用すると、TextQueryの条件に基づいて結果 Place が得られます。 これらのPlacesから、タイトルテキスト(「Pizza XL」)またはその他の関連する場所情報(住所など)を使用して、ユーザーにフィードバックを提供できます。たとえば、クリック可能な完了結果を提案することができます。 しかし、そのようなソリューションはアプリケーションの個々の要件に依存し、プラットフォームAPIを使用してアプリケーション側で実装する必要があります。

通常のテキストクエリと比較して、候補の検索では、入力したクエリの用語について、優先度でランク付けされた高速な結果が提供されます。

エンジンを使用して提案を検索する方法を確認しましょう。

GeoCoordinates centerGeoCoordinates = getMapViewCenter();

SearchOptions searchOptions = new SearchOptions();
searchOptions.languageCode = LanguageCode.EN_US;
searchOptions.maxItems = 5;

TextQuery.Area queryArea = new TextQuery.Area(centerGeoCoordinates);

// Simulate a user typing a search term.
searchEngine.suggest(
        new TextQuery("p", // User typed "p".
                queryArea),
        searchOptions,
        autosuggestCallback);

searchEngine.suggest(
        new TextQuery("pi", // User typed "pi".
                queryArea),
        searchOptions,
        autosuggestCallback);

searchEngine.suggest(
        new TextQuery("piz", // User typed "piz".
                queryArea),
        searchOptions,
        autosuggestCallback);

ヘルパーメソッド getMapViewCenter() は ここから削除され、付属のサンプルアプリで確認できます。 マップ ビューの中央に現在表示されているGeoCoordinatesを返すだけです。

新しいテキスト入力ごとに、次のリクエストを作成します。 ユーザーが「 Pizza 」と入力することを計画していると仮定します。まず「 p 」の結果を探し、次に「 pi 」の結果を探し、最後に「 piz 」の結果を探します。 ユーザーが実際に「pizza」を検索する場合は、 3 度目の呼び出しで十分な興味深い提案があるはずです。

suggest()メソッドは、 TaskHandle 進行中のコールのステータスを確認するため、またはコールをキャンセルするためにオプションで使用できるを返します。

結果の取得方法を確認しましょう。

private final SuggestCallback autosuggestCallback = new SuggestCallback() {
    @Override
    public void onSuggestCompleted(@Nullable SearchError searchError, @Nullable List<Suggestion> list) {
        if (searchError != null) {
            Log.d(LOG_TAG, "Autosuggest Error: " + searchError.name());
            return;
        }

        // If error is null, list is guaranteed to be not empty.
        Log.d(LOG_TAG, "Autosuggest results: " + list.size());

        for (Suggestion autosuggestResult : list) {
            String addressText = "Not a place.";
            Place place = autosuggestResult.getPlace();
            if (place != null) {
                addressText = place.getAddress().addressText;
            }

            Log.d(LOG_TAG, "Autosuggest result: " + autosuggestResult.getTitle() +
                    " addressText: " + addressText);
        }
    }
};

ここでは 、Suggestionで見つかったリストアイテムをログに記録するSuggestCallbackを定義します。 エラーがない場合、エンジンは結果のリストを保証します。エラーがない場合は null になります。

すべての提案があるわけではありません。 たとえば、「disco」などの一般的な用語を使用して、新しい検索に入力できます。 generic キーワードを使用すると、Suggestion結果にPlaceオブジェクトは含まれませんが、特定の場所を参照せずにテキストを表すのは titleだけです。 Suggestion 結果の使用可能なすべてのフィールドについては、『 API リファレンス 』を参照してください。

結果の順序はランク付けされますが、コールバックが到着する順序については保証がありません。 そのため、まれに、「 PI 」の結果よりも前に「 Piz 」の結果が表示されることがあります。

リバースジオコード:地理座標から住所を検索

これまでに、マップ上の特定の場所または地域でPlacesを検索する方法を確認しました。 しかし、地理座標のみがわかっている場合はどうすればよいですか。 このユースケースで最も一般的なのは、マップで何らかのアクションを実行しているユーザーです。 例えば、長押しジェスチャーです。 これにより、ユーザーがマップを操作する場所の緯度および経度座標が提供されます。 ユーザーはマップ上の場所を参照できますが、その場所に属する住所情報などの他の属性は把握していません。

リバースジオ コーディング が役立つ場所です。

関心のある場所は GeoCoordinates インスタンスで表されます。たとえば、マップをタップしたユーザーから取得できます。 その場所で「リバースジオコード」する方法については、次の方法を参照してください。

private void getAddressForCoordinates(GeoCoordinates geoCoordinates) {
  SearchOptions reverseGeocodingOptions = new SearchOptions();
  reverseGeocodingOptions.languageCode = LanguageCode.EN_GB;
  reverseGeocodingOptions.maxItems = 1;

    searchEngine.search(geoCoordinates, reverseGeocodingOptions, addressSearchCallback);
}

private final SearchCallback addressSearchCallback = new SearchCallback() {
    @Override
    public void onSearchCompleted(@Nullable SearchError searchError, @Nullable List<Place> list) {
        if (searchError != null) {
            showDialog("Reverse geocoding", "Error: " + searchError.toString());
            return;
        }

        // If error is null, list is guaranteed to be not empty.
        showDialog("Reverse geocoded address:", list.get(0).getAddress().addressText);
    }
};

SearchEngineによって提供される他の検索機能と同様 に、必要なLanguageCodeを設定するためのSearchOptionsインスタンスを提供する必要があります。 結果の住所の言語を指定します。 その後、エンジン search() のメソッドを呼び出して、渡された座標のアドレスをオンラインで検索できます。 デバイスがオフラインのときなど、エラー SearchError が発生した場合は、エラーの原因が保持されます。

リバースジオ コーディング応答にエラーまたは結果が含まれています : SearchError、 また、結果リストは一度にnullにすることも、null以外にすることもできません。

Place インスタンス内に含まれるオブジェクトAddress はデータクラスで、国、市区町村、番地などの生の場所の住所を記述する複数のフィールド String が含まれています。 詳細については、 API リファレンス を参照してください。 読み取り可能なアドレス表現の受信のみに関心がある場合 addressTextは、上の例に示すようにににアクセスできます。 これは、その場所のタイトルを含む、最も関連性の高い住所の詳細Stringを含みます。

スクリーンショット: 住所に解決された印刷機の長い座標を表示。

リバース ジオ コーディングでは、特定の検索領域は必要ありません。 世界中の住所に座標を解決できます。

ジオコード:アドレスから場所への変換

リバースジオ コーディング を使用すると、実際の座標から住所を取得できますが 、 フォワードジオ コーディング では逆の処理が行われ、道路名や都市名などの住所の詳細を入力するだけで、実際の座標やその他の位置情報を検索できます。

注 : ほとんどの場合、リバースジオ コーディングでは 1 つの結果しか得られませんが、ジオ コーディングでは 1 つ以上の結果が得られます。

ここでその方法をご案内します。 まず、検索したい場所の近くの座標を指定する必要があります。queryStringとして、正確な場所を見つけたい住所を設定します。

AddressQuery query = new AddressQuery(queryString, geoCoordinates);

SearchOptions options = new SearchOptions();
options.languageCode = LanguageCode.DE_DE;
options.maxItems = 30;

searchEngine.search(query, options, geocodeAddressSearchCallback);

...

private final SearchCallback geocodeAddressSearchCallback = new SearchCallback() {
    @Override
    public void onSearchCompleted(SearchError searchError, List<Place> list) {
        if (searchError != null) {
            showDialog("Geocoding", "Error: " + searchError.toString());
            return;
        }

        for (Place geocodingResult : list) {
            //...
        }

        showDialog("Geocoding result","Size: " + list.size());
    }
};

この例では、 HERE の Berlin HQ "Invalidenstra ß e 116" の通りの名前をクエリー文字列として渡します ( 任意で都市名を入力します ) 。 これはドイツ語の通り名な DE_DE ので、ドイツ語の言語コードを使用します。 これにより、返される結果の言語も決まります。

結果は指定した場所から遠く離れていてもかまいませんが、指定した座標に近い結果が高い順にランク付けされ、優先的に返されます。

SearchCallback がエラーなしで完了したことを確認した後 、エレメントPlaceのリストを確認します。

searchError が null の場合、結果 list は null ではないことが保証され、その逆も同様です。

結果は 、未加工の座標を含むPlaceオブジェクトにラップ されます。また、Addressオブジェクトや、 HERE Places API 内の位置を特定する場所 ID など、その他の住所の詳細情報もラップされます。 以下では、一覧表について繰り返し、住所のテキストと座標を取得します。

for (Place geocodingResult : list) {
    // Note: getGeoCoordinates() may return null only for Suggestions.
    GeoCoordinates geoCoordinates = geocodingResult.getGeoCoordinates();
    Address address = geocodingResult.getAddress();
    String locationDetails = address.addressText
            + ". GeoCoordinates: " + geoCoordinates.latitude
            + ", " + geoCoordinates.longitude;
    //...
}

ユーザーがマップからこのような結果を選択した場合の表示例については、以下のスクリーンショットを参照してください。 ご希望の場合は、添付の「検索」の例アプリを参照してください。この例では、住所のテキストを検索し、マップ上で見つかった場所にマップマーカーを配置する方法を示します。

スクリーンショット: 選択したジオ コーディング結果を表示。

ルートに沿って検索

SearchEngineは、長方形または円の領域で検索せずに、GeoPolylineおよび他のパラメーターで定義できるより複雑なGeoCorridor領域で検索する場合に、特殊な検索ケースをサポートします。

このような場合の最も一般的なシナリオは、 Route を検索してレストランを探すことです。 ルートオブジェクトがすでに計算されているとします。 経路の計算方法については、経路のセクションを参照してください。 TextQueryを指定すると、ルート全体を含む長方形の領域を簡単に定義できます。

TextQuery textQuery = TextQuery("restaurants", route.getBoundingBox())

ただし、より長いルートの場合、およびルートの形状によっては、route.boundingBox がルート全体を長方形の領域に包含する必要があるため、結果が実際のルートパスから非常に離れている場合があります。

HERE SDK は GeoCorridor 、ルートの実際の形状から検索領域を判断できるクラスを提供することで、より正確なソリューションを提供します。 この方法 では、パスの上または下にある検索結果のみが含まれます。

以下に、ルートに沿ってチャージステーションを検索する方法の例を示します。

// Perform a search for charging stations along the found route.
private void searchAlongARoute(Route route) {
    // We specify here that we only want to include results
    // within a max distance of xx meters from any point of the route.
    int halfWidthInMeters = 200;
    GeoCorridor routeCorridor = new GeoCorridor(route.getGeometry().vertices, halfWidthInMeters);
    TextQuery.Area queryArea = new TextQuery.Area(routeCorridor, mapView.getCamera().getState().targetCoordinates);
    TextQuery textQuery = new TextQuery("charging station", queryArea);

    SearchOptions searchOptions = new SearchOptions();
    searchOptions.languageCode = LanguageCode.EN_US;
    searchOptions.maxItems = 30;

    searchEngine.search(textQuery, searchOptions, new SearchCallback() {
        @Override
        public void onSearchCompleted(SearchError searchError, List<Place> items) {
            if (searchError != null) {
                if (searchError == SearchError.POLYLINE_TOO_LONG) {
                    // Increasing halfWidthInMeters will result in less precise results with the benefit of a less
                    // complex route shape.
                    Log.d("Search", "Route too long or halfWidthInMeters too small.");
                } else {
                    Log.d("Search", "No charging stations found along the route. Error: " + searchError);
                }
                return;
            }

            // If error is nil, it is guaranteed that the items will not be nil.
            Log.d("Search","Search along route found " + items.size() + " charging stations:");
            for (Place place : items) {
                // ...
            }
        }
    });
}

ご覧のように、GeoCorridorはルートGeoPolylinehalfWidthInMeters を必要とします。 この値は、ポリライン上の任意のポイントからコリドーの端までの最も遠いエッジを定義します。 小さな値を指定すると、実際のルートに沿って非常に近いエリアが結果のコリドーによって定義されます。

スクリーンショット: ルートに沿って見つかった充電ステーションを表示

ルートの始点と終点の座標では、コリドーは丸い形になります。一定の厚さのスネークが頭と尾に丸いエッジを持つようなものを想像してください。 上記のスクリーンショットと混同しないでください。ルートの始点と終点を示す緑色の円が表示されます。

特に長いルートの場合、内部的に検索アルゴリズムが検索経路の最適化を試行します。 ただし、ポリラインが長すぎる可能性があります。 上記のコード スニペットに示されているように、このケースをキャッチして、最終的にはより複雑でないルートの検索を再トリガすることにします。 これは halfWidthInMeters パラメータで制御できます。値を大きくすると、コリドーの複雑さが軽減され、結果の精度が低下しますが、少なくともこの方法ではより多くの結果が得られます。

ルートの複雑さは、フードの下の複数の要因によって決まります。そのため、ルートの明確な長さは一般に指定できません。

エラーが発生しなかった場合は、上記のセクションにすでに示されているように結果のPlace を処理できます。

このセクションのすべてのコードは 、EVRouting GitHub のサンプルアプリの一部として入手できます。

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

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