Displaying an Interactive Map with the Amazon Maps API v2

Your app can use the Amazon Maps API to display a map that the user can pan, zoom, and tilt. By default, the map handles user interaction in response to touch input.

Displaying the Map in a MapFragment

The simplest way to set up a Map is to define it in the XML file that specifies your app's layout. You can include the map in a MapFragment or SupportMapFragment (for devices earlier than API 12). Then make sure your Activity class references the layout.

For example, the following XML defines a MapFragment that can display an Amazon map. This XML can be placed anywhere within your layout:

<fragment
    android:id="@+id/mapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    class="com.amazon.geo.mapsv2.MapFragment" />

Then, set your Activity to display the fragment:

public class CoffeeActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);

        // Set the activity to display the fragment defined in activity_my_main.xml.
      setContentView(R.layout.activity_map_v2);
    }
}

Alternatively, you can define the fragment or view in code:

...
private MapFragment mMapFragment;
private static final String MAP_FRAGMENT_TAG = "mapfragment";

@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  // Set the activity to display the layout defined in programmatic_layout.xml.
  setContentView(R.layout.programmatic_layout);

  // Create a map fragment with default options
  MapFragment mMapFragment = MapFragment.newInstance();

  // Add the new fragment to the fragment manager. Note that
  // fragment_container is the ID for the frame layout defined in
  // programmatic_layout.xml
  getFragmentManager().beginTransaction()
        .add(R.id.fragment_container, mMapFragment, MAP_FRAGMENT_TAG).commit();
}

Setting Initial Map Options

You can define the initial settings for the map before displaying the map. For instance, you can set the map to initially display as a hybrid or satellite rather than the normal base map.

The initial map settings you can use are defined as part of the AmazonMapOptions class. How you set these depends on how you are adding your map to the app:

  • When defining your MapFragment or MapView in the layout XML, set the initial options in the XML with custom attributes.
  • When defining your MapFragment or MapView in code, pass the settings you want in an AmazonMapOptions object.

Defining Initial Settings in XML

To define map settings in the layout XML:

  1. Include the following XML namespace in the XML layout (note that the prefix can be any value; it does not need to be "map"):

    xmlns:map="http://schemas.android.com/apk/res-auto"
    
  2. Set the attributes you want. For example, use the map:amzn_mapType attribute to set the map type (normal, satellite, or hybrid).

    This example sets the map to satellite in the XML:

    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    map:amzn_mapType="amzn_satellite"
    class="com.amazon.geo.mapsv2.MapFragment"/>
    

The specific XML attributes are documented with the related AmazonMapOptions methods in the Maps API Reference.

Defining Initial Settings in Code

To define map settings in the code:

  1. Create an AmazonMapOptions object with the settings you want.

  2. Pass the AmazonMapOptions object to the MapFragment.newInstance() method.

This example sets the map to satellite in code:

// Create an AmazonMapOptions object to set the initial options on the map
AmazonMapOptions mapOpt = new AmazonMapOptions();
mapOpt.mapType(AmazonMap.MAP_TYPE_SATELLITE);

// Create a map fragment with options
MapFragment mMapFragment = MapFragment.newInstance(mapOpt);

Getting a Reference to the Map

AmazonMap is the primary class you use to interact with the map. You cannot instantiate this class. You must retrieve a reference to it from the fragment or view object with the .getMapAsync() method. Pass this method an object that implements the OnMapReadyCallback interface. When the map object is ready to be used, it is provided to you as an argument to the onMapReady() callback method. You can place your main map code within this method, or assign the object to a global variable to use elsewhere.

The AmazonMap object provided in the callback is never null, so you do not need to check it before using the object. Note that .getMapAsync() must be called on the main thread, and the callback is invoked on the main thread.

In the following example, the map is displayed in a MapFragment with the ID mapFragment:

private MapFragment mMapFragment;

...

