package de.blau.android.tasks;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import de.blau.android.App;
import de.blau.android.Map;
import de.blau.android.R;
import de.blau.android.osm.BoundingBox;
import de.blau.android.osm.Server;
import de.blau.android.resources.DataStyle;
import de.blau.android.util.GeoMath;
import de.blau.android.views.IMapView;
import de.blau.android.views.overlay.MapViewOverlay;
public class MapOverlay extends MapViewOverlay {
/** viewbox needs to be less wide than this for displaying bugs, just to avoid querying the whole world for bugs */
private static final int TOLERANCE_MIN_VIEWBOX_WIDTH = 40000 * 32;
private Bitmap cachedIconClosed;
private float w2closed = 0f;
private float h2closed = 0f;
private Bitmap cachedIconOpen;
private float w2open = 0f;
private float h2open = 0f;
private Bitmap cachedIconChanged;
private float w2changed = 0f;
private float h2changed = 0f;
/** Map this is an overlay of. */
private final Map map;
/** Bugs visible on the overlay. */
private TaskStorage tasks = App.getTaskStorage();
public MapOverlay(final Map map, Server s) {
this.map = map;
}
@Override
public boolean isReadyToDraw() {
return !map.getPrefs().areBugsEnabled() || map.getOpenStreetMapTilesOverlay().isReadyToDraw();
}
@Override
protected void onDraw(Canvas c, IMapView osmv) {
if (map.getPrefs().areBugsEnabled()) {
// the idea is to have the circles a bit bigger when zoomed in, not so
// big when zoomed out
// currently we don't adjust the icon size for density final float radius = Density.dpToPx(1.0f + osmv.getZoomLevel() / 2.0f);
BoundingBox bb = osmv.getViewBox();
//
int w = map.getWidth();
int h = map.getHeight();
ArrayList<Task> taskList = tasks.getTasks(bb);
if (taskList != null) {
Set<String>taskFilter = map.getPrefs().taskFilter();
for (Task t : taskList) {
// filter
if (t instanceof Note && !taskFilter.contains(t.bugFilterKey())) {
continue;
} else if (t instanceof OsmoseBug && !taskFilter.contains(t.bugFilterKey())) {
continue;
}
float x = GeoMath.lonE7ToX(w , bb, t.getLon());
float y = GeoMath.latE7ToY(h, w, bb, t.getLat());
if (t.isClosed()) {
if (cachedIconClosed == null) {
cachedIconClosed = BitmapFactory.decodeResource(map.getContext().getResources(), R.drawable.bug_closed);
w2closed = cachedIconClosed.getWidth()/2f;
h2closed = cachedIconClosed.getHeight()/2f;
}
c.drawBitmap(cachedIconClosed, x-w2closed, y-h2closed, null);
} else if (t.isNew() || t.hasBeenChanged()){
if (cachedIconChanged == null) {
cachedIconChanged = BitmapFactory.decodeResource(map.getContext().getResources(), R.drawable.bug_changed);
w2changed = cachedIconChanged.getWidth()/2f;
h2changed = cachedIconChanged.getHeight()/2f;
}
c.drawBitmap(cachedIconChanged, x-w2changed, y-h2changed, null);
} else{
if (cachedIconOpen == null) {
cachedIconOpen = BitmapFactory.decodeResource(map.getContext().getResources(), R.drawable.bug_open);
w2open = cachedIconOpen.getWidth()/2f;
h2open = cachedIconOpen.getHeight()/2f;
}
c.drawBitmap(cachedIconOpen, x-w2open, y-h2open, null);
}
}
}
}
}
@Override
protected void onDrawFinished(Canvas c, IMapView osmv) {
// do nothing
}
/**
* Given screen coordinates, find all nearby bugs.
* @param x Screen X-coordinate.
* @param y Screen Y-coordinate.
* @param viewBox Map view box.
* @return List of bugs close to given location.
*/
public List<Task> getClickedTasks(final float x, final float y, final BoundingBox viewBox) {
List<Task> result = new ArrayList<Task>();
if (map.getPrefs().areBugsEnabled()) {
final float tolerance = DataStyle.getCurrent().nodeToleranceValue;
ArrayList<Task> taskList = tasks.getTasks(viewBox);
if (taskList != null) {
Set<String>taskFilter = map.getPrefs().taskFilter();
for (Task t : taskList) {
// filter
if (t instanceof Note && !taskFilter.contains(t.bugFilterKey())) {
continue;
} else if (t instanceof OsmoseBug && !taskFilter.contains(t.bugFilterKey())) {
continue;
}
int lat = t.getLat();
int lon = t.getLon();
float differenceX = Math.abs(GeoMath.lonE7ToX(map.getWidth(), viewBox, lon) - x);
float differenceY = Math.abs(GeoMath.latE7ToY(map.getHeight(), map.getWidth(), viewBox, lat) - y);
if ((differenceX <= tolerance) && (differenceY <= tolerance)) {
if (Math.hypot(differenceX, differenceY) <= tolerance) {
result.add(t);
}
}
}
}
// For debugging the OSB editor when the OSB site is down:
//result.add(new Bug(GeoMath.yToLatE7(map.getHeight(), viewBox, y), GeoMath.xToLonE7(map.getWidth(), viewBox, x), true));
}
return result;
}
}