001 // License: GPL. For details, see LICENSE file. 002 package org.openstreetmap.josm.io; 003 004 import static org.openstreetmap.josm.tools.I18n.tr; 005 006 import java.io.File; 007 import java.io.FileInputStream; 008 import java.io.IOException; 009 import java.io.InputStream; 010 import java.util.zip.GZIPInputStream; 011 012 import javax.swing.JOptionPane; 013 014 import org.openstreetmap.josm.Main; 015 import org.openstreetmap.josm.actions.ExtensionFileFilter; 016 import org.openstreetmap.josm.gui.layer.GpxLayer; 017 import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer; 018 import org.openstreetmap.josm.gui.progress.ProgressMonitor; 019 import org.openstreetmap.josm.gui.util.GuiHelper; 020 import org.xml.sax.SAXException; 021 022 public class GpxImporter extends FileImporter { 023 024 public static final ExtensionFileFilter FILE_FILTER = new ExtensionFileFilter( 025 "gpx,gpx.gz", "gpx", tr("GPX Files") + " (*.gpx *.gpx.gz)"); 026 027 protected static class GpxImporterData { 028 public GpxLayer gpxLayer; 029 public MarkerLayer markerLayer; 030 public Runnable postLayerTask; 031 } 032 033 public GpxImporter() { 034 super(FILE_FILTER); 035 } 036 037 @Override public void importData(File file, ProgressMonitor progressMonitor) throws IOException { 038 InputStream is; 039 if (file.getName().endsWith(".gpx.gz")) { 040 is = new GZIPInputStream(new FileInputStream(file)); 041 } else { 042 is = new FileInputStream(file); 043 } 044 String fileName = file.getName(); 045 final GpxImporterData data = loadLayers(is, file, fileName, tr("Markers from {0}", fileName), progressMonitor); 046 047 // FIXME: remove UI stuff from the IO subsystem 048 GuiHelper.runInEDT(new Runnable() { 049 public void run() { 050 if (data.markerLayer != null) { 051 Main.main.addLayer(data.markerLayer); 052 } 053 if (data.gpxLayer != null) { 054 Main.main.addLayer(data.gpxLayer); 055 } 056 data.postLayerTask.run(); 057 } 058 }); 059 } 060 061 public GpxImporterData loadLayers(InputStream is, final File associatedFile, 062 final String gpxLayerName, String markerLayerName, ProgressMonitor progressMonitor) throws IOException { 063 final GpxImporterData data = new GpxImporterData(); 064 try { 065 final GpxReader r = new GpxReader(is); 066 final boolean parsedProperly = r.parse(true); 067 r.data.storageFile = associatedFile; 068 if (r.data.hasRoutePoints() || r.data.hasTrackPoints()) { 069 data.gpxLayer = new GpxLayer(r.data, gpxLayerName, associatedFile != null); 070 } 071 if (Main.pref.getBoolean("marker.makeautomarkers", true) && !r.data.waypoints.isEmpty()) { 072 data.markerLayer = new MarkerLayer(r.data, markerLayerName, associatedFile, data.gpxLayer, false); 073 if (data.markerLayer.data.size() == 0) { 074 data.markerLayer = null; 075 } 076 } 077 data.postLayerTask = new Runnable() { 078 @Override 079 public void run() { 080 if (data.markerLayer != null) { 081 data.markerLayer.addMouseHandler(); 082 } 083 if (!parsedProperly) { 084 String msg; 085 if (associatedFile == null) { 086 msg = tr("Error occurred while parsing gpx data for layer ''{0}''. Only a part of the file will be available.", 087 gpxLayerName); 088 } else { 089 msg = tr("Error occurred while parsing gpx file ''{0}''. Only a part of the file will be available.", 090 associatedFile.getPath()); 091 } 092 JOptionPane.showMessageDialog(null, msg); 093 } 094 } 095 }; 096 } catch (SAXException e) { 097 e.printStackTrace(); 098 throw new IOException(tr("Parsing data for layer ''{0}'' failed", gpxLayerName)); 099 } 100 return data; 101 } 102 }