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.actions.ExtensionFileFilter;
014import org.openstreetmap.josm.gui.HelpAwareOptionPane;
015import org.openstreetmap.josm.gui.MainApplication;
016import org.openstreetmap.josm.gui.Notification;
017import org.openstreetmap.josm.gui.io.importexport.GpxImporter.GpxImporterData;
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.Compression;
023import org.openstreetmap.josm.io.rtklib.RtkLibPosReader;
024import org.openstreetmap.josm.spi.preferences.Config;
025import org.xml.sax.SAXException;
026
027/**
028 * File importer allowing to import RTKLib files (*.pos files).
029 * @since 15247
030 */
031public class RtkLibImporter extends FileImporter {
032
033    /**
034     * The RtkLib file filter (*.pos files).
035     */
036    public static final ExtensionFileFilter FILE_FILTER = ExtensionFileFilter.newFilterWithArchiveExtensions(
037            "pos", "pos", tr("RTKLib Positioning Solution Files"), false);
038
039    /**
040     * Constructs a new {@code RtkLibImporter}.
041     */
042    public RtkLibImporter() {
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 RtkLibPosReader r = buildAndParse(fis);
051            if (r.getNumberOfCoordinates() > 0) {
052                r.getGpxData().storageFile = file;
053                final GpxLayer gpxLayer = new GpxLayer(r.getGpxData(), 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.getGpxData(), tr("Markers from {0}", fn), fileFinal, gpxLayer);
060                        if (!ml.data.isEmpty()) {
061                            MainApplication.getLayerManager().addLayer(ml);
062                        }
063                    }
064                });
065            }
066            showRtkLibInfobox(r.getNumberOfCoordinates() > 0, r);
067        }
068    }
069
070    private static void showRtkLibInfobox(boolean success, RtkLibPosReader r) {
071        final StringBuilder msg = new StringBuilder(160).append("<html>")
072           .append(tr("Coordinates imported: {0}", r.getNumberOfCoordinates()))
073           .append("</html>");
074        if (success) {
075            SwingUtilities.invokeLater(() -> new Notification(
076                    "<h3>" + tr("RTKLib import success:") + "</h3>" + msg.toString())
077                    .setIcon(JOptionPane.INFORMATION_MESSAGE)
078                    .show());
079        } else {
080            HelpAwareOptionPane.showMessageDialogInEDT(
081                    MainApplication.getMainFrame(),
082                    msg.toString(),
083                    tr("RTKLib import failure!"),
084                    JOptionPane.ERROR_MESSAGE, null);
085        }
086    }
087
088    /**
089     * Replies the new GPX and marker layers corresponding to the specified RTKLib file.
090     * @param is input stream to RTKLib data
091     * @param associatedFile RTKLib file
092     * @param gpxLayerName The GPX layer name
093     * @param markerLayerName The marker layer name
094     * @return the new GPX and marker layers corresponding to the specified RTKLib file
095     * @throws IOException if an I/O error occurs
096     */
097    public static GpxImporterData loadLayers(InputStream is, final File associatedFile,
098            final String gpxLayerName, String markerLayerName) throws IOException {
099        final RtkLibPosReader r = buildAndParse(is);
100        final boolean parsedProperly = r.getNumberOfCoordinates() > 0;
101        r.getGpxData().storageFile = associatedFile;
102        return GpxImporter.loadLayers(r.getGpxData(), parsedProperly, gpxLayerName, markerLayerName);
103    }
104
105    static RtkLibPosReader buildAndParse(InputStream fis) throws IOException {
106        final RtkLibPosReader r = new RtkLibPosReader(fis);
107        try {
108            r.parse(true);
109        } catch (SAXException e) {
110            throw new IOException(e);
111        }
112        return r;
113    }
114}