package mil.nga.giat.mage.map.marker;
import android.content.Context;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.common.collect.MinMaxPriorityQueue;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.Point;
import java.util.Comparator;
import java.util.Date;
import java.util.Set;
import mil.nga.giat.mage.sdk.datastore.location.Location;
import mil.nga.giat.mage.sdk.datastore.location.LocationHelper;
import mil.nga.giat.mage.sdk.push.LocationPushIntentService;
/**
* Class uses a queue like structure to limit the Collection size. Size determined
* by LocationPushIntentService.minNumberOfLocationsToKeep
*
* @author wiedemanns
*
*/
public class MyHistoricalLocationMarkerCollection extends LocationMarkerCollection {
// use a queue like structure to limit the Collection size
protected MinMaxPriorityQueue<Location> locationQueue = MinMaxPriorityQueue.orderedBy(new Comparator<Location>() {
@Override
public int compare(Location lhs, Location rhs) {
return lhs.getTimestamp().compareTo(rhs.getTimestamp());
}
}).expectedSize(LocationPushIntentService.minNumberOfLocationsToKeep).create();
public MyHistoricalLocationMarkerCollection(Context context, GoogleMap map) {
super(context, map);
}
@Override
public boolean onMarkerClick(Marker marker) {
Location l = markerIdToLocation.get(marker.getId());
return (l != null);
}
@Override
public void add(Location l) {
final Geometry g = l.getGeometry();
if (g != null) {
// If I got an observation that I already have in my list
// remove it from the map and clean-up my collections
Marker marker = locationIdToMarker.remove(l.getId());
if (marker != null) {
markerIdToLocation.remove(marker.getId());
marker.remove();
}
Point point = g.getCentroid();
MarkerOptions options = new MarkerOptions().position(new LatLng(point.getY(), point.getX())).icon(LocationBitmapFactory.dotBitmapDescriptor(context, l, l.getUser())).visible(visible);
marker = markerCollection.addMarker(options);
locationIdToMarker.put(l.getId(), marker);
markerIdToLocation.put(marker.getId(), l);
locationQueue.add(l);
while (locationQueue.size() > LocationPushIntentService.minNumberOfLocationsToKeep) {
remove(locationQueue.poll());
}
removeOldMarkers();
}
}
@Override
public Date getLatestDate() {
return locationQueue.peekLast().getTimestamp();
}
@Override
public void refreshMarkerIcons() {
for (Marker m : markerCollection.getMarkers()) {
Location tl = markerIdToLocation.get(m.getId());
if (tl != null) {
boolean showWindow = m.isInfoWindowShown();
// make sure to set the Anchor after this call as well, because the size of the icon might have changed
m.setIcon(LocationBitmapFactory.dotBitmapDescriptor(context, tl, tl.getUser()));
m.setAnchor(0.5f, 1.0f);
if (showWindow) {
m.showInfoWindow();
}
}
}
}
/**
* Used to remove markers for locations that have been removed from the local datastore.
*/
@Override
public void removeOldMarkers() {
LocationHelper lh = LocationHelper.getInstance(context.getApplicationContext());
Set<Long> locationIds = locationIdToMarker.keySet();
for (Long locationId : locationIds) {
Location locationExists = new Location();
locationExists.setId(locationId);
if (!lh.exists(locationExists)) {
Marker marker = locationIdToMarker.remove(locationId);
if (marker != null) {
Location l = markerIdToLocation.remove(marker.getId());
locationQueue.remove(l);
marker.remove();
}
}
}
}
@Override
public void clear() {
super.clear();
locationQueue.clear();
}
}