HERE SDK for Android (Premium Edition)
SDK for Android Developer's Guide

3D Venues FAQ

Can I customize the venue color scheme and venue icon?

Yes. Venue attributes can be customized using StyleSettings object.

There are two types of icons:
  • Icons displayed on the map for a space, point-space, or facility (SVG file format)
  • Icons displayed in native controls such as a search filter list (PNG file format)

Map icons can be customized in two ways: either by replacing the respective SVG asset files with customized ones, or by dynamically replacing them at runtime using StyleSettings object. See the following code snippet as an example on how to customize an icon for a space.

public void onVenueSelected(Venue venue) {
  if (venue.getId().equals("DM_12468")) {
    Space t1Space = venue.getSpace("Lv26051Ds3186063");
    if (t1Space != null) {
      VenueController venueCtlr = m_venueLayer.getVenueController(venue);
      Bitmap bitmap =  BitmapFactory.decodeResource(m_venueLayer.getActivity().getResources(),
      Image image = new Image();
      StyleSettings settings = new StyleSettings();
      venueCtlr.setStyleSettings(settings, t1Space);
Note: Using a private HERE account PNG icons that are displayed in native controls can also be customized by replacing the respective PNG icon files with customized ones. Note that there are 4 different sizes for each Android resolution type. To make these customizations, see Service Support to contact us for more details .

Can logos be added for individual spaces, e.g. for a restaurant?

Yes. You can modify the icon for an individual space dynamically using StyleSettings object. For details, see StyleSettings API Reference.

Is it possible to expose venue data, in a classified manner, for a single user?

Yes, you can create a private HERE account and expose a "customized" version of the venue to it. See Service Support to contact us for more details.

What fonts are supported by the Venues feature?

There is currently no support for fonts. Only the default font is supported.

Are there venue routing penalties for different types of connectors, like elevators?

Penalties are applied when the route is calculated in "fastest" mode. For "shortest" mode connectors are considered only if the geometry has a significant distance.

How can I create a colored MapMarker?

See the following code snippet or MapMarker API Reference.

MapMarker m_marker;

    public void onSpaceSelected(Venue venue, Space space) {
        Bitmap bitmap =  BitmapFactory.decodeResource(getResources(), R.drawable.pin_start);
        Image image = new Image();
        m_marker = new MapMarker(space.getCenter(), image);
        m_marker.setAnchorPoint(new PointF(image.getWidth() / 2f, 0.9f * image.getHeight()));
    public void onSpaceDeselected(Venue venue, Space space) {
    private void removeMarker() {
        if (m_marker != null) {
            m_marker = null;

How do I select point-spaces (spaces without geometry) and calculate a route to such a position?

Take the tapped position and calculate the route from those coordinates. The following is an example of how to handle the map tap events to get a location for a route.

public boolean onMapTapped(PointF point) {
  Map map = m_venueLayer.getMap();
  GeoCoordinate tapPoint = map.pixelToGeo(point);
  if (tapPoint == null || !tapPoint.isValid()) {
    return false;

  Venue venue = m_venueLayer.getSelectedVenue();
  VenueController venueController = null;
  if (venue != null) {
    venueController = m_venueLayer.getVenueController(venue);

  if (venueController == null) {
    // null controller means that there is no venue open in 3d mode,
    // so use the tap point as outdoor location
    BaseLocation location = new OutdoorLocation(tapPoint);
    return false;

  // if the controller is not null, get the tapped point as a location inside venue
  BaseLocation location = venueController.getLocation(point, m_preferSpaceSelection);

  return false;

private void addRoutePoint(BaseLocation location) {
  // Logic for saving route points

How do I calculate the length of a route?

  1. From CombinedRoute result object, get all the route sections. Route sections can be of three types: VENUE, LINK, or OUTDOOR.
  2. For each route type, you need to calculate its distance individually. See the following example on how to calculate length of different route types.

private void calculateLength(CombinedRoute combinedRoute) {

  List<IRouteSection> sections = combinedRoute.getRouteSections();
  double distance = 0.0;
  for (IRouteSection section : sections) {
    if (section instanceof VenueRoute) {
      // get length of indoor sections
      List<VenueManeuver> maneuvers = ((VenueRoute)section).getVenueManeuvers();
      distance += (double)maneuvers.get(maneuvers.size() - 1).getDistanceFromStart();
    } else if (section instanceof LinkingRoute) {
      // get length of link sections
      distance +=
        ((LinkingRoute)section).getFrom().distanceTo(((LinkingRoute) section).getTo());
    } else if (section instanceof OutdoorRoute) {
      // get length of outdoor sections route = ((OutdoorRoute)section).getRoute();
      distance += (double)route.getLength();

How can my app automatically open a venue right after the app starts?

At app start make sure the VenueService is initialized and then select the desired venue using VenueMapFragment as shown in the following example:

// 1. make sure VenueService is initialized
if (VenueMapFragment.getVenueService().getInitStatus()  == ONLINE_SUCCESS ||
  VenueMapFragment.getVenueService().getInitStatus()  == OFFLINE_SUCCESS) {
// 2. Then use the method to get the desired venue
  VenueMapFragment.selectVenueAsync(String id);

How can my app detect whether a route passes a specific type of space such as a security gate?

To identify if a route passes a certain type or category of space, loop through the route sections and inspect if a maneuver contains a space in the expected category. For example, the following code snippet shows how to find the first venue maneuver with category 4 which represents a security gate.

private void findSecurityGate(CombinedRoute route) {
  for (IRouteSection section: route.getRouteSections()) {
    if (section.getRouteSectionType() == IRouteSection.RouteSectionType.VENUE) {
      VenueRoute venueRoute = (VenueRoute) section;
      List<VenueManeuver> maneuvers = venueRoute.getVenueManeuvers();
      for (VenueManeuver maneuver: maneuvers) {
        if (maneuver.getSpace() != null && maneuver.getSpace().getContent() != null) {
          Content content = maneuver.getSpace().getContent();
          if (content.getCategoryId().equals("4")) {
            // create alert;

We get the spaces and facilities by iterating through all the levels and calling getSortedSpacesWithFacilities() method. Is it possible to also get the entrances?

This is the correct way to get a list with all the spaces and facilities. However, entrances (accessors) are not exposed as POIs at the moment.

Is there a way to only show the venue model without showing the map tiles beneath it?

At the moment a venue can only be shown on top of the map.

Is there a way to integrate 3D Venues with Apache Cordova?

We do not support Cordova plug-in. Only native Android and iOS SDKs are supported.

How can I get a nearby space based on a location and a radius?

This is not currently supported.

How can I get a nearby space based on an indoor routing line?

This is not possible at the moment. This is planned for a future release.

How can I get a certain area around a venue model for offline mode?

Once a venue has been downloaded, it is cached and will be available later in offline mode. However, you need to be online and request the venue prior to this.

Can venue entrance markers be customized?

HERE SDK already marks entrances on the map and on the route with entrance icons. For private venues these icons can be customized by contacting HERE representatives.

How do I pre-cache individual venues without user interaction?

You need to download venues using VenueService.
  • v.getVenueAsync()
  • v.getVenueAt()
  • v.getVenueById()
  • v.getVenuesIn()
For more information, see VenueService API Reference.

How do I translate geo locations into indoor locations expressed as latitude, longitude, and level, for a given functional call within HERE SDK?

You need to have the geo location which you want to map inside the venue as well as the level on which you intend to place those coordinates. Thus, you can use LevelLocation to construct the indoor location.

GeoCoordinate m_currentPosition;
String m_buildingId;
Integer m_levelId;
Level m_currentLevel;
LevelLocation m_levelLocation;
OutdoorLocation m_outdoorLocation;

public void onPositionUpdated(LocationMethod locationMethod, GeoPosition currentPosition,
    boolean isMapMatched) {

  // Get position in GeoCoordinates
  m_currentPosition = currentPosition.getCoordinate();
  m_map.setCenter(m_currentPosition, Animation.NONE);
  if (currentPosition.getBuildingId() != null) {
    // If inside a venue get building information and initiate venue opening
    // Get buidling id (venue id)
    m_buildingId = currentPosition.getBuildingId();
    // Get level number
    m_levelId = currentPosition.getFloorId();
    // Get 3d venue based on venue id
    // Venue object is available as parameter of onVenueSelected callback of VenueListener
    // In order to get that callback, register your application to receive this
    // callback with VenueService.addVenueLoadListener method
    if (m_venueLayer.getSelectedVenue() == null ||
  } else {
    // If not inside a venue, create an outdoor location
    m_outdoorLocation = new OutdoorLocation(m_currentPosition);

public void onVenueSelected(Venue venue) {
  // Get Level object based on level id
  // Java 8 offers more elegant way to iterate using filter but assume we need to stick to Java 7
  List<Level> levels = venue.getLevels();
  boolean found = false;
  for (int i = 0; i < levels.size() && !found; ++i ) {
    if (levels.get(i).getFloorNumber() == m_levelId) {
      m_currentLevel = levels.get(i);
      found = true;
  // Create LevelLocation object
  m_levelLocation =
    new LevelLocation(m_currentLevel, m_currentPosition, m_venueLayer.getVenueController(venue));