]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/save/KmlExporter.java
16624ad1495dd26c549a0af26a3c087fbb0364c7
[GpsPrune.git] / tim / prune / save / KmlExporter.java
1 package tim.prune.save;
2
3 import java.io.File;
4 import java.io.FileWriter;
5 import java.io.IOException;
6 import java.io.Writer;
7
8 import javax.swing.JFileChooser;
9 import javax.swing.JFrame;
10 import javax.swing.JOptionPane;
11 import javax.swing.filechooser.FileFilter;
12
13 import tim.prune.App;
14 import tim.prune.I18nManager;
15 import tim.prune.data.Coordinate;
16 import tim.prune.data.DataPoint;
17 import tim.prune.data.Track;
18
19 /**
20  * Class to export track information
21  * into a specified Kml file
22  */
23 public class KmlExporter
24 {
25         private App _app = null;
26         private JFrame _parentFrame = null;
27         private Track _track = null;
28         private JFileChooser _fileChooser = null;
29
30
31         /**
32          * Constructor giving App object, frame and track
33          * @param inApp application object to inform of success
34          * @param inParentFrame parent frame
35          * @param inTrack track object to save
36          */
37         public KmlExporter(App inApp, JFrame inParentFrame, Track inTrack)
38         {
39                 _app = inApp;
40                 _parentFrame = inParentFrame;
41                 _track = inTrack;
42         }
43
44
45         /**
46          * Show the dialog to select options and export file
47          */
48         public boolean showDialog()
49         {
50                 boolean fileSaved = false;
51                 Object description = JOptionPane.showInputDialog(_parentFrame,
52                         I18nManager.getText("dialog.exportkml.text"),
53                         I18nManager.getText("dialog.exportkml.title"),
54                         JOptionPane.QUESTION_MESSAGE, null, null, "");
55                 // TODO: Make dialog window including colour selection, line width, track description
56                 if (description != null)
57                 {
58                         // OK pressed, so choose output file
59                         if (_fileChooser == null)
60                                 _fileChooser = new JFileChooser();
61                         _fileChooser.setDialogType(JFileChooser.SAVE_DIALOG);
62                         _fileChooser.setFileFilter(new FileFilter() {
63                                 public boolean accept(File f)
64                                 {
65                                         return (f != null && (f.isDirectory() || f.getName().toLowerCase().endsWith(".kml")));
66                                 }
67                                 public String getDescription()
68                                 {
69                                         return I18nManager.getText("dialog.exportkml.filetype");
70                                 }
71                         });
72                         _fileChooser.setAcceptAllFileFilterUsed(false);
73                         // Allow choose again if an existing file is selected
74                         boolean chooseAgain = false;
75                         do
76                         {
77                                 chooseAgain = false;
78                                 if (_fileChooser.showSaveDialog(_parentFrame) == JFileChooser.APPROVE_OPTION)
79                                 {
80                                         // OK pressed and file chosen
81                                         File file = _fileChooser.getSelectedFile();
82                                         if (!file.getName().toLowerCase().endsWith(".kml"))
83                                         {
84                                                 file = new File(file.getAbsolutePath() + ".kml");
85                                         }
86                                         // Check if file exists and if necessary prompt for overwrite
87                                         Object[] buttonTexts = {I18nManager.getText("button.overwrite"), I18nManager.getText("button.cancel")};
88                                         if (!file.exists() || JOptionPane.showOptionDialog(_parentFrame,
89                                                         I18nManager.getText("dialog.save.overwrite.text"),
90                                                         I18nManager.getText("dialog.save.overwrite.title"), JOptionPane.YES_NO_OPTION,
91                                                         JOptionPane.WARNING_MESSAGE, null, buttonTexts, buttonTexts[1])
92                                                 == JOptionPane.YES_OPTION)
93                                         {
94                                                 if (exportFile(file, description.toString()))
95                                                 {
96                                                         fileSaved = true;
97                                                 }
98                                                 else
99                                                 {
100                                                         chooseAgain = true;
101                                                 }
102                                         }
103                                         else
104                                         {
105                                                 chooseAgain = true;
106                                         }
107                                 }
108                         } while (chooseAgain);
109                 }
110                 return fileSaved;
111         }
112
113
114         /**
115          * Export the track data to the specified file with description
116          * @param inFile File object to save to
117          * @param inDescription description to use, if any
118          */
119         private boolean exportFile(File inFile, String inDescription)
120         {
121                 FileWriter writer = null;
122                 try
123                 {
124                         writer = new FileWriter(inFile);
125                         writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://earth.google.com/kml/2.1\">\n<Folder>\n");
126                         writer.write("\t<name>");
127                         writer.write(inDescription);
128                         writer.write("</name>\n");
129
130                         int i = 0;
131                         DataPoint point = null;
132                         boolean hasTrackpoints = false;
133                         // Loop over waypoints
134                         boolean writtenPhotoHeader = false;
135                         int numPoints = _track.getNumPoints();
136                         for (i=0; i<numPoints; i++)
137                         {
138                                 point = _track.getPoint(i);
139                                 if (point.isWaypoint())
140                                 {
141                                         exportWaypoint(point, writer);
142                                 }
143                                 else if (point.getPhoto() != null)
144                                 {
145                                         if (!writtenPhotoHeader)
146                                         {
147                                                 writer.write("<Style id=\"camera_icon\"><IconStyle><Icon><href>http://maps.google.com/mapfiles/kml/pal4/icon46.png</href></Icon></IconStyle></Style>");
148                                                 writtenPhotoHeader = true;
149                                         }
150                                         exportPhotoPoint(point, writer);
151                                 }
152                                 else
153                                 {
154                                         hasTrackpoints = true;
155                                 }
156                         }
157                         if (hasTrackpoints)
158                         {
159                                 writer.write("\t<Placemark>\n\t\t<name>track</name>\n\t\t<Style>\n\t\t\t<LineStyle>\n"
160                                         + "\t\t\t\t<color>cc0000cc</color>\n\t\t\t\t<width>4</width>\n\t\t\t</LineStyle>\n"
161                                         + "\t\t</Style>\n\t\t<LineString>\n\t\t\t<coordinates>");
162                                 // Loop over track points
163                                 for (i=0; i<numPoints; i++)
164                                 {
165                                         point = _track.getPoint(i);
166                                         if (!point.isWaypoint())
167                                         {
168                                                 exportTrackpoint(point, writer);
169                                         }
170                                 }
171                                 writer.write("\t\t\t</coordinates>\n\t\t</LineString>\n\t</Placemark>");
172                         }
173                         writer.write("</Folder>\n</kml>");
174                         writer.close();
175                         JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("dialog.save.ok1")
176                                  + " " + numPoints + " " + I18nManager.getText("dialog.save.ok2")
177                                  + " " + inFile.getAbsolutePath(),
178                                 I18nManager.getText("dialog.save.oktitle"), JOptionPane.INFORMATION_MESSAGE);
179                         return true;
180                 }
181                 catch (IOException ioe)
182                 {
183                         try {
184                                 if (writer != null) writer.close();
185                         }
186                         catch (IOException ioe2) {}
187                         JOptionPane.showMessageDialog(_parentFrame, I18nManager.getText("error.save.failed") + ioe.getMessage(),
188                                 I18nManager.getText("error.save.dialogtitle"), JOptionPane.ERROR_MESSAGE);
189                 }
190                 return false;
191         }
192
193
194         /**
195          * Export the specified waypoint into the file
196          * @param inPoint waypoint to export
197          * @param inWriter writer object
198          * @throws IOException on write failure
199          */
200         private void exportWaypoint(DataPoint inPoint, Writer inWriter) throws IOException
201         {
202                 inWriter.write("\t<Placemark>\n\t\t<name>");
203                 inWriter.write(inPoint.getWaypointName().trim());
204                 inWriter.write("</name>\n");
205                 inWriter.write("\t\t<Point>\n\t\t\t<coordinates>");
206                 inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DEG_WITHOUT_CARDINAL));
207                 inWriter.write(',');
208                 inWriter.write(inPoint.getLatitude().output(Coordinate.FORMAT_DEG_WITHOUT_CARDINAL));
209                 inWriter.write(",0</coordinates>\n\t\t</Point>\n\t</Placemark>\n");
210         }
211
212
213         /**
214          * Export the specified photo into the file
215          * @param inPoint data point including photo
216          * @param inWriter writer object
217          * @throws IOException on write failure
218          */
219         private void exportPhotoPoint(DataPoint inPoint, Writer inWriter) throws IOException
220         {
221                 // TODO: Export photos to KML too - for photos need kmz!
222                 inWriter.write("\t<Placemark>\n\t\t<name>");
223                 inWriter.write(inPoint.getPhoto().getFile().getName());
224                 inWriter.write("</name>\n");
225                 inWriter.write("<styleUrl>#camera_icon</styleUrl>\n");
226                 inWriter.write("\t\t<Point>\n\t\t\t<coordinates>");
227                 inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DEG_WITHOUT_CARDINAL));
228                 inWriter.write(',');
229                 inWriter.write(inPoint.getLatitude().output(Coordinate.FORMAT_DEG_WITHOUT_CARDINAL));
230                 inWriter.write(",0</coordinates>\n\t\t</Point>\n\t</Placemark>\n");
231         }
232
233
234         /**
235          * Export the specified trackpoint into the file
236          * @param inPoint trackpoint to export
237          * @param inWriter writer object
238          */
239         private void exportTrackpoint(DataPoint inPoint, Writer inWriter) throws IOException
240         {
241                 inWriter.write(inPoint.getLongitude().output(Coordinate.FORMAT_DEG_WITHOUT_CARDINAL));
242                 inWriter.write(',');
243                 inWriter.write(inPoint.getLatitude().output(Coordinate.FORMAT_DEG_WITHOUT_CARDINAL));
244                 // Altitude not exported, locked to ground by Google Earth
245                 inWriter.write(",0\n");
246         }
247 }