Cleanup GpxTrackWriter

- remove xml-stylesheet (not used)
- remove the "<number>" tag (do not want to expose internally used track id)
- add <metadata> for name and description
- change the text for the "creator" attribute
- change KmlTrackWriter to use FileUtils.FILE_TIMESTAMP_FORMAT
This commit is contained in:
Jimmy Shih
2012-02-23 18:46:54 -08:00
parent 6087c862d8
commit 81122b59ad
7 changed files with 132 additions and 129 deletions
@@ -20,51 +20,41 @@ import com.google.android.apps.mytracks.content.Waypoint;
import com.google.android.apps.mytracks.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
import android.content.Context;
import android.location.Location;
import android.os.Build;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.text.NumberFormat;
import java.util.Date;
import java.util.Locale;
/**
* Log of one track.
* Write track as GPX to a file.
*
* @author Sandor Dornbush
*/
public class GpxTrackWriter implements TrackFormatWriter {
private final NumberFormat elevationFormatter;
private final NumberFormat coordinateFormatter;
private PrintWriter pw = null;
private Track track;
public GpxTrackWriter() {
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.
elevationFormatter = NumberFormat.getInstance(Locale.US);
elevationFormatter.setMaximumFractionDigits(1);
elevationFormatter.setGroupingUsed(false);
ELEVATION_FORMAT.setMaximumFractionDigits(1);
ELEVATION_FORMAT.setGroupingUsed(false);
coordinateFormatter = NumberFormat.getInstance(Locale.US);
coordinateFormatter.setMaximumFractionDigits(5);
coordinateFormatter.setMaximumIntegerDigits(3);
coordinateFormatter.setGroupingUsed(false);
COORDINATE_FORMAT.setMaximumFractionDigits(5);
COORDINATE_FORMAT.setMaximumIntegerDigits(3);
COORDINATE_FORMAT.setGroupingUsed(false);
}
private String formatLocation(Location l) {
return "lat=\"" + coordinateFormatter.format(l.getLatitude())
+ "\" lon=\"" + coordinateFormatter.format(l.getLongitude()) + "\"";
}
private final Context context;
private Track track;
private PrintWriter printWriter;
@SuppressWarnings("hiding")
@Override
public void prepare(Track track, OutputStream out) {
this.track = track;
this.pw = new PrintWriter(out);
public GpxTrackWriter(Context context) {
this.context = context;
}
@Override
@@ -72,81 +62,85 @@ public class GpxTrackWriter implements TrackFormatWriter {
return TrackFileFormat.GPX.getExtension();
}
@Override
public void prepare(Track aTrack, OutputStream outputStream) {
this.track = aTrack;
this.printWriter = new PrintWriter(outputStream);
}
@Override
public void close() {
if (printWriter != null) {
printWriter.close();
printWriter = null;
}
}
@Override
public void writeHeader() {
if (pw != null) {
pw.format("<?xml version=\"1.0\" encoding=\"%s\" standalone=\"yes\"?>\n",
Charset.defaultCharset().name());
pw.println("<?xml-stylesheet type=\"text/xsl\" href=\"details.xsl\"?>");
pw.println("<gpx");
pw.println(" version=\"1.1\"");
pw.format(" creator=\"My Tracks running on %s\"\n", Build.MODEL);
pw.println(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
pw.println(" xmlns=\"http://www.topografix.com/GPX/1/1\"");
pw.print(" xmlns:topografix=\"http://www.topografix.com/GPX/Private/"
+ "TopoGrafix/0/1\"");
pw.print(" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 ");
pw.print("http://www.topografix.com/GPX/1/1/gpx.xsd ");
pw.print("http://www.topografix.com/GPX/Private/TopoGrafix/0/1 ");
pw.println("http://www.topografix.com/GPX/Private/TopoGrafix/0/1/"
+ "topografix.xsd\">");
// TODO: Author etc.
if (printWriter != null) {
printWriter.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
printWriter.println("<gpx");
printWriter.println("version=\"1.1\"");
printWriter.println(
"creator=\"" + context.getString(R.string.send_google_by_my_tracks, "", "") + "\"");
printWriter.println("xmlns=\"http://www.topografix.com/GPX/1/1\"");
printWriter.println(
"xmlns:topografix=\"http://www.topografix.com/GPX/Private/TopoGrafix/0/1\"");
printWriter.println("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
printWriter.println("xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1"
+ " http://www.topografix.com/GPX/1/1/gpx.xsd"
+ " http://www.topografix.com/GPX/Private/TopoGrafix/0/1"
+ " http://www.topografix.com/GPX/Private/TopoGrafix/0/1/topografix.xsd\">");
printWriter.println("<metadata>");
printWriter.println("<name>" + StringUtils.stringAsCData(track.getName()) + "</name>");
printWriter.println("<desc>" + StringUtils.stringAsCData(track.getDescription()) + "</desc>");
printWriter.println("</metadata>");
}
}
@Override
public void writeFooter() {
if (pw != null) {
pw.println("</gpx>");
if (printWriter != null) {
printWriter.println("</gpx>");
}
}
@Override
public void writeBeginTrack(Location firstPoint) {
if (pw != null) {
pw.println("<trk>");
pw.println("<name>" + StringUtils.stringAsCData(track.getName())
+ "</name>");
pw.println("<desc>" + StringUtils.stringAsCData(track.getDescription())
+ "</desc>");
pw.println("<number>" + track.getId() + "</number>");
pw.println("<extensions><topografix:color>c0c0c0</topografix:color></extensions>");
public void writeBeginTrack(Location firstLocation) {
if (printWriter != null) {
printWriter.println("<trk>");
printWriter.println("<name>" + StringUtils.stringAsCData(track.getName()) + "</name>");
printWriter.println("<desc>" + StringUtils.stringAsCData(track.getDescription()) + "</desc>");
printWriter.println("<extensions><topografix:color>c0c0c0</topografix:color></extensions>");
}
}
@Override
public void writeEndTrack(Location lastPoint) {
if (pw != null) {
pw.println("</trk>");
public void writeEndTrack(Location lastLocation) {
if (printWriter != null) {
printWriter.println("</trk>");
}
}
@Override
public void writeOpenSegment() {
pw.println("<trkseg>");
printWriter.println("<trkseg>");
}
@Override
public void writeCloseSegment() {
pw.println("</trkseg>");
printWriter.println("</trkseg>");
}
@Override
public void writeLocation(Location l) {
if (pw != null) {
pw.println("<trkpt " + formatLocation(l) + ">");
Date d = new Date(l.getTime());
pw.println("<ele>" + elevationFormatter.format(l.getAltitude()) + "</ele>");
pw.println("<time>" + FileUtils.FILE_TIMESTAMP_FORMAT.format(d) + "</time>");
pw.println("</trkpt>");
}
}
@Override
public void close() {
if (pw != null) {
pw.close();
pw = null;
public void writeLocation(Location location) {
if (printWriter != null) {
printWriter.println("<trkpt " + formatLocation(location) + ">");
printWriter.println("<ele>" + ELEVATION_FORMAT.format(location.getAltitude()) + "</ele>");
printWriter.println(
"<time>" + FileUtils.FILE_TIMESTAMP_FORMAT.format(location.getTime()) + "</time>");
printWriter.println("</trkpt>");
}
}
@@ -162,18 +156,28 @@ public class GpxTrackWriter implements TrackFormatWriter {
@Override
public void writeWaypoint(Waypoint waypoint) {
if (pw != null) {
Location l = waypoint.getLocation();
if (l != null) {
pw.println("<wpt " + formatLocation(l) + ">");
pw.println("<ele>" + elevationFormatter.format(l.getAltitude()) + "</ele>");
pw.println("<time>" + FileUtils.FILE_TIMESTAMP_FORMAT.format(l.getTime()) + "</time>");
pw.println("<name>" + StringUtils.stringAsCData(waypoint.getName())
+ "</name>");
pw.println("<desc>"
+ StringUtils.stringAsCData(waypoint.getDescription()) + "</desc>");
pw.println("</wpt>");
if (printWriter != null) {
Location location = waypoint.getLocation();
if (location != null) {
printWriter.println("<wpt " + formatLocation(location) + ">");
printWriter.println("<ele>" + ELEVATION_FORMAT.format(location.getAltitude()) + "</ele>");
printWriter.println(
"<time>" + FileUtils.FILE_TIMESTAMP_FORMAT.format(location.getTime()) + "</time>");
printWriter.println("<name>" + StringUtils.stringAsCData(waypoint.getName()) + "</name>");
printWriter.println(
"<desc>" + StringUtils.stringAsCData(waypoint.getDescription()) + "</desc>");
printWriter.println("</wpt>");
}
}
}
/**
* Formats a location with latitude and longitude coordinates.
*
* @param location the location
*/
private String formatLocation(Location location) {
return "lat=\"" + COORDINATE_FORMAT.format(location.getLatitude()) + "\" lon=\""
+ COORDINATE_FORMAT.format(location.getLongitude()) + "\"";
}
}
@@ -24,6 +24,7 @@ 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.io.file.TrackWriterFactory.TrackFileFormat;
import com.google.android.apps.mytracks.util.FileUtils;
import com.google.android.apps.mytracks.util.StringUtils;
import com.google.android.maps.mytracks.R;
import com.google.common.annotations.VisibleForTesting;
@@ -65,7 +66,7 @@ public class KmlTrackWriter implements TrackFormatWriter {
private boolean hasCadence;
private boolean hasHeartRate;
private boolean hasBatteryLevel;
public KmlTrackWriter(Context context) {
this(context, new DescriptionGeneratorImpl(context));
}
@@ -231,7 +232,8 @@ public class KmlTrackWriter implements TrackFormatWriter {
@Override
public void writeLocation(Location location) {
if (printWriter != null) {
printWriter.println("<when>" + StringUtils.formatXmlDateTime(location.getTime()) + "</when>");
printWriter.println(
"<when>" + FileUtils.FILE_TIMESTAMP_FORMAT.format(location.getTime()) + "</when>");
printWriter.println(
"<gx:coord>" + location.getLongitude() + " " + location.getLatitude() + " "
+ location.getAltitude() + "</gx:coord>");
@@ -347,7 +349,7 @@ public class KmlTrackWriter implements TrackFormatWriter {
/**
* Writes a sensor style.
*
*
* @param name the name of the sesnor
* @param displayName the sensor display name
*/
@@ -38,7 +38,7 @@ public class TrackWriterFactory {
GPX {
@Override
TrackFormatWriter newFormatWriter(Context context) {
return new GpxTrackWriter();
return new GpxTrackWriter(context);
}
},
KML {
@@ -144,15 +144,6 @@ public class StringUtils {
BASE_XML_DATE_FORMAT.setTimeZone(new SimpleTimeZone(0, "UTC"));
}
/**
* Formats the time to the XML date time format.
*
* @param time time in milliseconds
*/
public static final String formatXmlDateTime(long time) {
return BASE_XML_DATE_FORMAT.format(new Date(time));
}
private static final Pattern XML_DATE_EXTRAS_PATTERN =
Pattern.compile("^(\\.\\d+)?(?:Z|([+-])(\\d{2}):(\\d{2}))?$");