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