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

Last change on this file since 16625 was 16625, checked in by simon04, 4 years ago

see #19334 - https://errorprone.info/bugpattern/UnusedVariable

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