// Extract a reference to the map fragment
  mMapFragment = (MapFragment) getFragmentManager().findFragmentById(
          R.id.mapFragment);

  // Call .getMapAsync() and pass it an object that implements
  // the OnMapReadyCallback interface.
  mMapFragment.getMapAsync(new OnMapReadyCallback() {
    @Override
    public void onMapReady(AmazonMap amazonMap) {
      // This method is called when the map is ready. The AmazonMap
      // object provided to this method will never be null.

      // Use the map reference to set UI settings and other options.
      amazonMap.getUiSettings().setZoomControlsEnabled(true);
      amazonMap.setTrafficEnabled(true);
    }
  });

Showing the User's Location and "Locate Me" Button

You can show the user's current location with the my location overlay.

public void onMapReady(AmazonMap amazonMap) {
  // Turn on the my location overlay. By default, this displays both the user's
  // location on the map and the "locate me" button to go to that location.
  amazonMap.setMyLocationEnabled(true);

  ...
}

By default, the "locate" button centers the map camera on the user's current location. You can change this behavior by setting an OnMyLocationButtonClickListener on the map. For example:

public void onMapReady(AmazonMap amazonMap) {
  // Turn on the my location overlay. By default, this displays both the user's
  // location on the map and the "locate me" button to go to that location.
  amazonMap.setMyLocationEnabled(true);

  // Set a listener to override the default "locate me" button behavior
  amazonMap.setOnMyLocationButtonClickListener(new AmazonMap.OnMyLocationButtonClickListener() {
      @Override
      public boolean onMyLocationButtonClick() {
          // Just display a message when the location button is clicked
          Toast.makeText(
                  MyLocationActivity.this,
                  "My location button clicked",
                  Toast.LENGTH_SHORT).show();

          // Return false so the default behavior (animating the camera to the
          // user's location) still occurs.
          return false;
      }
  });
}

Moving and Zooming the Camera

The map camera determines the area of the world shown by the map (latitude/longitude, zoom, bearing, and tilt). The current camera position is represented by a CameraPosition object; you can retrieve this object from the AmazonMap but cannot change the CameraPosition directly.

To change the part of the world shown by the map, create a CameraUpdate object representing the new position and pass it to one of the AmazonMap.moveCamera or AmazonMap.animateCamera methods. Use the methods in the CameraUpdateFactory class to create the CameraUpdate object; these methods let you specify which camera properties you want to change.

You can change any or all of the camera properties:

  • Target - the latitude and longitude position at the center of the map.
  • Zoom level - the scale of the area shown. As the number becomes larger, the camera moves closer to the earth to show less area but with more detail.
  • Bearing - the orientation of the map. Bearing is measured in degrees and works similar to compass bearings. For example, setting bearing to 0 orients the map with North at the top, while setting the bearing to 270 rotates the map to position due West at the top.
  • Tilt - the angle of the camera in relation to the earth, expressed in degrees.

For example, call CameraUpdateFactory.newLatLongZoom() to create a CameraUpdate that changes the camera latitude, longitude, and zoom level but leaves all other properties untouched:

// Define the latitude, longitude, and zoom level
private static final double COFFEE_LATITUDE = 47.624548;
private static final double COFFEE_LONGITUDE = -122.321006;
private static final LatLng COFFEE_LATLNG = new LatLng(COFFEE_LATITUDE, COFFEE_LONGITUDE);
private static final float COFFEE_ZOOM = 18.0F;

@Override
public void onMapReady(AmazonMap amazonMap) {
  // Animate the camera to the specified location and zoom level
  amazonMap.animateCamera(CameraUpdateFactory.newLatLngZoom(COFFEE_LATLNG, COFFEE_ZOOM));

...
}

Next Steps

For details about adding markers and other shapes to the map, see Drawing Markers and Objects on the Map.

For information on setting up your project to use the Amazon Maps API, see Configuring Your Project to use the Amazon Maps API.

For information about migrating your app from Google Maps, see Migrating an App from Google Maps v2.

For information about registering your app so you can display map tiles, as well as testing guidelines, see Registering and Testing Your Maps App.

 For a full sample app illustrating the Amazon Maps API, see Using the Amazon Maps API v2 Sample App

For a full reference to the classes and methods in the Amazon Maps API, see Amazon Maps API v2 Reference.

For additional help and information, see the Amazon Maps API Frequently Asked Questions