aboutsummaryrefslogtreecommitdiffstats
path: root/main/src/cgeo/geocaching/maps/PositionDrawer.java
diff options
context:
space:
mode:
authorBananeweizen <bananeweizen@gmx.de>2013-12-18 19:30:20 +0100
committerBananeweizen <bananeweizen@gmx.de>2013-12-18 19:30:20 +0100
commitcf77b87b439e016999afc181fca133d68313867d (patch)
treee340355fa8da99a5ff3922fb3b176c0cde71931d /main/src/cgeo/geocaching/maps/PositionDrawer.java
parente20a20f09474ad7187dccdd54ce044c91d165196 (diff)
downloadcgeo-cf77b87b439e016999afc181fca133d68313867d.zip
cgeo-cf77b87b439e016999afc181fca133d68313867d.tar.gz
cgeo-cf77b87b439e016999afc181fca133d68313867d.tar.bz2
refactoring: reduce mapsforge memory usage
This puts scale and position into one overlay, instead of using 2 overlays. That reduces memory usage by 2 times a full screen bitmap due to double buffering in mapsforge. The only downside is that scale and position now have to be drawn at the same depth-level (below or on top of the caches), but they were both on top previously anyway.
Diffstat (limited to 'main/src/cgeo/geocaching/maps/PositionDrawer.java')
-rw-r--r--main/src/cgeo/geocaching/maps/PositionDrawer.java189
1 files changed, 189 insertions, 0 deletions
diff --git a/main/src/cgeo/geocaching/maps/PositionDrawer.java b/main/src/cgeo/geocaching/maps/PositionDrawer.java
new file mode 100644
index 0000000..1a5dcaf
--- /dev/null
+++ b/main/src/cgeo/geocaching/maps/PositionDrawer.java
@@ -0,0 +1,189 @@
+package cgeo.geocaching.maps;
+
+import cgeo.geocaching.R;
+import cgeo.geocaching.geopoint.Geopoint;
+import cgeo.geocaching.maps.interfaces.GeoPointImpl;
+import cgeo.geocaching.maps.interfaces.MapItemFactory;
+import cgeo.geocaching.maps.interfaces.MapProjectionImpl;
+import cgeo.geocaching.settings.Settings;
+
+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.location.Location;
+
+import java.util.ArrayList;
+
+public class PositionDrawer {
+
+ private Location coordinates = null;
+ private GeoPointImpl location = null;
+ private float heading = 0f;
+ private Paint accuracyCircle = null;
+ private Paint historyLine = null;
+ private Paint historyLineShadow = null;
+ private Point center = new Point();
+ private Point left = new Point();
+ private Bitmap arrow = null;
+ private int widthArrowHalf = 0;
+ private int heightArrowHalf = 0;
+ private PaintFlagsDrawFilter setfil = null;
+ private PaintFlagsDrawFilter remfil = null;
+ private PositionHistory positionHistory = new PositionHistory();
+ private Activity activity;
+ private MapItemFactory mapItemFactory;
+
+ public PositionDrawer(Activity activity) {
+ this.activity = activity;
+ this.mapItemFactory = Settings.getMapProvider().getMapItemFactory();
+ }
+
+ void drawPosition(Canvas canvas, MapProjectionImpl projection) {
+ if (coordinates == null || location == null) {
+ return;
+ }
+
+ if (accuracyCircle == null) {
+ accuracyCircle = new Paint();
+ accuracyCircle.setAntiAlias(true);
+ accuracyCircle.setStrokeWidth(1.0f);
+ }
+
+ if (historyLine == null) {
+ historyLine = new Paint();
+ historyLine.setAntiAlias(true);
+ historyLine.setStrokeWidth(3.0f);
+ historyLine.setColor(0xFFFFFFFF);
+ }
+
+ if (historyLineShadow == null) {
+ historyLineShadow = new Paint();
+ historyLineShadow.setAntiAlias(true);
+ historyLineShadow.setStrokeWidth(7.0f);
+ historyLineShadow.setColor(0x66000000);
+ }
+
+ 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);
+
+ double latitude = coordinates.getLatitude();
+ double longitude = coordinates.getLongitude();
+ float accuracy = coordinates.getAccuracy();
+
+ float[] result = new float[1];
+
+ Location.distanceBetween(latitude, longitude, latitude, longitude + 1, result);
+ float longitudeLineDistance = result[0];
+
+ final Geopoint leftCoords = new Geopoint(latitude, longitude - accuracy / longitudeLineDistance);
+ GeoPointImpl leftGeo = mapItemFactory.getGeoPointBase(leftCoords);
+ projection.toPixels(leftGeo, left);
+ projection.toPixels(location, center);
+ int radius = center.x - left.x;
+
+ accuracyCircle.setColor(0x66000000);
+ accuracyCircle.setStyle(Style.STROKE);
+ canvas.drawCircle(center.x, center.y, radius, accuracyCircle);
+
+ accuracyCircle.setColor(0x08000000);
+ accuracyCircle.setStyle(Style.FILL);
+ canvas.drawCircle(center.x, center.y, radius, accuracyCircle);
+
+ positionHistory.rememberTrailPosition(coordinates);
+
+ if (Settings.isMapTrail()) {
+ // always add current position to drawn history to have a closed connection
+ final ArrayList<Location> paintHistory = new ArrayList<Location>(positionHistory.getHistory());
+ paintHistory.add(coordinates);
+
+ int size = paintHistory.size();
+ if (size > 1) {
+ int alphaCnt = size - 201;
+ if (alphaCnt < 1) {
+ alphaCnt = 1;
+ }
+
+ Point pointNow = new Point();
+ Point pointPrevious = new Point();
+ Location prev = paintHistory.get(0);
+ projection.toPixels(mapItemFactory.getGeoPointBase(new Geopoint(prev)), pointPrevious);
+
+ for (int cnt = 1; cnt < size; cnt++) {
+ Location now = paintHistory.get(cnt);
+ projection.toPixels(mapItemFactory.getGeoPointBase(new Geopoint(now)), pointNow);
+
+ int alpha;
+ if ((alphaCnt - cnt) > 0) {
+ alpha = 255 / (alphaCnt - cnt);
+ }
+ else {
+ alpha = 255;
+ }
+
+ historyLineShadow.setAlpha(alpha);
+ historyLine.setAlpha(alpha);
+
+ canvas.drawLine(pointPrevious.x, pointPrevious.y, pointNow.x, pointNow.y, historyLineShadow);
+ canvas.drawLine(pointPrevious.x, pointPrevious.y, pointNow.x, pointNow.y, historyLine);
+
+ pointPrevious.set(pointNow.x, pointNow.y);
+ }
+ }
+ }
+
+ if (arrow == null) {
+ arrow = BitmapFactory.decodeResource(activity.getResources(), R.drawable.my_location_chevron);
+ widthArrowHalf = arrow.getWidth() / 2;
+ heightArrowHalf = arrow.getHeight() / 2;
+ }
+
+ int marginLeft = center.x - widthArrowHalf;
+ int marginTop = center.y - heightArrowHalf;
+
+ Matrix matrix = new Matrix();
+ matrix.setRotate(heading, widthArrowHalf, heightArrowHalf);
+ matrix.postTranslate(marginLeft, marginTop);
+
+ canvas.drawBitmap(arrow, matrix, null);
+
+ canvas.setDrawFilter(remfil);
+ }
+
+ public ArrayList<Location> getHistory() {
+ return positionHistory.getHistory();
+ }
+
+ public void setHistory(ArrayList<Location> history) {
+ positionHistory.setHistory(history);
+ }
+
+ public void setHeading(float bearingNow) {
+ heading = bearingNow;
+ }
+
+ public float getHeading() {
+ return heading;
+ }
+
+ public void setCoordinates(Location coordinatesIn) {
+ coordinates = coordinatesIn;
+ location = mapItemFactory.getGeoPointBase(new Geopoint(coordinates));
+ }
+
+ public Location getCoordinates() {
+ return coordinates;
+ }
+
+}