forked from upstream-mirrors/OpenTracks
Fix Map View to improve the initial camera position after screen rotation.
If showing a marker, after rotation, will zoom to the marker. If showing a track, after rotation, will zoom to the current location if is recording and is in tracking mode, else will zoom to the track.
This commit is contained in:
@@ -83,7 +83,6 @@ public class MyTracksMapFragment extends SupportMapFragment implements TrackData
|
|||||||
private static final String CURRENT_LOCATION_KEY = "current_location_key";
|
private static final String CURRENT_LOCATION_KEY = "current_location_key";
|
||||||
private static final String
|
private static final String
|
||||||
KEEP_CURRENT_LOCATION_VISIBLE_KEY = "keep_current_location_visible_key";
|
KEEP_CURRENT_LOCATION_VISIBLE_KEY = "keep_current_location_visible_key";
|
||||||
private static final String ZOOM_TO_CURRENT_LOCATION_KEY = "zoom_to_current_location_key";
|
|
||||||
|
|
||||||
private static final float DEFAULT_ZOOM_LEVEL = 18f;
|
private static final float DEFAULT_ZOOM_LEVEL = 18f;
|
||||||
|
|
||||||
@@ -114,22 +113,6 @@ public class MyTracksMapFragment extends SupportMapFragment implements TrackData
|
|||||||
*/
|
*/
|
||||||
private boolean keepCurrentLocationVisible;
|
private boolean keepCurrentLocationVisible;
|
||||||
|
|
||||||
/**
|
|
||||||
* True to zoom/center the current location when it is available.
|
|
||||||
* <p>
|
|
||||||
* Set to true when <br>
|
|
||||||
* 1. user clicks on the my location button <br>
|
|
||||||
* 2. first location during a recording <br>
|
|
||||||
* Set to false when <br>
|
|
||||||
* 1. showing a marker <br>
|
|
||||||
* 2. user manually zooms/pans <br>
|
|
||||||
* 3. after zooming to the current location <br>
|
|
||||||
* <p>
|
|
||||||
* The last one is to support the use case of zooming only once. After zoom,
|
|
||||||
* set it to false. E.g., only zoom to the first location during a recording.
|
|
||||||
*/
|
|
||||||
private boolean zoomToCurrentLocation;
|
|
||||||
|
|
||||||
private OnLocationChangedListener onLocationChangedListener;
|
private OnLocationChangedListener onLocationChangedListener;
|
||||||
|
|
||||||
// Current track
|
// Current track
|
||||||
@@ -181,9 +164,8 @@ public class MyTracksMapFragment extends SupportMapFragment implements TrackData
|
|||||||
public void onLocationChanged(Location location) {
|
public void onLocationChanged(Location location) {
|
||||||
myTracksLocationManager.close();
|
myTracksLocationManager.close();
|
||||||
keepCurrentLocationVisible = true;
|
keepCurrentLocationVisible = true;
|
||||||
zoomToCurrentLocation = true;
|
|
||||||
setCurrentLocation(location);
|
setCurrentLocation(location);
|
||||||
updateCurrentLocation();
|
updateCurrentLocation(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -199,9 +181,12 @@ public class MyTracksMapFragment extends SupportMapFragment implements TrackData
|
|||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
keepCurrentLocationVisible = savedInstanceState.getBoolean(
|
keepCurrentLocationVisible = savedInstanceState.getBoolean(
|
||||||
KEEP_CURRENT_LOCATION_VISIBLE_KEY, false);
|
KEEP_CURRENT_LOCATION_VISIBLE_KEY, false);
|
||||||
zoomToCurrentLocation = savedInstanceState.getBoolean(ZOOM_TO_CURRENT_LOCATION_KEY, false);
|
if (keepCurrentLocationVisible) {
|
||||||
Location location = (Location) savedInstanceState.getParcelable(CURRENT_LOCATION_KEY);
|
Location location = (Location) savedInstanceState.getParcelable(CURRENT_LOCATION_KEY);
|
||||||
setCurrentLocation(location);
|
if (location != null) {
|
||||||
|
setCurrentLocation(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -260,7 +245,6 @@ public class MyTracksMapFragment extends SupportMapFragment implements TrackData
|
|||||||
if (isResumed() && keepCurrentLocationVisible && currentLocation != null
|
if (isResumed() && keepCurrentLocationVisible && currentLocation != null
|
||||||
&& !isLocationVisible(currentLocation)) {
|
&& !isLocationVisible(currentLocation)) {
|
||||||
keepCurrentLocationVisible = false;
|
keepCurrentLocationVisible = false;
|
||||||
zoomToCurrentLocation = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -296,12 +280,22 @@ public class MyTracksMapFragment extends SupportMapFragment implements TrackData
|
|||||||
|
|
||||||
// setWarningMessage depends on resumeTrackDataHub being invoked beforehand
|
// setWarningMessage depends on resumeTrackDataHub being invoked beforehand
|
||||||
setWarningMessage(isGpsProviderEnabled);
|
setWarningMessage(isGpsProviderEnabled);
|
||||||
updateCurrentLocation();
|
|
||||||
|
if (markerId == -1L && isInTrackingMode()) {
|
||||||
|
updateCurrentLocation(true);
|
||||||
|
} else {
|
||||||
|
if (googleMap != null) {
|
||||||
|
googleMap.moveCamera(
|
||||||
|
CameraUpdateFactory.newLatLngZoom(getDefaultLatLng(), googleMap.getMinZoomLevel()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onSaveInstanceState(Bundle outState) {
|
public void onSaveInstanceState(Bundle outState) {
|
||||||
super.onSaveInstanceState(outState);
|
super.onSaveInstanceState(outState);
|
||||||
|
|
||||||
|
outState.putBoolean(KEEP_CURRENT_LOCATION_VISIBLE_KEY, keepCurrentLocationVisible);
|
||||||
if (currentLocation != null) {
|
if (currentLocation != null) {
|
||||||
/*
|
/*
|
||||||
* currentLocation is a MyTracksLocation object, which cannot be
|
* currentLocation is a MyTracksLocation object, which cannot be
|
||||||
@@ -310,8 +304,6 @@ public class MyTracksMapFragment extends SupportMapFragment implements TrackData
|
|||||||
*/
|
*/
|
||||||
outState.putParcelable(CURRENT_LOCATION_KEY, new Location(currentLocation));
|
outState.putParcelable(CURRENT_LOCATION_KEY, new Location(currentLocation));
|
||||||
}
|
}
|
||||||
outState.putBoolean(KEEP_CURRENT_LOCATION_VISIBLE_KEY, keepCurrentLocationVisible);
|
|
||||||
outState.putBoolean(ZOOM_TO_CURRENT_LOCATION_KEY, zoomToCurrentLocation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -384,14 +376,11 @@ public class MyTracksMapFragment extends SupportMapFragment implements TrackData
|
|||||||
public void onSelectedTrackChanged(final Track track) {
|
public void onSelectedTrackChanged(final Track track) {
|
||||||
if (isResumed()) {
|
if (isResumed()) {
|
||||||
currentTrack = track;
|
currentTrack = track;
|
||||||
boolean hasTrack = track != null;
|
mapOverlay.setShowEndMarker(!isSelectedTrackRecording());
|
||||||
if (hasTrack) {
|
if (markerId != -1L) {
|
||||||
mapOverlay.setShowEndMarker(!isSelectedTrackRecording());
|
showMarker(markerId);
|
||||||
if (markerId != -1L) {
|
} else {
|
||||||
// Show the marker
|
if (!isInTrackingMode()) {
|
||||||
showMarker(markerId);
|
|
||||||
} else {
|
|
||||||
// Show the track
|
|
||||||
showTrack();
|
showTrack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -447,12 +436,13 @@ public class MyTracksMapFragment extends SupportMapFragment implements TrackData
|
|||||||
if (hasStartMarker) {
|
if (hasStartMarker) {
|
||||||
reloadPaths = false;
|
reloadPaths = false;
|
||||||
}
|
}
|
||||||
if (!isSelectedTrackRecording() || isSelectedTrackPaused()) {
|
|
||||||
lastTrackPoint = null;
|
if (lastTrackPoint != null && isSelectedTrackRecording()) {
|
||||||
}
|
boolean firstLocation = setCurrentLocation(lastTrackPoint);
|
||||||
if (lastTrackPoint != null) {
|
if (firstLocation) {
|
||||||
setCurrentLocation(lastTrackPoint);
|
keepCurrentLocationVisible = true;
|
||||||
updateCurrentLocation();
|
}
|
||||||
|
updateCurrentLocation(firstLocation);
|
||||||
setWarningMessage(true);
|
setWarningMessage(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -542,32 +532,28 @@ public class MyTracksMapFragment extends SupportMapFragment implements TrackData
|
|||||||
return trackDataHub != null && trackDataHub.isSelectedTrackRecording();
|
return trackDataHub != null && trackDataHub.isSelectedTrackRecording();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the selected track is paused. Needs to be synchronized
|
|
||||||
* because trackDataHub can be accessed by multiple threads.
|
|
||||||
*/
|
|
||||||
private synchronized boolean isSelectedTrackPaused() {
|
|
||||||
return trackDataHub != null && trackDataHub.isSelectedTrackPaused();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current location.
|
* Sets the current location.
|
||||||
*
|
*
|
||||||
* @param location the location
|
* @param location the location
|
||||||
|
* @return true if this is the first location
|
||||||
*/
|
*/
|
||||||
private void setCurrentLocation(Location location) {
|
private boolean setCurrentLocation(Location location) {
|
||||||
// If recording, zoom to the first location
|
boolean firstLocation = false;
|
||||||
if (isSelectedTrackRecording() && currentLocation == null && location != null) {
|
if (currentLocation == null && location != null) {
|
||||||
keepCurrentLocationVisible = true;
|
firstLocation = true;
|
||||||
zoomToCurrentLocation = true;
|
|
||||||
}
|
}
|
||||||
currentLocation = location;
|
currentLocation = location;
|
||||||
|
return firstLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the current location and zoom to it if necessary.
|
* Updates the current location.
|
||||||
|
*
|
||||||
|
* @param forceZoom true to force zoom to the current location regardless of
|
||||||
|
* the keepCurrentLocationVisible policy
|
||||||
*/
|
*/
|
||||||
private void updateCurrentLocation() {
|
private void updateCurrentLocation(final boolean forceZoom) {
|
||||||
getActivity().runOnUiThread(new Runnable() {
|
getActivity().runOnUiThread(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (!isResumed() || googleMap == null || onLocationChangedListener == null
|
if (!isResumed() || googleMap == null || onLocationChangedListener == null
|
||||||
@@ -575,11 +561,9 @@ public class MyTracksMapFragment extends SupportMapFragment implements TrackData
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
onLocationChangedListener.onLocationChanged(currentLocation);
|
onLocationChangedListener.onLocationChanged(currentLocation);
|
||||||
if (zoomToCurrentLocation
|
if (forceZoom || (keepCurrentLocationVisible && !isLocationVisible(currentLocation))) {
|
||||||
|| (keepCurrentLocationVisible && !isLocationVisible(currentLocation))) {
|
|
||||||
LatLng latLng = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
|
LatLng latLng = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
|
||||||
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, DEFAULT_ZOOM_LEVEL));
|
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, DEFAULT_ZOOM_LEVEL));
|
||||||
zoomToCurrentLocation = false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -649,7 +633,6 @@ public class MyTracksMapFragment extends SupportMapFragment implements TrackData
|
|||||||
Location location = waypoint.getLocation();
|
Location location = waypoint.getLocation();
|
||||||
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
|
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
|
||||||
keepCurrentLocationVisible = false;
|
keepCurrentLocationVisible = false;
|
||||||
zoomToCurrentLocation = false;
|
|
||||||
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, DEFAULT_ZOOM_LEVEL);
|
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, DEFAULT_ZOOM_LEVEL);
|
||||||
googleMap.moveCamera(cameraUpdate);
|
googleMap.moveCamera(cameraUpdate);
|
||||||
}
|
}
|
||||||
@@ -662,16 +645,20 @@ public class MyTracksMapFragment extends SupportMapFragment implements TrackData
|
|||||||
*/
|
*/
|
||||||
private LatLng getDefaultLatLng() {
|
private LatLng getDefaultLatLng() {
|
||||||
MyTracksProviderUtils myTracksProviderUtils = MyTracksProviderUtils.Factory.get(getActivity());
|
MyTracksProviderUtils myTracksProviderUtils = MyTracksProviderUtils.Factory.get(getActivity());
|
||||||
Track track = myTracksProviderUtils.getLastTrack();
|
Location location = myTracksProviderUtils.getLastValidTrackPoint();
|
||||||
if (track != null) {
|
if (location != null) {
|
||||||
Location location = myTracksProviderUtils.getLastValidTrackPoint(track.getId());
|
return new LatLng(location.getLatitude(), location.getLongitude());
|
||||||
if (location != null) {
|
|
||||||
return new LatLng(location.getLatitude(), location.getLongitude());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return new LatLng(DEFAULT_LATITUDE, DEFAULT_LONGITUDE);
|
return new LatLng(DEFAULT_LATITUDE, DEFAULT_LONGITUDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if in tracking mode.
|
||||||
|
*/
|
||||||
|
private boolean isInTrackingMode() {
|
||||||
|
return keepCurrentLocationVisible && currentLocation != null && isSelectedTrackRecording();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the location is visible. Needs to run on the UI thread.
|
* Returns true if the location is visible. Needs to run on the UI thread.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -252,6 +252,12 @@ public interface MyTracksProviderUtils {
|
|||||||
*/
|
*/
|
||||||
public Location getLastValidTrackPoint(long trackId);
|
public Location getLastValidTrackPoint(long trackId);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the last valid location.
|
||||||
|
*/
|
||||||
|
public Location getLastValidTrackPoint();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a location cursor. The caller owns the returned cursor and is
|
* Creates a location cursor. The caller owns the returned cursor and is
|
||||||
* responsible for closing it.
|
* responsible for closing it.
|
||||||
|
|||||||
+8
@@ -816,6 +816,14 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
|
|||||||
return findTrackPointBy(selection, selectionArgs);
|
return findTrackPointBy(selection, selectionArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Location getLastValidTrackPoint() {
|
||||||
|
String selection = TrackPointsColumns._ID + "=(select max(" + TrackPointsColumns._ID + ") from "
|
||||||
|
+ TrackPointsColumns.TABLE_NAME + " WHERE " + TrackPointsColumns.LATITUDE + "<="
|
||||||
|
+ MAX_LATITUDE + ")";
|
||||||
|
return findTrackPointBy(selection, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Cursor getTrackPointCursor(
|
public Cursor getTrackPointCursor(
|
||||||
long trackId, long startTrackPointId, int maxLocations, boolean descending) {
|
long trackId, long startTrackPointId, int maxLocations, boolean descending) {
|
||||||
|
|||||||
Reference in New Issue
Block a user