diff options
Diffstat (limited to 'src/cgeo/geocaching/mapcommon')
| -rw-r--r-- | src/cgeo/geocaching/mapcommon/ItemizedOverlayBase.java | 9 | ||||
| -rw-r--r-- | src/cgeo/geocaching/mapcommon/cgMapMyOverlay.java | 33 | ||||
| -rw-r--r-- | src/cgeo/geocaching/mapcommon/cgMapOverlay.java | 124 | ||||
| -rw-r--r-- | src/cgeo/geocaching/mapcommon/cgOverlayScale.java | 12 | ||||
| -rw-r--r-- | src/cgeo/geocaching/mapcommon/cgeomap.java | 22 |
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."); } |
