X-Git-Url: http://gitweb.fperrin.net/?a=blobdiff_plain;f=tim%2Fprune%2Fsave%2FGpxExporter.java;h=8203593b0d6d72387293df350e1366a8ddf097ae;hb=3745d70b1427bb8ac1a085e47cbdc566936784e1;hp=019cc438bdbf96003595e7c7ebe7d84654839d11;hpb=1ee49ae3c8ef3aa2e63eadd458531e5f8bd4f92c;p=GpsPrune.git
diff --git a/tim/prune/save/GpxExporter.java b/tim/prune/save/GpxExporter.java
index 019cc43..8203593 100644
--- a/tim/prune/save/GpxExporter.java
+++ b/tim/prune/save/GpxExporter.java
@@ -6,11 +6,14 @@ import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
+import java.nio.charset.Charset;
import javax.swing.BorderFactory;
import javax.swing.Box;
@@ -38,6 +41,8 @@ import tim.prune.data.Field;
import tim.prune.data.Timestamp;
import tim.prune.data.TrackInfo;
import tim.prune.load.GenericFileFilter;
+import tim.prune.save.xml.GpxCacherList;
+
/**
* Class to export track information
@@ -127,6 +132,14 @@ public class GpxExporter extends GenericFunction implements Runnable
mainPanel.add(checkPanel);
dialogPanel.add(mainPanel, BorderLayout.CENTER);
+ // close dialog if escape pressed
+ _nameField.addKeyListener(new KeyAdapter() {
+ public void keyReleased(KeyEvent e) {
+ if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
+ _dialog.dispose();
+ }
+ }
+ });
// button panel at bottom
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
@@ -142,8 +155,7 @@ public class GpxExporter extends GenericFunction implements Runnable
buttonPanel.add(okButton);
JButton cancelButton = new JButton(I18nManager.getText("button.cancel"));
cancelButton.addActionListener(new ActionListener() {
- public void actionPerformed(ActionEvent e)
- {
+ public void actionPerformed(ActionEvent e) {
_dialog.dispose();
}
});
@@ -288,8 +300,9 @@ public class GpxExporter extends GenericFunction implements Runnable
// Instantiate source file cachers in case we want to copy output
GpxCacherList gpxCachers = null;
if (inUseCopy) gpxCachers = new GpxCacherList(inInfo.getFileInfo());
- // Write or copy header
- inWriter.write(getHeaderString(gpxCachers));
+ // Write or copy headers
+ inWriter.write(getXmlHeaderString(inWriter));
+ inWriter.write(getGpxHeaderString(gpxCachers));
// Name field
String trackName = "PruneTrack";
if (inName != null && !inName.equals(""))
@@ -301,12 +314,7 @@ public class GpxExporter extends GenericFunction implements Runnable
}
// Description field
inWriter.write("\t");
- if (inDesc != null && !inDesc.equals("")) {
- inWriter.write(inDesc);
- }
- else {
- inWriter.write("Export from Prune");
- }
+ inWriter.write((inDesc != null && !inDesc.equals(""))?inDesc:"Export from Prune");
inWriter.write("\n");
int i = 0;
@@ -334,7 +342,7 @@ public class GpxExporter extends GenericFunction implements Runnable
if (point.isWaypoint()) {
if (exportWaypoints)
{
- String pointSource = (inUseCopy?gpxCachers.getSourceString(point):null);
+ String pointSource = (inUseCopy?getPointSource(gpxCachers, point):null);
if (pointSource != null) {
inWriter.write(pointSource);
inWriter.write('\n');
@@ -404,7 +412,7 @@ public class GpxExporter extends GenericFunction implements Runnable
if ((point.getPhoto()==null && inExportTrackpoints) || (point.getPhoto()!=null && inExportPhotos))
{
// get the source from the point (if any)
- String pointSource = (inCachers!=null?inCachers.getSourceString(point):null);
+ String pointSource = getPointSource(inCachers, point);
boolean writePoint = (pointSource != null && pointSource.toLowerCase().startsWith(inPointTag))
|| (pointSource == null && !inOnlyCopies);
if (writePoint)
@@ -430,12 +438,83 @@ public class GpxExporter extends GenericFunction implements Runnable
return numSaved;
}
+
+ /**
+ * Get the point source for the specified point
+ * @param inCachers list of GPX cachers to ask for source
+ * @param inPoint point object
+ * @return xml source if available, or null otherwise
+ */
+ private static String getPointSource(GpxCacherList inCachers, DataPoint inPoint)
+ {
+ if (inCachers == null || inPoint == null) {return null;}
+ String source = inCachers.getSourceString(inPoint);
+ if (source == null || !inPoint.isModified()) {return source;}
+ // Point has been modified - maybe it's possible to modify the source
+ 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, "", "", inPoint.getAltitude().getStringValue(Altitude.Format.METRES));
+ source = replaceGpxTags(source, "", inPoint.getTimestamp().getText(Timestamp.FORMAT_ISO_8601));
+ if (inPoint.isWaypoint()) {source = replaceGpxTags(source, "", "", inPoint.getWaypointName());} // only for waypoints
+ return source;
+ }
+
+ /**
+ * Replace the given value into the given XML string
+ * @param inSource source XML for point
+ * @param inStartTag start tag for field
+ * @param inEndTag end tag for field
+ * @param inValue value to replace between start tag and end tag
+ * @return modified String, or null if not possible
+ */
+ private static String replaceGpxTags(String inSource, String inStartTag, String inEndTag, String inValue)
+ {
+ if (inSource == null) {return null;}
+ // Look for start and end tags within source
+ final int startPos = inSource.indexOf(inStartTag);
+ final int endPos = inSource.indexOf(inEndTag, startPos+inStartTag.length());
+ if (startPos > 0 && endPos > 0)
+ {
+ String origValue = inSource.substring(startPos + inStartTag.length(), endPos);
+ if (inValue != null && origValue.equals(inValue)) {
+ // Value unchanged
+ return inSource;
+ }
+ else if (inValue == null || inValue.equals("")) {
+ // Need to delete value
+ return inSource.substring(0, startPos) + inSource.substring(endPos + inEndTag.length());
+ }
+ else {
+ // Need to replace value
+ return inSource.substring(0, startPos+inStartTag.length()) + inValue + inSource.substring(endPos);
+ }
+ }
+ // Value not found for this field in original source
+ if (inValue == null || inValue.equals("")) {return inSource;}
+ return null;
+ }
+
+ /**
+ * Get the header string for the xml document including encoding
+ * @param inWriter writer object
+ * @return header string defining encoding
+ */
+ private static String getXmlHeaderString(OutputStreamWriter inWriter)
+ {
+ String encoding = inWriter.getEncoding();
+ try {
+ encoding = Charset.forName(encoding).name();
+ }
+ catch (Exception e) {} // ignore failure to find encoding
+ return "\n";
+ }
+
/**
- * Get the header string for the gpx
+ * Get the header string for the gpx tag
* @param inCachers cacher list to ask for headers, if available
* @return header string from cachers or as default
*/
- private static String getHeaderString(GpxCacherList inCachers)
+ private static String getGpxHeaderString(GpxCacherList inCachers)
{
String gpxHeader = null;
if (inCachers != null) {gpxHeader = inCachers.getFirstHeader();}
@@ -447,7 +526,7 @@ public class GpxExporter extends GenericFunction implements Runnable
+ " xmlns=\"http://www.topografix.com/GPX/1/0\""
+ " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">\n";
}
- return "\n" + gpxHeader + "\n";
+ return gpxHeader + "\n";
}
/**