3D Venues
This section gives an overview of the classes and interfaces associated with the 3D Venues feature. Examples of available 3D venues include shopping malls and airports. This section also explores three use cases: searching for a venue, opening a venue, and getting a notification when a venue is visible in the viewport.
VenueMapFragment
VenueMapView
VenueService
VenueMapFragment.VenueListener
VenueLayerAdapter
VenueService.VenueServiceListener

The 3D Venues feature can be used with or without a map. To use it with a map, use the VenueMapFragment
or VenueMapView
. To use 3D Venues without a map, use VenueService
class.
3D Venues Example on GitHub
You can find an example that demonstrates this feature at https://github.com/heremaps/.
Using VenueMapFragment
VenueMapFragment
provides developers with access to all 3D venue-related features. As with AndroidXMapFragment
, VenueMapFragment
needs to be added to the layout file of the application, for example:
<!-- Example fragment. This can be integrated and annotated like any other android
Fragment of View widget -->
<fragment
android:id="@+id/map_fragment"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
class="com.here.android.mpa.venues3d.VenueMapFragment" />
The fragment must then be initialized in the same manner as AndroidXMapFragment
.
VenueListener
To receive venue-related events, implement VenueMapFragment.VenueListener
and add it to the VenueMapFragment
, similar to the following code example. As with a AndroidXMapFragment
, you can mark VenueMapFragment
initialization as successfully completed by looking for OnEngineInitListener.Error.NONE
error status code.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Search for the VenueMapFragment
final VenueMapFragment mapFragment = (VenueMapFragment)
getFragmentManager().findFragmentById(R.id.mapfragment);
// initialize the Map Fragment and
// retrieve the map that is associated with the fragment
mapFragment.init(new OnEngineInitListener() {
@Override
public void onEngineInitializationCompleted(OnEngineInitListener.Error error) {
if (error == OnEngineInitListener.Error.NONE) {
// add listeners
mapFragment.addListener(myVenueListener);
mapFragment.getVenueService().addListener(myVenueServicelistener);
map = mapFragment.getMap();
} else {
System.out.println("ERROR: Cannot initialize VenueMapFragment");
}
}
});
}
In this example myVenueListener
is assumed to implement VenueMapFragment.VenueListener
, and myVenueServiceListener
implements VenueService.VenueServiceListener
. For more information about these listener classes, see VenueService and VenueServiceListener.
Using VenueMapView
VenueMapView
provides developers with similar features as VenueMapFragment
but as a MapView
-based class. Like MapView
, VenueMapView
needs to be added to the layout file of the application:
<!-- An example VenueMapView -->
<com.here.android.mpa.venues3d.VenueMapView
android:id="@+id/mapcanvas"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
The view must then be initialized in the same manner as MapView
. As with a MapView
, you can mark VenueMapView
initialization as successfully completed by looking for OnEngineInitListener.Error.NONE
error status:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Search for the VenueMapView
final VenueMapView mVenueMapView = (VenueMapView)findViewById(R.id.venuemapview);
// get and initialize the MapEngine and
// assign the VenueMapView to it
ApplicationContext context = new ApplicationContext(this);
MapEngine.getInstance().init(context, new OnEngineInitListener() {
@Override
public void onEngineInitializationCompleted(OnEngineInitListener.Error error) {
if (error == OnEngineInitListener.Error.NONE) {
// create and assign map
mMap = new Map();
mVenueMapView.setMap(mMap);
mVenueMapView.initialize(this);
mVenueMapView.addListener(mVenueListener);
} else {
System.out.println("ERROR: Cannot initialize VenueMapView");
}
}
});
}
Working with 3D Venue Models
Once a VenueMapFragment
or VenueMapView
is correctly initialized, 3D-enabled venues become visible on the map. These venues can be distinguished by their colors and icons as in the screenshot below. This screenshot was taken from an app that uses VenueMapFragment
but the same visuals also appear on a VenueMapView
.

