package com.papagiannis.tuberun.fetchers;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;
import android.location.Location;
import com.papagiannis.tuberun.Locatable;
public abstract class NearbyFetcher<C extends Locatable> extends Fetcher{
private static final long serialVersionUID = 1L;
/*
* A max-heap based implementation of the nearest neighbours algorithm.
*/
protected ArrayList<C> getNearbyStations(final Location myLocation,
ArrayList<? extends C> allItems, int maxStations) {
if (allItems==null || allItems.size()==0) return new ArrayList<C>();
PriorityQueue<C> result=new PriorityQueue<C>(maxStations, new Comparator<C>() {
//This is a max heap, the furthest away stays on top
@Override
public int compare(C lhs, C rhs) {
float leftDist=myLocation.distanceTo(lhs.getLocation());
float rightDist=myLocation.distanceTo(rhs.getLocation());
if (Math.abs(leftDist-rightDist)<1) {
return 0;
}
else if (leftDist < rightDist)
return 1;
else return -1;
}
});
for (C l : allItems) {
if (result.size()<maxStations) {
result.add(l);
continue;
}
C max=result.peek();
float maxDistance = myLocation.distanceTo(max.getLocation());
float thisDistance = myLocation.distanceTo(l.getLocation());
if (thisDistance<maxDistance) {
result.add(l);
result.poll();
}
}
//transform the max-heap to a min-first array
ArrayList<C> res=new ArrayList<C>(maxStations);
while (!result.isEmpty()) {
res.add(result.poll());
}
for (int i=0 ; i < maxStations/2 ; i++) {
C tmp=res.get(i);
res.set(i, res.get(maxStations-i-1));
res.set(maxStations-i-1, tmp);
}
return res;
}
protected ArrayList<C> getNearbyStations(Location my_location,
ArrayList<? extends C> all_stations) {
return getNearbyStations(my_location, all_stations, 6);
}
}