Merge heads

This commit is contained in:
youtaol
2013-01-04 15:06:31 +08:00
parent f371e9e0e2
commit d7b4eeb05b
54 changed files with 703 additions and 2455 deletions
@@ -1,14 +1,5 @@
#Tue Jul 17 10:23:26 PDT 2012
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
org.eclipse.jdt.core.compiler.problem.deadCode=warning
@@ -17,7 +8,6 @@ org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
@@ -74,7 +64,6 @@ org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disa
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field=1585
org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field.count_dependent=1585|-1|1585
@@ -17,6 +17,7 @@
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.stats.ExtremityMonitor;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.StringUtils;
@@ -565,7 +566,7 @@ public class ChartView extends View {
x, topBorder + spacer + markerHeight / 2, x, topBorder + effectiveHeight, markerPaint);
canvas.translate(
x - (float) (markerWidth * MapOverlay.WAYPOINT_X_ANCHOR), topBorder + spacer);
if (waypoints.get(i).getType() == Waypoint.TYPE_STATISTICS) {
if (waypoints.get(i).getType() == WaypointType.STATISTICS) {
statisticsMarker.draw(canvas);
} else {
waypointMarker.draw(canvas);
@@ -174,7 +174,7 @@ public class ImportAsyncTask extends AsyncTask<Void, Integer, Boolean> {
try {
int minRecordingDistance = PreferencesUtils.getInt(importActivity,
R.string.min_recording_distance_key, PreferencesUtils.MIN_RECORDING_DISTANCE_DEFAULT);
long trackIds[] = GpxImporter.importGPXFile(
long trackIds[] = GpxImporter.importGPXFile(importActivity,
new FileInputStream(file), myTracksProviderUtils, minRecordingDistance);
int length = trackIds.length;
if (length > 0) {
@@ -19,6 +19,7 @@ package com.google.android.apps.mytracks;
import static com.google.android.apps.mytracks.Constants.TAG;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.maps.TrackPath;
import com.google.android.apps.mytracks.maps.TrackPathFactory;
import com.google.android.apps.mytracks.util.LocationUtils;
@@ -274,7 +275,7 @@ public class MapOverlay {
for (Waypoint waypoint : waypoints) {
Location location = waypoint.getLocation();
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
int drawableId = waypoint.getType() == Waypoint.TYPE_STATISTICS ? R.drawable.yellow_pushpin
int drawableId = waypoint.getType() == WaypointType.STATISTICS ? R.drawable.yellow_pushpin
: R.drawable.blue_pushpin;
MarkerOptions markerOptions = new MarkerOptions().position(latLng)
.anchor(WAYPOINT_X_ANCHOR, WAYPOINT_Y_ANCHOR).draggable(false).visible(true)
@@ -18,6 +18,7 @@ package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.fragments.DeleteOneMarkerDialogFragment;
import com.google.android.apps.mytracks.util.IntentUtils;
import com.google.android.apps.mytracks.util.StatsUtils;
@@ -78,7 +79,7 @@ public class MarkerDetailActivity extends AbstractMyTracksActivity {
return;
}
name.setText(getString(R.string.generic_name_line, waypoint.getName()));
if (waypoint.getType() == Waypoint.TYPE_WAYPOINT) {
if (waypoint.getType() == WaypointType.WAYPOINT) {
waypointSection.setVisibility(View.VISIBLE);
statisticsSection.setVisibility(View.GONE);
@@ -18,8 +18,8 @@ package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
import com.google.android.apps.mytracks.content.WaypointCreationRequest.WaypointType;
import com.google.android.apps.mytracks.services.TrackRecordingServiceConnection;
import com.google.android.apps.mytracks.util.TrackRecordingServiceConnectionUtils;
import com.google.android.maps.mytracks.R;
@@ -131,7 +131,7 @@ public class MarkerEditActivity extends AbstractMyTracksActivity {
statisticsSection.setVisibility(View.GONE);
waypointSection.setVisibility(View.VISIBLE);
int nextWaypointNumber = trackId == -1L ? -1
: MyTracksProviderUtils.Factory.get(this).getNextWaypointNumber(trackId, false);
: MyTracksProviderUtils.Factory.get(this).getNextWaypointNumber(trackId, WaypointType.WAYPOINT);
if (nextWaypointNumber == -1) {
nextWaypointNumber = 0;
}
@@ -146,7 +146,7 @@ public class MarkerEditActivity extends AbstractMyTracksActivity {
finish();
return;
}
boolean statistics = waypoint.getType() == Waypoint.TYPE_STATISTICS;
boolean statistics = waypoint.getType() == WaypointType.STATISTICS;
statisticsSection.setVisibility(statistics ? View.VISIBLE : View.GONE);
waypointSection.setVisibility(statistics ? View.GONE : View.VISIBLE);
if (statistics) {
@@ -178,7 +178,7 @@ public class MarkerEditActivity extends AbstractMyTracksActivity {
* Saves a marker.
*/
private void saveMarker() {
boolean statistics = waypoint.getType() == Waypoint.TYPE_STATISTICS;
boolean statistics = waypoint.getType() == WaypointType.STATISTICS;
if (statistics) {
waypoint.setName(statisticsName.getText().toString());
} else {
@@ -17,7 +17,7 @@
package com.google.android.apps.mytracks;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.content.WaypointsColumns;
import com.google.android.apps.mytracks.fragments.DeleteOneMarkerDialogFragment;
import com.google.android.apps.mytracks.util.ApiAdapterFactory;
@@ -149,7 +149,8 @@ public class MarkerListActivity extends AbstractMyTracksActivity {
int timeIndex = cursor.getColumnIndexOrThrow(WaypointsColumns.TIME);
int descriptionIndex = cursor.getColumnIndex(WaypointsColumns.DESCRIPTION);
boolean statistics = cursor.getInt(typeIndex) == Waypoint.TYPE_STATISTICS;
boolean statistics = WaypointType.values()[cursor.getInt(typeIndex)]
== WaypointType.STATISTICS;
int iconId = statistics ? R.drawable.yellow_pushpin : R.drawable.blue_pushpin;
String category = statistics ? null : cursor.getString(categoryIndex);
String description = statistics ? null : cursor.getString(descriptionIndex);
@@ -23,6 +23,7 @@ import com.google.android.apps.mytracks.content.SearchEngine.SearchQuery;
import com.google.android.apps.mytracks.content.SearchEngineProvider;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.fragments.DeleteOneMarkerDialogFragment;
import com.google.android.apps.mytracks.fragments.DeleteOneTrackDialogFragment;
import com.google.android.apps.mytracks.fragments.DeleteOneTrackDialogFragment.DeleteOneTrackCaller;
@@ -432,7 +433,7 @@ public class SearchListActivity extends AbstractMyTracksActivity implements Dele
}
}
boolean statistics = waypoint.getType() == Waypoint.TYPE_STATISTICS;
boolean statistics = waypoint.getType() == WaypointType.STATISTICS;
long time = waypoint.getLocation().getTime();
resultMap.put(IS_RECORDING_FIELD, false);
@@ -13,16 +13,25 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.Constants;
import com.google.android.apps.mytracks.content.DescriptionGeneratorImpl;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.services.TrackRecordingService;
import com.google.android.apps.mytracks.stats.TripStatistics;
import com.google.android.apps.mytracks.stats.TripStatisticsUpdater;
import com.google.android.apps.mytracks.util.LocationUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.apps.mytracks.util.TrackIconUtils;
import com.google.android.maps.mytracks.R;
import android.content.Context;
import android.database.Cursor;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
@@ -52,25 +61,67 @@ import org.xml.sax.helpers.DefaultHandler;
*/
public class GpxImporter extends DefaultHandler {
// GPX tag names and attributes
/**
* Data for the current track.
*
* @author Jimmy Shih
*/
private class TrackData {
// The current track
Track track = new Track();
// The parsed depth for the current track
int parsedDepth = 0;
// The number of segments processed for the current track
int numberOfSegments = 0;
/*
* The last location in the current segment. Null if the current segment
* doesn't have a last location.
*/
Location lastLocationInCurrentSegment;
// The number of locations processed for the current track
int numberOfLocations = 0;
// The trip statistics updater for the current track
TripStatisticsUpdater tripStatisticsUpdater;
// The default location time for the current track. -1L to not use it.
long defaultLocationTime = -1L;
// The buffered locations
Location[] bufferedLocations = new Location[MAX_BUFFERED_LOCATIONS];
// The number of buffered locations
int numBufferedLocations = 0;
}
// GPX tags
private static final String TAG_ALTITUDE = "ele";
private static final String TAG_DESCRIPTION = "desc";
private static final String TAG_COMMENT = "cmt";
private static final String TAG_GPX = "gpx";
private static final String TAG_NAME = "name";
private static final String TAG_TIME = "time";
private static final String TAG_TRACK = "trk";
private static final String TAG_TRACK_POINT = "trkpt";
private static final Object TAG_TRACK_SEGMENT = "trkseg";
private static final String TAG_TRACK_SEGMENT = "trkseg";
private static final String TAG_TYPE = "type";
private static final String TAG_WAYPOINT = "wpt";
// GPX attributes
private static final String ATT_LAT = "lat";
private static final String ATT_LON = "lon";
// The maximum number of buffered locations for bulk-insertion
private static final int MAX_BUFFERED_LOCATIONS = 512;
private final Context context;
private final MyTracksProviderUtils myTracksProviderUtils;
private final int minRecordingDistance;
// List of successfully imported track ids
private final List<Long> tracksIds;
// The SAX locator to get the current line information
@@ -79,60 +130,37 @@ public class GpxImporter extends DefaultHandler {
// The current element content
private String content;
// True if if we're inside a track's xml element
private boolean isInTrackElement = false;
// The current track data
private TrackData trackData = null;
// The current child depth for the current track
private int trackChildDepth = 0;
// The current waypoint
private Waypoint currentWaypoint;
// The current track
private Track track;
// The list of waypoints
private List<Waypoint> waypoints = new ArrayList<Waypoint>();
// True if the current track parsing is finished
private boolean isCurrentTrackFinished = true;
// The number of track segments processed for the current track
private int numberOfTrackSegments = 0;
// The number of locations processed for the current track
private int numberOfLocations = 0;
// The trip statistics updater for the current track
private TripStatisticsUpdater tripStatisticsUpdater;
// True if the current track has a start time
private boolean hasStartTime;
// The import time
private long importTime;
// The current location
/*
* The current location, used for both track point location and waypoint
* location.
*/
private Location location;
// The last location in the current segment
private Location lastLocationInSegment;
// The buffered locations
private Location[] bufferedLocations = new Location[MAX_BUFFERED_LOCATIONS];
// The number of buffered locations
private int numBufferedLocations = 0;
/**
* Reads GPS tracks from a GPX file and writes tracks and their coordinates to
* the database.
* Reads GPS tracks from a GPX file and writes tracks, waypoints, and track
* points to the database.
*
* @param context the context
* @param inputStream the input stream for the GPX file
* @param myTracksProviderUtils my tracks provider utils
* @param minRecordingDistance the min recording distance
* @return long[] array of track ids written to the database.
*/
public static long[] importGPXFile(InputStream inputStream,
public static long[] importGPXFile(Context context, InputStream inputStream,
MyTracksProviderUtils myTracksProviderUtils, int minRecordingDistance)
throws ParserConfigurationException, SAXException, IOException {
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser();
GpxImporter gpxImporter = new GpxImporter(myTracksProviderUtils, minRecordingDistance);
GpxImporter gpxImporter = new GpxImporter(context, myTracksProviderUtils, minRecordingDistance);
long[] trackIds = new long[0];
try {
@@ -154,10 +182,12 @@ public class GpxImporter extends DefaultHandler {
return trackIds;
}
public GpxImporter(MyTracksProviderUtils myTracksProviderUtils, int minRecordingDistance) {
public GpxImporter(
Context context, MyTracksProviderUtils myTracksProviderUtils, int minRecordingDistance) {
this.context = context;
this.myTracksProviderUtils = myTracksProviderUtils;
this.minRecordingDistance = minRecordingDistance;
tracksIds = new ArrayList<Long>();
this.tracksIds = new ArrayList<Long>();
}
@Override
@@ -178,55 +208,58 @@ public class GpxImporter extends DefaultHandler {
@Override
public void startElement(String uri, String localName, String name, Attributes attributes)
throws SAXException {
if (isInTrackElement) {
trackChildDepth++;
if (trackData != null) {
trackData.parsedDepth++;
if (localName.equals(TAG_TRACK)) {
throw new SAXException(createErrorMessage("Invalid GPX. Already inside a track."));
} else if (localName.equals(TAG_TRACK_SEGMENT)) {
onTrackSegmentElementStart();
} else if (localName.equals(TAG_TRACK_POINT)) {
onTrackPointElementStart(attributes);
}
} else if (localName.equals(TAG_TRACK)) {
isInTrackElement = true;
trackChildDepth = 0;
onTrackElementStart();
}
} else {
if (localName.equals(TAG_TRACK)) {
onTrackElementStart();
} else if (localName.equals(TAG_WAYPOINT)) {
onWaypointElementStart(attributes);
}
}
}
@Override
public void endElement(String uri, String localName, String name) throws SAXException {
if (!isInTrackElement) {
content = null;
return;
}
if (localName.equals(TAG_TRACK)) {
onTrackElementEnd();
isInTrackElement = false;
trackChildDepth = 0;
} else if (localName.equals(TAG_NAME)) {
// we are only interested in the first level name element
if (trackChildDepth == 1) {
onNameElementEnd();
}
if (localName.equals(TAG_NAME)) {
onNameElementEnd();
} else if (localName.equals(TAG_DESCRIPTION)) {
// we are only interested in the first level description element
if (trackChildDepth == 1) {
onDescriptionElementEnd();
}
} else if (localName.equals(TAG_TRACK_SEGMENT)) {
onTrackSegmentElementEnd();
} else if (localName.equals(TAG_TRACK_POINT)) {
onTrackPointElementEnd();
onDescriptionElementEnd();
} else if (localName.equals(TAG_TYPE)) {
onTypeElementEnd();
} else if (localName.equals(TAG_ALTITUDE)) {
onAltitudeElementEnd();
} else if (localName.equals(TAG_TIME)) {
onTimeElementEnd();
} else if (localName.equals(TAG_GPX)) {
onGpxElementEnd();
}
trackChildDepth--;
// reset element content
if (trackData != null) {
trackData.parsedDepth--;
if (localName.equals(TAG_TRACK)) {
onTrackElementEnd();
} else if (localName.equals(TAG_TRACK_SEGMENT)) {
onTrackSegmentElementEnd();
} else if (localName.equals(TAG_TRACK_POINT)) {
onTrackPointElementEnd();
}
} else {
if (localName.equals(TAG_WAYPOINT)) {
onWaypointElementEnd();
} else if (localName.equals(TAG_COMMENT)) {
onCommentElementEnd();
}
}
// Reset element content
content = null;
}
@@ -239,9 +272,23 @@ public class GpxImporter extends DefaultHandler {
* Rolls back last track if possible.
*/
public void rollbackUnfinishedTracks() {
if (!isCurrentTrackFinished && track != null) {
myTracksProviderUtils.deleteTrack(track.getId());
isCurrentTrackFinished = true;
if (trackData != null) {
myTracksProviderUtils.deleteTrack(trackData.track.getId());
trackData = null;
}
}
/**
* On gpx element end.
*/
private void onGpxElementEnd() {
int size = tracksIds.size();
if (size > 0) {
long trackId = tracksIds.get(size - 1);
Track track = myTracksProviderUtils.getTrack(trackId);
if (track != null) {
addWaypoints(track);
}
}
}
@@ -249,64 +296,44 @@ public class GpxImporter extends DefaultHandler {
* On track element start.
*/
private void onTrackElementStart() {
track = new Track();
Uri uri = myTracksProviderUtils.insertTrack(track);
track.setId(Long.parseLong(uri.getLastPathSegment()));
isCurrentTrackFinished = false;
numberOfTrackSegments = 0;
numberOfLocations = 0;
tripStatisticsUpdater = null;
trackData = new TrackData();
Uri uri = myTracksProviderUtils.insertTrack(trackData.track);
trackData.track.setId(Long.parseLong(uri.getLastPathSegment()));
}
/**
* On track element end.
*/
private void onTrackElementEnd() {
flushPoints();
if (tripStatisticsUpdater == null) {
flushPoints(trackData);
if (trackData.tripStatisticsUpdater == null) {
long now = System.currentTimeMillis();
tripStatisticsUpdater = new TripStatisticsUpdater(now);
tripStatisticsUpdater.updateTime(now);
}
track.setStopId(getLastPointId());
track.setTripStatistics(tripStatisticsUpdater.getTripStatistics());
track.setNumberOfPoints(numberOfLocations);
myTracksProviderUtils.updateTrack(track);
tracksIds.add(track.getId());
isCurrentTrackFinished = true;
}
/**
* On name element end.
*/
private void onNameElementEnd() {
if (content != null) {
track.setName(content.toString().trim());
}
}
/**
* On description element end.
*/
private void onDescriptionElementEnd() {
if (content != null) {
track.setDescription(content.toString().trim());
trackData.tripStatisticsUpdater = new TripStatisticsUpdater(now);
trackData.tripStatisticsUpdater.updateTime(now);
}
trackData.track.setTripStatistics(trackData.tripStatisticsUpdater.getTripStatistics());
trackData.track.setNumberOfPoints(trackData.numberOfLocations);
myTracksProviderUtils.updateTrack(trackData.track);
tracksIds.add(trackData.track.getId());
insertFirstWaypoint(trackData.track);
trackData = null;
}
/**
* On track segment start.
*/
private void onTrackSegmentElementStart() {
numberOfTrackSegments++;
// If not the first segment, add a pause separator if there is at least one
// location in the last segment
if (numberOfTrackSegments > 1 && lastLocationInSegment != null) {
insertPoint(createNewLocation(
TrackRecordingService.PAUSE_LATITUDE, 0.0, lastLocationInSegment.getTime()));
trackData.numberOfSegments++;
/*
* If not the first segment, add a pause separator if there is at least one
* location in the last segment.
*/
if (trackData.numberOfSegments > 1 && trackData.lastLocationInCurrentSegment != null) {
insertPoint(createNewLocation(TrackRecordingService.PAUSE_LATITUDE, 0.0,
trackData.lastLocationInCurrentSegment.getTime()));
}
location = null;
lastLocationInSegment = null;
trackData.lastLocationInCurrentSegment = null;
}
/**
@@ -322,27 +349,7 @@ public class GpxImporter extends DefaultHandler {
* @param attributes the attributes
*/
private void onTrackPointElementStart(Attributes attributes) throws SAXException {
if (location != null) {
throw new SAXException(createErrorMessage("Found a track point inside another one."));
}
String latitude = attributes.getValue(ATT_LAT);
String longitude = attributes.getValue(ATT_LON);
if (latitude == null || longitude == null) {
throw new SAXException(createErrorMessage("Point with no longitude or latitude."));
}
double latitudeValue;
double longitudeValue;
try {
latitudeValue = Double.parseDouble(latitude);
longitudeValue = Double.parseDouble(longitude);
} catch (NumberFormatException e) {
throw new SAXException(
createErrorMessage("Unable to parse latitude/longitude: " + latitude + "/" + longitude),
e);
}
location = createNewLocation(latitudeValue, longitudeValue, -1L);
parseLocation(attributes);
}
/**
@@ -353,25 +360,95 @@ public class GpxImporter extends DefaultHandler {
throw new SAXException(createErrorMessage("Invalid location detected: " + location));
}
if (numberOfTrackSegments > 1 && lastLocationInSegment == null) {
// If not the first segment, add a resume separator before adding the
// first location.
if (trackData.numberOfSegments > 1 && trackData.lastLocationInCurrentSegment == null) {
/*
* If not the first segment, add a resume separator before adding the
* first location.
*/
insertPoint(
createNewLocation(TrackRecordingService.RESUME_LATITUDE, 0.0, location.getTime()));
}
// insert in db
insertPoint(location);
// set the start id if necessary
if (track.getStartId() == -1L) {
track.setStartId(getFirstPointId());
if (trackData.track.getStartId() == -1L) {
// Flush the location to set the track start id and the track end id
flushPoints(trackData);
}
lastLocationInSegment = location;
trackData.lastLocationInCurrentSegment = location;
location = null;
}
/**
* On waypoint element start.
*
* @param attributes the attributes
*/
private void onWaypointElementStart(Attributes attributes) throws SAXException {
if (currentWaypoint != null) {
throw new SAXException(createErrorMessage("Found waypoint inside another waypoint."));
}
parseLocation(attributes);
currentWaypoint = new Waypoint();
}
/**
* On waypoint element end.
*/
private void onWaypointElementEnd() throws SAXException {
if (!LocationUtils.isValidLocation(location)) {
throw new SAXException(createErrorMessage("Invalid location detected: " + location));
}
currentWaypoint.setLocation(location);
waypoints.add(currentWaypoint);
location = null;
currentWaypoint = null;
}
/**
* On name element end.
*/
private void onNameElementEnd() {
if (content != null) {
String name = content.toString().trim();
if (trackData != null && trackData.parsedDepth == 1) {
trackData.track.setName(name);
} else if (currentWaypoint != null) {
currentWaypoint.setName(name);
}
}
}
/**
* On description element end.
*/
private void onDescriptionElementEnd() {
if (content != null) {
String description = content.toString().trim();
if (trackData != null && trackData.parsedDepth == 1) {
trackData.track.setDescription(description);
} else if (currentWaypoint != null) {
currentWaypoint.setDescription(description);
}
}
}
/**
* On type element end.
*/
private void onTypeElementEnd() {
if (content != null) {
String type = content.toString().trim();
if (trackData != null && trackData.parsedDepth == 1) {
trackData.track.setCategory(type);
trackData.track.setIcon(TrackIconUtils.getIconValue(context, type));
} else if (currentWaypoint != null) {
currentWaypoint.setCategory(type);
}
}
}
/**
* On altitude element end.
*/
@@ -407,11 +484,12 @@ public class GpxImporter extends DefaultHandler {
}
location.setTime(time);
// Calculate derived attributes from previous point
if (lastLocationInSegment != null && lastLocationInSegment.getTime() != 0) {
long timeDifference = time - lastLocationInSegment.getTime();
// Calculate derived attributes from the previous point
if (trackData != null && trackData.lastLocationInCurrentSegment != null
&& trackData.lastLocationInCurrentSegment.getTime() != 0) {
long timeDifference = time - trackData.lastLocationInCurrentSegment.getTime();
// check for negative time change
// Check for negative time change
if (timeDifference <= 0) {
Log.w(Constants.TAG, "Time difference not postive.");
} else {
@@ -422,29 +500,74 @@ public class GpxImporter extends DefaultHandler {
* speed and bearing will likely be off, so the statistics for things
* like max speed will also be off.
*/
float speed = lastLocationInSegment.distanceTo(location) * 1000.0f / timeDifference;
float speed = trackData.lastLocationInCurrentSegment.distanceTo(location) * 1000.0f
/ timeDifference;
location.setSpeed(speed);
}
location.setBearing(lastLocationInSegment.bearingTo(location));
location.setBearing(trackData.lastLocationInCurrentSegment.bearingTo(location));
}
}
/**
* On comment element end.
*/
private void onCommentElementEnd() {
if (content != null) {
String comment = content.toString().trim();
if (currentWaypoint != null) {
WaypointType waypointType = WaypointType.STATISTICS.name().equals(comment) ? WaypointType.STATISTICS
: WaypointType.WAYPOINT;
currentWaypoint.setType(waypointType);
}
}
}
/**
* Parses a location.
*
* @param attributes the attributes
*/
private void parseLocation(Attributes attributes) throws SAXException {
if (location != null) {
throw new SAXException(createErrorMessage("Found a location inside another one."));
}
String latitude = attributes.getValue(ATT_LAT);
String longitude = attributes.getValue(ATT_LON);
if (latitude == null || longitude == null) {
throw new SAXException(createErrorMessage("Point with no longitude or latitude."));
}
double latitudeValue;
double longitudeValue;
try {
latitudeValue = Double.parseDouble(latitude);
longitudeValue = Double.parseDouble(longitude);
} catch (NumberFormatException e) {
throw new SAXException(
createErrorMessage("Unable to parse latitude/longitude: " + latitude + "/" + longitude),
e);
}
location = createNewLocation(latitudeValue, longitudeValue, -1L);
}
/**
* Creates a new location
*
* @param latitude location latitude
* @param longitude location longitude
* @param time location time
*/
private Location createNewLocation(double latitude, double longitude, long time) {
Location loc = new Location(LocationManager.GPS_PROVIDER);
loc.setLatitude(latitude);
loc.setLongitude(longitude);
loc.setAltitude(0.0f);
loc.setTime(time);
loc.removeAccuracy();
loc.removeBearing();
loc.removeSpeed();
return loc;
Location newLocation = new Location(LocationManager.GPS_PROVIDER);
newLocation.setLatitude(latitude);
newLocation.setLongitude(longitude);
newLocation.setAltitude(0.0f);
newLocation.setTime(time);
newLocation.removeAccuracy();
newLocation.removeBearing();
newLocation.removeSpeed();
return newLocation;
}
/**
@@ -453,36 +576,43 @@ public class GpxImporter extends DefaultHandler {
* @param newLocation the location
*/
private void insertPoint(Location newLocation) {
if (tripStatisticsUpdater == null) {
hasStartTime = newLocation.getTime() != -1L;
importTime = System.currentTimeMillis();
tripStatisticsUpdater = new TripStatisticsUpdater(
hasStartTime ? newLocation.getTime() : importTime);
if (trackData.tripStatisticsUpdater == null) {
// Set the default location time if the newLocation does not have a time
trackData.defaultLocationTime = newLocation.getTime() == -1L ? System.currentTimeMillis()
: -1L;
trackData.tripStatisticsUpdater = new TripStatisticsUpdater(
newLocation.getTime() != -1L ? newLocation.getTime() : trackData.defaultLocationTime);
}
if (!hasStartTime) {
newLocation.setTime(importTime);
if (trackData.defaultLocationTime != -1L) {
newLocation.setTime(trackData.defaultLocationTime);
}
tripStatisticsUpdater.addLocation(newLocation, minRecordingDistance);
bufferedLocations[numBufferedLocations] = newLocation;
numBufferedLocations++;
numberOfLocations++;
trackData.tripStatisticsUpdater.addLocation(newLocation, minRecordingDistance);
if (numBufferedLocations >= MAX_BUFFERED_LOCATIONS) {
flushPoints();
trackData.bufferedLocations[trackData.numBufferedLocations] = newLocation;
trackData.numBufferedLocations++;
trackData.numberOfLocations++;
if (trackData.numBufferedLocations >= MAX_BUFFERED_LOCATIONS) {
flushPoints(trackData);
}
}
/**
* Flushes the points to the database.
*
* @param data the track data
*/
private void flushPoints() {
if (numBufferedLocations <= 0) {
private void flushPoints(TrackData data) {
if (data.numBufferedLocations <= 0) {
return;
}
myTracksProviderUtils.bulkInsertTrackPoint(
bufferedLocations, numBufferedLocations, track.getId());
numBufferedLocations = 0;
data.bufferedLocations, data.numBufferedLocations, data.track.getId());
data.numBufferedLocations = 0;
if (data.track.getStartId() == -1L) {
data.track.setStartId(myTracksProviderUtils.getFirstTrackPointId(data.track.getId()));
}
data.track.setStopId(myTracksProviderUtils.getLastTrackPointId(data.track.getId()));
}
/**
@@ -496,22 +626,6 @@ public class GpxImporter extends DefaultHandler {
return result;
}
/**
* Gets the first point id inserted into the database.
*/
private long getFirstPointId() {
flushPoints();
return myTracksProviderUtils.getFirstTrackPointId(track.getId());
}
/**
* Gets the last point id inserted into the database.
*/
private long getLastPointId() {
flushPoints();
return myTracksProviderUtils.getLastTrackPointId(track.getId());
}
/**
* Creates an error message.
*
@@ -521,4 +635,115 @@ public class GpxImporter extends DefaultHandler {
return String.format(Locale.US, "Parsing error at line: %d column: %d. %s",
locator.getLineNumber(), locator.getColumnNumber(), message);
}
/**
* Inserts the first track waypoint, the track statistics waypoint.
*
* @param track the track
*/
private void insertFirstWaypoint(Track track) {
String name = context.getString(R.string.marker_split_name_format, 0);
String category = "";
TripStatisticsUpdater updater = new TripStatisticsUpdater(
track.getTripStatistics().getStartTime());
TripStatistics tripStatistics = updater.getTripStatistics();
String description = new DescriptionGeneratorImpl(context).generateWaypointDescription(
tripStatistics);
String icon = context.getString(R.string.marker_statistics_icon_url);
double length = 0.0;
long duration = 0L;
Location waypointLocation = new Location("");
waypointLocation.setLatitude(100);
waypointLocation.setLongitude(180);
Waypoint waypoint = new Waypoint(name, description, category, icon, track.getId(),
WaypointType.STATISTICS, length, duration, -1L, -1L, waypointLocation, tripStatistics);
myTracksProviderUtils.insertWaypoint(waypoint);
}
/**
* Adds waypoints to a track.
*
* @param track the track
*/
private void addWaypoints(Track track) {
Cursor trackPointCursor = null;
try {
trackPointCursor = myTracksProviderUtils.getTrackPointCursor(track.getId(), -1L, -1, false);
if (trackPointCursor == null) {
return;
}
int waypointPosition = -1;
Waypoint waypoint = null;
int trackPointPosition = -1;
Location trackPoint = null;
TripStatisticsUpdater trackTripStatisticstrackUpdater = new TripStatisticsUpdater(
track.getTripStatistics().getStartTime());
TripStatisticsUpdater markerTripStatisticsUpdater = new TripStatisticsUpdater(
track.getTripStatistics().getStartTime());
while (true) {
if (waypoint == null) {
waypointPosition++;
waypoint = waypointPosition < waypoints.size() ? waypoints.get(waypointPosition) : null;
if (waypoint == null) {
// No more waypoints
return;
}
}
if (trackPoint == null) {
trackPointPosition++;
trackPoint = trackPointCursor.moveToPosition(trackPointPosition) ? myTracksProviderUtils
.createTrackPoint(trackPointCursor)
: null;
if (trackPoint == null) {
// No more track points. Ignore the rest of the waypoints.
return;
}
trackTripStatisticstrackUpdater.addLocation(trackPoint, minRecordingDistance);
markerTripStatisticsUpdater.addLocation(trackPoint, minRecordingDistance);
}
if (waypoint.getLocation().getTime() > trackPoint.getTime()) {
trackPoint = null;
} else if (waypoint.getLocation().getTime() < trackPoint.getTime()) {
waypoint = null;
} else {
// The waypoint location time matches the track point time
if (trackPoint.getLatitude() == waypoint.getLocation().getLatitude()
&& trackPoint.getLongitude() == waypoint.getLocation().getLongitude()) {
// Get tripStatistics, description, and icon
TripStatistics tripStatistics;
String description;
String icon;
if (waypoint.getType() == WaypointType.STATISTICS) {
tripStatistics = markerTripStatisticsUpdater.getTripStatistics();
markerTripStatisticsUpdater = new TripStatisticsUpdater(trackPoint.getTime());
description = new DescriptionGeneratorImpl(context).generateWaypointDescription(
tripStatistics);
icon = context.getString(R.string.marker_statistics_icon_url);
} else {
tripStatistics = null;
description = waypoint.getDescription();
icon = context.getString(R.string.marker_waypoint_icon_url);
}
// Get length and duration
double length = trackTripStatisticstrackUpdater.getTripStatistics().getTotalDistance();
long duration = trackTripStatisticstrackUpdater.getTripStatistics().getTotalTime();
// Insert waypoint
Waypoint newWaypoint = new Waypoint(waypoint.getName(), description,
waypoint.getCategory(), icon, track.getId(), waypoint.getType(), length, duration,
-1L, -1L, trackPoint, tripStatistics);
myTracksProviderUtils.insertWaypoint(newWaypoint);
}
waypoint = null;
}
}
} finally {
if (trackPointCursor != null) {
trackPointCursor.close();
}
}
}
}
@@ -13,6 +13,7 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.android.apps.mytracks.io.file;
import com.google.android.apps.mytracks.content.Track;
@@ -31,7 +32,7 @@ import java.util.Locale;
/**
* Write track as GPX to a file.
*
*
* @author Sandor Dornbush
*/
public class GpxTrackWriter implements TrackFormatWriter {
@@ -39,8 +40,10 @@ public class GpxTrackWriter implements TrackFormatWriter {
private static final NumberFormat ELEVATION_FORMAT = NumberFormat.getInstance(Locale.US);
private static final NumberFormat COORDINATE_FORMAT = NumberFormat.getInstance(Locale.US);
static {
// GPX readers expect to see fractional numbers with US-style punctuation.
// That is, they want periods for decimal points, rather than commas.
/*
* GPX readers expect to see fractional numbers with US-style punctuation.
* That is, they want periods for decimal points, rather than commas.
*/
ELEVATION_FORMAT.setMaximumFractionDigits(1);
ELEVATION_FORMAT.setGroupingUsed(false);
@@ -112,6 +115,7 @@ public class GpxTrackWriter implements TrackFormatWriter {
printWriter.println("<trk>");
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
printWriter.println("<desc>" + StringUtils.formatCData(track.getDescription()) + "</desc>");
printWriter.println("<type>" + StringUtils.formatCData(track.getCategory()) + "</type>");
printWriter.println("<extensions><topografix:color>c0c0c0</topografix:color></extensions>");
}
}
@@ -138,7 +142,8 @@ public class GpxTrackWriter implements TrackFormatWriter {
if (printWriter != null) {
printWriter.println("<trkpt " + formatLocation(location) + ">");
printWriter.println("<ele>" + ELEVATION_FORMAT.format(location.getAltitude()) + "</ele>");
printWriter.println("<time>" + StringUtils.formatDateTimeIso8601(location.getTime()) + "</time>");
printWriter.println(
"<time>" + StringUtils.formatDateTimeIso8601(location.getTime()) + "</time>");
printWriter.println("</trkpt>");
}
}
@@ -160,10 +165,13 @@ public class GpxTrackWriter implements TrackFormatWriter {
if (location != null) {
printWriter.println("<wpt " + formatLocation(location) + ">");
printWriter.println("<ele>" + ELEVATION_FORMAT.format(location.getAltitude()) + "</ele>");
printWriter.println("<time>" + StringUtils.formatDateTimeIso8601(location.getTime()) + "</time>");
printWriter.println(
"<time>" + StringUtils.formatDateTimeIso8601(location.getTime()) + "</time>");
printWriter.println("<name>" + StringUtils.formatCData(waypoint.getName()) + "</name>");
printWriter.println("<cmt>" + StringUtils.formatCData(waypoint.getType().name()) + "</cmt>");
printWriter.println(
"<desc>" + StringUtils.formatCData(waypoint.getDescription()) + "</desc>");
printWriter.println("<type>" + StringUtils.formatCData(waypoint.getCategory()) + "</type>");
printWriter.println("</wpt>");
}
}
@@ -171,7 +179,7 @@ public class GpxTrackWriter implements TrackFormatWriter {
/**
* Formats a location with latitude and longitude coordinates.
*
*
* @param location the location
*/
private String formatLocation(Location location) {
@@ -23,6 +23,7 @@ import com.google.android.apps.mytracks.content.Sensor.SensorData;
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
@@ -37,7 +38,7 @@ import java.util.ArrayList;
/**
* Write track as KML to a file.
*
*
* @author Leif Hendrik Wilden
*/
public class KmlTrackWriter implements TrackFormatWriter {
@@ -57,16 +58,16 @@ public class KmlTrackWriter implements TrackFormatWriter {
private static final String HEART_RATE = "heart_rate";
private static final String POWER = "power";
private static final String WAYPOINT_ICON =
"http://maps.google.com/mapfiles/kml/pushpin/blue-pushpin.png";
private static final String STATISTICS_ICON =
"http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png";
private static final String START_ICON =
"http://maps.google.com/mapfiles/kml/paddle/grn-circle.png";
private static final String END_ICON =
"http://maps.google.com/mapfiles/kml/paddle/red-circle.png";
private static final String TRACK_ICON =
"http://earth.google.com/images/kml-icons/track-directional/track-0.png";
private static final String
WAYPOINT_ICON = "http://maps.google.com/mapfiles/kml/pushpin/blue-pushpin.png";
private static final String
STATISTICS_ICON = "http://maps.google.com/mapfiles/kml/pushpin/ylw-pushpin.png";
private static final String
START_ICON = "http://maps.google.com/mapfiles/kml/paddle/grn-circle.png";
private static final String
END_ICON = "http://maps.google.com/mapfiles/kml/paddle/red-circle.png";
private static final String
TRACK_ICON = "http://earth.google.com/images/kml-icons/track-directional/track-0.png";
private final Context context;
private final DescriptionGenerator descriptionGenerator;
@@ -113,16 +114,14 @@ public class KmlTrackWriter implements TrackFormatWriter {
if (printWriter != null) {
printWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
printWriter.println("<kml xmlns=\"http://www.opengis.net/kml/2.2\"");
printWriter.println("xmlns:atom=\"http://www.w3.org/2005/Atom\"");
printWriter.println("xmlns:gx=\"http://www.google.com/kml/ext/2.2\">");
printWriter.println("xmlns:gx=\"http://www.google.com/kml/ext/2.2\"");
printWriter.println("xmlns:atom=\"http://www.w3.org/2005/Atom\">");
printWriter.println("<Document>");
printWriter.println("<open>1</open>");
printWriter.println("<visibility>1</visibility>");
printWriter.println(
"<description>" + StringUtils.formatCData(track.getDescription()) + "</description>");
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
printWriter.println("<atom:author><atom:name>" + StringUtils.formatCData(
context.getString(R.string.send_google_by_my_tracks, "", ""))
printWriter.println("<atom:author><atom:name>"
+ StringUtils.formatCData(context.getString(R.string.send_google_by_my_tracks, "", ""))
+ "</atom:name></atom:author>");
writeTrackStyle();
writePlacemarkerStyle(START_STYLE, START_ICON, 32, 1);
@@ -148,9 +147,9 @@ public class KmlTrackWriter implements TrackFormatWriter {
@Override
public void writeBeginWaypoints() {
if (printWriter != null) {
printWriter.println(
"<Folder><name>" + StringUtils.formatCData(context.getString(R.string.menu_markers))
+ "</name>");
printWriter.println("<Folder><name>"
+ StringUtils.formatCData(context.getString(R.string.menu_markers)) + "</name>");
printWriter.println("<open>1</open>");
}
}
@@ -164,10 +163,10 @@ public class KmlTrackWriter implements TrackFormatWriter {
@Override
public void writeWaypoint(Waypoint waypoint) {
if (printWriter != null) {
String styleName = waypoint.getType() == Waypoint.TYPE_STATISTICS ? STATISTICS_STYLE
String styleName = waypoint.getType() == WaypointType.STATISTICS ? STATISTICS_STYLE
: WAYPOINT_STYLE;
writePlacemark(
waypoint.getName(), waypoint.getDescription(), styleName, waypoint.getLocation());
writePlacemark(waypoint.getName(), waypoint.getCategory(), waypoint.getDescription(),
styleName, waypoint.getLocation());
}
}
@@ -175,12 +174,13 @@ public class KmlTrackWriter implements TrackFormatWriter {
public void writeBeginTrack(Location firstLocation) {
if (printWriter != null) {
String name = context.getString(R.string.marker_label_start, track.getName());
writePlacemark(name, track.getDescription(), START_STYLE, firstLocation);
writePlacemark(name, "", "", START_STYLE, firstLocation);
printWriter.println("<Placemark id=\"" + TOUR_FEATURE_ID + "\">");
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
printWriter.println(
"<description>" + StringUtils.formatCData(track.getDescription()) + "</description>");
printWriter.println("<name>" + StringUtils.formatCData(track.getName()) + "</name>");
printWriter.println("<styleUrl>#" + TRACK_STYLE + "</styleUrl>");
writeCategory(track.getCategory());
printWriter.println("<gx:MultiTrack>");
printWriter.println("<altitudeMode>absolute</altitudeMode>");
printWriter.println("<gx:interpolate>1</gx:interpolate>");
@@ -194,7 +194,7 @@ public class KmlTrackWriter implements TrackFormatWriter {
printWriter.println("</Placemark>");
String name = context.getString(R.string.marker_label_end, track.getName());
String description = descriptionGenerator.generateTrackDescription(track, null, null, false);
writePlacemark(name, description, END_STYLE, lastLocation);
writePlacemark(name, "", description, END_STYLE, lastLocation);
}
}
@@ -234,10 +234,10 @@ public class KmlTrackWriter implements TrackFormatWriter {
@Override
public void writeLocation(Location location) {
if (printWriter != null) {
printWriter.println("<when>" + StringUtils.formatDateTimeIso8601(location.getTime()) + "</when>");
printWriter.println(
"<gx:coord>" + location.getLongitude() + " " + location.getLatitude() + " "
+ location.getAltitude() + "</gx:coord>");
"<when>" + StringUtils.formatDateTimeIso8601(location.getTime()) + "</when>");
printWriter.println("<gx:coord>" + location.getLongitude() + " " + location.getLatitude()
+ " " + location.getAltitude() + "</gx:coord>");
if (location instanceof MyTracksLocation) {
SensorDataSet sensorDataSet = ((MyTracksLocation) location).getSensorDataSet();
int power = -1;
@@ -265,7 +265,7 @@ public class KmlTrackWriter implements TrackFormatWriter {
hasHeartRate = true;
heartRate = sensorData.getValue();
}
}
}
}
powerList.add(power);
cadenceList.add(cadence);
@@ -276,7 +276,7 @@ public class KmlTrackWriter implements TrackFormatWriter {
/**
* Writes the sensor data.
*
*
* @param list a list of sensor data
* @param name the name of the sensor data
*/
@@ -290,29 +290,45 @@ public class KmlTrackWriter implements TrackFormatWriter {
/**
* Writes a placemark.
*
* @param name the name of the placemark
*
* @param name the name
* @param category the category
* @param description the description
* @param styleName the style name
* @param location the location
*/
private void writePlacemark(
String name, String description, String styleName, Location location) {
String name, String category, String description, String styleName, Location location) {
if (location != null) {
printWriter.println("<Placemark>");
printWriter.println("<name>" + StringUtils.formatCData(name) + "</name>");
printWriter.println(
"<description>" + StringUtils.formatCData(description) + "</description>");
printWriter.println("<name>" + StringUtils.formatCData(name) + "</name>");
printWriter.println("<styleUrl>#" + styleName + "</styleUrl>");
writeCategory(category);
printWriter.println("<Point>");
printWriter.println(
"<coordinates>" + location.getLongitude() + "," + location.getLatitude() + ","
+ location.getAltitude() + "</coordinates>");
printWriter.println("<coordinates>" + location.getLongitude() + "," + location.getLatitude()
+ "," + location.getAltitude() + "</coordinates>");
printWriter.println("</Point>");
printWriter.println("</Placemark>");
}
}
/**
* Writes the category.
*
* @param category the category
*/
private void writeCategory(String category) {
if (category == null || category.equals("")) {
return;
}
printWriter.println("<ExtendedData>");
printWriter.println(
"<Data name=\"type\"><value>" + StringUtils.formatCData(category) + "</value></Data>");
printWriter.println("</ExtendedData>");
}
/**
* Writes the track style.
*/
@@ -328,7 +344,7 @@ public class KmlTrackWriter implements TrackFormatWriter {
/**
* Writes a placemarker style.
*
*
* @param name the name of the style
* @param url the url of the style icon
* @param x the x position of the hotspot
@@ -345,14 +361,13 @@ public class KmlTrackWriter implements TrackFormatWriter {
/**
* Writes a sensor style.
*
*
* @param name the name of the sesnor
* @param displayName the sensor display name
*/
private void writeSensorStyle(String name, String displayName) {
printWriter.println("<gx:SimpleArrayField name=\"" + name + "\" type=\"int\">");
printWriter.println(
"<displayName>" + StringUtils.formatCData(displayName) + "</displayName>");
printWriter.println("<displayName>" + StringUtils.formatCData(displayName) + "</displayName>");
printWriter.println("</gx:SimpleArrayField>");
}
}
@@ -8,6 +8,7 @@ import com.google.android.apps.mytracks.content.DescriptionGeneratorImpl;
import com.google.android.apps.mytracks.content.MyTracksProviderUtils;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.io.sendtogoogle.AbstractSendAsyncTask;
import com.google.android.apps.mytracks.io.sendtogoogle.SendToGoogleUtils;
import com.google.android.apps.mytracks.stats.TripStatisticsUpdater;
@@ -335,7 +336,7 @@ public class SendFusionTablesAsyncTask extends AbstractSendAsyncTask {
// track).
while (cursor.moveToNext()) {
Waypoint wpt = myTracksProviderUtils.createWaypoint(cursor);
String type = wpt.getType() == Waypoint.TYPE_STATISTICS ? MARKER_TYPE_STATISTICS
String type = wpt.getType() == WaypointType.STATISTICS ? MARKER_TYPE_STATISTICS
: MARKER_TYPE_WAYPOINT;
if (!createNewPoint(wpt.getName(), wpt.getDescription(), wpt.getLocation(), type)) {
Log.d(TAG, "Upload waypoints failed");
@@ -28,8 +28,8 @@ import com.google.android.apps.mytracks.content.Sensor;
import com.google.android.apps.mytracks.content.Sensor.SensorDataSet;
import com.google.android.apps.mytracks.content.Track;
import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.content.Waypoint.WaypointType;
import com.google.android.apps.mytracks.content.WaypointCreationRequest;
import com.google.android.apps.mytracks.content.WaypointCreationRequest.WaypointType;
import com.google.android.apps.mytracks.services.sensors.SensorManager;
import com.google.android.apps.mytracks.services.sensors.SensorManagerFactory;
import com.google.android.apps.mytracks.services.tasks.AnnouncementPeriodicTaskFactory;
@@ -413,13 +413,16 @@ public class TrackRecordingService extends Service {
return -1L;
}
boolean isStatistics = waypointCreationRequest.getType() == WaypointType.STATISTICS;
WaypointType waypointType = waypointCreationRequest.getType();
boolean isStatistics = waypointType == WaypointType.STATISTICS;
// Get name
String name;
if (waypointCreationRequest.getName() != null) {
name = waypointCreationRequest.getName();
} else {
int nextWaypointNumber = myTracksProviderUtils.getNextWaypointNumber(
recordingTrackId, isStatistics);
recordingTrackId, waypointType);
if (nextWaypointNumber == -1) {
nextWaypointNumber = 0;
}
@@ -428,29 +431,33 @@ public class TrackRecordingService extends Service {
nextWaypointNumber);
}
// Get category
String category = waypointCreationRequest.getCategory() != null ? waypointCreationRequest
.getCategory()
: "";
// Get tripStatistics, description, and icon
TripStatistics tripStatistics;
String description;
String icon;
if (isStatistics) {
long now = System.currentTimeMillis();
markerTripStatisticsUpdater.updateTime(now);
tripStatistics = markerTripStatisticsUpdater.getTripStatistics();
markerTripStatisticsUpdater = new TripStatisticsUpdater(now);
description = new DescriptionGeneratorImpl(this).generateWaypointDescription(tripStatistics);
icon = getString(R.string.marker_statistics_icon_url);
} else {
tripStatistics = null;
description = waypointCreationRequest.getDescription() != null ? waypointCreationRequest
.getDescription()
: "";
icon = getString(R.string.marker_waypoint_icon_url);
}
String category = waypointCreationRequest.getCategory() != null ? waypointCreationRequest
.getCategory()
: "";
String icon = getString(
isStatistics ? R.string.marker_statistics_icon_url : R.string.marker_waypoint_icon_url);
int type = isStatistics ? Waypoint.TYPE_STATISTICS : Waypoint.TYPE_WAYPOINT;
long duration;
// Get length and duration
double length;
long duration;
Location location = getLastValidTrackPointInCurrentSegment(recordingTrackId);
if (location != null && trackTripStatisticsUpdater != null) {
TripStatistics stats = trackTripStatisticsUpdater.getTripStatistics();
@@ -464,10 +471,12 @@ public class TrackRecordingService extends Service {
location = new Location("");
location.setLatitude(100);
location.setLongitude(180);
length = 0;
duration = 0;
length = 0.0;
duration = 0L;
}
Waypoint waypoint = new Waypoint(name, description, category, icon, recordingTrackId, type,
// Insert waypoint
Waypoint waypoint = new Waypoint(name, description, category, icon, recordingTrackId, waypointType,
length, duration, -1L, -1L, location, tripStatistics);
Uri uri = myTracksProviderUtils.insertWaypoint(waypoint);
return Long.parseLong(uri.getLastPathSegment());
@@ -592,7 +601,7 @@ public class TrackRecordingService extends Service {
trackTripStatisticsUpdater = new TripStatisticsUpdater(tripStatistics.getStartTime());
long markerStartTime;
Waypoint waypoint = myTracksProviderUtils.getLastStatisticsWaypoint(recordingTrackId);
Waypoint waypoint = myTracksProviderUtils.getLastWaypoint(recordingTrackId, WaypointType.STATISTICS);
if (waypoint != null && waypoint.getTripStatistics() != null) {
markerStartTime = waypoint.getTripStatistics().getStopTime();
} else {