001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.io.importexport; 003 004import static org.openstreetmap.josm.tools.I18n.tr; 005 006import java.io.File; 007import java.io.IOException; 008import java.io.InputStream; 009 010import javax.swing.JOptionPane; 011import javax.swing.SwingUtilities; 012 013import org.openstreetmap.josm.Main; 014import org.openstreetmap.josm.actions.ExtensionFileFilter; 015import org.openstreetmap.josm.gui.HelpAwareOptionPane; 016import org.openstreetmap.josm.gui.MainApplication; 017import org.openstreetmap.josm.gui.Notification; 018import org.openstreetmap.josm.gui.io.importexport.GpxImporter.GpxImporterData; 019import org.openstreetmap.josm.gui.layer.GpxLayer; 020import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer; 021import org.openstreetmap.josm.gui.progress.ProgressMonitor; 022import org.openstreetmap.josm.gui.util.GuiHelper; 023import org.openstreetmap.josm.io.Compression; 024import org.openstreetmap.josm.io.nmea.NmeaReader; 025import org.openstreetmap.josm.spi.preferences.Config; 026 027/** 028 * File importer allowing to import NMEA-0183 files (*.nmea/nme/nma/log/txt files). 029 * @since 1637 030 */ 031public class NMEAImporter extends FileImporter { 032 033 /** 034 * The NMEA file filter (*.nmea *.nme *.nma *.log *.txt files). 035 */ 036 public static final ExtensionFileFilter FILE_FILTER = ExtensionFileFilter.newFilterWithArchiveExtensions( 037 "nmea,nme,nma,log,txt", "nmea", tr("NMEA-0183 Files"), false); 038 039 /** 040 * Constructs a new {@code NMEAImporter}. 041 */ 042 public NMEAImporter() { 043 super(FILE_FILTER); 044 } 045 046 @Override 047 public void importData(File file, ProgressMonitor progressMonitor) throws IOException { 048 final String fn = file.getName(); 049 try (InputStream fis = Compression.getUncompressedFileInputStream(file)) { 050 final NmeaReader r = new NmeaReader(fis); 051 if (r.getNumberOfCoordinates() > 0) { 052 r.data.storageFile = file; 053 final GpxLayer gpxLayer = new GpxLayer(r.data, fn, true); 054 final File fileFinal = file; 055 056 GuiHelper.runInEDT(() -> { 057 MainApplication.getLayerManager().addLayer(gpxLayer); 058 if (Config.getPref().getBoolean("marker.makeautomarkers", true)) { 059 MarkerLayer ml = new MarkerLayer(r.data, tr("Markers from {0}", fn), fileFinal, gpxLayer); 060 if (!ml.data.isEmpty()) { 061 MainApplication.getLayerManager().addLayer(ml); 062 } 063 } 064 }); 065 } 066 showNmeaInfobox(r.getNumberOfCoordinates() > 0, r); 067 } 068 } 069 070 private static void showNmeaInfobox(boolean success, NmeaReader r) { 071 final StringBuilder msg = new StringBuilder(160).append("<html>") 072 .append(tr("Coordinates imported: {0}", r.getNumberOfCoordinates())).append("<br>") 073 .append(tr("Malformed sentences: {0}", r.getParserMalformed())).append("<br>") 074 .append(tr("Checksum errors: {0}", r.getParserChecksumErrors())).append("<br>"); 075 if (!success) { 076 msg.append(tr("Unknown sentences: {0}", r.getParserUnknown())).append("<br>"); 077 } 078 msg.append(tr("Zero coordinates: {0}", r.getParserZeroCoordinates())) 079 .append("</html>"); 080 if (success) { 081 SwingUtilities.invokeLater(() -> new Notification( 082 "<h3>" + tr("NMEA import success:") + "</h3>" + msg.toString()) 083 .setIcon(JOptionPane.INFORMATION_MESSAGE) 084 .show()); 085 } else { 086 HelpAwareOptionPane.showMessageDialogInEDT( 087 Main.parent, 088 msg.toString(), 089 tr("NMEA import failure!"), 090 JOptionPane.ERROR_MESSAGE, null); 091 } 092 } 093 094 /** 095 * Replies the new GPX and marker layers corresponding to the specified NMEA file. 096 * @param is input stream to NMEA 0183 data 097 * @param associatedFile NMEA file 098 * @param gpxLayerName The GPX layer name 099 * @param markerLayerName The marker layer name 100 * @return the new GPX and marker layers corresponding to the specified NMEA file 101 * @throws IOException if an I/O error occurs 102 */ 103 public static GpxImporterData loadLayers(InputStream is, final File associatedFile, 104 final String gpxLayerName, String markerLayerName) throws IOException { 105 final NmeaReader r = new NmeaReader(is); 106 final boolean parsedProperly = r.getNumberOfCoordinates() > 0; 107 r.data.storageFile = associatedFile; 108 return GpxImporter.loadLayers(r.data, parsedProperly, gpxLayerName, markerLayerName); 109 } 110}