source: josm/trunk/src/org/openstreetmap/josm/gui/io/importexport/GpxImporter.java@ 12671

Last change on this file since 12671 was 12671, checked in by Don-vip, 7 years ago

see #15182 - move file importers/exporters from io package to gui.io.importexport package, as they rely heavily on GUI and are mainly used from Open/Save actions

  • Property svn:eol-style set to native
File size: 7.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io.importexport;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.File;
7import java.io.IOException;
8import java.io.InputStream;
9
10import javax.swing.JOptionPane;
11
12import org.openstreetmap.josm.Main;
13import org.openstreetmap.josm.actions.ExtensionFileFilter;
14import org.openstreetmap.josm.data.gpx.GpxData;
15import org.openstreetmap.josm.gui.MainApplication;
16import org.openstreetmap.josm.gui.layer.GpxLayer;
17import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
18import org.openstreetmap.josm.gui.progress.ProgressMonitor;
19import org.openstreetmap.josm.gui.util.GuiHelper;
20import org.openstreetmap.josm.io.Compression;
21import org.openstreetmap.josm.io.GpxReader;
22import org.openstreetmap.josm.tools.Logging;
23import org.xml.sax.SAXException;
24
25/**
26 * File importer allowing to import GPX files (*.gpx/gpx.gz files).
27 *
28 */
29public class GpxImporter extends FileImporter {
30
31 /**
32 * Utility class containing imported GPX and marker layers, and a task to run after they are added to MapView.
33 */
34 public static class GpxImporterData {
35 /**
36 * The imported GPX layer. May be null if no GPX data.
37 */
38 private final GpxLayer gpxLayer;
39 /**
40 * The imported marker layer. May be null if no marker.
41 */
42 private final MarkerLayer markerLayer;
43 /**
44 * The task to run after GPX and/or marker layer has been added to MapView.
45 */
46 private final Runnable postLayerTask;
47
48 /**
49 * Constructs a new {@code GpxImporterData}.
50 * @param gpxLayer The imported GPX layer. May be null if no GPX data.
51 * @param markerLayer The imported marker layer. May be null if no marker.
52 * @param postLayerTask The task to run after GPX and/or marker layer has been added to MapView.
53 */
54 public GpxImporterData(GpxLayer gpxLayer, MarkerLayer markerLayer, Runnable postLayerTask) {
55 this.gpxLayer = gpxLayer;
56 this.markerLayer = markerLayer;
57 this.postLayerTask = postLayerTask;
58 }
59
60 /**
61 * Returns the imported GPX layer. May be null if no GPX data.
62 * @return the imported GPX layer. May be null if no GPX data.
63 */
64 public GpxLayer getGpxLayer() {
65 return gpxLayer;
66 }
67
68 /**
69 * Returns the imported marker layer. May be null if no marker.
70 * @return the imported marker layer. May be null if no marker.
71 */
72 public MarkerLayer getMarkerLayer() {
73 return markerLayer;
74 }
75
76 /**
77 * Returns the task to run after GPX and/or marker layer has been added to MapView.
78 * @return the task to run after GPX and/or marker layer has been added to MapView.
79 */
80 public Runnable getPostLayerTask() {
81 return postLayerTask;
82 }
83 }
84
85 /**
86 * Constructs a new {@code GpxImporter}.
87 */
88 public GpxImporter() {
89 super(getFileFilter());
90 }
91
92 /**
93 * Returns a GPX file filter (*.gpx and *.gpx.gz files).
94 * @return a GPX file filter
95 */
96 public static ExtensionFileFilter getFileFilter() {
97 return ExtensionFileFilter.newFilterWithArchiveExtensions(
98 "gpx", Main.pref.get("save.extension.gpx", "gpx"), tr("GPX Files"), true);
99 }
100
101 @Override
102 public void importData(File file, ProgressMonitor progressMonitor) throws IOException {
103 final String fileName = file.getName();
104
105 try (InputStream is = Compression.getUncompressedFileInputStream(file)) {
106 GpxReader r = new GpxReader(is);
107 boolean parsedProperly = r.parse(true);
108 r.getGpxData().storageFile = file;
109 addLayers(loadLayers(r.getGpxData(), parsedProperly, fileName, tr("Markers from {0}", fileName)));
110 } catch (SAXException e) {
111 Logging.error(e);
112 throw new IOException(tr("Parsing data for layer ''{0}'' failed", fileName), e);
113 }
114 }
115
116 /**
117 * Adds the specified GPX and marker layers to Map.main
118 * @param data The layers to add
119 * @see #loadLayers
120 */
121 public static void addLayers(final GpxImporterData data) {
122 // FIXME: remove UI stuff from the IO subsystem
123 GuiHelper.runInEDT(() -> {
124 if (data.markerLayer != null) {
125 MainApplication.getLayerManager().addLayer(data.markerLayer);
126 }
127 if (data.gpxLayer != null) {
128 MainApplication.getLayerManager().addLayer(data.gpxLayer);
129 }
130 data.postLayerTask.run();
131 });
132 }
133
134 /**
135 * Replies the new GPX and marker layers corresponding to the specified GPX data.
136 * @param data The GPX data
137 * @param parsedProperly True if GPX data has been properly parsed by {@link GpxReader#parse}
138 * @param gpxLayerName The GPX layer name
139 * @param markerLayerName The marker layer name
140 * @return the new GPX and marker layers corresponding to the specified GPX data, to be used with {@link #addLayers}
141 * @see #addLayers
142 */
143 public static GpxImporterData loadLayers(final GpxData data, final boolean parsedProperly,
144 final String gpxLayerName, String markerLayerName) {
145 GpxLayer gpxLayer = null;
146 MarkerLayer markerLayer = null;
147 if (data.hasRoutePoints() || data.hasTrackPoints()) {
148 gpxLayer = new GpxLayer(data, gpxLayerName, data.storageFile != null);
149 }
150 if (Main.pref.getBoolean("marker.makeautomarkers", true) && !data.waypoints.isEmpty()) {
151 markerLayer = new MarkerLayer(data, markerLayerName, data.storageFile, gpxLayer);
152 if (markerLayer.data.isEmpty()) {
153 markerLayer = null;
154 }
155 }
156 Runnable postLayerTask = () -> {
157 if (!parsedProperly) {
158 String msg;
159 if (data.storageFile == null) {
160 msg = tr("Error occurred while parsing gpx data for layer ''{0}''. Only a part of the file will be available.",
161 gpxLayerName);
162 } else {
163 msg = tr("Error occurred while parsing gpx file ''{0}''. Only a part of the file will be available.",
164 data.storageFile.getPath());
165 }
166 JOptionPane.showMessageDialog(null, msg);
167 }
168 };
169 return new GpxImporterData(gpxLayer, markerLayer, postLayerTask);
170 }
171
172 /**
173 * Replies the new GPX and marker layers corresponding to the specified GPX file.
174 * @param is input stream to GPX data
175 * @param associatedFile GPX file
176 * @param gpxLayerName The GPX layer name
177 * @param markerLayerName The marker layer name
178 * @param progressMonitor The progress monitor
179 * @return the new GPX and marker layers corresponding to the specified GPX file
180 * @throws IOException if an I/O error occurs
181 */
182 public static GpxImporterData loadLayers(InputStream is, final File associatedFile,
183 final String gpxLayerName, String markerLayerName, ProgressMonitor progressMonitor) throws IOException {
184 try {
185 final GpxReader r = new GpxReader(is);
186 final boolean parsedProperly = r.parse(true);
187 r.getGpxData().storageFile = associatedFile;
188 return loadLayers(r.getGpxData(), parsedProperly, gpxLayerName, markerLayerName);
189 } catch (SAXException e) {
190 Logging.error(e);
191 throw new IOException(tr("Parsing data for layer ''{0}'' failed", gpxLayerName), e);
192 }
193 }
194}
Note: See TracBrowser for help on using the repository browser.