Drawing Markers and Objects on the Map with the Amazon Maps API v2

Once you have a reference to an AmazonMap object, you can draw objects on the map, such as markers indicating points of interest or destinations, lines representing routes, and other shapes. AmazonMap objects support markers, circles, lines (polylines), and polygons.

The basic steps to draw an object on the map are the same for all the different supported objects. You create an Options object for the item you want to draw, then pass that to the appropriate add method of the AmazonMap object.

For example, to place a marker on the map, you create a MarkerOptions object with the settings you want for the marker, then pass it to the AmazonMap.addMarker() method. All of the methods for drawing items (.addMarker(), .addCircle(), and so on) return a reference to the newly added item on the map, so you can update the properties of the object to change its appearance or behavior as necessary.

Adding Markers to the Map

A marker indicates a single point on a map. You place a marker at a specific geographic location by providing the latitude and longitude coordinates in a LatLng object. When creating the MarkerOptions for the new marker, you must at a minimum set the location for the new marker. Pass a LatLng to the MarkerOptions.position() method. Then pass the MarkerOptions object to AmazonMap.addMarker().

By default, clicking a marker on the map does the following:

  • Centers the map camera on the marker
  • Displays a simple info window if the marker has a title defined.
  • Displays a toolbar with options to open the Amazon Maps app and get turn-by-turn driving directions. Note that the toolbar option is enabled by default. You can disable or enable it with UiSettings.setMapToolbarEnabled().

To override the marker click behavior, implement the AmazonMap.OnMarkerClickListener interface.

The following example adds a default marker to the location specified by the LatLng referenced by point. It includes a simple title and snippet text that appears in the default info window.

private AmazonMap mMap;
private List<Marker> markers = new ArrayList<Marker>();

...

// Set marker options with the marker position, a simple title,
// and snippet text with the latitude / longitude location
MarkerOptions opt = new MarkerOptions()
    .position(point)
    .title("Marker at:")
    .snippet(point.toString());

// Add the marker to the map
Marker m = mMap.addMarker(opt);

// Keep track of the added markers in a list
markers.add(m);

Customizing the Marker Info Window

The default info window displays the marker’s title on the first line and the snippet on the second line. The snippet is displayed on one line and is not wrapped, and so long text may be cut off in the window.

You can provide your own formatting for info windows by setting a custom info window adapter. Implement the AmazonMap.InfoWindowAdapter interface and pass it to AmazonMap.setInfoWindowAdapter().

To customize the entire info window, return a View in .getInfoWindow() and return null in getInfoContents(). To customize just the contents of the info window but use the default frame, return a View from .getInfoContents() and return null from .getInfoWindow().

For example, the following InfoWindowAdapter implementation changes the info window contents. It assigns the marker’s title and snippet to TextViews defined in the custom_info_window layout. When a marker is clicked, the .getInfoContents() method is called:

class CustomInfoWindowContents implements InfoWindowAdapter{
    @Override
    public View getInfoContents(Marker marker) {
        // Return a view from this method to customize the
        // info window contents.

        // Inflate the view provided in the layout XML
        View v = getLayoutInflater().inflate(R.layout.custom_info_window, null);

        // Assign the title and snippet text from the marker
        // to the TextViews in the layout
        String markerTitle = marker.getTitle();
        String markerSnippet = marker.getSnippet();
        if (markerTitle != null) {
            TextView viewTitle = (TextView) v.findViewById(R.id.title);
            viewTitle.setText(markerTitle);

            if (markerSnippet != null){
                TextView viewInfo = (TextView) v.findViewById(R.id.info);
                viewInfo.setText(markerSnippet);
            }

            // Return the custom view
            return v;
        }
        else
            // The marker does not have a title. Return
            // null to use the normal marker click behavior
            return null;
    }

    @Override
    public View getInfoWindow(Marker marker) {
        // Return null to use getInfoContents
        return null;
    }
}

Call AmazonMap.setInfoWindowAdapater() to use the window adapter:

// Set the info window adapter
mMap.setInfoWindowAdapter(new CustomInfoWindowContents());

In the above example, the custom_info_window layout is defined in XML. This creates a layout with two text views. The TextView used for the marker title (title) is formatted with bold, purple text, while the TextView used for the snippet (info) is formatted with smaller gray text. The info TextView allows text to wrap.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"  >

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:singleLine="true"
        android:textColor="#661e89"
        android:textSize="16sp"
        android:textStyle="bold" />
    <TextView
        android:id="@+id/info"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="14sp"
        android:textColor="#ff7f7f7f" />
</LinearLayout>

Customizing the Marker Icon

