Search and Discovery
SDK for Android provides application developers with Places API which allows places discovery and information retrieval.
Steps for performing a search
- Implement the
ResultListener
interface to handle the completion of the search - Create a request and apply request options
- Invoke the request by calling
Request.execute(ResultListener)
-
ResultListener.onCompleted()
callback is triggered when the request is finished
- Search
- Request for Details
- Perform Actions
Search and Discovery Example on GitHub
You can find an example that demonstrates this feature at https://github.com/heremaps/.
The Place Class
The Place
class represents a detailed set of data about a physical place acting as a container for various attributes, collections of media about a place, and key-value pairs of related places. A Place
object can belong to a specific Category
and has attributes such as:
- A unique identifier (ID)
- A name
- A
Location
object representing the physical location of the place including access locations - A
List
ofCategory
objects that link to the categories assigned to the place - A URL to the icon that best represents the place
- Optional information such as related places, user ratings, reviews, and other editorial media
For more information please see the API Reference.
Discovery Requests
HERE Places Search API supports the following discovery requests:
Request | HERE SDK class | Purpose |
---|---|---|
Search | SearchRequest | Finds places that match user provided search terms. |
Explore | ExploreRequest | Finds interesting places nearby or in the map viewport sorted by popularity. Use this type of request if you are trying to answer the question "What are the interesting places nearby?" The results may be optionally restricted to a given set of categories which acts as a filter in terms of what places get returned. |
Here | HereRequest | Helps users identify places at the given location by finding places of interest near a given point sorted by distance. Use this type of request if you are trying to answer the question "What is near this location?" or "Where am I?" You can use this endpoint to implement features like "check-in" (by identifying places at the user's current position) or "tap to get more information about this place of interest". Note: Normally, the closest known places are returned with the Here Discovery request but if the uncertainty in the given position is high, then some nearer places are excluded from the result in favor of more popular places in the area of uncertainty. |
Around | AroundRequest | Allows users to request places near a given point based on a location precision parameter. The places around that point are returned in order of proximity. This type of request is intended for applications that employ features such as augmented reality where places around the user's location are displayed on a device. It is intended to provide places that are likely to be visible to the user as well as important places that are farther away. The Around request is considered experimental and its behavior and functionality are still evolving. Check future documentation for updates to this feature. |
The following code example demonstrates how to perform a search discovery request:
// Example Search request listener
class SearchRequestListener implements ResultListener<DiscoveryResultPage> {
@Override
public void onCompleted(DiscoveryResultPage data, ErrorCode error) {
if (error != ErrorCode.NONE) {
// Handle error
...
} else {
// Process result data
...
}
}
}
// Create a request to search for restaurants in Seattle
try {
// use following filter to show results only in the USA
AddressFilter filter = new AddressFilter();
filter.setCountryCode("USA");
GeoCoordinate seattle
= new GeoCoordinate(47.592229, -122.315147);
SearchRequest request =
new SearchRequest("restaurant").setSearchCenter(seattle);
request.setAddressFilter(filter);
// limit number of items in each result page to 10
request.setCollectionSize(10);
ErrorCode error = request.execute(new SearchRequestListener());
if( error != ErrorCode.NONE ) {
// Handle request error
...
}
} catch (IllegalArgumentException ex) {
// Handle invalid create search request parameters
...
}
The result of a discovery request is a DiscoveryResultPage
. The DiscoveryResultPage
represents a paginated collection of items from which the following can be retrieved:
- Next page and previous page requests - discovery requests used to retrieve additional pages of search items
- Items for the current page - a
List
ofDiscoveryResult
When additional pages of search results are needed, retrieve and invoke the DiscoveryRequest
returned by DiscoveryResultPage.getNextPageRequest()
. If the next page request is null, no additional results are available.
The following is an example:
DiscoveryResultPage mResultPage = null;
// Example Search request listener
class SearchRequestListener implements ResultListener<DiscoveryResultPage> {
@Override
public void onCompleted(DiscoveryResultPage data, ErrorCode error) {
if (error != ErrorCode.NONE) {
// Handle error
...
} else {
// Store the last DiscoveryResultPage for later processing
mResultPage = data;
...
}
}
}
...
// When the next page of results is needed...
DiscoveryRequest nextPageRequest = mResultPage.getNextPageRequest();
if (nextPageRequest != null) {
// More data is available if the nextPageRequest is not null
ErrorCode error = nextPageRequest.execute(new SearchRequestListener());
if( error != ErrorCode.NONE ) {
// Handle request error
...
}
}
Calling DiscoveryResultPage.getItems()
returns a List
containing one of the following types of objects which are DiscoveryResult
instances. DiscoveryResult
is a collection of Link
subtypes.
-
PlaceLink
- Represents discovery information about aPlace
. ThePlaceLink
contains a brief summary about a place. Details about a place are available from thePlace
that thePlaceLink
references. -
DiscoveryLink
- Represents a discovery-related API link used to retrieve additionalDiscoveryResultPage
. This type ofLink
can be a result item in an Explore or Here type of search. TheDiscoveryLink
references refined discovery requests resulting in more specific results. For example, theDiscoveryLink
may link to a discovery request to search for 'Eat & Drink', 'Going Out', 'Accommodation', and so on.
Since there may be new types of Link
items in the future, it is recommended that each type of DiscoveryResult
be checked before it is used (as shown in the following code snippet). In the following example, it is shown how a Place
is retrieved through a PlaceLink
:
// Implement a search result listener
ResultListener<DiscoveryResultPage> searchListener = new ResultListener<DiscoveryResultPage>() {
@Override
public void onCompleted(DiscoveryResultPage results, ErrorCode error) {
if (error == ErrorCode.NONE) {
// The results is a DiscoveryResultPage which represents a
// paginated collection of items.
List<DiscoveryResult> items = results.getItems();
// Iterate through the found place items.
for (DiscoveryResult item : items) {
// A Item can either be a PlaceLink (meta information
// about a Place) or a DiscoveryLink (which is a reference
// to another refined search that is related to the
// original search; for example, a search for
// "Leisure & Outdoor").
if (item.getResultType() == ResultType.PLACE) {
PlaceLink placeLink = (PlaceLink) item;
// PlaceLink should be presented to the user, so the link can be
// selected in order to retrieve additional details about a place
// of interest.
...
} else if (item.getResultType() == ResultType.DISCOVERY) {
DiscoveryLink discoveryLink = (DiscoveryLink) item;
// DiscoveryLink can also be presented to the user.
// When a DiscoveryLink is selected, another search request should be
// performed to retrieve results for a specific category.
...
}
}
} else {
// Handle search request error.
}
}
};
...
// Implement a Place listener for handling user interaction with a displayed PlaceLink
class PlaceListener implements ResultListener<Place> {
@Override
public void onCompleted(Place data, ErrorCode error) {
if (error != ErrorCode.NONE) {
// Handle error
...
} else {
// Present the place details to the user.
String placeName = data.getName();
List<Category> placeCategories = data.getCategories();
...
}
}
}
// Retrieve the place details when the user selects a displayed PlaceLink.
private void onPlaceLinkSelected(PlaceLink placeLink) {
PlaceRequest placeRequest = placeLink.getDetailsRequest();
if( placeRequest.execute(new PlaceListener()) == ErrorCode.NONE ) {
// Request successful. Additional work can be done here, however, place details will
// be returned in PlaceListener.onCompleted().
...
} else {
// Handle the error
...
}
}
Text AutoSuggestion Requests
HERE Places Search API also supports text autosuggestion requests. This type of request is used for retrieving a list of instant results (AutoSuggestPlace
) and refined search links (AutoSuggestSearch
) that are related to a specified location context and a partial search term. For example, if you make a request with the String "rest" in Berlin, the results contain search terms such as "Restaurant", "Rest area", and "Restorf, Höhbeck, Germany".
To use text suggestions, implement a listener to handle a list of AutoSuggest
objects and call new TextAutoSuggestionRequest(String)
as follows:
// Example request listener
class AutoSuggestionQueryListener implements ResultListener<List<AutoSuggest>> {
@Override
public void onCompleted(List<AutoSuggest> data, ErrorCode error) {
for (AutoSuggest r : data) {
try {
String term = "rest";
TextAutoSuggestionRequest request = null;
request = new TextAutoSuggestionRequest(term).setSearchCenter(myMap.getCenter());
if (request.execute(new AutoSuggestionQueryListener()) !=
ErrorCode.NONE ) {
//Handle request error
//...
}
} catch (IllegalArgumentException ex) {
//Handle invalid create search request parameters
}
}
}
}
You can retrieve the results of a TextAutoSuggestionRequest
by first checking the autosuggest object type as shown in the following example. Note that it is possible for AutoSuggestSearch
to contain additional paginated results through the DiscoveryRequest
object. If the object is AutoSuggestPlace
, you can request for more details through its PlaceRequest
object.
//assume autoSuggestList contains the list of results
try {
AutoSuggest autoSuggest = autoSuggestList.get(index);
// set title
String title = autoSuggest.getTitle();
// get highlightedTitle
String highlightedTitle = Html.fromHtml(autoSuggest.getHighlightedTitle()).toString();
if (autoSuggest instanceof AutoSuggestPlace) {
AutoSuggestPlace autoSuggestPlace = (AutoSuggestPlace)autoSuggest;
// vicinity
if (autoSuggestPlace.getVicinity() != null) {
String vicinity = autoSuggestPlace.getVicinity();
}
// set category
if (autoSuggestPlace.getCategory() != null) {
String category = autoSuggestPlace.getCategory();
}
// set position
if (autoSuggestPlace.getPosition() != null) {
String position = autoSuggestPlace.getPosition().toString();
}
// set boundaryBox
if (((AutoSuggestPlace)autoSuggest).getBoundingBox() != null) {
String boundingBox = ((AutoSuggestPlace)autoSuggest).getBoundingBox().toString();
}
} else if (autoSuggest instanceof AutoSuggestSearch) {
AutoSuggestSearch autoSuggestSearch = (AutoSuggestSearch)autoSuggest;
// set category
if (autoSuggestSearch.getCategory() != null) {
String category = autoSuggestSearch.getCategory();
}
// set position
if (autoSuggestSearch.getPosition() != null) {
String position = autoSuggestSearch.getPosition().toString();
}
// set boundaryBox
if (autoSuggestSearch.getBoundingBox() != null) {
String boundingBox = autoSuggestSearch.getBoundingBox().toString();
}
DiscoveryRequest myDiscoveryRequest = autoSuggestSearch.getSuggestedSearchRequest();
myDiscoveryRequest.execute(myDiscoveryResultPagelistener);
} catch (Exception e) {
Log.e("ERROR: ", e.getMessage());
}
External References
A place of interest can contain a reference to a foreign system outside of HERE SDK. For example, a Place
representing a restaurant contains an external reference to an entry in a restaurant reviews website. Each external reference is tied to a single reference source. However, each reference can have one or multiple identifiers.
PlaceRequest
and DiscoveryRequest
: -
Request.PVID_ID_REFERENCE_NAME
- Source for HERE Core Maps POI data -
"yelp"
- Source for Yelp IDs
An external reference is returned in the form of one or multiple String
identifiers in Place
, PlaceLink
, or Location
. To retrieve a reference, add a source to the PlaceRequest
or DiscoveryRequest
, as shown in the following example:
// Create a request to search for restaurants in Vancouver
GeoCoordinate vancouver =
new GeoCoordinate(48.263392, -123.12203);
DiscoveryRequest request =
new SearchRequest("restaurant").setSearchCenter(vancouver);
// We also want to retrieve the Yelp ID external reference
request.addReference("yelp");
request.setCollectionSize(10);
ErrorCode error = request.execute(new SearchRequestListener());
After the request execution is complete, you can retrieve the results by using getReference(String)
method. If an external reference returns multiple results, e.g. a single Place
is associated with multiple identifiers, use getAlternativeReferenceIds(String)
method in Place
or PlaceLink
to retrieve the remaining result items.
//...
class SearchRequestListener implements ResultListener<DiscoveryResultPage> {
@Override
public void onCompleted(DiscoveryResultPage data, ErrorCode error) {
if (error != ErrorCode.NONE) {
// Handle error
//...
} else {
//...
mResultPage = data;
for (PlaceLink link : mResultPage.getPlaceLinks())
{
String yelpReferenceID = link.getReference("yelp");
}
//...
}
}
}
//...
Additional external reference sources are supported through details requests as shown in the next example. For instance, you can use getDetailsRequest()
from a PlaceLink
object and retrieve reference IDs by executing the details request.
-
Request.PVID_ID_REFERENCE_NAME
- Source for HERE Core Maps POI data
//...
class SearchRequestListener implements ResultListener<DiscoveryResultPage> {
@Override
public void onCompleted(DiscoveryResultPage data, ErrorCode error) {
if (error != ErrorCode.NONE) {
// Handle error
//...
} else {
//...
mResultPage = data;
for (PlaceLink link : mResultPage.getPlaceLinks())
{
PlaceRequest detailsRequest = link.getDetailsRequest();
detailsRequest.addReference("tripadvisor");
// assuming you have created DetailsListener()
if( placeRequest.execute(new DetailsListener()) == ErrorCode.NONE ) {
// Request successful.
// Check the returned Place objects in DetailsListener.onCompleted().
...
} else {
// Handle the error
...
}
}
//...
}
}
}
//...
PlaceRequest(String, String)
constructor. You can also use an external PVID reference in the reverse scenario to retrieve a particular Place
by using a PlaceRequest
created with PlaceRequest(String, String)
constructor. For example:
PlaceRequest placeRequest =
new PlaceRequest(Request.PVID_ID_REFERENCE_NAME, "1126226306");