source: josm/trunk/src/org/openstreetmap/josm/io/GpxImporter.java@ 12466

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

see #14924 - improve NMEA documentation thanks to gpsd (http://www.catb.org/gpsd/NMEA.html) + add support for NMEA sentences coming from GLONASS, Galileo or Beidu receivers

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