Amazon Maps includes a default pin icon for map markers. You can change the color of this icon, or use a completely different image.

To customize the marker icon, you provide a BitmapDescriptor object. Use the methods of the BitmapDescriptorFactory class to create the BitmapDescriptor. The methods let you specify different sources for the bitmap. You can also create a default marker bitmap with a different color by passing a numeric value for the hue.

For example, the following code adds a marker with a custom color defined by generating a random number. The float passed to BitmapDescriptor.defaultMarker() to define the color must be between 0 and 360:

private AmazonMap mMap;

...

// Set marker options with the marker position
// and a custom marker color.

// Get a random number between 0 and 360
float hue = (float) Math.random() * 360;

MarkerOptions opt = new MarkerOptions()
    .position(point)
    .title("Random Color Marker")
    .snippet("Color: " + hue)
    .icon(BitmapDescriptorFactory.defaultMarker(hue));

// Add the marker to the map
Marker m = mMap.addMarker(opt);

To use a completely different bitmap, use the BitmapDescriptorFactory method appropriate for the source of the image. This example uses an image called customicon that has been added to the project’s resources as a Drawable:

private AmazonMap mMap;

...

// Set marker options with the marker position
// and a custom bitmap defined in resources

MarkerOptions opt = new MarkerOptions()
    .position(point)
    .title("Custom Bitmap Marker")
    .icon(BitmapDescriptorFactory.fromResource(R.drawable.customicon));

    // Add the marker to the map
    Marker m = mMap.addMarker(opt);

Drawing Other Shapes and Lines

Amazon Maps supports drawing other objects and shapes on the map, including polylines (a line connecting a series of points on the map), circles, and polygons. As with markers, use an Options object to define the properties of the item, and then call the appropriate .add method on the AmazonMap object to draw the object.

  • Use PolylineOptions to define the properties for a line connecting a series of points on the map. At a minimum, provide the list of LatLng points to be connected by the line. Set PolylineOptions.geodesic() to draw each line segment as a curve that corresponds to the shortest path between the points.
  • Use CircleOptions to define the properties for a circle. At a minimum, provide the LatLng representing the center of the circle and the radius in meters.
  • Use PolygonOptions to define the properties for a polygon. At a minimum, provide the list of LatLng points to be connected by the shape. Note that a valid polygon must have at least three points. If the line segments to connect the points overlap, the lines are still drawn, but the shape is not filled in. Set PolygonOptions.geodesic() to draw each polygon segment as a curve that corresponds to the shortest path between the points.

Unlike markers, the lines and shapes do not have info windows and do not listen for clicks once they are drawn on the map.

The following example uses an existing list of markers to define a set of LatLng points, draws a line connecting the markers on the map, and then removes the markers.

private AmazonMap mMap;
private List<Marker> markers = new ArrayList<Marker>();
private List<Polyline> polylines = new ArrayList<Polyline>();

...

// Get all the LatLng points from the markers
ArrayList<LatLng> points = new ArrayList<LatLng>(markers.size());
for (Marker m : markers) {
    points.add(m.getPosition());
}

// Create the PolylineOptions. This creates a red line
// between the specified points.
PolylineOptions opt = new PolylineOptions()
    .addAll(points)
    .color(Color.RED);

// Add the new line. Keep track of the added polylines
// in a list.
Polyline p = mMap.addPolyline(opt);
polylines.add(p);

// Remove the markers used to create the line.
clearMarkers();

Updating Objects Drawn on the Map

Changing the Options object for an item already drawn on the map has no effect on the object. To change the attributes of a marker, shape, or line, use the setter methods for the object.

For example, to change the properties on an existing Marker, use methods on the Marker itself.

The following example assumes that all references to the previously-added markers were saved into an ArrayList of Marker objects. It changes the color, title text, and snippet text for all of the markers in the list.

private AmazonMap mMap;
private List<Marker> markers = new ArrayList<Marker>();

...

// Get a random number between 0 and 360
float newHue = (float) Math.random() * 360;

// Change the color for each markers in the list
for (Marker m : markers){
    m.setIcon(BitmapDescriptorFactory.defaultMarker(newHue));

    // Update the snippet to note the new color
    m.setTitle("Random Color Marker");
    m.setSnippet("New Color: " + newHue);
}

Clearing the Map

You can clear all drawn objects off the map with the AmazonMap.clear() method. Note that this removes all items (markers, circles, polygons, and so on). If you want to clear items selectively, call the .remove() method for the specific item to remove from the map.

Next Steps

For details about displaying a map and retrieving a reference to the map, see Displaying an Interactive Map with the Amazon Maps API v2.

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

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 Amazon Maps API v2 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.