SDK for Android Developer's Guide

Search and Discovery

SDK for Android provides application developers with Places API which allows places discovery and information retrieval.

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 of Category 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 of DiscoveryResult

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 a Place. The PlaceLink contains a brief summary about a place. Details about a place are available from the Place that the PlaceLink references.
  • DiscoveryLink - Represents a discovery-related API link used to retrieve additional DiscoveryResultPage. This type of Link can be a result item in an Explore or Here type of search. The DiscoveryLink references refined discovery requests resulting in more specific results. For example, the DiscoveryLink 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.

The following external reference sources are supported in 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.

Note: You can retrieve the following external references through a 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
          ...
        }
      }
      //...
    }
  }
}
//...
Note: Sources marked with [*] cannot be used with the 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");