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