VenueMapFragment
offers two ways to select a venue and open the indoor map view. When a user taps the venue, onVenueTapped(VenueController, float, float)
method in VenueMapFragment.VenueListener
is called with a Venue
object as a parameter. The venue can then be opened by giving the Venue
object to selectVenue(Venue)
. For example:
public void onVenueTapped(Venue venue, float x, float y) {
mapFragment.selectVenue(venue);
}
When the venue is selected, onVenueSelected(Venue)
callback of VenueMapFragment.VenueListener
interface is called. A venue can also be selected and opened by giving its identifier to selectVenueAsync(String venueId)
method of VenueLayerAdapter
, which is implemented by VenueMapFragment
. For example, a typical scenario is a venue search where a successful search results in an opened venue.
selectVenue(Venue)
method opens the venue right away in a synchronous manner by taking a downloaded Venue
object as a parameter. However, selectVenueAsync(String)
and selectVenueAsync(String, String)
methods may involve downloading the venue from the backend, asynchronously, while the venue is selected and opened. You can get a notification for when asynchronous loading is complete by listening for onGetVenueCompleted(Venue)
callback in VenueService.ServiceListener
.
It is also possible to receive a notification when there is a venue in the viewport. You can use this callback to implement a feature such as drawing user attention to the venue when it is visible.
The triggering area for this is a rectangle at the center of the viewport. The width of the area is two-thirds of the screen width, and the height is equal to the width. When the center point of the venue enters this triggering area, such as during map panning, onVenueVisibleInViewport(Venue, boolean)
of VenueMapFragment.VenueListener
is called. The boolean parameter indicates whether the venue is entering or exiting from the triggering area. Note that to get the notifications, you must first set setVenuesInViewportCallback(boolean)
to true. For example:
// enabling onVenueVisibleInViewport notification
mapFragment.setVenuesInViewportCallback(true);
//...
@Override
public void onVenueVisibleInViewport(Venue venue, boolean visible) {
if (visible) {
// venue entered triggering area
} else {
// venue disappeared from triggering area
}
}
To change the current floor for a given venue, retrieve a VenueController
object by using getVenueController(String venueId)
method and then call VenueController.selectLevel(Level)
method.
You can enable animations for venue selection and floor transitions by calling setFloorChangingAnimation(true)
and setVenueEnteringAnimation(true)
.
VenueService and VenueServiceListener
In the case where you are not using a VenueMapFragment
, you can use the VenueService
instead. The service initialization status is provided as a parameter to onInitializationCompleted(InitStatus)
callback method in VenueService.VenueServiceListener
interface. You can also retrieve the status using getInitStatus()
method in VenueService
.
boolean cacheInUse = false
//...
@Override
public void onInitializationCompleted(InitStatus result) {
if (result == InitStatus.ONLINE_SUCCESS) {
// init ok, online content available
} else if (result == InitStatus.OFFLINE_SUCCESS) {
// cached content available
cacheInUse = true;
} else if (result == InitStatus.ONLINE_FAILED && cacheInUse) {
// failed to authenticate but cached content available
} else {
// something else has gone wrong
}
}
VenueService
offers methods for searching and loading venues without using a map. For example, the code below retrieves the closest venue inside a given radius near a given location. The area can also be defined by GeoBoundingBox
rather than a radius.
private void loadClosestVenue() {
VenueService venueService = VenueService.getInstance(getActivity().getApplicationContext());
GeoCoordinate myLocation = new GeoCoordinante(60.43704, 22.21710);
float radiusInMeters = 5000.0f;
VenueInfo closestVenue = venueService.getVenuesAt(myLocation, radiusInMeters);
venueService.getVenueAsync(closestVenue);
}
@Override
public void onVenueLoadCompleted(Venue venue, VenueInfo venueInfo, VenueLoadStatus loadStatus) {
// closest venue available through the venue object
}
VenueService
is also invoked when VenueMapFragment
is used. As such, some venue features can be used in a common manner between these classes. Venue Objects
The following is a list of venue objects (as Java classes) in com.here.android.mpa.venues3d
package. These objects are presented here from the lowest to the highest level of conceptual detail, and each level is involved in a has-a relationship. For example, each Venue
object may have multiple Level
member objects which contain multiple OuterArea
objects.
Java class | Description |
---|---|
com.here.android.mpa.venues3d.Venue | Represents a building which may contain one or more structures and levels. |
com.here.android.mpa.venues3d.Level | Represents a floor or horizontal layer within a Venue. |
com.here.android.mpa.venues3d.OuterArea | Represents a part of one Level contained within one exterior wall of a structure. |
com.here.android.mpa.venues3d.Space | Represents a spatial area on a Level like a store or a facility, e.g. an escalator. It may contain subspaces which represent the next level of detail about a space. |
com.here.android.mpa.venues3d.Content | Point of interest information about a spatial area within the venue. |
A Venue
object consists of one or more Level
objects. The Level
objects represent physical levels of the venue. Each Level
object consists of one or more OuterArea
objects. For example, a building with common ground level areas can contain two separate towers on top of that common area, and so there would be two OuterArea
objects in higher levels in that venue. An OuterArea
consists of one or more Space
objects.
Note that both Venue
and Space
classes have a member Content
class which holds point-of-interest information. This allows for a venue (such as a museum) and a space (such as a shop within a shopping mall) to hold separate address and phone numbers. Your app can use methods such as getPhoneNumber()
, getWebsite()
, and getOpeningTimes()
to retrieve the relevant directory information from Content
objects.
Working with Venues
Venue
, OuterArea
, and Space
objects can be interacted by the user through tapping. For an opened venue, use VenueMapFragment.VenueListener.onVenueSelected(Venue)
callback. For a selected space, use VenueMapFragment.VenueListener.onSpaceSelected(Venue, Space)
callback. Selected spaces are highlighted with different color in an opened venue.
Both Venue
and Space
objects contain Content
objects. Content
encapsulates information related to the object such as name, address, other contact information, and category of the venue or space. There is also a concept of selected floor, which is the same as the visible floor. This is demonstrated in the following screenshot. Note that the floor selection widget in this screenshot is not a part of HERE SDK.

