aboutsummaryrefslogtreecommitdiffstats
path: root/src/cgeo/geocaching/mapcommon
diff options
context:
space:
mode:
Diffstat (limited to 'src/cgeo/geocaching/mapcommon')
-rw-r--r--src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java9
-rw-r--r--src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java33
-rw-r--r--src/cgeo/geocaching/mapcommon/cgMapOverlay.java124
-rw-r--r--src/cgeo/geocaching/mapcommon/cgOverlayScale.java12
-rw-r--r--src/cgeo/geocaching/mapcommon/cgeomap.java22
5 files changed, 128 insertions, 72 deletions
diff --git a/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java b/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java
index 41739e2..4e0379c 100644
--- a/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java
+++ b/src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java
@@ -6,6 +6,8 @@ import android.graphics.drawable.Drawable;
import cgeo.geocaching.mapinterfaces.ItemizedOverlayImpl;
import cgeo.geocaching.mapinterfaces.MapProjectionImpl;
import cgeo.geocaching.mapinterfaces.MapViewImpl;
+import cgeo.geocaching.mapinterfaces.OverlayBase;
+import cgeo.geocaching.mapinterfaces.OverlayImpl;
import cgeo.geocaching.mapinterfaces.OverlayItemImpl;
/**
@@ -14,7 +16,7 @@ import cgeo.geocaching.mapinterfaces.OverlayItemImpl;
* @author rsudev
*
*/
-public abstract class ItemizedOverlayBase {
+public abstract class ItemizedOverlayBase implements OverlayBase {
private ItemizedOverlayImpl ovlImpl;
@@ -50,6 +52,11 @@ public abstract class ItemizedOverlayBase {
MapProjectionImpl projection, byte drawZoomLevel) {
ovlImpl.superDrawOverlayBitmap(canvas, drawPosition, projection, drawZoomLevel);
}
+
+ @Override
+ public OverlayImpl getOverlayImpl() {
+ return ovlImpl;
+ }
public abstract OverlayItemImpl createItem(int index);
diff --git a/src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java b/src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java
index cbf065c..b8c8723 100644
--- a/src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java
+++ b/src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java
@@ -6,10 +6,11 @@ import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
+import android.graphics.Matrix;
import android.graphics.Paint;
-import android.graphics.Paint.Style;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Point;
+import android.graphics.Paint.Style;
import android.location.Location;
import cgeo.geocaching.R;
import cgeo.geocaching.cgBase;
@@ -19,6 +20,7 @@ import cgeo.geocaching.mapinterfaces.MapFactory;
import cgeo.geocaching.mapinterfaces.MapProjectionImpl;
import cgeo.geocaching.mapinterfaces.MapViewImpl;
import cgeo.geocaching.mapinterfaces.OverlayBase;
+import cgeo.geocaching.mapinterfaces.OverlayImpl;
public class cgMapMyOverlay implements OverlayBase {
private cgSettings settings = null;
@@ -31,8 +33,8 @@ public class cgMapMyOverlay implements OverlayBase {
private Point center = new Point();
private Point left = new Point();
private Bitmap arrow = null;
- private int widthArrow = 0;
- private int heightArrow = 0;
+ private int widthArrowHalf = 0;
+ private int heightArrowHalf = 0;
private PaintFlagsDrawFilter setfil = null;
private PaintFlagsDrawFilter remfil = null;
private Location historyRecent = null;
@@ -41,11 +43,13 @@ public class cgMapMyOverlay implements OverlayBase {
private Point historyPointP = new Point();
private Activity activity;
private MapFactory mapFactory = null;
+ private OverlayImpl ovlImpl = null;
- public cgMapMyOverlay(cgSettings settingsIn, Activity activity) {
+ public cgMapMyOverlay(cgSettings settingsIn, Activity activity, OverlayImpl ovlImpl) {
settings = settingsIn;
this.activity = activity;
this.mapFactory = settings.getMapFactory();
+ this.ovlImpl = ovlImpl;
}
public void setCoordinates(Location coordinatesIn) {
@@ -184,22 +188,29 @@ public class cgMapMyOverlay implements OverlayBase {
if (arrow == null) {
arrow = BitmapFactory.decodeResource(activity.getResources(), R.drawable.my_location_chevron);
- widthArrow = arrow.getWidth();
- heightArrow = arrow.getHeight();
+ widthArrowHalf = arrow.getWidth() / 2;
+ heightArrowHalf = arrow.getHeight() / 2;
}
int marginLeft;
int marginTop;
- marginLeft = center.x - (widthArrow / 2);
- marginTop = center.y - (heightArrow / 2);
+ marginLeft = center.x - widthArrowHalf;
+ marginTop = center.y - heightArrowHalf;
+
+ Matrix matrix = new Matrix();
+ matrix.setRotate(heading.floatValue(), widthArrowHalf, heightArrowHalf);
+ matrix.postTranslate(marginLeft, marginTop);
- canvas.rotate(heading.floatValue(), center.x, center.y);
- canvas.drawBitmap(arrow, marginLeft, marginTop, null);
- canvas.rotate(-(heading.floatValue()), center.x, center.y);
+ canvas.drawBitmap(arrow, matrix, null);
canvas.setDrawFilter(remfil);
//super.draw(canvas, mapView, shadow);
}
+
+ @Override
+ public OverlayImpl getOverlayImpl() {
+ return this.ovlImpl;
+ }
} \ No newline at end of file
diff --git a/src/cgeo/geocaching/mapcommon/cgMapOverlay.java b/src/cgeo/geocaching/mapcommon/cgMapOverlay.java
index 80eba5a..d3f7c00 100644
--- a/src/cgeo/geocaching/mapcommon/cgMapOverlay.java
+++ b/src/cgeo/geocaching/mapcommon/cgMapOverlay.java
@@ -10,9 +10,9 @@ import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
-import android.graphics.Paint.Style;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Point;
+import android.graphics.Paint.Style;
import android.location.Location;
import android.text.Html;
import android.util.Log;
@@ -74,10 +74,16 @@ public class cgMapOverlay extends ItemizedOverlayBase implements OverlayBase {
item.setMarker(boundCenterBottom(item.getMarker(0)));
}
- items = new ArrayList<CacheOverlayItemImpl>(itemsPre);
-
- setLastFocusedItemIndex(-1); // to reset tap during data change
- populate();
+ // ensure no interference between the draw and content changing routines
+ getOverlayImpl().lock();
+ try {
+ items = new ArrayList<CacheOverlayItemImpl>(itemsPre);
+
+ setLastFocusedItemIndex(-1); // to reset tap during data change
+ populate();
+ } finally {
+ getOverlayImpl().unlock();
+ }
}
public boolean getCircles() {
@@ -107,51 +113,56 @@ public class cgMapOverlay extends ItemizedOverlayBase implements OverlayBase {
private void drawInternal(Canvas canvas, MapProjectionImpl projection) {
- if (displayCircles) {
- if (blockedCircle == null) {
- blockedCircle = new Paint();
- blockedCircle.setAntiAlias(true);
- blockedCircle.setStrokeWidth(1.0f);
- blockedCircle.setARGB(127, 0, 0, 0);
- blockedCircle.setPathEffect(new DashPathEffect(new float[] {3,2}, 0));
- }
-
- if (setfil == null) setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG);
- if (remfil == null) remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0);
-
- canvas.setDrawFilter(setfil);
-
- for (CacheOverlayItemImpl item : items) {
- final cgCoord itemCoord = item.getCoord();
- float[] result = new float[1];
-
- Location.distanceBetween(itemCoord.latitude, itemCoord.longitude, itemCoord.latitude, itemCoord.longitude + 1, result);
- final float longitudeLineDistance = result[0];
-
- GeoPointImpl itemGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)(itemCoord.longitude * 1e6));
- GeoPointImpl leftGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)((itemCoord.longitude - 161 / longitudeLineDistance) * 1e6));
-
- projection.toPixels(itemGeo, center);
- projection.toPixels(leftGeo, left);
- int radius = center.x - left.x;
-
- final String type = item.getType();
- if (type == null || "multi".equals(type) || "mystery".equals(type) || "virtual".equals(type)) {
- blockedCircle.setColor(0x66000000);
- blockedCircle.setStyle(Style.STROKE);
- canvas.drawCircle(center.x, center.y, radius, blockedCircle);
- } else {
- blockedCircle.setColor(0x66BB0000);
- blockedCircle.setStyle(Style.STROKE);
- canvas.drawCircle(center.x, center.y, radius, blockedCircle);
-
- blockedCircle.setColor(0x44BB0000);
- blockedCircle.setStyle(Style.FILL);
- canvas.drawCircle(center.x, center.y, radius, blockedCircle);
+ // prevent content changes
+ getOverlayImpl().lock();
+ try {
+ if (displayCircles) {
+ if (blockedCircle == null) {
+ blockedCircle = new Paint();
+ blockedCircle.setAntiAlias(true);
+ blockedCircle.setStrokeWidth(1.0f);
+ blockedCircle.setARGB(127, 0, 0, 0);
+ blockedCircle.setPathEffect(new DashPathEffect(new float[] {3,2}, 0));
}
+
+ if (setfil == null) setfil = new PaintFlagsDrawFilter(0, Paint.FILTER_BITMAP_FLAG);
+ if (remfil == null) remfil = new PaintFlagsDrawFilter(Paint.FILTER_BITMAP_FLAG, 0);
+
+ canvas.setDrawFilter(setfil);
+
+ for (CacheOverlayItemImpl item : items) {
+ final cgCoord itemCoord = item.getCoord();
+ float[] result = new float[1];
+
+ Location.distanceBetween(itemCoord.latitude, itemCoord.longitude, itemCoord.latitude, itemCoord.longitude + 1, result);
+ final float longitudeLineDistance = result[0];
+
+ GeoPointImpl itemGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)(itemCoord.longitude * 1e6));
+ GeoPointImpl leftGeo = mapFactory.getGeoPointBase((int)(itemCoord.latitude * 1e6), (int)((itemCoord.longitude - 161 / longitudeLineDistance) * 1e6));
+
+ projection.toPixels(itemGeo, center);
+ projection.toPixels(leftGeo, left);
+ int radius = center.x - left.x;
+
+ final String type = item.getType();
+ if (type == null || "multi".equals(type) || "mystery".equals(type) || "virtual".equals(type)) {
+ blockedCircle.setColor(0x66000000);
+ blockedCircle.setStyle(Style.STROKE);
+ canvas.drawCircle(center.x, center.y, radius, blockedCircle);
+ } else {
+ blockedCircle.setColor(0x66BB0000);
+ blockedCircle.setStyle(Style.STROKE);
+ canvas.drawCircle(center.x, center.y, radius, blockedCircle);
+
+ blockedCircle.setColor(0x44BB0000);
+ blockedCircle.setStyle(Style.FILL);
+ canvas.drawCircle(center.x, center.y, radius, blockedCircle);
+ }
+ }
+ canvas.setDrawFilter(remfil);
}
-
- canvas.setDrawFilter(remfil);
+ } finally {
+ getOverlayImpl().unlock();
}
}
@@ -170,7 +181,22 @@ public class cgMapOverlay extends ItemizedOverlayBase implements OverlayBase {
}
waitDialog.show();
- CacheOverlayItemImpl item = items.get(index);
+ CacheOverlayItemImpl item = null;
+
+ // prevent concurrent changes
+ getOverlayImpl().lock();
+ try {
+ if (index < items.size()) {
+ item = items.get(index);
+ }
+ } finally {
+ getOverlayImpl().unlock();
+ }
+
+ if (item == null) {
+ return false;
+ }
+
cgCoord coordinate = item.getCoord();
if (coordinate.type != null && coordinate.type.equalsIgnoreCase("cache") && coordinate.geocode != null && coordinate.geocode.length() > 0) {
diff --git a/src/cgeo/geocaching/mapcommon/cgOverlayScale.java b/src/cgeo/geocaching/mapcommon/cgOverlayScale.java
index 4aae3d5..93de894 100644
--- a/src/cgeo/geocaching/mapcommon/cgOverlayScale.java
+++ b/src/cgeo/geocaching/mapcommon/cgOverlayScale.java
@@ -14,6 +14,7 @@ import cgeo.geocaching.mapinterfaces.GeoPointImpl;
import cgeo.geocaching.mapinterfaces.MapProjectionImpl;
import cgeo.geocaching.mapinterfaces.MapViewImpl;
import cgeo.geocaching.mapinterfaces.OverlayBase;
+import cgeo.geocaching.mapinterfaces.OverlayImpl;
public class cgOverlayScale implements OverlayBase {
private cgSettings settings = null;
@@ -26,9 +27,11 @@ public class cgOverlayScale implements OverlayBase {
private double distance = 0d;
private double distanceRound = 0d;
private String units = null;
+ private OverlayImpl ovlImpl=null;
- public cgOverlayScale(Activity activity, cgSettings settingsIn) {
+ public cgOverlayScale(Activity activity, cgSettings settingsIn, OverlayImpl overlayImpl) {
settings = settingsIn;
+ this.ovlImpl = overlayImpl;
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
@@ -138,4 +141,9 @@ public class cgOverlayScale implements OverlayBase {
canvas.drawLine(10, bottom, (int)(pixels + 10), bottom, scale);
canvas.drawText(String.format("%.0f", distanceRound) + " " + units, (float)(pixels - (10 * pixelDensity)), (bottom - (10 * pixelDensity)), scale);
}
-} \ No newline at end of file
+
+ @Override
+ public OverlayImpl getOverlayImpl() {
+ return getOverlayImpl();
+ }
+}
diff --git a/src/cgeo/geocaching/mapcommon/cgeomap.java b/src/cgeo/geocaching/mapcommon/cgeomap.java
index 474b881..8500e1c 100644
--- a/src/cgeo/geocaching/mapcommon/cgeomap.java
+++ b/src/cgeo/geocaching/mapcommon/cgeomap.java
@@ -28,13 +28,13 @@ import cgeo.geocaching.cgCoord;
import cgeo.geocaching.cgDirection;
import cgeo.geocaching.cgGeo;
import cgeo.geocaching.cgSettings;
-import cgeo.geocaching.cgSettings.mapSourceEnum;
import cgeo.geocaching.cgUpdateDir;
import cgeo.geocaching.cgUpdateLoc;
import cgeo.geocaching.cgUser;
import cgeo.geocaching.cgWaypoint;
import cgeo.geocaching.cgeoapplication;
import cgeo.geocaching.activity.ActivityMixin;
+import cgeo.geocaching.cgSettings.mapSourceEnum;
import cgeo.geocaching.mapinterfaces.ActivityImpl;
import cgeo.geocaching.mapinterfaces.CacheOverlayItemImpl;
import cgeo.geocaching.mapinterfaces.GeoPointImpl;
@@ -269,8 +269,7 @@ public class cgeomap extends MapBase {
mapView.clearOverlays();
if (overlayMyLoc == null) {
- overlayMyLoc = new cgMapMyOverlay(settings, activity);
- mapView.addOverlay(mapFactory.getOverlayBaseWrapper(overlayMyLoc));
+ overlayMyLoc = mapView.createAddPositionOverlay(activity, settings);
}
if (settings.publicLoc > 0 && overlayUsers == null) {
@@ -282,8 +281,7 @@ public class cgeomap extends MapBase {
}
if (overlayScale == null && mapView.needsScaleOverlay()) {
- overlayScale = new cgOverlayScale(activity, settings);
- mapView.addOverlay(mapFactory.getOverlayBaseWrapper(overlayScale));
+ overlayScale = mapView.createAddScaleOverlay(activity, settings);
}
mapView.invalidate();
@@ -747,9 +745,10 @@ public class cgeomap extends MapBase {
}
try {
+ boolean repaintRequired = false;
+
if (overlayMyLoc == null && mapView != null) {
- overlayMyLoc = new cgMapMyOverlay(settings, activity);
- mapView.addOverlay(settings.getMapFactory().getOverlayBaseWrapper(overlayMyLoc));
+ overlayMyLoc = mapView.createAddPositionOverlay(activity, settings);
}
if (overlayMyLoc != null && geo.location != null) {
@@ -760,8 +759,7 @@ public class cgeomap extends MapBase {
if (followMyLocation) {
myLocationInMiddle();
} else {
- // move blue arrow
- mapView.invalidate();
+ repaintRequired = true;
}
}
@@ -771,7 +769,13 @@ public class cgeomap extends MapBase {
} else {
overlayMyLoc.setHeading(Double.valueOf(0));
}
+ repaintRequired = true;
+ }
+
+ if (repaintRequired) {
+ mapView.repaintRequired(overlayMyLoc);
}
+
} catch (Exception e) {
Log.w(cgSettings.tag, "Failed to update location.");
}