package com.google.maps.android;
import android.view.View;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Keeps track of collections of markers on the map. Delegates all Marker-related events to each
* collection's individually managed listeners.
* <p/>
* All marker operations (adds and removes) should occur via its collection class. That is, don't
* add a marker via a collection, then remove it via Marker.remove()
*/
public class MarkerManager implements GoogleMap.OnInfoWindowClickListener, GoogleMap.OnMarkerClickListener, GoogleMap.OnMarkerDragListener, GoogleMap.InfoWindowAdapter {
private final GoogleMap mMap;
private final Map<String, Collection> mNamedCollections = new HashMap<String, Collection>();
private final Map<Marker, Collection> mAllMarkers = new HashMap<Marker, Collection>();
public MarkerManager(GoogleMap map) {
this.mMap = map;
}
public Collection newCollection() {
return new Collection();
}
/**
* Create a new named collection, which can later be looked up by {@link #getCollection(String)}
* @param id a unique id for this collection.
*/
public Collection newCollection(String id) {
if (mNamedCollections.get(id) != null) {
throw new IllegalArgumentException("collection id is not unique: " + id);
}
Collection collection = new Collection();
mNamedCollections.put(id, collection);
return collection;
}
/**
* Gets a named collection that was created by {@link #newCollection(String)}
* @param id the unique id for this collection.
*/
public Collection getCollection(String id) {
return mNamedCollections.get(id);
}
@Override
public View getInfoWindow(Marker marker) {
Collection collection = mAllMarkers.get(marker);
if (collection != null && collection.mInfoWindowAdapter != null) {
return collection.mInfoWindowAdapter.getInfoWindow(marker);
}
return null;
}
@Override
public View getInfoContents(Marker marker) {
Collection collection = mAllMarkers.get(marker);
if (collection != null && collection.mInfoWindowAdapter != null) {
return collection.mInfoWindowAdapter.getInfoContents(marker);
}
return null;
}
@Override
public void onInfoWindowClick(Marker marker) {
Collection collection = mAllMarkers.get(marker);
if (collection != null && collection.mInfoWindowClickListener != null) {
collection.mInfoWindowClickListener.onInfoWindowClick(marker);
}
}
@Override
public boolean onMarkerClick(Marker marker) {
Collection collection = mAllMarkers.get(marker);
if (collection != null && collection.mMarkerClickListener != null) {
return collection.mMarkerClickListener.onMarkerClick(marker);
}
return false;
}
@Override
public void onMarkerDragStart(Marker marker) {
Collection collection = mAllMarkers.get(marker);
if (collection != null && collection.mMarkerDragListener != null) {
collection.mMarkerDragListener.onMarkerDragStart(marker);
}
}
@Override
public void onMarkerDrag(Marker marker) {
Collection collection = mAllMarkers.get(marker);
if (collection != null && collection.mMarkerDragListener != null) {
collection.mMarkerDragListener.onMarkerDrag(marker);
}
}
@Override
public void onMarkerDragEnd(Marker marker) {
Collection collection = mAllMarkers.get(marker);
if (collection != null && collection.mMarkerDragListener != null) {
collection.mMarkerDragListener.onMarkerDragEnd(marker);
}
}
/**
* Removes a marker from its collection.
*
* @param marker the marker to remove.
* @return true if the marker was removed.
*/
public boolean remove(Marker marker) {
Collection collection = mAllMarkers.get(marker);
return collection != null && collection.remove(marker);
}
public class Collection {
private final Set<Marker> mMarkers = new HashSet<Marker>();
private GoogleMap.OnInfoWindowClickListener mInfoWindowClickListener;
private GoogleMap.OnMarkerClickListener mMarkerClickListener;
private GoogleMap.OnMarkerDragListener mMarkerDragListener;
private GoogleMap.InfoWindowAdapter mInfoWindowAdapter;
public Collection() {
}
public Marker addMarker(MarkerOptions opts) {
Marker marker = mMap.addMarker(opts);
mMarkers.add(marker);
mAllMarkers.put(marker, Collection.this);
return marker;
}
public boolean remove(Marker marker) {
if (mMarkers.remove(marker)) {
mAllMarkers.remove(marker);
marker.remove();
return true;
}
return false;
}
public void clear() {
for (Marker marker : mMarkers) {
marker.remove();
mAllMarkers.remove(marker);
}
mMarkers.clear();
}
public java.util.Collection<Marker> getMarkers() {
return Collections.unmodifiableCollection(mMarkers);
}
public void setOnInfoWindowClickListener(GoogleMap.OnInfoWindowClickListener infoWindowClickListener) {
mInfoWindowClickListener = infoWindowClickListener;
}
public void setOnMarkerClickListener(GoogleMap.OnMarkerClickListener markerClickListener) {
mMarkerClickListener = markerClickListener;
}
public void setOnMarkerDragListener(GoogleMap.OnMarkerDragListener markerDragListener) {
mMarkerDragListener = markerDragListener;
}
public void setOnInfoWindowAdapter(GoogleMap.InfoWindowAdapter infoWindowAdapter) {
mInfoWindowAdapter = infoWindowAdapter;
}
}
}