The following example shows how to add a MapMarker
to a space upon an onSpaceSelected
event, and how to remove it when the space is deselected.
@Override
public void onSpaceSelected(Venue venue, Space space) {
removeMarker();
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.pin_start);
Image image = new Image();
image.setBitmap(bitmap);
m_marker = new MapMarker(space.getCenter(), image);
m_marker.setAnchorPoint(new PointF(image.getWidth() / 2f, 0.9f * image.getHeight()));
m_marker.setOverlayType(MapOverlayType.FOREGROUND_OVERLAY);
m_marker.setZIndex(100);
getMap().addMapObject(m_marker);
}
@Override
public void onSpaceDeselected(Venue venue, Space space) {
removeMarker();
}
private void removeMarker() {
if (m_marker != null) {
getMap().removeMapObject(m_marker);
m_marker = null;
}
}
Open Mode
When open mode is enabled, venues that are in the viewport are opened automatically rather than requiring the user to click on the venue to open it. The venue closest to the center of the screen is always selected.
Open mode can be enabled on VenueMapLayer
, VenueMapView
, VenueMapFragment
, or VenueMapAdapter
.
venueMapLayer.setOpenMode(true);
boolean isOpenMode = venueMapLayer.getOpenMode();
Dynamic Styles
StyleSettings
encapsulates the parameters that have an impact on the visual appearances of opened venues. You can set space names, icons, and colors by using this object. The fill and outline colors can be also set separately for selected and unselected spaces.
The following example shows how to set the name, label, fill color, and outline color to the given Space
object. The code snippet does not contain completed code but assumes that variables have been initialized.
import com.here.android.mpa.common.Image;
//...
private void updateStyles(Venue venue, Space space) {
Integer selectedColor = 0xFFFF0000; // red, format 0xAARRGGBB
Integer unselectedColor = 0xFFFFFF00; // yellow
Integer outlineColor = 0xFF0000FF; // blue
VenueController controller = m_venueMapFragment.getVenueController(venue);
StyleSettings settings = new StyleSettings();
settings.setLabelName("My Space");
Image img = new Image();
img.setImageResource(com.example.android.UnitTest.R.drawable.png);
settings.setLabelImage(img);
settings.setSelectedFillColor(selectedColor);
settings.setFillColor(unselectedColor);
settings.setOutlineColor(outlineColor);
controller.setStyleSettings(settings, space);
}
Nearby Spaces
You can find all spaces in a radius around a given position by using a Level
or an OuterArea
object. The position needs to be given as a geocoordinate, and the radius in meters. The returned list of spaces contains all spaces that fall within or intersect with the radius.
GeoCoordinate myLocation = new GeoCoordinante(60.43704, 22.21710);
List nearbySpaces = level.getNearbySpaces(myLocation, 10.0);
Area at Position
You can retrieve areas in a level by specifying a position. The area returned will either be a Space
or an OuterArea
. Similarly, you can also get spaces in an OuterArea
.
In case of nested spaces the innermost nested space encompassing the position is returned.
GeoCoordinate myLocation = new GeoCoordinante(60.43704, 22.21710);
Area area = level.getAreaAtPosition(myLocation);
Space space = outerArea.getSpaceAtPosition(myLocation);
Frequently Asked Questions
You can find additional information about 3D Venues in 3D Venues FAQ.