diff options
author | rsudev <rasch@munin-soft.de> | 2012-06-17 17:37:31 +0200 |
---|---|---|
committer | rsudev <rasch@munin-soft.de> | 2012-06-17 17:37:31 +0200 |
commit | 532302258f1a06b3c3fcaee613caa9f9d0016ed9 (patch) | |
tree | fcf6f720bb7b2c19bc63adf0a9e79556ceaf0ba1 /main | |
parent | d802aa775188458c6639338821d8f13f5191c9bf (diff) | |
parent | dfd6f35370c0ae7bfc22bf2dc578c9e862992c2f (diff) | |
download | cgeo-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.java | 106 | ||||
-rw-r--r-- | main/src/cgeo/geocaching/maps/PositionOverlay.java | 12 | ||||
-rw-r--r-- | main/src/cgeo/geocaching/ui/CompassView.java | 2 |
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 +} |