Submit my changes before merging.

This commit is contained in:
Sandor Dornbush
2010-09-23 11:02:45 -07:00
parent d05c394c68
commit 19a770445e
7 changed files with 101 additions and 26 deletions
@@ -176,12 +176,16 @@ public class ChartActivity extends Activity implements
final int idColumnIdx = final int idColumnIdx =
cursor.getColumnIndexOrThrow(TrackPointsColumns._ID); cursor.getColumnIndexOrThrow(TrackPointsColumns._ID);
ArrayList<double[]> data = new ArrayList<double[]>(); ArrayList<double[]> data = new ArrayList<double[]>();
// Need two locations so we can keep track of the last location.
Location[] locations = { new Location(""), new Location("")};
int i = 0;
do { do {
lastSeenLocationId = cursor.getLong(idColumnIdx); lastSeenLocationId = cursor.getLong(idColumnIdx);
Location location = providerUtils.createLocation(cursor); providerUtils.fillLocation(cursor, locations[i]);
if (location != null && MyTracksUtils.isValidLocation(location)) { if (MyTracksUtils.isValidLocation(locations[i])) {
data.add(getDataPoint(location, track)); data.add(getDataPoint(locations[i], track));
} }
i = (i + 1) % 2;
} while (cursor.moveToPrevious()); } while (cursor.moveToPrevious());
cv.addDataPoints(data); cv.addDataPoints(data);
} }
@@ -556,6 +560,9 @@ public class ChartActivity extends Activity implements
try { try {
final ArrayList<double[]> theData = new ArrayList<double[]>(); final ArrayList<double[]> theData = new ArrayList<double[]>();
int points = 0; 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()) { while (lastLocationRead < track.getStopId()) {
cursor = providerUtils.getLocationsCursor( cursor = providerUtils.getLocationsCursor(
selectedTrackId, lastLocationRead, bufferSize, false); selectedTrackId, lastLocationRead, bufferSize, false);
@@ -567,15 +574,16 @@ public class ChartActivity extends Activity implements
cursor.getColumnIndexOrThrow(TrackPointsColumns._ID); cursor.getColumnIndexOrThrow(TrackPointsColumns._ID);
while (cursor.moveToNext()) { while (cursor.moveToNext()) {
points++; points++;
Location location = providerUtils.createLocation(cursor); providerUtils.fillLocation(cursor, locations[i]);
if (MyTracksUtils.isValidLocation(location)) { if (MyTracksUtils.isValidLocation(locations[i])) {
lastLocationRead = lastSeenLocationId = lastLocationRead = lastSeenLocationId =
cursor.getLong(idColumnIdx); cursor.getLong(idColumnIdx);
double[] point = getDataPoint(location, track); double[] point = getDataPoint(locations[i], track);
if (points % chartSamplingFrequency == 0) { if (points % chartSamplingFrequency == 0) {
theData.add(point); theData.add(point);
} }
} }
i = (i + 1) % 2;
} }
} else { } else {
lastLocationRead += bufferSize; lastLocationRead += bufferSize;
@@ -1002,6 +1002,7 @@ public class MyTracksMap extends MapActivity
int bufferSize = 1024; int bufferSize = 1024;
int points = 0; int points = 0;
long tailLocationId = selectedTrack.getStopId() - 10; long tailLocationId = selectedTrack.getStopId() - 10;
Location location;
while (lastSeenLocationId < (selectedTrack.getStopId() + 10)) { while (lastSeenLocationId < (selectedTrack.getStopId() + 10)) {
cursor = providerUtils.getLocationsCursor( cursor = providerUtils.getLocationsCursor(
selectedTrack.getId(), lastSeenLocationId + 1, bufferSize, false); selectedTrack.getId(), lastSeenLocationId + 1, bufferSize, false);
@@ -1010,7 +1011,7 @@ public class MyTracksMap extends MapActivity
TrackPointsColumns._ID); TrackPointsColumns._ID);
do { do {
points++; points++;
Location location = providerUtils.createLocation(cursor); location = providerUtils.createLocation(cursor);
lastSeenLocationId = cursor.getLong(idColumnIdx); lastSeenLocationId = cursor.getLong(idColumnIdx);
// Include a point if it fits one of the following criteria: // Include a point if it fits one of the following criteria:
// - Has the mod for the sampling frequency. // - Has the mod for the sampling frequency.
@@ -1021,7 +1022,7 @@ public class MyTracksMap extends MapActivity
points % samplingFrequency == 0 || points % samplingFrequency == 0 ||
points == 0 || points == 0 ||
lastSeenLocationId > tailLocationId) { lastSeenLocationId > tailLocationId) {
mapOverlay.addLocation(location); mapOverlay.addLocation(new Location(location));
} }
} while (cursor.moveToNext()); } while (cursor.moveToNext());
} else { } else {
@@ -17,9 +17,11 @@ package com.google.android.apps.mytracks;
import com.google.android.maps.mytracks.R; import com.google.android.maps.mytracks.R;
import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Handler; import android.os.Handler;
import android.util.DisplayMetrics;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@@ -28,6 +30,7 @@ import android.view.animation.Animation;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.RelativeLayout.LayoutParams; import android.widget.RelativeLayout.LayoutParams;
import android.widget.TextView;
/** /**
* Creates previous and next arrows for a given activity. * Creates previous and next arrows for a given activity.
@@ -55,16 +58,23 @@ public class NavControls {
private final ImageView arrow; private final ImageView arrow;
private final ImageView icon; private final ImageView icon;
public TouchLayout(Context context, boolean isLeft) { public TouchLayout(Activity activity, boolean isLeft) {
super(context); super(activity);
arrow = new ImageView(context); arrow = new ImageView(activity);
arrow.setImageDrawable(context.getResources().getDrawable( arrow.setImageDrawable(activity.getResources().getDrawable(
isLeft ? R.drawable.btn_arrow_left : R.drawable.btn_arrow_right)); isLeft ? R.drawable.btn_arrow_left : R.drawable.btn_arrow_right));
icon = new ImageView(context); icon = new ImageView(activity);
icon.setVisibility(View.GONE); icon.setVisibility(View.GONE);
addView(arrow); addView(arrow);
addView(icon); 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) { public void setIcon(Drawable drawable) {
@@ -114,9 +124,9 @@ public class NavControls {
private boolean hasNext = true; private boolean hasNext = true;
private boolean hasPrev = true; private boolean hasPrev = true;
public NavControls(Context context, ViewGroup container, public NavControls(Activity activity, ViewGroup container,
Runnable prevRunnable, Runnable nextRunnable) { Runnable prevRunnable, Runnable nextRunnable) {
this.context = context; this.context = activity;
this.prevRunnable = prevRunnable; this.prevRunnable = prevRunnable;
this.nextRunnable = nextRunnable; this.nextRunnable = nextRunnable;
LayoutParams prevParams = new LayoutParams( LayoutParams prevParams = new LayoutParams(
@@ -124,7 +134,7 @@ public class NavControls {
LayoutParams.WRAP_CONTENT); LayoutParams.WRAP_CONTENT);
prevParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT); prevParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
prevParams.addRule(RelativeLayout.CENTER_VERTICAL); prevParams.addRule(RelativeLayout.CENTER_VERTICAL);
prevImage = new TouchLayout(context, true); prevImage = new TouchLayout(activity, true);
prevImage.setLayoutParams(prevParams); prevImage.setLayoutParams(prevParams);
prevImage.setVisibility(View.INVISIBLE); prevImage.setVisibility(View.INVISIBLE);
container.addView(prevImage); container.addView(prevImage);
@@ -133,7 +143,7 @@ public class NavControls {
LayoutParams.WRAP_CONTENT); LayoutParams.WRAP_CONTENT);
nextParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT); nextParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
nextParams.addRule(RelativeLayout.CENTER_VERTICAL); nextParams.addRule(RelativeLayout.CENTER_VERTICAL);
nextImage = new TouchLayout(context, false); nextImage = new TouchLayout(activity, false);
nextImage.setLayoutParams(nextParams); nextImage.setLayoutParams(nextParams);
nextImage.setVisibility(View.INVISIBLE); nextImage.setVisibility(View.INVISIBLE);
container.addView(nextImage); container.addView(nextImage);
@@ -206,6 +206,19 @@ public interface MyTracksProviderUtils {
*/ */
void getTrackPoints(Track track, TrackBuffer buffer); 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. * Creates a cursor over the tracks provider with a given selection.
* Caller gets to own the returned cursor. Don't forget to close it. * 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 * @return a new location object
*/ */
Location createLocation(Cursor cursor); 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. * Creates a waypoint object from a given cursor.
* *
@@ -168,6 +168,13 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
@Override @Override
public Location createLocation(Cursor cursor) { 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 idxLatitude = cursor.getColumnIndexOrThrow(TrackPointsColumns.LATITUDE);
int idxLongitude = int idxLongitude =
cursor.getColumnIndexOrThrow(TrackPointsColumns.LONGITUDE); cursor.getColumnIndexOrThrow(TrackPointsColumns.LONGITUDE);
@@ -177,7 +184,6 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
int idxAccuracy = cursor.getColumnIndexOrThrow(TrackPointsColumns.ACCURACY); int idxAccuracy = cursor.getColumnIndexOrThrow(TrackPointsColumns.ACCURACY);
int idxSpeed = cursor.getColumnIndexOrThrow(TrackPointsColumns.SPEED); int idxSpeed = cursor.getColumnIndexOrThrow(TrackPointsColumns.SPEED);
Location location = new Location("");
if (!cursor.isNull(idxLatitude)) { if (!cursor.isNull(idxLatitude)) {
location.setLatitude(1. * cursor.getInt(idxLatitude) / 1E6); location.setLatitude(1. * cursor.getInt(idxLatitude) / 1E6);
} }
@@ -199,7 +205,6 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
if (!cursor.isNull(idxAccuracy)) { if (!cursor.isNull(idxAccuracy)) {
location.setAccuracy(cursor.getFloat(idxAccuracy)); location.setAccuracy(cursor.getFloat(idxAccuracy));
} }
return location;
} }
@Override @Override
@@ -822,6 +827,16 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
@Override @Override
public void getTrackPoints(Track track, TrackBuffer buffer) { 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() long startingPoint = buffer.getLastLocationRead() == 0 ? track.getStartId()
: buffer.getLastLocationRead(); : buffer.getLastLocationRead();
buffer.reset(); buffer.reset();
@@ -849,11 +864,15 @@ public class MyTracksProviderUtilsImpl implements MyTracksProviderUtils {
final int idColumnIdx = final int idColumnIdx =
cursor.getColumnIndexOrThrow(TrackPointsColumns._ID); cursor.getColumnIndexOrThrow(TrackPointsColumns._ID);
do { do {
Location location = createLocation(cursor); if (reuseLocations) {
if (location == null) { fillLocation(cursor, buffer.location(cursor.getLong(idColumnIdx)));
continue; } else {
Location location = createLocation(cursor);
if (location == null) {
continue;
}
buffer.add(location, cursor.getLong(idColumnIdx));
} }
buffer.add(location, cursor.getLong(idColumnIdx));
} while (cursor.moveToNext()); } while (cursor.moveToNext());
if (buffer.getLocationsLoaded() == 0) { if (buffer.getLocationsLoaded() == 0) {
@@ -94,6 +94,22 @@ public class TrackBuffer {
buffer[locationsLoaded++] = location; buffer[locationsLoaded++] = location;
lastLocationRead = Math.max(lastLocationRead, id); 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 * @return The id of the last location loaded into the buffer
@@ -264,7 +264,7 @@ public class TrackWriter {
while (buffer.getLastLocationRead() < track.getStopId()) { while (buffer.getLastLocationRead() < track.getStopId()) {
Log.d(MyTracksConstants.TAG, Log.d(MyTracksConstants.TAG,
"Reading track points starting at: " + buffer.getLastLocationRead()); "Reading track points starting at: " + buffer.getLastLocationRead());
providerUtils.getTrackPoints(track, buffer); providerUtils.fillTrackPoints(track, buffer);
if (!wroteFirst) { if (!wroteFirst) {
Location first = buffer.findStartLocation(); Location first = buffer.findStartLocation();
writer.writeBeginTrack(first); writer.writeBeginTrack(first);