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).

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 and zoom level. 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 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();

Animations

The map supports three types of animations when changing attributes:

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

// 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 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.

MapState and Listening for Map Transform Events

MapState is an object that is a composite of the 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.

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.