Venue Routing

The SDK for Android extends its 3D venue maps functionality to provide indoor routing. The SDK supports the following use cases:

Routing from store A to store B within a venue

Routing from an outside point to a point in a venue

Routing from a point in a venue to an outside point

Routing from a venue to another venue, with endpoints being a store or a point in a venue

Both on-line and off-line routing are supported. The classes that support this feature can be found in the com.here.android.mpa.venues3d and com.here.android.mpa.routing packages.

Note that if HERE has no routing information for an area between the outdoor part of the route and the venue entry point, the route visualization represents the unknown section of the route with a dotted line.

Routing Between Locations in a Venue

This section demonstrates how to calculate and display an indoor route by using a code example. The example is based on a scenario where a device user wants to find out how to reach another location in the same venue. In real life, the user would select the starting point and destination for the route by tapping on the map of the venue. However, for the sake of simplicity, the code below calculates a route by assuming the spaces are already selected.

Note: See the Getting Indoor Location Based on a Tap Point section for a code example of how to handle tap events to get a location for indoor venue routes.

The code below shows the implementation and is assumed to be part of an application. Previous initialization steps are assumed.

// Add the application as a listener for route-calculation-completed:
m_venueMapFragment.getRoutingController().addListener(m_activity);
// Route start and end set-up – they are spaces in a user-selected 3D venue.
// Set route start. You can choose an item from all spaces associated with the venue, or
// allow the application user to select an item and then use the callback onSpaceSelected().
SpaceLocation startLocation = new SpaceLocation(startSpace,
m_venueMapFragment.getVenueController(venue));
// Set route end.
SpaceLocation endLocation = new SpaceLocation(endSpace,
m_venueMapFragment.getVenueController(venue));
// Get route option objects
VenueRouteOptions venueRouteOptions = new VenueRouteOptions();
RouteOptions options = venueRouteOptions.getRouteOptions();
// Set route type, transport mode, number of routes to calculate:
options.setRouteType(Type.values()[m_routingOptionType.getSelectedItemPosition()]);
options.setTransportMode(
TransportMode.values()[m_routingOptionMode.getSelectedItemPosition()]);
options.setRouteCount(1);
// Set route options:
venueRouteOptions.setRouteOptions(options);
// Calculate route - this is an asynchronous call, once the calculation is done
// onCombinedRouteCompleted() is called – see below.
routingController.calculateCombinedRoute(startLocation, endLocation,
venueRouteOptions);
//...
// Callback invoked when the route calculation is done to display the route passed
// to it as an argument.
public void onCombinedRouteCompleted(CombinedRoute route) {
// Use RoutingController to show route:
m_venueMapFragment.getRoutingController().showRoute(route);

Routing Between Venues

You can perform routing between venues by using separate VenueController objects. For example, in the following, two different venues are used to retrieve VenueController objects:

// In this example m_startVenue and m_endVenue are assumed to be initialized
// with proper references.
SpaceLocation startLocation = new SpaceLocation(startSpace,
m_venueMapFragment.getVenueController(m_startVenue));
SpaceLocation endLocation = new SpaceLocation(endSpace,
m_venueMapFragment.getVenueController(m_endVenue));
}
// Other parts like in the previous example

Routing Using an Arbitrary Indoor Location

It is also possible to use an arbitrary indoor location that is not at a store or designated space as a route endpoint. An example of this kind of location is a point in a corridor. The next code snippet demonstrates the initialization of such an endpoint.

// Create a free point location to be used as a start location
// Here we assume that both current level and geo position is available in
// m_currentPosition. This can be obtained from, for example, some indoor positioning service.
LevelLocation startLocation = new LevelLocation(m_currentPosition.getLevel(),
m_currentPosition.getGeoCoordinate(),
m_venueMapFragment.getVenueController(venue));

The LevelLocation class extends BaseLocation and can be used as start or end location in calculateCombinedRoute() method of RoutingController, similar to SpaceLocation and OutdoorLocation.

The next example demonstrates route calculation from an indoor location, using type LevelLocation, to some location outside the venue, represented by an OutdoorLocation class.

// Create a free point location to be used as a start location
// Here we assume that both current level and geo position is available in
// m_currentPosition. This could be obtained from some indoor positioning
// service (not covered in this section).
LevelLocation startLocation = new LevelLocation(m_currentPosition.getLevel(),
m_currentPosition.getGeoCoordinate(),
m_venueMapFragment.getVenueController(venue));
// Create an outdoor location.
GeoCoordinate endPosition = new GeoCoordinate(52.517072, 13.411232);
OutdoorLocation endLocation = new OutdoorLocation(endPosition);
// Get route options objects
VenueRouteOptions venueRouteOptions = new VenueRouteOptions();
RouteOptions options = venueRouteOptions.getRouteOptions();
// Set route type, transport mode, number of routes to calculate:
options.setRouteType(Type.FASTEST);
options.setTransportMode(TransportMode.CAR);
options.setRouteCount(1);
// Set route options:
venueRouteOptions.setRouteOptions(options);
// Calculate route - this is an asynchronous call, once the calculation is done
// onCombinedRouteCompleted() is called – see below.
routingController.calculateCombinedRoute(startLocation, endLocation,
venueRouteOptions);
//...
// Callback invoked when the route calculation is done to display the route passed
// to it as an argument.
public void onCombinedRouteCompleted(CombinedRoute route) {
// Use RoutingController to show route:
m_venueMapFragment.getRoutingController().showRoute(route);
}

Venue Route Options

VenueRouteOptions encapsulate options used in indoor routing. It is possible to set many parameters related to visualization of the route line (for example color, line width, visibility of start and end flags) as well as parameters related to how the route is calculated (for example if elevators are allowed, if stairs are allowed, if corridors are preferred). The next example shows route calculation from one level to another level while avoiding stairs. Initialization steps for used variables are assumed.

// set up start and end locations, assuming they're on different levels
// ...
// Set venue route options, including flag to avoid stairs:
VenueRouteOptions venueRouteOptions = new VenueRouteOptions();
venueRouteOptions.setStairsAllowed(false);
venueRouteOptions.setCorridorsPreferred(true);
// Set other route options
RouteOptions options = venueRouteOptions.getRouteOptions();
options.setRouteType(Type.SHORTEST);
options.setTransportMode(TransportMode.PEDESTRIAN);
options.setRouteCount(1);
venueRouteOptions.setRouteOptions(options);
// Calculate route - this is an asynchronous call, once the calculation is done
// onCombinedRouteCompleted() is called
routingController.calculateCombinedRoute(startLocation, endLocation,
venueRouteOptions);
//...

Getting Indoor Location Based on a Tap Point

The next code example shows how to add a route point to an indoor route using the onTapEvent(PointF point) method of com.here.android.mpa.mapping.MapGesture.OnGestureListener.

Bounding Boxes for Parts of Venue Routes

Venue and outdoor route sections provide axis-aligned bounding boxes for the route. Axis-aligned bounding boxes are provided for individual route segments for each level. These methods return null if a route has no segment on the given level.