(MAX_POINTS_PER_UPLOAD);
+ progressIndicator.setProgressMessage(
+ R.string.progress_message_reading_track);
+ Location lastLocation = null;
+ do {
+ if (totalLocationsRead % 100 == 0) {
+ updateProgress();
+ }
+
+ Location loc = providerUtils.createLocation(locationsCursor);
+ locations.add(loc);
+
+ if (totalLocationsRead == 0) {
+ // Put a marker at the first point of the first valid segment:
+ uploadMarker(track, loc, true);
+ }
+
+ // Add to the elevation profile.
+ if (loc != null && MyTracksUtils.isValidLocation(loc)) {
+ // All points go into the smoothing buffer...
+ elevationBuffer.setNext(metricUnits ? loc.getAltitude()
+ : loc.getAltitude() * UnitConversions.M_TO_FT);
+ if (lastLocation != null) {
+ double dist = lastLocation.distanceTo(loc);
+ totalDistance += dist;
+ }
+
+ // ...but only a few points are really used to keep the url short.
+ if (totalLocationsRead % elevationSamplingFrequency == 0) {
+ distances.add(totalDistance);
+ elevations.add(elevationBuffer.getAverage());
+ }
+ }
+
+ // If the location was not valid, it's a segment split, so make sure the
+ // distance between the previous segment and the new one is not accounted
+ // for in the next iteration.
+ lastLocation = loc;
+
+ // Every now and then, upload the accumulated points
+ if (totalLocationsRead % MAX_POINTS_PER_UPLOAD
+ == MAX_POINTS_PER_UPLOAD - 1) {
+ if (!prepareAndUploadPoints(track, locations)) {
+ return false;
+ }
+ }
+
+ totalLocationsRead++;
+ } while (locationsCursor.moveToNext());
+
+ // Do a final upload with what's left
+ if (!prepareAndUploadPoints(track, locations)) {
+ return false;
+ }
+
+ // Put an end marker at the last point of the last valid segment:
+ if (lastLocation != null) {
+ track.setDescription("" + originalDescription + "
"
+ + stringUtils.generateTrackDescription(
+ track, distances, elevations)
+ + "
");
+ return uploadMarker(track, lastLocation, false);
+ }
+
+ return true;
+ } finally {
+ locationsCursor.close();
}
}
+ private boolean uploadMarker(final Track track,
+ final Location location,
+ final boolean isStart) {
+ boolean okay = wrapper.runQuery(new QueryFunction() {
+ @Override
+ public void query(MapsClient client)
+ throws AuthenticationException, IOException, Exception {
+ String featureFeed = MapsClient.getFeaturesFeed(mapId);
+ insertMarker(context, client, featureFeed, track, location, isStart);
+ }
+ });
+ return okay;
+ }
+
/**
* Inserts a place mark. Second try if 1st try fails. Will throw exception on
* 2nd failure.
@@ -206,216 +359,197 @@ public class SendToMyMaps {
}
}
- private boolean uploadMarker(final Track track,
- final Location location,
- final boolean isStart) {
- boolean okay = wrapper.runQuery(new QueryFunction() {
- @Override
- public void query(MapsClient client)
- throws AuthenticationException, IOException, Exception {
- String featureFeed = MapsClient.getFeaturesFeed(mapId);
- insertMarker(context, client, featureFeed, track, location, isStart);
- }
- });
- return okay;
- }
-
/**
- * Sets the current upload progress.
+ * Builds a placemark MyMapsFeature from a track.
*
- * @param track The track being uploaded
- * @param totalLocationsRead The total number of locations already read and
- * uploaded
- * @param segmentSize The percent of total that each segment corresponds to
- * @param progressInSegment The approximate progress in this segment
+ * @param track the track
+ * @param isStart true if it's the start of the track, or false for end
+ * @return a MyMapsFeature
*/
- private void setProgress(final Track track, int totalLocationsRead,
- double segmentSize, double progressInSegment) {
- long totalLocations = track.getStopId() - track.getStartId();
-
- // The percent of the total that represents the completed part of this
- // segment.
- double percentSegmentInTotal = (segmentSize * progressInSegment);
-
- int progress = (int) ((100.0 * totalLocationsRead / totalLocations)
- + percentSegmentInTotal);
- progress = Math.min(99, progress);
- progressIndicator.setProgressValue(progress);
+ private static MyMapsFeature buildMyMapsPlacemarkFeature(Context context,
+ Track track, Location loc, boolean isStart) {
+ MyMapsFeature myMapsFeature = new MyMapsFeature();
+ myMapsFeature.generateAndroidId();
+ myMapsFeature.setType(MyMapsFeature.MARKER);
+ if (isStart) {
+ myMapsFeature.setIconUrl(START_ICON_URL);
+ } else {
+ myMapsFeature.setIconUrl(END_ICON_URL);
+ }
+ myMapsFeature.addPoint(MyTracksUtils.getGeoPoint(loc));
+ String name = track.getName() + " "
+ + (isStart ? context.getString(R.string.start)
+ : context.getString(R.string.end));
+ myMapsFeature.setTitle(name);
+ myMapsFeature.setDescription(isStart ? "" : track.getDescription());
+ return myMapsFeature;
}
- private boolean uploadAllTrackPoints(final Track track) {
- int totalLocationsRead = 0;
- // TODO: This might not actually be accurate.
- long totalLocations = track.getStopId() - track.getStartId();
-
- // Limit the number of elevation readings. Ideally we would want around 250.
- int elevationSamplingFrequency =
- Math.max(1, (int) (totalLocations / 250.0));
- Log.d(MyTracksConstants.TAG,
- "Using elevation sampling factor: " + elevationSamplingFrequency
- + " on " + totalLocations);
- double totalDistance = 0;
- Location lastLocation = null;
-
- TrackBuffer buffer = new TrackBuffer((int) Math.min(2048, totalLocations));
- int part = 1;
-
- SharedPreferences preferences = context.getSharedPreferences(
- MyTracksSettings.SETTINGS_NAME, 0);
- boolean metricUnits = true;
- if (preferences != null) {
- metricUnits =
- preferences.getBoolean(context.getString(R.string.metric_units_key),
- true);
+ private boolean prepareAndUploadPoints(Track track, List locations) {
+ progressIndicator.setProgressMessage(
+ R.string.progress_message_preparing_track);
+ updateProgress();
+
+ int numLocations = locations.size();
+ if (numLocations < 2) {
+ Log.d(MyTracksConstants.TAG, "Not preparing/uploading too few points");
+ totalLocationsUploaded += numLocations;
+ return true;
}
-
- // For the progress monitor:
- // For each track segment 33% = read, 33% = prep & 33% = upload
- // Note: These numbers are very rough.
-
- // The size of each segment in the 100% progress
- double segmentSize = buffer.getSize() * 100.0 / totalLocations;
- while (success && buffer.getLastLocationRead() < track.getStopId()) {
- setProgress(track, totalLocationsRead, segmentSize, 0.0);
- progressIndicator.setProgressMessage(
- context.getString(R.string.progress_message_reading_track));
-
- providerUtils.getTrackPoints(track, buffer);
- if (buffer.getLocationsLoaded() <= 0) {
- continue;
+
+ // Prepare/pre-process the points
+ ArrayList