Merged Rodrigo's changes.

This commit is contained in:
Sandor Dornbush
2010-09-23 11:07:31 -07:00
parent 19a770445e
commit 21b0a517a9
2 changed files with 211 additions and 177 deletions
@@ -70,8 +70,9 @@ import android.widget.Toast;
* @author Leif Hendrik Wilden * @author Leif Hendrik Wilden
*/ */
public class MyTracksMap extends MapActivity public class MyTracksMap extends MapActivity
implements LocationListener, SensorEventListener, View.OnTouchListener, implements View.OnTouchListener, View.OnClickListener,
View.OnClickListener, SharedPreferences.OnSharedPreferenceChangeListener { SharedPreferences.OnSharedPreferenceChangeListener {
private static final int TRACKPOINT_BUFFER_SIZE = 1024;
// Saved instance state keys: // Saved instance state keys:
// --------------------------- // ---------------------------
@@ -82,9 +83,9 @@ public class MyTracksMap extends MapActivity
public static final String KEY_HAVE_GOOD_FIX = "haveGoodFix"; public static final String KEY_HAVE_GOOD_FIX = "haveGoodFix";
/** /**
* The currently selected track (or null if nothing selected). * The ID of the currently selected track (or -1 if nothing selected).
*/ */
private Track selectedTrack; private long selectedTrackId = -1;
/** /**
* The id of the currently recording track. * The id of the currently recording track.
@@ -97,13 +98,19 @@ public class MyTracksMap extends MapActivity
*/ */
private boolean keepMyLocationVisible; private boolean keepMyLocationVisible;
/**
* Id of the first location that was seen when reading tracks from the
* provider.
*/
private long firstSeenLocationId = -1;
/** /**
* Id of the last location that was seen when reading tracks from the * Id of the last location that was seen when reading tracks from the
* provider. This is used to determine which locations are new compared to the * provider. This is used to determine which locations are new compared to the
* last time the mapOverlay was updated. * last time the mapOverlay was updated.
*/ */
private long lastSeenLocationId = -1; private long lastSeenLocationId = -1;
/** /**
* Magnetic variation. * Magnetic variation.
*/ */
@@ -130,19 +137,13 @@ public class MyTracksMap extends MapActivity
* A thread with a looper. Post to updateTrackHandler to execute Runnables on * A thread with a looper. Post to updateTrackHandler to execute Runnables on
* this thread. * this thread.
*/ */
private final HandlerThread updateTrackThread = private HandlerThread updateTrackThread;
new HandlerThread("updateTrackThread");
/** Handler for updateTrackThread */ /** Handler for updateTrackThread */
private Handler updateTrackHandler; private Handler updateTrackHandler;
private MyTracksProviderUtils providerUtils; private MyTracksProviderUtils providerUtils;
/**
* This value is used to decide how many points to display.
*/
private int samplingFrequency = 1;
/** /**
* A runnable that updates the track from the provider (looking for points * A runnable that updates the track from the provider (looking for points
* added after "lastSeenLocationId". * added after "lastSeenLocationId".
@@ -150,7 +151,7 @@ public class MyTracksMap extends MapActivity
private final Runnable updateTrackRunnable = new Runnable() { private final Runnable updateTrackRunnable = new Runnable() {
@Override @Override
public void run() { public void run() {
if (selectedTrack == null) { if (!isATrackSelected()) {
return; return;
} }
readAllNewTrackPoints(); readAllNewTrackPoints();
@@ -163,11 +164,12 @@ public class MyTracksMap extends MapActivity
private Runnable restoreTrackRunnable = new Runnable() { private Runnable restoreTrackRunnable = new Runnable() {
@Override @Override
public void run() { public void run() {
if (selectedTrack == null) { if (!isATrackSelected()) {
return; return;
} }
mapOverlay.clearPoints(); mapOverlay.clearPoints();
lastSeenLocationId = selectedTrack.getStartId(); firstSeenLocationId = -1;
lastSeenLocationId = -1;
readAllNewTrackPoints(); readAllNewTrackPoints();
} }
}; };
@@ -178,7 +180,7 @@ public class MyTracksMap extends MapActivity
private final Runnable restoreWaypointsRunnable = new Runnable() { private final Runnable restoreWaypointsRunnable = new Runnable() {
@Override @Override
public void run() { public void run() {
if (selectedTrack == null) { if (!isATrackSelected()) {
return; return;
} }
@@ -188,7 +190,7 @@ public class MyTracksMap extends MapActivity
// We will silently drop extra waypoints to make the app responsive. // We will silently drop extra waypoints to make the app responsive.
// TODO: Try to only load the waypoints in the view port. // TODO: Try to only load the waypoints in the view port.
cursor = providerUtils.getWaypointsCursor( cursor = providerUtils.getWaypointsCursor(
selectedTrack.getId(), 0, selectedTrackId, 0,
MyTracksConstants.MAX_DISPLAYED_WAYPOINTS_POINTS); MyTracksConstants.MAX_DISPLAYED_WAYPOINTS_POINTS);
if (cursor != null) { if (cursor != null) {
if (cursor.moveToFirst()) { if (cursor.moveToFirst()) {
@@ -219,10 +221,9 @@ public class MyTracksMap extends MapActivity
public void run() { public void run() {
uiHandler.post(new Runnable() { uiHandler.post(new Runnable() {
public void run() { public void run() {
showTrack(selectedTrack); showTrack(selectedTrackId);
mapOverlay.setSelectedTrack(selectedTrack); mapOverlay.setTrackDrawingEnabled(isATrackSelected());
mapOverlay.setShowEndMarker(selectedTrack == null || mapOverlay.setShowEndMarker(!isRecordingSelected());
selectedTrack.getId() != recordingTrackId);
mapView.invalidate(); mapView.invalidate();
busyPane.setVisibility(View.GONE); busyPane.setVisibility(View.GONE);
updateOptionsButton(); updateOptionsButton();
@@ -316,6 +317,7 @@ public class MyTracksMap extends MapActivity
locationManager = locationManager =
(LocationManager) getSystemService(Context.LOCATION_SERVICE); (LocationManager) getSystemService(Context.LOCATION_SERVICE);
updateTrackThread = new HandlerThread("updateTrackThread");
updateTrackThread.start(); updateTrackThread.start();
updateTrackHandler = new Handler(updateTrackThread.getLooper()); updateTrackHandler = new Handler(updateTrackThread.getLooper());
@@ -331,8 +333,7 @@ public class MyTracksMap extends MapActivity
// No track is being recorded. We should not be here. // No track is being recorded. We should not be here.
return; return;
} }
if (selectedTrack == null if (!isRecordingSelected()) {
|| selectedTrack.getId() != recordingTrackId) {
// No track, or one other than the recording track is selected, // No track, or one other than the recording track is selected,
// don't bother. // don't bother.
return; return;
@@ -348,7 +349,7 @@ public class MyTracksMap extends MapActivity
public void onChange(boolean selfChange) { public void onChange(boolean selfChange) {
Log.d(MyTracksConstants.TAG, Log.d(MyTracksConstants.TAG,
"MyTracksMap: ContentObserver.onChange waypoints"); "MyTracksMap: ContentObserver.onChange waypoints");
if (selectedTrack == null) { if (!isATrackSelected()) {
return; return;
} }
updateTrackHandler.post(restoreWaypointsRunnable); updateTrackHandler.post(restoreWaypointsRunnable);
@@ -375,6 +376,21 @@ public class MyTracksMap extends MapActivity
} }
} }
/**
* Returns whether there's a track currently selected for display.
*/
private boolean isATrackSelected() {
return selectedTrackId >= 0;
}
/**
* Returns whether we're currently recording the same track that's selected
* for display.
*/
private boolean isRecordingSelected() {
return isATrackSelected() && selectedTrackId == recordingTrackId;
}
protected void setupZoomControls() { protected void setupZoomControls() {
mapView.setBuiltInZoomControls(true); mapView.setBuiltInZoomControls(true);
} }
@@ -384,6 +400,9 @@ public class MyTracksMap extends MapActivity
// Final cleanup before activity is destroyed. // Final cleanup before activity is destroyed.
// May not be called at all in some situations. // May not be called at all in some situations.
Log.d(MyTracksConstants.TAG, "MyTracksMap.onDestroy"); Log.d(MyTracksConstants.TAG, "MyTracksMap.onDestroy");
updateTrackThread.quit();
super.onDestroy(); super.onDestroy();
} }
@@ -449,10 +468,9 @@ public class MyTracksMap extends MapActivity
// While this activity was paused the user may have deleted the selected // While this activity was paused the user may have deleted the selected
// track. In that case the map overlay needs to be cleared: // track. In that case the map overlay needs to be cleared:
Track track = mapOverlay.getSelectedTrack(); if (isATrackSelected() && !providerUtils.trackExists(selectedTrackId)) {
if (track != null && !providerUtils.trackExists(track.getId())) {
// The recording track must have been deleted meanwhile. // The recording track must have been deleted meanwhile.
mapOverlay.setSelectedTrack(null); mapOverlay.setTrackDrawingEnabled(false);
mapView.invalidate(); mapView.invalidate();
} }
} }
@@ -514,10 +532,10 @@ public class MyTracksMap extends MapActivity
+ gpsProvider.getName()); + gpsProvider.getName());
} }
locationManager.requestLocationUpdates(gpsProvider.getName(), locationManager.requestLocationUpdates(gpsProvider.getName(),
0 /*minTime*/, 0 /*minDist*/, this); 0 /*minTime*/, 0 /*minDist*/, locationListener);
try { try {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
1000 * 60 * 5 /*minTime*/, 0 /*minDist*/, this); 1000 * 60 * 5 /*minTime*/, 0 /*minDist*/, locationListener);
} catch (RuntimeException e) { } catch (RuntimeException e) {
// If anything at all goes wrong with getting a cell location do not // If anything at all goes wrong with getting a cell location do not
// abort. Cell location is not essential to this app. // abort. Cell location is not essential to this app.
@@ -535,7 +553,7 @@ public class MyTracksMap extends MapActivity
Log.d(MyTracksConstants.TAG, Log.d(MyTracksConstants.TAG,
"MyTracksMap: Now registering sensor listeners."); "MyTracksMap: Now registering sensor listeners.");
sensorManager.registerListener( sensorManager.registerListener(
this, compass, SensorManager.SENSOR_DELAY_UI); sensorListener, compass, SensorManager.SENSOR_DELAY_UI);
} }
/** /**
@@ -545,12 +563,12 @@ public class MyTracksMap extends MapActivity
if (locationManager != null) { if (locationManager != null) {
Log.d(MyTracksConstants.TAG, Log.d(MyTracksConstants.TAG,
"MyTracksMap: Now unregistering location listeners."); "MyTracksMap: Now unregistering location listeners.");
locationManager.removeUpdates(this); locationManager.removeUpdates(locationListener);
} }
if (sensorManager != null) { if (sensorManager != null) {
Log.d(MyTracksConstants.TAG, Log.d(MyTracksConstants.TAG,
"MyTracksMap: Now unregistering sensor listeners."); "MyTracksMap: Now unregistering sensor listeners.");
sensorManager.unregisterListener(this); sensorManager.unregisterListener(sensorListener);
} }
} }
@@ -579,7 +597,7 @@ public class MyTracksMap extends MapActivity
*/ */
private void updateOptionsButton() { private void updateOptionsButton() {
optionsBtn.setVisibility( optionsBtn.setVisibility(
selectedTrack != null ? View.VISIBLE : View.INVISIBLE); isATrackSelected() ? View.VISIBLE : View.INVISIBLE);
} }
/** /**
@@ -632,12 +650,18 @@ public class MyTracksMap extends MapActivity
/** /**
* Zooms and pans the map so that the given track is visible. * Zooms and pans the map so that the given track is visible.
* *
* @param track a given track * @param trackId a given track ID
*/ */
public void showTrack(Track track) { public void showTrack(long trackId) {
if (track == null || mapView == null || track.getNumberOfPoints() < 2) { if (mapView == null) {
return; return;
} }
Track track = providerUtils.getTrack(trackId);
if (track == null || track.getNumberOfPoints() < 2) {
return;
}
TripStatistics stats = track.getStatistics(); TripStatistics stats = track.getStatistics();
int bottom = stats.getBottom(); int bottom = stats.getBottom();
int left = stats.getLeft(); int left = stats.getLeft();
@@ -680,24 +704,30 @@ public class MyTracksMap extends MapActivity
* @param trackId a given track id * @param trackId a given track id
*/ */
public void setSelectedTrack(final long trackId) { public void setSelectedTrack(final long trackId) {
if (selectedTrack != null && selectedTrack.getId() == trackId) { if (selectedTrackId == trackId) {
// Selected track did not change, nothing to do. // Selected track did not change, nothing to do.
mapOverlay.setSelectedTrack(selectedTrack); mapOverlay.setTrackDrawingEnabled(isATrackSelected());
mapView.invalidate(); mapView.invalidate();
updateOptionsButton(); updateOptionsButton();
return; return;
} }
if (trackId < 0) { if (trackId < 0) {
// Remove selection. // Remove selection.
selectedTrack = null; selectedTrackId = -1;
mapOverlay.setSelectedTrack(null); mapOverlay.setTrackDrawingEnabled(false);
mapOverlay.clearWaypoints(); mapOverlay.clearWaypoints();
updateOptionsButton(); updateOptionsButton();
mapView.invalidate(); mapView.invalidate();
return; return;
} }
busyPane.setVisibility(View.VISIBLE); busyPane.setVisibility(View.VISIBLE);
selectedTrack = providerUtils.getTrack(trackId); selectedTrackId = trackId;
loadSelectedTrack();
}
private void loadSelectedTrack() {
updateTrackHandler.post(restoreTrackRunnable); updateTrackHandler.post(restoreTrackRunnable);
updateTrackHandler.post(restoreWaypointsRunnable); updateTrackHandler.post(restoreWaypointsRunnable);
updateTrackHandler.post(setSelectedTrackRunnable); updateTrackHandler.post(setSelectedTrackRunnable);
@@ -753,8 +783,7 @@ public class MyTracksMap extends MapActivity
menu.setHeaderTitle(R.string.tracklist_this_track); menu.setHeaderTitle(R.string.tracklist_this_track);
menu.add(0, MyTracksConstants.MENU_EDIT, 0, menu.add(0, MyTracksConstants.MENU_EDIT, 0,
R.string.tracklist_edit_track); R.string.tracklist_edit_track);
if (!MyTracks.getInstance().isRecording() || (selectedTrack != null if (!MyTracks.getInstance().isRecording() || !isRecordingSelected()) {
&& selectedTrack.getId() != recordingTrackId)) {
menu.add(0, MyTracksConstants.MENU_SEND_TO_GOOGLE, 0, menu.add(0, MyTracksConstants.MENU_SEND_TO_GOOGLE, 0,
R.string.tracklist_send_to_google); R.string.tracklist_send_to_google);
SubMenu share = menu.addSubMenu(0, MyTracksConstants.MENU_SHARE, 0, SubMenu share = menu.addSubMenu(0, MyTracksConstants.MENU_SHARE, 0,
@@ -791,7 +820,7 @@ public class MyTracksMap extends MapActivity
@Override @Override
public boolean onMenuItemSelected(int featureId, MenuItem item) { public boolean onMenuItemSelected(int featureId, MenuItem item) {
if (!super.onMenuItemSelected(featureId, item)) { if (!super.onMenuItemSelected(featureId, item)) {
if (selectedTrack != null) { if (isATrackSelected()) {
MyTracks.getInstance().onActivityResult( MyTracks.getInstance().onActivityResult(
MyTracksConstants.getActionFromMenuId(item.getItemId()), RESULT_OK, MyTracksConstants.getActionFromMenuId(item.getItemId()), RESULT_OK,
new Intent()); new Intent());
@@ -852,8 +881,7 @@ public class MyTracksMap extends MapActivity
public void onClick(View v) { public void onClick(View v) {
if (v == messagePane) { if (v == messagePane) {
launchMyLocationSettings(); launchMyLocationSettings();
} } else if (v == optionsBtn) {
if (v == optionsBtn) {
optionsBtn.performLongClick(); optionsBtn.performLongClick();
} }
} }
@@ -895,9 +923,8 @@ public class MyTracksMap extends MapActivity
sharedPreferences.getLong( sharedPreferences.getLong(
getString(R.string.recording_track_key), getString(R.string.recording_track_key),
-1); -1);
if (selectedTrack != null) { if (isATrackSelected()) {
mapOverlay.setShowEndMarker( mapOverlay.setShowEndMarker(!isRecordingSelected());
selectedTrack.getId() != recordingTrackId);
mapView.postInvalidate(); mapView.postInvalidate();
} }
} }
@@ -906,136 +933,139 @@ public class MyTracksMap extends MapActivity
} }
} }
@Override private final LocationListener locationListener = new LocationListener() {
public void onProviderEnabled(String provider) { @Override
if (provider.equals(MyTracksConstants.GPS_PROVIDER)) { public void onProviderEnabled(String provider) {
messageText.setText(R.string.wait_for_fix); if (provider.equals(MyTracksConstants.GPS_PROVIDER)) {
} messageText.setText(R.string.wait_for_fix);
}
@Override
public void onProviderDisabled(String provider) {
if (provider.equals(MyTracksConstants.GPS_PROVIDER)) {
messageText.setText(R.string.status_enable_gps);
messagePane.setVisibility(View.VISIBLE);
messagePane.setOnClickListener(this);
screen.requestLayout();
}
}
@Override
public void onLocationChanged(Location location) {
if (location.getProvider().equals(MyTracksConstants.GPS_PROVIDER)) {
// Recalculate the variation if there was a jump in location > 1km:
if (currentLocation == null
|| location.distanceTo(currentLocation) > 1000) {
setVariation(location);
} }
currentLocation = location; }
boolean haveGoodFixNow =
currentLocation.getAccuracy() < minRequiredAccuracy; @Override
if (haveGoodFixNow != haveGoodFix) { public void onProviderDisabled(String provider) {
haveGoodFix = haveGoodFixNow; if (provider.equals(MyTracksConstants.GPS_PROVIDER)) {
messagePane.setVisibility(haveGoodFix ? View.GONE : View.VISIBLE); messageText.setText(R.string.status_enable_gps);
messagePane.setVisibility(View.VISIBLE);
messagePane.setOnClickListener(MyTracksMap.this);
screen.requestLayout(); screen.requestLayout();
} }
showCurrentLocation();
} else {
Log.d(MyTracksConstants.TAG,
"MyTracksMap: Network location update received.");
} }
}
@Override @Override
public void onStatusChanged(String provider, int status, Bundle extras) { public void onLocationChanged(Location location) {
if (provider.equals(MyTracksConstants.GPS_PROVIDER)) { if (location.getProvider().equals(MyTracksConstants.GPS_PROVIDER)) {
switch (status) { // Recalculate the variation if there was a jump in location > 1km:
case LocationProvider.OUT_OF_SERVICE: if (currentLocation == null
case LocationProvider.TEMPORARILY_UNAVAILABLE: || location.distanceTo(currentLocation) > 1000) {
haveGoodFix = false; setVariation(location);
messagePane.setVisibility(View.VISIBLE); }
currentLocation = location;
boolean haveGoodFixNow =
currentLocation.getAccuracy() < minRequiredAccuracy;
if (haveGoodFixNow != haveGoodFix) {
haveGoodFix = haveGoodFixNow;
messagePane.setVisibility(haveGoodFix ? View.GONE : View.VISIBLE);
screen.requestLayout(); screen.requestLayout();
break; }
showCurrentLocation();
} else {
Log.d(MyTracksConstants.TAG,
"MyTracksMap: Network location update received.");
} }
} }
}
@Override @Override
public void onSensorChanged(SensorEvent se) { public void onStatusChanged(String provider, int status, Bundle extras) {
synchronized (this) { if (provider.equals(MyTracksConstants.GPS_PROVIDER)) {
float magneticHeading = se.values[0]; switch (status) {
double heading = magneticHeading + variation; case LocationProvider.OUT_OF_SERVICE:
if (mapOverlay.setHeading((float) heading)) { case LocationProvider.TEMPORARILY_UNAVAILABLE:
mapView.invalidate(); haveGoodFix = false;
messagePane.setVisibility(View.VISIBLE);
screen.requestLayout();
break;
}
} }
} }
} };
@Override private final SensorEventListener sensorListener = new SensorEventListener() {
public void onAccuracyChanged(Sensor s, int accuracy) { @Override
// do nothing public void onSensorChanged(SensorEvent se) {
} synchronized (this) {
float magneticHeading = se.values[0];
/** double heading = magneticHeading + variation;
* Set the sampling frequency from the total number of points in the track. if (mapOverlay.setHeading((float) heading)) {
* mapView.invalidate();
* @param track The track to read the total number of points from. }
*/ }
private void setSamplingFrequency(Track track) { }
long totalLocations = track.getStopId() - track.getStartId();
@Override
public void onAccuracyChanged(Sensor s, int accuracy) {
// do nothing
}
};
// Limit the number of map points readings.
samplingFrequency =
(int) (1 +
totalLocations / MyTracksConstants.TARGET_DISPLAYED_TRACK_POINTS);
Log.i(MyTracksConstants.TAG, "Sampling locations: " + samplingFrequency);
}
private void readAllNewTrackPoints() { private void readAllNewTrackPoints() {
Cursor cursor = null; int numPoints = mapOverlay.getNumLocations();
// Refetch the track to get the latest StopId if (numPoints >= MyTracksConstants.MAX_DISPLAYED_TRACK_POINTS) {
selectedTrack = providerUtils.getTrack(selectedTrack.getId()); // We're about to exceed the maximum allowed number of points, so reload
long totalLocations = selectedTrack.getStopId() - // the whole track with fewer points (the sampling frequency will be
selectedTrack.getStartId(); // lower).
loadSelectedTrack();
return;
}
long lastStoredLocationId =
providerUtils.getLastLocationId(selectedTrackId);
int samplingFrequency = -1;
for (;;) {
Cursor cursor = null;
try {
cursor = providerUtils.getLocationsCursor(selectedTrackId,
lastSeenLocationId + 1, TRACKPOINT_BUFFER_SIZE, false);
if (cursor == null || !cursor.moveToFirst()) {
// No (more) data
break;
}
setSamplingFrequency(selectedTrack);
int bufferSize = 1024;
int points = 0;
long tailLocationId = selectedTrack.getStopId() - 10;
Location location;
while (lastSeenLocationId < (selectedTrack.getStopId() + 10)) {
cursor = providerUtils.getLocationsCursor(
selectedTrack.getId(), lastSeenLocationId + 1, bufferSize, false);
if (cursor != null && cursor.moveToFirst()) {
final int idColumnIdx = cursor.getColumnIndexOrThrow( final int idColumnIdx = cursor.getColumnIndexOrThrow(
TrackPointsColumns._ID); TrackPointsColumns._ID);
do { do {
points++; long locationId = cursor.getLong(idColumnIdx);
location = providerUtils.createLocation(cursor); lastSeenLocationId = locationId;
lastSeenLocationId = cursor.getLong(idColumnIdx); if (firstSeenLocationId == -1) {
// Include a point if it fits one of the following criteria: // This was our first point, keep its ID
// - Has the mod for the sampling frequency. firstSeenLocationId = locationId;
// - Is the first point.
// - Is on of the last n points.
// => This is to make sure we draw the last points people are probably zoomed in to.
if (!MyTracksUtils.isValidLocation(location) ||
points % samplingFrequency == 0 ||
points == 0 ||
lastSeenLocationId > tailLocationId) {
mapOverlay.addLocation(new Location(location));
} }
if (samplingFrequency == -1) {
// Now we already have at least one point, calculate the sampling
// frequency
long numTotalPoints = lastStoredLocationId - firstSeenLocationId;
samplingFrequency = (int) (1 +
numTotalPoints / MyTracksConstants.TARGET_DISPLAYED_TRACK_POINTS);
}
Location location = providerUtils.createLocation(cursor);
// Include a point if it fits one of the following criteria:
// - Has the mod for the sampling frequency (includes first point).
// - Is the last point and we are not recording this track.
// - The point is a segment split
if (numPoints % samplingFrequency == 0 ||
(!isRecordingSelected() && locationId == lastStoredLocationId) ||
!MyTracksUtils.isValidLocation(location)) {
mapOverlay.addLocation(location);
}
numPoints++;
} while (cursor.moveToNext()); } while (cursor.moveToNext());
} else { } finally {
// TODO this is wrong sometimes. Should just return. if (cursor != null) {
if (lastSeenLocationId >= selectedTrack.getStopId()) {
cursor.close(); cursor.close();
mapView.postInvalidate();
return;
} }
lastSeenLocationId += bufferSize;
} }
cursor.close();
cursor = null;
} }
mapView.postInvalidate(); mapView.postInvalidate();
} }
@@ -15,10 +15,8 @@
*/ */
package com.google.android.apps.mytracks; package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint; import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.util.MyTracksUtils; import com.google.android.apps.mytracks.util.MyTracksUtils;
import com.google.android.maps.GeoPoint; import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView; import com.google.android.maps.MapView;
import com.google.android.maps.Overlay; import com.google.android.maps.Overlay;
@@ -58,7 +56,7 @@ public class MyTracksOverlay extends Overlay {
private final ArrayList<Waypoint> waypoints = new ArrayList<Waypoint>(); private final ArrayList<Waypoint> waypoints = new ArrayList<Waypoint>();
private final ArrayList<Location> points = new ArrayList<Location>(1024); private final ArrayList<Location> points = new ArrayList<Location>(1024);
private Track selectedTrack; private boolean trackDrawingEnabled;
private int lastHeading = 0; private int lastHeading = 0;
private Location myLocation; private Location myLocation;
private boolean showEndMarker = true; private boolean showEndMarker = true;
@@ -122,14 +120,6 @@ public class MyTracksOverlay extends Overlay {
errorCirclePaint.setAntiAlias(true); errorCirclePaint.setAntiAlias(true);
} }
public void setSelectedTrack(Track track) {
selectedTrack = track;
}
public Track getSelectedTrack() {
return selectedTrack;
}
/** /**
* Add a location to the map overlay. * Add a location to the map overlay.
* *
@@ -145,6 +135,10 @@ public class MyTracksOverlay extends Overlay {
waypoints.add(wpt); waypoints.add(wpt);
} }
public int getNumLocations() {
return points.size();
}
public void clearWaypoints() { public void clearWaypoints() {
waypoints.clear(); waypoints.clear();
} }
@@ -153,21 +147,33 @@ public class MyTracksOverlay extends Overlay {
points.clear(); points.clear();
} }
public void setTrackDrawingEnabled(boolean trackDrawingEnabled) {
this.trackDrawingEnabled = trackDrawingEnabled;
}
public void setShowEndMarker(boolean showEndMarker) { public void setShowEndMarker(boolean showEndMarker) {
this.showEndMarker = showEndMarker; this.showEndMarker = showEndMarker;
} }
@Override @Override
public void draw(Canvas canvas, MapView mapView, boolean shadow) { public void draw(Canvas canvas, MapView mapView, boolean shadow) {
if (shadow) { if (shadow) {
return; return;
} }
// Draw the selected track: if (trackDrawingEnabled) {
drawTrack(canvas, mapView, selectedTrack, true); // Draw the selected track:
drawTrack(canvas, mapView);
// Draw the waypoints: // Draw the waypoints:
drawWaypoints(canvas, mapView);
}
// Draw the current location
drawMyLocation(canvas, mapView);
}
private void drawWaypoints(Canvas canvas, MapView mapView) {
ArrayList<Waypoint> currentWaypoints = waypoints; ArrayList<Waypoint> currentWaypoints = waypoints;
for (int i = 1; i < currentWaypoints.size(); i++) { for (int i = 1; i < currentWaypoints.size(); i++) {
Waypoint wpt = currentWaypoints.get(i); Waypoint wpt = currentWaypoints.get(i);
@@ -190,11 +196,14 @@ public class MyTracksOverlay extends Overlay {
} }
canvas.restore(); canvas.restore();
} }
}
private void drawMyLocation(Canvas canvas, MapView mapView) {
// Draw the arrow icon: // Draw the arrow icon:
if (myLocation == null) { if (myLocation == null) {
return; return;
} }
GeoPoint geoPoint = new GeoPoint( GeoPoint geoPoint = new GeoPoint(
(int) (myLocation.getLatitude() * 1E6), (int) (myLocation.getLatitude() * 1E6),
(int) (myLocation.getLongitude() * 1E6)); (int) (myLocation.getLongitude() * 1E6));
@@ -211,12 +220,7 @@ public class MyTracksOverlay extends Overlay {
canvas.drawCircle(pt.x, pt.y, radius, errorCirclePaint); canvas.drawCircle(pt.x, pt.y, radius, errorCirclePaint);
} }
public void drawTrack(Canvas canvas, MapView mapView, Track track, private void drawTrack(Canvas canvas, MapView mapView) {
boolean selected) {
if (track == null) {
return;
}
if (points.size() < 2) { if (points.size() < 2) {
return; return;
} }