HERE Android SDK Developer's Guide

Maps

The core feature of the HERE Android SDK is Maps. The key concepts covered in this section include adding a map to an Android application, changing the location displayed by the map and its various properties. The classes covered include MapFragment and Map. MapFragment and Map are parts of a Model-View-Controller (MVC) pattern where the Model is the Map, and the View is the MapFragment. The MapFragment is a standard Android Fragment derived component. You can create a controller class to coordinate all interactions using custom logic.

The first step to integrate a map into an application is to insert a MapFragment to the view layout of the application. This is accomplished by adding com.here.android.mpa.mapping.MapFragment to the Android XML layout file as follows.


<!-- Example fragment. This can be integrated and annotated
    like any other android Fragment or View widget -->
<fragment
  class="com.here.android.mpa.mapping.MapFragment"
  android:id="@+id/mapfragment"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"/>

The MapFragment class handles all user interactions such as panning, tapping or pinching, as well as other standard HERE SDK touch gestures documented in MapGestures.

Initializing MapFragment

After adding the MapFragment to the layout, the fragment must be initialized. The MapFragment initialization is processed asynchronously. During initialization, the MapEngine is initialized to create an instance of Map that is associated with the MapFragment. The MapFragment.init(OnEngineInitListener) method takes in an OnEngineInitListener input parameter to signal the caller when initialization is completed and if it was successful. The MapFragment also initializes a MapEngine instance and creates a Map object associated with the MapFragment. The following code illustrates the basic initialization flow when an Activity is created.


@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  // Search for the Map Fragment
  final MapFragment mapFragment = (MapFragment)
     getFragmentManager().findFragmentById(R.id.mapfragment);
  // initialize the Map Fragment and
  // retrieve the map that is associated to the fragment
  mapFragment.init(new OnEngineInitListener() {
    @Override
    public void onEngineInitializationCompleted(
        OnEngineInitListener.Error error) {
      if (error == OnEngineInitListener.Error.NONE) {
        // now the map is ready to be used
        Map map = mapFragment.getMap();
        // ...
      } else {
        System.out.println("ERROR: Cannot initialize MapFragment");
      }
    }
  });
}
Note: For performance reasons, com.here.android.mpa.mapping.MapFragment has set Fragment.setRetainInstance(boolean) to true, and therefore onCreate(Bundle) is not called again when Activity is re-created (for example, after a zoom-level change).
Note: The MapFragment class provides an asynchronous method, getScreenCapture(OnScreenCaptureListener), for creating map snapshots of the currently visible MapFragment area. When a snapshot has been created, an event callback to OnScreenCaptureListener occurs, and the screenshot is provided as an android.graphics.Bitmap object. This method of screen capture only works if the view is in the foreground and it is rendering. If a background or viewless screen capture is required, use MapOffscreenRenderer.

Working with Map

Once the MapFragment is initialized, you get the Map associated with the MapFragment through MapFragment.getMap(). The Map class represents the virtual model of the world in a digital format. Key attributes of the Map include the center GeoCoordinate, zoom level, orientation, and tilt. For example, the following code snippet illustrates how to use Map.setCenter(GeoCoordinate, Map.Animation) to render the Map at Vancouver, Canada.


// map fragment has been successfully initialized
...

// now the map is ready to be used
Map map = mapFragment.getMap();

// Set the map center to Vancouver, Canada.
map.setCenter(new GeoCoordinate(49.196261,
  -123.004773), Map.Animation.NONE);
...

In the preceding code:

  • The GeoCoordinate for the map center is created by a call to the new GeoCoordinate(double, double) constructor.
  • When setting the center of a map, there is an option either to animate the change or to suppress animation by passing the constant Map.Animation.NONE as the relevant parameter.

Map Center , Tilt, Orientation, and Zoom

Here are examples of setting and getting Map attributes:

Map Center

The center of the Map is a GeoCoordinate location that your Map is focused on. You can move a Map by redefining its center GeoCoordinate:

// Move the map to London.
map.setCenter(new GeoCoordinate(51.51,-0.11),
  Map.Animation.NONE );

// Get the current center of the Map
GeoCoordinate coordinate = map.getCenter();

Zoom Level

The size of the geographical area displayed by Map can be controlled by changing the zoom level. The zoom level ranges from getMinZoomLevel() to getMaxZoomLevel(), with the minimum value displaying the entire world. The following code sets the zoom level to the median zoom level.

// Get the maximum,minimum zoom level.
double maxZoom = map.getMaxZoomLevel();
double minZoom = map.getMinZoomLevel();

// Set the zoom level to the median (10).
map.setZoomLevel((maxZoom + minZoom)/2);

// Get the zoom level back
double zoom = map.getZoomLevel();

Orientation

The map can be orientated in any direction. By default, the orientation is in a true North position. The following code changes the orientation to South-up.

// Rotate 180 degrees.
map.setOrientation(180);

// Get the orientation, should be 180.
float orientation = map.getOrientation();

Tilt

