import tim.prune.data.MediaObject;
import tim.prune.data.Photo;
import tim.prune.data.RecentFile;
+import tim.prune.data.SourceInfo;
import tim.prune.data.Timestamp;
import tim.prune.data.TrackInfo;
import tim.prune.data.UnitSetLibrary;
private JPanel _encodingsPanel = null;
private JRadioButton _useSystemRadio = null, _forceUtf8Radio = null;
private File _exportFile = null;
+ /** Remember the previous sourceInfo object to tell whether it has changed */
+ private SourceInfo _previousSourceInfo = null;
/** this program name */
private static final String GPX_CREATOR = "GpsPrune v" + GpsPrune.VERSION_NUMBER + " activityworkshop.net";
_useSystemRadio.setText(I18nManager.getText("dialog.exportgpx.encoding.system")
+ " (" + (systemEncoding == null ? "unknown" : systemEncoding) + ")");
}
+ setFileTitle();
_dialog.setVisible(true);
}
return dialogPanel;
}
+ /**
+ * Set the suggestion for the name with which to export
+ */
+ private void setFileTitle()
+ {
+ // Get the most recent file info
+ SourceInfo currentSource = _app.getTrackInfo().getFileInfo().getLastFileInfo();
+ if (currentSource != _previousSourceInfo)
+ {
+ String lastTitle = currentSource.getFileTitle();
+ if (lastTitle != null && !lastTitle.equals(""))
+ {
+ // Take the title of the last file loaded
+ _nameField.setText(lastTitle);
+ }
+ }
+ if (_nameField.getText().equals(""))
+ {
+ // no name given in the field already, so try to overwrite it
+ String lastTitle = _app.getTrackInfo().getFileInfo().getLastFileTitle();
+ if (lastTitle != null && !lastTitle.equals(""))
+ {
+ _nameField.setText(lastTitle);
+ }
+ }
+ // Remember this source info so we don't use it again
+ _previousSourceInfo = currentSource;
+ }
/**
* Start the export process based on the input parameters
writer = new OutputStreamWriter(new FileOutputStream(_exportFile), "UTF-8");
else
writer = new OutputStreamWriter(new FileOutputStream(_exportFile));
- final boolean[] saveFlags = {_pointTypeSelector.getTrackpointsSelected(), _pointTypeSelector.getWaypointsSelected(),
- _pointTypeSelector.getPhotopointsSelected(), _pointTypeSelector.getAudiopointsSelected(),
- _pointTypeSelector.getJustSelection(), _timestampsCheckbox.isSelected()};
+ // TODO: Move to new method
+ SettingsForExport settings = new SettingsForExport();
+ settings.setExportTrackPoints(_pointTypeSelector.getTrackpointsSelected());
+ settings.setExportWaypoints(_pointTypeSelector.getWaypointsSelected());
+ settings.setExportPhotoPoints(_pointTypeSelector.getPhotopointsSelected());
+ settings.setExportAudiopoints(_pointTypeSelector.getAudiopointsSelected());
+ settings.setExportJustSelection(_pointTypeSelector.getJustSelection());
+ settings.setExportTimestamps(_timestampsCheckbox.isSelected());
// write file
final int numPoints = exportData(writer, _trackInfo, _nameField.getText(),
- _descriptionField.getText(), saveFlags, gpxCachers);
+ _descriptionField.getText(), settings, gpxCachers);
// close file
writer.close();
* @param inInfo track info object
* @param inName name of track (optional)
* @param inDesc description of track (optional)
- * @param inSaveFlags array of booleans to export tracks, waypoints, photos, audios, selection, timestamps
+ * @param inExportSettings flags for what to export and how
* @param inGpxCachers list of Gpx cachers containing input data
* @return number of points written
* @throws IOException if io errors occur on write
*/
public static int exportData(OutputStreamWriter inWriter, TrackInfo inInfo, String inName,
- String inDesc, boolean[] inSaveFlags, GpxCacherList inGpxCachers) throws IOException
+ String inDesc, SettingsForExport inSettings, GpxCacherList inGpxCachers) throws IOException
{
// Write or copy headers
inWriter.write(getXmlHeaderString(inWriter));
final String gpxHeader = getGpxHeaderString(inGpxCachers);
final boolean isVersion1_1 = (gpxHeader.toUpperCase().indexOf("GPX/1/1") > 0);
inWriter.write(gpxHeader);
- // Name field
- String trackName = (inName != null && !inName.equals("")) ? inName : "GpsPruneTrack";
- writeNameAndDescription(inWriter, inName, inDesc, isVersion1_1);
+ // name and description
+ String trackName = (inName != null && !inName.equals("")) ? XmlUtils.fixCdata(inName) : "GpsPruneTrack";
+ String desc = (inDesc != null && !inDesc.equals("")) ? XmlUtils.fixCdata(inDesc) : "Export from GpsPrune";
+ writeNameAndDescription(inWriter, trackName, desc, isVersion1_1);
- int i = 0;
DataPoint point = null;
- final boolean exportTrackpoints = inSaveFlags[0];
- final boolean exportWaypoints = inSaveFlags[1];
- final boolean exportPhotos = inSaveFlags[2];
- final boolean exportAudios = inSaveFlags[3];
- final boolean exportSelection = inSaveFlags[4];
- final boolean exportTimestamps = inSaveFlags[5];
+ final boolean exportWaypoints = inSettings.getExportWaypoints();
+ final boolean exportSelection = inSettings.getExportJustSelection();
+ final boolean exportTimestamps = inSettings.getExportTimestamps();
// Examine selection
int selStart = -1, selEnd = -1;
if (exportSelection) {
// Loop over waypoints
final int numPoints = inInfo.getTrack().getNumPoints();
int numSaved = 0;
- for (i=0; i<numPoints; i++)
+ for (int i=0; i<numPoints; i++)
{
point = inInfo.getTrack().getPoint(i);
if (!exportSelection || (i>=selStart && i<=selEnd))
inWriter.write('\n');
}
else {
- exportWaypoint(point, inWriter, exportTimestamps, exportPhotos, exportAudios);
+ exportWaypoint(point, inWriter, inSettings);
}
numSaved++;
}
}
}
// Export both route points and then track points
- if (exportTrackpoints || exportPhotos || exportAudios)
+ if (inSettings.getExportTrackPoints() || inSettings.getExportPhotoPoints() || inSettings.getExportAudioPoints())
{
// Output all route points (if any)
- numSaved += writeTrackPoints(inWriter, inInfo, exportSelection, exportTrackpoints, exportPhotos,
- exportAudios, exportTimestamps, true, inGpxCachers, "<rtept", "\t<rte><number>1</number>\n",
+ numSaved += writeTrackPoints(inWriter, inInfo, inSettings,
+ true, inGpxCachers, "<rtept", "\t<rte><number>1</number>\n",
null, "\t</rte>\n");
// Output all track points, if any
String trackStart = "\t<trk>\n\t\t<name>" + trackName + "</name>\n\t\t<number>1</number>\n\t\t<trkseg>\n";
- numSaved += writeTrackPoints(inWriter, inInfo, exportSelection, exportTrackpoints, exportPhotos,
- exportAudios, exportTimestamps, false, inGpxCachers, "<trkpt", trackStart,
+ numSaved += writeTrackPoints(inWriter, inInfo, inSettings,
+ false, inGpxCachers, "<trkpt", trackStart,
"\t</trkseg>\n\t<trkseg>\n", "\t\t</trkseg>\n\t</trk>\n");
}
private static void writeNameAndDescription(OutputStreamWriter inWriter,
String inName, String inDesc, boolean inIsVersion1_1) throws IOException
{
- String desc = (inDesc != null && !inDesc.equals("")) ? inDesc : "Export from GpsPrune";
// Position of name and description fields needs to be different for GPX1.0 and GPX1.1
if (inIsVersion1_1)
{
}
if (inIsVersion1_1) {inWriter.write('\t');}
inWriter.write("\t<desc>");
- inWriter.write(desc);
+ inWriter.write(inDesc);
inWriter.write("</desc>\n");
if (inIsVersion1_1)
{
* Loop through the track outputting the relevant track points
* @param inWriter writer object for output
* @param inInfo track info object containing track
- * @param inExportSelection true to just output current selection
- * @param inExportTrackpoints true to output track points
- * @param inExportPhotos true to output photo points
- * @param inExportAudios true to output audio points
- * @param inExportTimestamps true to include timestamps in export
+ * @param inSettings export settings defining what should be exported
* @param inOnlyCopies true to only export if source can be copied
* @param inCachers list of GpxCachers
* @param inPointTag tag to match for each point
* @param inEndTag end tag to output
*/
private static int writeTrackPoints(OutputStreamWriter inWriter,
- TrackInfo inInfo, boolean inExportSelection, boolean inExportTrackpoints,
- boolean inExportPhotos, boolean inExportAudios, boolean exportTimestamps,
+ TrackInfo inInfo, SettingsForExport inSettings,
boolean inOnlyCopies, GpxCacherList inCachers, String inPointTag,
String inStartTag, String inSegmentTag, String inEndTag)
throws IOException
{
- // Note: far too many input parameters to this method but avoids duplication
+ // Note: Too many input parameters to this method but avoids duplication
// of output functionality for writing track points and route points
int numPoints = inInfo.getTrack().getNumPoints();
int selStart = inInfo.getSelection().getStart();
int selEnd = inInfo.getSelection().getEnd();
int numSaved = 0;
+ final boolean exportSelection = inSettings.getExportJustSelection();
+ final boolean exportTrackPoints = inSettings.getExportTrackPoints();
+ final boolean exportPhotos = inSettings.getExportPhotoPoints();
+ final boolean exportAudios = inSettings.getExportAudioPoints();
+ final boolean exportTimestamps = inSettings.getExportTimestamps();
// Loop over track points
for (int i=0; i<numPoints; i++)
{
DataPoint point = inInfo.getTrack().getPoint(i);
- if ((!inExportSelection || (i>=selStart && i<=selEnd)) && !point.isWaypoint())
+ if ((!exportSelection || (i>=selStart && i<=selEnd)) && !point.isWaypoint())
{
- if ((point.getPhoto()==null && inExportTrackpoints) || (point.getPhoto()!=null && inExportPhotos)
- || (point.getAudio()!=null && inExportAudios))
+ if ((point.getPhoto()==null && exportTrackPoints) || (point.getPhoto()!=null && exportPhotos)
+ || (point.getAudio()!=null && exportAudios))
{
// get the source from the point (if any)
String pointSource = getPointSource(inCachers, point);
inWriter.write(pointSource);
inWriter.write('\n');
}
- else {
- if (!inOnlyCopies) {exportTrackpoint(point, inWriter, exportTimestamps, inExportPhotos, inExportAudios);}
+ else
+ {
+ if (!inOnlyCopies) {
+ exportTrackpoint(point, inWriter, inSettings);
+ }
}
numSaved++;
}
}
}
}
- if (numSaved > 0) {inWriter.write(inEndTag);}
+ if (numSaved > 0) {
+ inWriter.write(inEndTag);
+ }
return numSaved;
}
source = replaceGpxTags(source, "lat=\"", "\"", inPoint.getLatitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
source = replaceGpxTags(source, "lon=\"", "\"", inPoint.getLongitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
source = replaceGpxTags(source, "<ele>", "</ele>", inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES));
- source = replaceGpxTags(source, "<time>", "</time>", inPoint.getTimestamp().getText(Timestamp.FORMAT_ISO_8601));
+ source = replaceGpxTags(source, "<time>", "</time>", inPoint.getTimestamp().getText(Timestamp.Format.ISO8601, null));
if (inPoint.isWaypoint())
{
- source = replaceGpxTags(source, "<name>", "</name>", inPoint.getWaypointName());
- source = replaceGpxTags(source, "<description>", "</description>",
+ source = replaceGpxTags(source, "<name>", "</name>", XmlUtils.fixCdata(inPoint.getWaypointName()));
+ if (source != null)
+ {
+ source = source.replaceAll("<description>", "<desc>").replaceAll("</description>", "</desc>");
+ }
+ source = replaceGpxTags(source, "<desc>", "</desc>",
XmlUtils.fixCdata(inPoint.getFieldValue(Field.DESCRIPTION)));
}
// photo / audio links
* Export the specified waypoint into the file
* @param inPoint waypoint to export
* @param inWriter writer object
- * @param inTimestamps true to export timestamps too
- * @param inPhoto true to export link to photo
- * @param inAudio true to export link to audio
+ * @param inSettings export settings
* @throws IOException on write failure
*/
- private static void exportWaypoint(DataPoint inPoint, Writer inWriter, boolean inTimestamps,
- boolean inPhoto, boolean inAudio)
+ private static void exportWaypoint(DataPoint inPoint, Writer inWriter,
+ SettingsForExport inSettings)
throws IOException
{
inWriter.write("\t<wpt lat=\"");
inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
inWriter.write("\">\n");
// altitude if available
- if (inPoint.hasAltitude())
+ if (inPoint.hasAltitude() || inSettings.getExportMissingAltitudesAsZero())
{
inWriter.write("\t\t<ele>");
- inWriter.write("" + inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES));
+ inWriter.write(inPoint.hasAltitude() ? inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES) : "0");
inWriter.write("</ele>\n");
}
- // timestamp if available (point might have timestamp and then be turned into a waypoint)
- if (inPoint.hasTimestamp() && inTimestamps)
+ // timestamp if available (some waypoints have timestamps, some not)
+ if (inPoint.hasTimestamp() && inSettings.getExportTimestamps())
{
inWriter.write("\t\t<time>");
- inWriter.write(inPoint.getTimestamp().getText(Timestamp.FORMAT_ISO_8601));
+ inWriter.write(inPoint.getTimestamp().getText(Timestamp.Format.ISO8601, null));
inWriter.write("</time>\n");
}
// write waypoint name after elevation and time
inWriter.write("\t\t<name>");
- inWriter.write(inPoint.getWaypointName().trim());
+ inWriter.write(XmlUtils.fixCdata(inPoint.getWaypointName().trim()));
inWriter.write("</name>\n");
// description, if any
String desc = XmlUtils.fixCdata(inPoint.getFieldValue(Field.DESCRIPTION));
if (desc != null && !desc.equals(""))
{
- inWriter.write("\t\t<description>");
+ inWriter.write("\t\t<desc>");
inWriter.write(desc);
- inWriter.write("</description>\n");
+ inWriter.write("</desc>\n");
}
// Media links, if any
- if (inPhoto && inPoint.getPhoto() != null)
+ if (inSettings.getExportPhotoPoints() && inPoint.getPhoto() != null)
{
inWriter.write("\t\t");
inWriter.write(makeMediaLink(inPoint.getPhoto()));
inWriter.write('\n');
}
- if (inAudio && inPoint.getAudio() != null)
+ if (inSettings.getExportAudioPoints() && inPoint.getAudio() != null)
{
inWriter.write("\t\t");
inWriter.write(makeMediaLink(inPoint.getAudio()));
* Export the specified trackpoint into the file
* @param inPoint trackpoint to export
* @param inWriter writer object
- * @param inTimestamps true to export timestamps too
- * @param inExportPhoto true to export photo link
- * @param inExportAudio true to export audio link
+ * @param inSettings export settings
*/
- private static void exportTrackpoint(DataPoint inPoint, Writer inWriter, boolean inTimestamps,
- boolean inExportPhoto, boolean inExportAudio)
+ private static void exportTrackpoint(DataPoint inPoint, Writer inWriter, SettingsForExport inSettings)
throws IOException
{
inWriter.write("\t\t\t<trkpt lat=\"");
inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DECIMAL_FORCE_POINT));
inWriter.write("\">\n");
// altitude
- if (inPoint.hasAltitude())
+ if (inPoint.hasAltitude() || inSettings.getExportMissingAltitudesAsZero())
{
inWriter.write("\t\t\t\t<ele>");
- inWriter.write("" + inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES));
+ inWriter.write(inPoint.hasAltitude() ? inPoint.getAltitude().getStringValue(UnitSetLibrary.UNITS_METRES) : "0");
inWriter.write("</ele>\n");
}
+ // Maybe take timestamp from photo if the point hasn't got one
+ Timestamp pointTimestamp = getPointTimestamp(inPoint, inSettings);
// timestamp if available (and selected)
- if (inPoint.hasTimestamp() && inTimestamps)
+ if (pointTimestamp != null && inSettings.getExportTimestamps())
{
inWriter.write("\t\t\t\t<time>");
- inWriter.write(inPoint.getTimestamp().getText(Timestamp.FORMAT_ISO_8601));
+ inWriter.write(pointTimestamp.getText(Timestamp.Format.ISO8601, null));
inWriter.write("</time>\n");
}
// photo, audio
- if (inPoint.getPhoto() != null && inExportPhoto) {
+ if (inPoint.getPhoto() != null && inSettings.getExportPhotoPoints())
+ {
+ inWriter.write("\t\t\t\t");
inWriter.write(makeMediaLink(inPoint.getPhoto()));
+ inWriter.write("\n");
}
- if (inPoint.getAudio() != null && inExportAudio) {
+ if (inPoint.getAudio() != null && inSettings.getExportAudioPoints()) {
inWriter.write(makeMediaLink(inPoint.getAudio()));
}
inWriter.write("\t\t\t</trkpt>\n");
{
return inPointSource.replaceAll("[ \t]*<time>.*?</time>", "");
}
+
+ /**
+ * Get the timestamp from the point or its media
+ * @param inPoint point object
+ * @param inSettings export settings
+ * @return Timestamp object if available, or null
+ */
+ private static Timestamp getPointTimestamp(DataPoint inPoint, SettingsForExport inSettings)
+ {
+ if (inPoint.hasTimestamp())
+ {
+ return inPoint.getTimestamp();
+ }
+ if (inPoint.getPhoto() != null && inSettings.getExportPhotoPoints())
+ {
+ if (inPoint.getPhoto().hasTimestamp())
+ {
+ return inPoint.getPhoto().getTimestamp();
+ }
+ }
+ if (inPoint.getAudio() != null && inSettings.getExportAudioPoints())
+ {
+ if (inPoint.getAudio().hasTimestamp())
+ {
+ return inPoint.getAudio().getTimestamp();
+ }
+ }
+ return null;
+ }
}