aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authorrsudev <rasch@munin-soft.de>2012-06-17 17:37:31 +0200
committerrsudev <rasch@munin-soft.de>2012-06-17 17:37:31 +0200
commit532302258f1a06b3c3fcaee613caa9f9d0016ed9 (patch)
treefcf6f720bb7b2c19bc63adf0a9e79556ceaf0ba1 /main
parentd802aa775188458c6639338821d8f13f5191c9bf (diff)
parentdfd6f35370c0ae7bfc22bf2dc578c9e862992c2f (diff)
downloadcgeo-532302258f1a06b3c3fcaee613caa9f9d0016ed9.zip
cgeo-532302258f1a06b3c3fcaee613caa9f9d0016ed9.tar.gz
cgeo-532302258f1a06b3c3fcaee613caa9f9d0016ed9.tar.bz2
Merge branch 'issue-1709' into master
Conflicts: main/src/cgeo/geocaching/DirectionProvider.java main/src/cgeo/geocaching/ui/CacheListAdapter.java
Diffstat (limited to 'main')
-rw-r--r--main/src/cgeo/geocaching/maps/CGeoMap.java106
-rw-r--r--main/src/cgeo/geocaching/maps/PositionOverlay.java12
-rw-r--r--main/src/cgeo/geocaching/ui/CompassView.java2
3 files changed, 89 insertions, 31 deletions
diff --git a/main/src/cgeo/geocaching/maps/CGeoMap.java b/main/src/cgeo/geocaching/maps/CGeoMap.java
index 69c3530..fbbd80d 100644
--- a/main/src/cgeo/geocaching/maps/CGeoMap.java
+++ b/main/src/cgeo/geocaching/maps/CGeoMap.java
@@ -34,6 +34,7 @@ import cgeo.geocaching.maps.interfaces.MapSource;
import cgeo.geocaching.maps.interfaces.MapViewImpl;
import cgeo.geocaching.maps.interfaces.OnMapDragListener;
import cgeo.geocaching.maps.interfaces.OtherCachersOverlayItemImpl;
+import cgeo.geocaching.utils.AngleUtils;
import cgeo.geocaching.utils.CancellableHandler;
import cgeo.geocaching.utils.GeoDirHandler;
import cgeo.geocaching.utils.LeastRecentlyUsedSet;
@@ -51,6 +52,7 @@ import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
+import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -864,48 +866,96 @@ public class CGeoMap extends AbstractMap implements OnMapDragListener, ViewFacto
// class: update location
private class UpdateLoc extends GeoDirHandler {
+ // use the following constants for fine tuning - find good compromise between smooth updates and as less updates as possible
+
+ // minimum time in milliseconds between position overlay updates
+ private static final long MIN_UPDATE_INTERVAL = 500;
+ // minimum change of heading in grad for position overlay update
+ private static final float MIN_HEADING_DELTA = 15f;
+ // minimum change of location in fraction of map width/height (whatever is smaller) for position overlay update
+ private static final float MIN_LOCATION_DELTA = 0.01f;
+
+ Location currentLocation = new Location("");
+ float currentHeading;
+
+ private long timeLastPositionOverlayCalculation = 0;
@Override
protected void updateGeoData(final IGeoData geo) {
- try {
- boolean repaintRequired = false;
+ currentLocation = geo.getLocation();
- if (overlayPosition == null && mapView != null) {
- overlayPosition = mapView.createAddPositionOverlay(activity);
- }
+ if (!Settings.isUseCompass() || geo.getSpeed() > 5) { // use GPS when speed is higher than 18 km/h
+ currentHeading = geo.getBearing();
+ }
- if ((overlayPosition != null && geo.getLocation() != null)) {
- overlayPosition.setCoordinates(geo.getLocation());
- }
+ repaintPositionOverlay();
+ }
- if (geo.getCoords() != null) {
- if (followMyLocation) {
- myLocationInMiddle(geo);
- } else {
- repaintRequired = true;
+ @Override
+ public void updateDirection(final float direction) {
+ if (app.currentGeo().getSpeed() <= 5) { // use compass when speed is lower than 18 km/h
+ currentHeading = DirectionProvider.getDirectionNow(activity, direction);
+ repaintPositionOverlay();
+ }
+ }
+
+ /**
+ * Repaint position overlay but only with a max frequency and if position or heading changes sufficiently.
+ */
+ void repaintPositionOverlay() {
+ final long currentTimeMillis = System.currentTimeMillis();
+ if (currentTimeMillis > timeLastPositionOverlayCalculation + MIN_UPDATE_INTERVAL) {
+ timeLastPositionOverlayCalculation = currentTimeMillis;
+
+ try {
+ if (mapView != null) {
+ if (overlayPosition == null) {
+ overlayPosition = mapView.createAddPositionOverlay(activity);
+ }
+
+ boolean needsRepaintForDistance = needsRepaintForDistance();
+ boolean needsRepaintForHeading = needsRepaintForHeading();
+
+ if (needsRepaintForDistance) {
+ if (followMyLocation) {
+ centerMap(new Geopoint(currentLocation));
+ }
+ }
+
+ if (needsRepaintForDistance || needsRepaintForHeading) {
+ overlayPosition.setCoordinates(currentLocation);
+ overlayPosition.setHeading(currentHeading);
+ mapView.repaintRequired(overlayPosition);
+ }
}
+ } catch (Exception e) {
+ Log.w("Failed to update location.");
}
+ }
+ }
- if (!Settings.isUseCompass() || geo.getSpeed() > 5) { // use GPS when speed is higher than 18 km/h
- overlayPosition.setHeading(geo.getBearing());
- repaintRequired = true;
- }
+ boolean needsRepaintForHeading() {
+ return Math.abs(AngleUtils.difference(currentHeading, overlayPosition.getHeading())) > MIN_HEADING_DELTA;
+ }
- if (repaintRequired && mapView != null) {
- mapView.repaintRequired(overlayPosition);
- }
+ boolean needsRepaintForDistance() {
+ final Location lastLocation = overlayPosition.getCoordinates();
- } catch (Exception e) {
- Log.w("Failed to update location.");
+ float dist = Float.MAX_VALUE;
+ if (lastLocation != null) {
+ dist = currentLocation.distanceTo(lastLocation);
}
- }
- @Override
- public void updateDirection(final float direction) {
- if (overlayPosition != null && mapView != null && (app.currentGeo().getSpeed() <= 5)) { // use compass when speed is lower than 18 km/h
- overlayPosition.setHeading(DirectionProvider.getDirectionNow(activity, direction));
- mapView.repaintRequired(overlayPosition);
+ final float[] mapDimension = new float[1];
+ if (mapView.getWidth() < mapView.getHeight()) {
+ final double span = mapView.getLongitudeSpan() / 1e6;
+ Location.distanceBetween(currentLocation.getLatitude(), currentLocation.getLongitude(), currentLocation.getLatitude(), currentLocation.getLongitude() + span, mapDimension);
+ } else {
+ final double span = mapView.getLatitudeSpan() / 1e6;
+ Location.distanceBetween(currentLocation.getLatitude(), currentLocation.getLongitude(), currentLocation.getLatitude() + span, currentLocation.getLongitude(), mapDimension);
}
+
+ return dist > (mapDimension[0] * MIN_LOCATION_DELTA);
}
}
diff --git a/main/src/cgeo/geocaching/maps/PositionOverlay.java b/main/src/cgeo/geocaching/maps/PositionOverlay.java
index c32061d..1aa2d3b 100644
--- a/main/src/cgeo/geocaching/maps/PositionOverlay.java
+++ b/main/src/cgeo/geocaching/maps/PositionOverlay.java
@@ -27,7 +27,7 @@ import java.util.List;
public class PositionOverlay implements GeneralOverlay {
private Location coordinates = null;
private GeoPointImpl location = null;
- private Float heading = 0f;
+ private float heading = 0f;
private Paint accuracyCircle = null;
private Paint historyLine = null;
private Paint historyLineShadow = null;
@@ -57,10 +57,18 @@ public class PositionOverlay implements GeneralOverlay {
location = mapItemFactory.getGeoPointBase(new Geopoint(coordinates));
}
- public void setHeading(Float bearingNow) {
+ public Location getCoordinates() {
+ return coordinates;
+ }
+
+ public void setHeading(float bearingNow) {
heading = bearingNow;
}
+ public float getHeading() {
+ return heading;
+ }
+
@Override
public void drawOverlayBitmap(Canvas canvas, Point drawPosition,
MapProjectionImpl projection, byte drawZoomLevel) {
diff --git a/main/src/cgeo/geocaching/ui/CompassView.java b/main/src/cgeo/geocaching/ui/CompassView.java
index 4a24966..71ffd52 100644
--- a/main/src/cgeo/geocaching/ui/CompassView.java
+++ b/main/src/cgeo/geocaching/ui/CompassView.java
@@ -260,4 +260,4 @@ public class CompassView extends View {
return result;
}
-} \ No newline at end of file
+}