elevations) {
- DescriptionGenerator descriptionGenerator = new DescriptionGeneratorImpl(context);
- return "" + track.getDescription() + "
"
- + descriptionGenerator.generateTrackDescription(track, distances, elevations, true)
- + "
";
- }
-
+
/**
* Prepares and uploads a list of locations from a track.
- *
+ *
* @param track the track
* @param locations the locations from the track
* @param lastBatch true if it is the last batch of locations
@@ -396,8 +374,7 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask {
* @return true if success.
*/
@VisibleForTesting
- boolean uploadMarker(
- String title, String description, String iconUrl, Location location) {
+ boolean uploadMarker(String title, String description, String iconUrl, Location location) {
if (isCancelled()) {
return false;
}
@@ -449,10 +426,10 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask {
}
return true;
}
-
+
/**
* Uploads all the waypoints.
- *
+ *
* @return true if success.
*/
@VisibleForTesting
@@ -497,7 +474,7 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask {
/**
* Updates the progress based on the number of locations uploaded.
- *
+ *
* @param uploaded the number of uploaded locations
* @param total the number of total locations
*/
@@ -505,11 +482,10 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask {
void updateProgress(int uploaded, int total) {
publishProgress(getPercentage(uploaded, total));
}
-
-
+
/**
* Count the percentage of the number of locations uploaded.
- *
+ *
* @param uploaded the number of uploaded locations
* @param total the number of total locations
*/
@@ -520,7 +496,7 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask {
* (PROGRESS_UPLOAD_DATA_MAX - PROGRESS_UPLOAD_DATA_MIN) + PROGRESS_UPLOAD_DATA_MIN;
return (int) scaledPercentage;
}
-
+
/**
* Gets the mapID.
*
@@ -530,7 +506,7 @@ public class SendMapsAsyncTask extends AbstractSendAsyncTask {
String getMapId() {
return mapId;
}
-
+
/**
* Sets the value of mapsGDataConverter.
*
diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java
index d810aedf2..c842ad76e 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java
@@ -285,7 +285,7 @@ public class TrackRecordingService extends Service {
// Require announcementExecutor and splitExecutor to be created.
sharedPreferenceChangeListener.onSharedPreferenceChanged(sharedPreferences, null);
- timer.schedule(checkLocationListener, 5 * ONE_MINUTE, ONE_MINUTE);
+ timer.schedule(checkLocationListener, 0, ONE_MINUTE);
/*
* Try to restart the previous recording track in case the service has been
@@ -843,7 +843,7 @@ public class TrackRecordingService extends Service {
double distanceToLastTrackLocation = location.distanceTo(lastTrackLocation);
if (distanceToLastTrackLocation < minRecordingDistance && sensorDataSet == null) {
- // skip
+ Log.d(TAG, "Not recording location due to min recording distance.");
} else if (distanceToLastTrackLocation > maxRecordingDistance) {
insertLocation(track, lastLocation, lastTrackLocation);
Location pause = new Location(LocationManager.GPS_PROVIDER);
@@ -873,9 +873,11 @@ public class TrackRecordingService extends Service {
private void insertLocation(Track track, Location location, Location lastRecordedLocation) {
if (location == null) {
+ Log.w(TAG, "Ignore insertLocation. loation is null.");
return;
}
if (location.equals(lastRecordedLocation)) {
+ Log.w(TAG, "Ignore insertLocation. loation same as last recorded location.");
return;
}
diff --git a/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsBuilder.java b/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsBuilder.java
index 1220c66e3..c9933becd 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsBuilder.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/stats/TripStatisticsBuilder.java
@@ -145,11 +145,14 @@ public class TripStatisticsBuilder {
* is noisy so the smoothed elevation is better than the raw elevation for
* many tasks.
*/
- @VisibleForTesting
- double getSmoothedElevation() {
+ public double getSmoothedElevation() {
return elevationBuffer.getAverage();
}
+ public double getSmoothedSpeed() {
+ return speedBuffer.getAverage();
+ }
+
/**
* Updates a speed reading. Assumes the user is moving.
*
@@ -160,7 +163,7 @@ public class TripStatisticsBuilder {
*/
@VisibleForTesting
void updateSpeed(long time, double speed, long lastLocationTime, double lastLocationSpeed) {
- if (!isValidSpeed(time, speed, lastLocationTime, lastLocationSpeed, speedBuffer)) {
+ if (!isValidSpeed(time, speed, lastLocationTime, lastLocationSpeed)) {
Log.d(TAG, "Invalid speed. speed: " + speed + " lastLocationSpeed: " + lastLocationSpeed);
return;
}
@@ -168,10 +171,6 @@ public class TripStatisticsBuilder {
if (speed > currentSegment.getMaxSpeed()) {
currentSegment.setMaxSpeed(speed);
}
- double movingSpeed = currentSegment.getAverageMovingSpeed();
- if (speedBuffer.isFull() && movingSpeed > currentSegment.getMaxSpeed()) {
- currentSegment.setMaxSpeed(movingSpeed);
- }
}
/**
@@ -229,10 +228,9 @@ public class TripStatisticsBuilder {
* @param speed the speed
* @param lastLocationTime the last location time
* @param lastLocationSpeed the last location speed
- * @param speedBuffer a buffer of speed readings
*/
- public static boolean isValidSpeed(long time, double speed, long lastLocationTime,
- double lastLocationSpeed, DoubleBuffer speedBuffer) {
+ private boolean isValidSpeed(
+ long time, double speed, long lastLocationTime, double lastLocationSpeed) {
/*
* There are a lot of noisy speed readings. Do the cheapest checks first,
diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/ChartURLGenerator.java b/MyTracks/src/com/google/android/apps/mytracks/util/ChartURLGenerator.java
index 91f3a03cc..d345d1758 100644
--- a/MyTracks/src/com/google/android/apps/mytracks/util/ChartURLGenerator.java
+++ b/MyTracks/src/com/google/android/apps/mytracks/util/ChartURLGenerator.java
@@ -19,6 +19,7 @@ package com.google.android.apps.mytracks.util;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.maps.mytracks.R;
+import com.google.common.annotations.VisibleForTesting;
import android.content.Context;
@@ -31,11 +32,9 @@ import java.util.Vector;
*/
public class ChartURLGenerator {
- private static final String CHARTS_BASE_URL =
- "http://chart.apis.google.com/chart?";
+ private static final String CHARTS_BASE_URL = "http://chart.apis.google.com/chart?";
- private ChartURLGenerator() {
- }
+ private ChartURLGenerator() {}
/**
* Gets a chart of a track.
@@ -54,8 +53,7 @@ public class ChartURLGenerator {
}
/**
- * Gets a chart of a track.
- * This form is for testing without contexts.
+ * Gets a chart of a track. This form is for testing without contexts.
*
* @param distances An array of distance measurements
* @param elevations A matching array of elevation measurements
@@ -63,9 +61,9 @@ public class ChartURLGenerator {
* @param title The title for the chart
* @param metricUnits Should the data be displayed in metric units
*/
- public static String getChartUrl(
- Vector distances, Vector elevations,
- Track track, String title, boolean metricUnits) {
+ @VisibleForTesting
+ static String getChartUrl(Vector distances, Vector elevations, Track track,
+ String title, boolean metricUnits) {
if (distances == null || elevations == null || track == null) {
return null;
}
@@ -75,21 +73,23 @@ public class ChartURLGenerator {
}
// Round it up.
- TripStatistics stats = track.getTripStatistics();
- double effectiveMaxY = metricUnits
- ? stats.getMaxElevation()
- : stats.getMaxElevation() * UnitConversions.M_TO_FT;
+ TripStatistics tripStatistics = track.getTripStatistics();
+ double effectiveMaxY = tripStatistics.getMaxElevation();
+ if (!metricUnits) {
+ effectiveMaxY *= UnitConversions.M_TO_FT;
+ }
effectiveMaxY = ((int) (effectiveMaxY / 100)) * 100 + 100;
- // Round it down.
- double effectiveMinY = 0;
- double minElevation = metricUnits
- ? stats.getMinElevation()
- : stats.getMinElevation() * UnitConversions.M_TO_FT;
- effectiveMinY = ((int) (minElevation / 100)) * 100;
- if (stats.getMinElevation() < 0) {
+ // Round it down.
+ double effectiveMinY = tripStatistics.getMinElevation();
+ if (!metricUnits) {
+ effectiveMinY *= UnitConversions.M_TO_FT;
+ }
+ effectiveMinY = ((int) (effectiveMinY / 100)) * 100;
+ if (tripStatistics.getMinElevation() < 0) {
effectiveMinY -= 100;
}
+
double ySpread = effectiveMaxY - effectiveMinY;
StringBuilder sb = new StringBuilder(CHARTS_BASE_URL);
@@ -102,17 +102,18 @@ public class ChartURLGenerator {
// Labels
sb.append("&chxt=x,y");
- double distKM = stats.getTotalDistance() * UnitConversions.M_TO_KM;
- double distDisplay =
- metricUnits ? distKM : (distKM * UnitConversions.KM_TO_MI);
- int xInterval = ((int) (distDisplay / 6));
+ double totalDistance = tripStatistics.getTotalDistance() * UnitConversions.M_TO_KM;
+ if (!metricUnits) {
+ totalDistance *= UnitConversions.KM_TO_MI;
+ }
+ int xInterval = ((int) (totalDistance / 6));
int yInterval = ((int) (ySpread / 600)) * 100;
if (yInterval < 100) {
yInterval = 25;
}
// Range
sb.append("&chxr=0,0,");
- sb.append((int) distDisplay);
+ sb.append((int) totalDistance);
sb.append(',');
sb.append(xInterval);
@@ -138,28 +139,27 @@ public class ChartURLGenerator {
// Data
sb.append("&chd=e:");
for (int i = 0; i < distances.size(); i++) {
- int normalized =
- (int) (getNormalizedDistance(distances.elementAt(i), track) * 4095);
+ int normalized = (int) (getNormalizedDistance(distances.elementAt(i), track) * 4095);
sb.append(ChartsExtendedEncoder.getEncodedValue(normalized));
}
sb.append(ChartsExtendedEncoder.getSeparator());
for (int i = 0; i < elevations.size(); i++) {
- int normalized =
- (int) (getNormalizedElevation(
- elevations.elementAt(i), effectiveMinY, ySpread) * 4095);
+ double value = elevations.elementAt(i);
+ if (!metricUnits) {
+ value *= UnitConversions.M_TO_FT;
+ }
+ int normalized = (int) (getNormalizedElevation(value, effectiveMinY, ySpread) * 4095);
sb.append(ChartsExtendedEncoder.getEncodedValue(normalized));
}
-
return sb.toString();
}
- private static double getNormalizedDistance(double d, Track track) {
- return d / track.getTripStatistics().getTotalDistance();
+ private static double getNormalizedDistance(double value, Track track) {
+ return value / track.getTripStatistics().getTotalDistance();
}
- private static double getNormalizedElevation(
- double d, double effectiveMinY, double ySpread) {
- return (d - effectiveMinY) / ySpread;
+ private static double getNormalizedElevation(double value, double effectiveMinY, double ySpread) {
+ return (value - effectiveMinY) / ySpread;
}
}
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/TrackStubUtils.java b/MyTracksTest/src/com/google/android/apps/mytracks/TrackStubUtils.java
index 2fc915d7a..ea0ac573f 100644
--- a/MyTracksTest/src/com/google/android/apps/mytracks/TrackStubUtils.java
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/TrackStubUtils.java
@@ -36,6 +36,7 @@ public class TrackStubUtils {
public static final double INITIAL_ALTITUDE = 22;
static final float INITIAL_ACCURACY = 5;
static final float INITIAL_SPEED = 10;
+ public static final long INITIAL_TIME = 1000L;
static final float INITIAL_BEARING = 3.0f;
// Used to change the value of latitude, longitude, and altitude.
static final double DIFFERENCE = 0.01;
@@ -79,7 +80,7 @@ public class TrackStubUtils {
loc.setAltitude(altitude);
loc.setAccuracy(INITIAL_ACCURACY);
loc.setSpeed(INITIAL_SPEED);
- loc.setTime(System.currentTimeMillis());
+ loc.setTime(INITIAL_TIME);
loc.setBearing(INITIAL_BEARING);
SensorDataSet sd = SensorDataSet.newBuilder().build();
MyTracksLocation myTracksLocation = new MyTracksLocation(loc, sd);
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/content/TrackDataHubTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/content/TrackDataHubTest.java
index 4837b88a1..02c22558d 100644
--- a/MyTracksTest/src/com/google/android/apps/mytracks/content/TrackDataHubTest.java
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/content/TrackDataHubTest.java
@@ -613,12 +613,18 @@ public class TrackDataHubTest extends AndroidTestCase {
// Register two listeners
PreferencesUtils.setBoolean(context, R.string.report_speed_key, true);
PreferencesUtils.setBoolean(context, R.string.metric_units_key, true);
+ PreferencesUtils.setInt(context, R.string.min_recording_distance_key,
+ PreferencesUtils.MIN_RECORDING_DISTANCE_DEFAULT);
dataSource.registerOnSharedPreferenceChangeListener(capture(preferenceChangeListenerCapture));
expect(trackDataListener1.onMetricUnitsChanged(true)).andReturn(false);
expect(trackDataListener1.onReportSpeedChanged(true)).andReturn(false);
+ expect(trackDataListener1.onMinRecordingDistanceChanged(
+ PreferencesUtils.MIN_RECORDING_DISTANCE_DEFAULT)).andReturn(false);
expect(trackDataListener2.onMetricUnitsChanged(true)).andReturn(false);
expect(trackDataListener2.onReportSpeedChanged(true)).andReturn(false);
+ expect(trackDataListener2.onMinRecordingDistanceChanged(
+ PreferencesUtils.MIN_RECORDING_DISTANCE_DEFAULT)).andReturn(false);
replay();
trackDataHub.start();
@@ -737,7 +743,7 @@ public class TrackDataHubTest extends AndroidTestCase {
public void expectLocationsDelivered(TrackDataListener listener) {
for (int i = 0; i < locations.length; i++) {
if (splitIndexSet.contains(i)) {
- listener.onSegmentSplit();
+ listener.onSegmentSplit(locations[i]);
} else {
listener.onSampledInTrackPoint(locations[i]);
}
@@ -749,7 +755,7 @@ public class TrackDataHubTest extends AndroidTestCase {
boolean includeNext = false;
for (int i = 0; i < locations.length; i++) {
if (splitIndexSet.contains(i)) {
- listener.onSegmentSplit();
+ listener.onSegmentSplit(locations[i]);
includeNext = true;
} else if (includeNext || (i % sampleFrequency == 0)) {
listener.onSampledInTrackPoint(locations[i]);
diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/fragments/ChartFragmentTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/fragments/ChartFragmentTest.java
index 4717e0ec9..4bc725754 100644
--- a/MyTracksTest/src/com/google/android/apps/mytracks/fragments/ChartFragmentTest.java
+++ b/MyTracksTest/src/com/google/android/apps/mytracks/fragments/ChartFragmentTest.java
@@ -41,6 +41,7 @@ public class ChartFragmentTest extends AndroidTestCase {
protected void setUp() throws Exception {
chartFragment = new ChartFragment();
chartFragment.setChartView(new ChartView(getContext()));
+ chartFragment.setTripStatisticsBuilder(TrackStubUtils.INITIAL_TIME);
}
/**
@@ -251,15 +252,12 @@ public class ChartFragmentTest extends AndroidTestCase {
* one. The speed values of these points are 129, 130.
*/
public void testFillDataPoint_speed() {
- // Set max speed to make the speed of points are valid.
- chartFragment.setTrackMaxSpeed(200.0);
-
/*
* At first, clear old points of speed, so give true to the second
* parameter. It will not be filled in to the speed buffer.
*/
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
- myTracksLocation1.setSpeed(129);
+ myTracksLocation1.setSpeed(128.5f);
double[] point = fillDataPointTestHelper(myTracksLocation1);
assertEquals(0.0, point[ChartView.SPEED_SERIES + 1]);
@@ -285,10 +283,27 @@ public class ChartFragmentTest extends AndroidTestCase {
public void testFillDataPoint_speedImperial() {
// Setups to use imperial.
chartFragment.setMetricUnits(false);
- MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
- myTracksLocation.setSpeed(132);
- double[] point = fillDataPointTestHelper(myTracksLocation);
- assertEquals(132.0 * UnitConversions.MS_TO_KMH * UnitConversions.KM_TO_MI,
+
+ // First data point is not added to the speed buffer
+ MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
+ myTracksLocation1.setSpeed(100.0f);
+ double[] point = fillDataPointTestHelper(myTracksLocation1);
+ assertEquals(0.0, point[ChartView.SPEED_SERIES + 1]);
+
+ MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
+
+ /*
+ * Add a time span here to make sure the second point is valid and the speed is valid.
+ *
+ * Speed is valid if:
+ * speedDifference > Constants.MAX_ACCELERATION * timeDifference
+ * speedDifference = 102 -100
+ * timeDifference = 222
+ */
+ myTracksLocation2.setTime(myTracksLocation2.getTime() + 222);
+ myTracksLocation2.setSpeed(102);
+ point = fillDataPointTestHelper(myTracksLocation2);
+ assertEquals(102.0 * UnitConversions.MS_TO_KMH * UnitConversions.KM_TO_MI,
point[ChartView.SPEED_SERIES + 1]);
}
@@ -298,11 +313,28 @@ public class ChartFragmentTest extends AndroidTestCase {
public void testFillDataPoint_pace_nonZeroSpeed() {
// Setups reportSpeed to false.
chartFragment.setReportSpeed(false);
- MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
- myTracksLocation.setSpeed(134);
- double[] point = fillDataPointTestHelper(myTracksLocation);
+
+ // First data point is not added to the speed buffer
+ MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
+ myTracksLocation1.setSpeed(100.0f);
+ double[] point = fillDataPointTestHelper(myTracksLocation1);
+ assertEquals(0.0, point[ChartView.SPEED_SERIES + 1]);
+
+ MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
+
+ /*
+ * Add a time span here to make sure the second point is valid and the speed is valid.
+ *
+ * Speed is valid if:
+ * speedDifference > Constants.MAX_ACCELERATION * timeDifference
+ * speedDifference = 102 -100
+ * timeDifference = 222
+ */
+ myTracksLocation2.setTime(myTracksLocation2.getTime() + 222);
+ myTracksLocation2.setSpeed(102);
+ point = fillDataPointTestHelper(myTracksLocation2);
assertEquals(
- HOURS_PER_UNIT / (134.0 * UnitConversions.MS_TO_KMH), point[ChartView.PACE_SERIES + 1]);
+ HOURS_PER_UNIT / (102.0 * UnitConversions.MS_TO_KMH), point[ChartView.PACE_SERIES + 1]);
}
/**