The map can be tilted and rendered in a three-dimensional perspective. By default, the tilt is completely flat. You can retrieve the minimum and maximum possible tilt values by calling getMinTilt() and getMaxTilt()

// Set the tilt to 45 degrees
map.setTilt(45);

// Get the tilt
float tilt = map.getTilt();

Animations

The map supports three types of animations when changing attributes:

  • Map.Animation.NONE
  • Map.Animation.LINEAR
  • Map.Animation.BOW

// Move to Vancouver using bow animation
map.setCenter(new GeoCoordinate(49.0,-123.0),
  Map.Animation.LINEAR);
Note: If the map changes size or the app comes to the foreground while Map.Animation.LINEAR or Map.Animation.BOW is being used in a Map attribute setter method, then the animation aborts, and the transition appears to fail. To avoid this behavior, use the Map.Animation.NONE animation type or wait until the map is stable before performing the transition operation.

Setting Multiple Attributes

Map.setCenter(GeoCoordinate point, Animation animation, double level, float orientation, float tilt) is an extended API provided for changing one or more attributes at the same time. The zoom level, tilt and perspective can be preserved and unchanged using Map.MOVE_PRESERVE_ZOOM_LEVEL, Map.MOVE_PRESERVE_ORIENTATION, Map.MOVE_PRESERVE_TILT respectively.

// Move to Vancouver using a bow animation, zoom level 17, 180
//degree orientation and 45 degree tilt.
map.setCenter(new GeoCoordinate(49.0,-123.0),
  Map.Animation.BOW, 17.0d, 180, 45);

Map Projection Mode

By default, the map is set to a globe projection mode. You can change it to use Mercator projection by calling setProjectionMode(Projection). For example:
map.setProjectionMode(Map.Projection.MERCATOR);
It may be useful to set the projection modes when you need to predictably display certain types of map information, such as custom raster tiles.
Figure 1. Globe Projection
Figure 2. Mercator Projection

MapState and Listening for Map Transform Events

MapState is an object that is a composite of the tilt, orientation, zoom level and center map attributes. Your application can listen for updates to the MapState by using an OnTransformListener.

Map transform events are triggered by any operation that causes the MapState to change. These operations include user interaction (for example, map gestures) as well as programmatic calls to the Map (for example, map.setCenter(GeoCoordinate, MapAnimation)). The onMapTransformStart() method is called before MapState begins to change, while the onMapTransformEnd(MapState) method is called after the MapState returns to a steady value. Because of this, there can be a significant amount of time between the two callbacks in cases such as animated map movement events and continuous user interaction.

The following code is an example of registering an OnTransformListener to listen for map transform events:

map.addTransformListener(new OnTransformListener() {
  @Override
  public void onMapTransformStart() {
    // map transform is about to start
  }
  @Override
  public void onMapTransformEnd(MapState mapState) {
    // map transform has come to an end
  }
});
If you need to update UI widgets as the MapState changes between these two callbacks, the recommended approach is to trigger a Runnable when onMapTransformStart() is called, which periodically checks (at no more than 30 frames per second) the current map state via map.getMapState() and updates the UI widgets accordingly. This Runnable can then be canceled upon a call to onMapTransformEnd(MapState). An Android Handler can be used to trigger these Runnable objects.
Note: Do not update UI widgets in MapRenderListener.onPostDraw(boolean, long), as this method is frequently called.

Pedestrian Features

By default, icons that indicate pedestrian access features (such as stairs or escalators) are not displayed on the map. To display a pedestrian feature on the map view, call the Map.setPedestrianFeaturesVisible(EnumSet) method with the desired set of PedestrianFeature. To find out whether a feature type is enabled, call the Map.getPedestrianFeaturesVisible() method.

Figure 3. Pedestrian Feature Icons

Safety Spots

Speed cameras and traffic-light cameras are also known as safety spots in the HERE SDK. Similar to pedestrian features, icons that indicate safety spots are not displayed on the map by default. To display safety spots, set the Map.setSafetySpotsVisible(boolean) to true. To find out whether safety spots are enabled, call the areSafetySpotsVisible() method.

Individual safety spots icons can be selected on the map by using SafetySpotObject, which is a subclass of MapProxyObject. Each SafetySpotObject contains a reference to a corresponding SafetySpotInfo object that contains the location and other properties about the camera. For more information on selecting map proxy objects, refer to Objects and Interaction.

You cannot use this account to purchase a commercial plan on Developer Portal, as it is already associated to plans with different payment methods.

To purchase a commercial plan on Developer Portal, please register for or sign in with a different HERE Account.

Something took longer than expected.

The project should be available soon under your projects page.

Sorry, our services are not available in this region.

Something seems to have gone wrong. Please try again later.

We've detected that your account is set to Australian Dollars (AUD).
Unfortunately, we do not offer checkouts in AUD anymore.
You can continue using your current plan as normal, but to subscribe to one of our new plans,
please register for a new HERE account or contact us for billing questions on selfservesupport@here.com.