From 19a770445e37646204f25503aa4c1ad8fdd7c755 Mon Sep 17 00:00:00 2001 From: Sandor Dornbush Date: Thu, 23 Sep 2010 11:02:45 -0700 Subject: [PATCH] Submit my changes before merging. --- .../android/apps/mytracks/ChartActivity.java | 20 ++++++++---- .../android/apps/mytracks/MyTracksMap.java | 5 +-- .../android/apps/mytracks/NavControls.java | 30 ++++++++++++------ .../content/MyTracksProviderUtils.java | 23 +++++++++++++- .../content/MyTracksProviderUtilsImpl.java | 31 +++++++++++++++---- .../apps/mytracks/content/TrackBuffer.java | 16 ++++++++++ .../android/apps/mytracks/io/TrackWriter.java | 2 +- 7 files changed, 101 insertions(+), 26 deletions(-) diff --git a/MyTracks/src/com/google/android/apps/mytracks/ChartActivity.java b/MyTracks/src/com/google/android/apps/mytracks/ChartActivity.java index f665d1b5e..6fc01a45d 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/ChartActivity.java +++ b/MyTracks/src/com/google/android/apps/mytracks/ChartActivity.java @@ -176,12 +176,16 @@ public class ChartActivity extends Activity implements final int idColumnIdx = cursor.getColumnIndexOrThrow(TrackPointsColumns._ID); ArrayList data = new ArrayList(); + // Need two locations so we can keep track of the last location. + Location[] locations = { new Location(""), new Location("")}; + int i = 0; do { lastSeenLocationId = cursor.getLong(idColumnIdx); - Location location = providerUtils.createLocation(cursor); - if (location != null && MyTracksUtils.isValidLocation(location)) { - data.add(getDataPoint(location, track)); + providerUtils.fillLocation(cursor, locations[i]); + if (MyTracksUtils.isValidLocation(locations[i])) { + data.add(getDataPoint(locations[i], track)); } + i = (i + 1) % 2; } while (cursor.moveToPrevious()); cv.addDataPoints(data); } @@ -556,6 +560,9 @@ public class ChartActivity extends Activity implements try { final ArrayList theData = new ArrayList(); int points = 0; + // Need two locations so we can keep track of the last location. + Location[] locations = { new Location(""), new Location("")}; + int i = 0; while (lastLocationRead < track.getStopId()) { cursor = providerUtils.getLocationsCursor( selectedTrackId, lastLocationRead, bufferSize, false); @@ -567,15 +574,16 @@ public class ChartActivity extends Activity implements cursor.getColumnIndexOrThrow(TrackPointsColumns._ID); while (cursor.moveToNext()) { points++; - Location location = providerUtils.createLocation(cursor); - if (MyTracksUtils.isValidLocation(location)) { + providerUtils.fillLocation(cursor, locations[i]); + if (MyTracksUtils.isValidLocation(locations[i])) { lastLocationRead = lastSeenLocationId = cursor.getLong(idColumnIdx); - double[] point = getDataPoint(location, track); + double[] point = getDataPoint(locations[i], track); if (points % chartSamplingFrequency == 0) { theData.add(point); } } + i = (i + 1) % 2; } } else { lastLocationRead += bufferSize; diff --git a/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java b/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java index 6f36e94d0..2184c1cf5 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java +++ b/MyTracks/src/com/google/android/apps/mytracks/MyTracksMap.java @@ -1002,6 +1002,7 @@ public class MyTracksMap extends MapActivity 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); @@ -1010,7 +1011,7 @@ public class MyTracksMap extends MapActivity TrackPointsColumns._ID); do { points++; - Location location = providerUtils.createLocation(cursor); + location = providerUtils.createLocation(cursor); lastSeenLocationId = cursor.getLong(idColumnIdx); // Include a point if it fits one of the following criteria: // - Has the mod for the sampling frequency. @@ -1021,7 +1022,7 @@ public class MyTracksMap extends MapActivity points % samplingFrequency == 0 || points == 0 || lastSeenLocationId > tailLocationId) { - mapOverlay.addLocation(location); + mapOverlay.addLocation(new Location(location)); } } while (cursor.moveToNext()); } else { diff --git a/MyTracks/src/com/google/android/apps/mytracks/NavControls.java b/MyTracks/src/com/google/android/apps/mytracks/NavControls.java index 3b402b851..9a5682d8c 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/NavControls.java +++ b/MyTracks/src/com/google/android/apps/mytracks/NavControls.java @@ -17,9 +17,11 @@ package com.google.android.apps.mytracks; import com.google.android.maps.mytracks.R; +import android.app.Activity; import android.content.Context; import android.graphics.drawable.Drawable; import android.os.Handler; +import android.util.DisplayMetrics; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; @@ -28,6 +30,7 @@ import android.view.animation.Animation; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.RelativeLayout.LayoutParams; +import android.widget.TextView; /** * Creates previous and next arrows for a given activity. @@ -55,16 +58,23 @@ public class NavControls { private final ImageView arrow; private final ImageView icon; - public TouchLayout(Context context, boolean isLeft) { - super(context); - arrow = new ImageView(context); - arrow.setImageDrawable(context.getResources().getDrawable( + public TouchLayout(Activity activity, boolean isLeft) { + super(activity); + arrow = new ImageView(activity); + arrow.setImageDrawable(activity.getResources().getDrawable( isLeft ? R.drawable.btn_arrow_left : R.drawable.btn_arrow_right)); - icon = new ImageView(context); + icon = new ImageView(activity); icon.setVisibility(View.GONE); addView(arrow); addView(icon); - icon.setPadding((isLeft ? 15 : 10), 27, 15, 0); + DisplayMetrics metrics = new DisplayMetrics(); + activity.getWindowManager().getDefaultDisplay().getMetrics(metrics); + // TODO: This should be a smooth function not a step function. + if (metrics.heightPixels > 600) { + icon.setPadding((isLeft ? 25 : 15), 39, 15, 0); + } else { + icon.setPadding((isLeft ? 15 : 10), 27, 15, 0); + } } public void setIcon(Drawable drawable) { @@ -114,9 +124,9 @@ public class NavControls { private boolean hasNext = true; private boolean hasPrev = true; - public NavControls(Context context, ViewGroup container, + public NavControls(Activity activity, ViewGroup container, Runnable prevRunnable, Runnable nextRunnable) { - this.context = context; + this.context = activity; this.prevRunnable = prevRunnable; this.nextRunnable = nextRunnable; LayoutParams prevParams = new LayoutParams( @@ -124,7 +134,7 @@ public class NavControls { LayoutParams.WRAP_CONTENT); prevParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); prevParams.addRule(RelativeLayout.CENTER_VERTICAL); - prevImage = new TouchLayout(context, true); + prevImage = new TouchLayout(activity, true); prevImage.setLayoutParams(prevParams); prevImage.setVisibility(View.INVISIBLE); container.addView(prevImage); @@ -133,7 +143,7 @@ public class NavControls { LayoutParams.WRAP_CONTENT); nextParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); nextParams.addRule(RelativeLayout.CENTER_VERTICAL); - nextImage = new TouchLayout(context, false); + nextImage = new TouchLayout(activity, false); nextImage.setLayoutParams(nextParams); nextImage.setVisibility(View.INVISIBLE); container.addView(nextImage); diff --git a/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProviderUtils.java b/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProviderUtils.java index b71e8440a..ff5b1e8e7 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProviderUtils.java +++ b/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProviderUtils.java @@ -206,6 +206,19 @@ public interface MyTracksProviderUtils { */ void getTrackPoints(Track track, TrackBuffer buffer); + /** + * Fetches some number of locations for the given track. + * + * This is designed to be used to stream through large tracks without loading + * all points into memory. + * This method will reuse the Location objects in the buffer. If you need a + * Location object copy the object. + * + * @param track to load locations for + * @param buffer an array of locations to fill + */ + void fillTrackPoints(Track track, TrackBuffer buffer); + /** * Creates a cursor over the tracks provider with a given selection. * Caller gets to own the returned cursor. Don't forget to close it. @@ -293,7 +306,15 @@ public interface MyTracksProviderUtils { * @return a new location object */ Location createLocation(Cursor cursor); - + + /** + * Fill a location object with values from a given cursor. + * + * @param cursor a cursor pointing at a db or provider with locations + * @param location a location object to be overwritten + */ + void fillLocation(Cursor cursor, Location location); + /** * Creates a waypoint object from a given cursor. * diff --git a/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProviderUtilsImpl.java b/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProviderUtilsImpl.java index e0e940bbe..19b4ca9be 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProviderUtilsImpl.java +++ b/MyTracks/src/com/google/android/apps/mytracks/content/MyTracksProviderUtilsImpl.java @@ -168,6 +168,13 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils { @Override public Location createLocation(Cursor cursor) { + Location location = new Location(""); + fillLocation(cursor, location); + return location; + } + + @Override + public void fillLocation(Cursor cursor, Location location) { int idxLatitude = cursor.getColumnIndexOrThrow(TrackPointsColumns.LATITUDE); int idxLongitude = cursor.getColumnIndexOrThrow(TrackPointsColumns.LONGITUDE); @@ -177,7 +184,6 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils { int idxAccuracy = cursor.getColumnIndexOrThrow(TrackPointsColumns.ACCURACY); int idxSpeed = cursor.getColumnIndexOrThrow(TrackPointsColumns.SPEED); - Location location = new Location(""); if (!cursor.isNull(idxLatitude)) { location.setLatitude(1. * cursor.getInt(idxLatitude) / 1E6); } @@ -199,7 +205,6 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils { if (!cursor.isNull(idxAccuracy)) { location.setAccuracy(cursor.getFloat(idxAccuracy)); } - return location; } @Override @@ -822,6 +827,16 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils { @Override public void getTrackPoints(Track track, TrackBuffer buffer) { + getTrackPoints(track, buffer, false); + } + + @Override + public void fillTrackPoints(Track track, TrackBuffer buffer) { + getTrackPoints(track, buffer, true); + } + + public void getTrackPoints(Track track, TrackBuffer buffer, + boolean reuseLocations) { long startingPoint = buffer.getLastLocationRead() == 0 ? track.getStartId() : buffer.getLastLocationRead(); buffer.reset(); @@ -849,11 +864,15 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils { final int idColumnIdx = cursor.getColumnIndexOrThrow(TrackPointsColumns._ID); do { - Location location = createLocation(cursor); - if (location == null) { - continue; + if (reuseLocations) { + fillLocation(cursor, buffer.location(cursor.getLong(idColumnIdx))); + } else { + Location location = createLocation(cursor); + if (location == null) { + continue; + } + buffer.add(location, cursor.getLong(idColumnIdx)); } - buffer.add(location, cursor.getLong(idColumnIdx)); } while (cursor.moveToNext()); if (buffer.getLocationsLoaded() == 0) { diff --git a/MyTracks/src/com/google/android/apps/mytracks/content/TrackBuffer.java b/MyTracks/src/com/google/android/apps/mytracks/content/TrackBuffer.java index 88d569002..f80b3c8f4 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/content/TrackBuffer.java +++ b/MyTracks/src/com/google/android/apps/mytracks/content/TrackBuffer.java @@ -94,6 +94,22 @@ public class TrackBuffer { buffer[locationsLoaded++] = location; lastLocationRead = Math.max(lastLocationRead, id); } + + /** + * Get a location from the end of the buffer. + * This may reuse Location objects already allocated to the buffer. + * @param id The of the location to be added. + * @return The location object associated with the give id. + */ + public Location location(long id) { + lastLocationRead = Math.max(lastLocationRead, id); + if (buffer[locationsLoaded] == null) { + buffer[locationsLoaded] = new Location(""); + } else { + buffer[locationsLoaded].reset(); + } + return buffer[locationsLoaded++]; + } /** * @return The id of the last location loaded into the buffer diff --git a/MyTracks/src/com/google/android/apps/mytracks/io/TrackWriter.java b/MyTracks/src/com/google/android/apps/mytracks/io/TrackWriter.java index 0554c2c02..4c3638c3a 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/io/TrackWriter.java +++ b/MyTracks/src/com/google/android/apps/mytracks/io/TrackWriter.java @@ -264,7 +264,7 @@ public class TrackWriter { while (buffer.getLastLocationRead() < track.getStopId()) { Log.d(MyTracksConstants.TAG, "Reading track points starting at: " + buffer.getLastLocationRead()); - providerUtils.getTrackPoints(track, buffer); + providerUtils.fillTrackPoints(track, buffer); if (!wroteFirst) { Location first = buffer.findStartLocation(); writer.writeBeginTrack(first);