HERE Android SDK Developer's Guide

Extruded Buildings

Figure 1. Extruded Buildings on a Map of San Francisco

HERE Android SDK supports 3D representations of buildings and structures. This feature is called extruded buildings, and you can display them by using the setExtrudedBuildingsVisible() method in com.here.android.mpa.mapping.Map. Extruded buildings are available for most metropolitan areas in North America and Europe.

The MapBuildingLayer Class

The main entry point for extruded buildings is the MapBuildingLayer class, which can be retrieved by calling getMapBuildingLayer() from a Map. MapBuildingLayer provides methods for working with building groups and individual buildings such as:
  • getBuilding()
  • createNewBuildingGroup()
  • releaseBuildingGroup()
  • getDefaultBuildingGroup()
These APIs provide a way for the developer to create groups of buildings (for example, to highlight them in a blue color), or to retrieve a default group containing all possible extruded buildings on-screen.
Note: The extruded building methods are available even when buildings are invisible. For example, calling getDefaultBuildingGroup() returns the default group, even if you have called setExtrudedBuildingsShown(false) or if the current zoom level does not allow visible extruded buildings.

The MapBuildingGroup Class

The MapBuildingGroup class represents a group of buildings. There are two types of groups:
  • New building groups - Created by calling createNewBuildingGroup(). No building is attached to this group when it is created. An application can have a maximum of six new building groups at a time.
  • Default building groups - Retrieved by calling getDefaultBuildingGroup(). The default building group is a generic group that represents all possible buildings in the entire world. There are two distinct types of default building groups— IMPORTANT_BUILDINGS, which are textured landmark buildings, and NORMAL_BUILDINGS, which include all other buildings.
Each MapBuildingGroup holds an EnumSet of building faces, a color, as well as a building height scaling factor. To control the appearance of extruded buildings, you can set these attributes and add buildings to the group. For example, to highlight a building's roof, create a new building group, set the group's roof color as Color.RED, and then add a building to this group, as in the following code:

// retrieve a reference of the map from the map fragment
map = mapFragment.getMap();

// Create a custom building group
buildingGroup = map.getMapBuildingLayer().createNewBuildingGroup();

// Set the buildingGroup's roof color to "red"
buildingGroup.setColor(Color.RED, EnumSet.of(MapBuildingGroup.BuildingFace.ROOF));

// Set the buildingGroup's height
buildingGroup.setVerticalScale(0.90f);

buildingGroup.addBuilding(myBuildingIdentifier);
Note: Remember to call releaseBuildingGroup() to release any unused building groups. Otherwise, users may receive a null pointer exception after the device has been rotated a few times.
Figure 2. Highlighting a Building
Note: By default, a new MapBuildingGroup has the color MapBuildingLayer.DefaultBuildingColor.SELECTED on all building faces.
The following images show the values that can be used to highlight building faces:
MapBuildingGroup.BuildingFace.ROOF
MapBuildingGroup.BuildingFace.OUTLINE
MapBuildingGroup.BuildingFace.WALLBOTTOM
MapBuildingGroup.BuildingFace.WALLTOP
MapBuildingGroup.BuildingFace.LANDMARKS - Note that this value is only applicable for landmarks. When this value is used, the entire landmark is shaded.

The MapBuildingObject Class

The MapBuildingObject class represents a single building, with the following attributes:
  • a name
  • a geocoordinate position
  • the building height, in meters
  • a unique map building identifier

To detect whether a user has tapped on an extruded building, use MapGesture.OnGestureListener and look for the selected MapBuildingObject:


private MapGesture.OnGestureListener gestureListener =
  new MapGesture.OnGestureListener.OnGestureListenerAdapter() {
    public boolean onMapObjectsSelected(List<ViewObject> objects) {
      for (ViewObject vo : objects) {
        if (vo instanceof MapBuildingObject) {
          // Remove currently selected building
          buildingGroup.removeAllBuildings();

          // Add this building to the group.
          MapBuildingObject building = (MapBuildingObject) vo;
          buildingGroup.addBuilding(building.getIdentifier());
        }
      }
      return false;
    }
  };