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;
009import java.util.Arrays;
010import java.util.Locale;
011
012import javax.json.JsonException;
013import javax.swing.JOptionPane;
014
015import org.openstreetmap.josm.actions.ExtensionFileFilter;
016import org.openstreetmap.josm.data.osm.DataSet;
017import org.openstreetmap.josm.gui.MainApplication;
018import org.openstreetmap.josm.gui.layer.OsmDataLayer;
019import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
020import org.openstreetmap.josm.gui.progress.ProgressMonitor;
021import org.openstreetmap.josm.gui.util.GuiHelper;
022import org.openstreetmap.josm.io.CachedFile;
023import org.openstreetmap.josm.io.Compression;
024import org.openstreetmap.josm.io.GeoJSONReader;
025import org.openstreetmap.josm.io.IllegalDataException;
026import org.openstreetmap.josm.tools.Logging;
027import org.openstreetmap.josm.tools.Utils;
028
029/**
030 * GeoJSON file importer.
031 * @author Ian Dees <ian.dees@gmail.com>
032 * @author matthieun <https://github.com/matthieun>
033 * @since 15424
034 */
035public class GeoJSONImporter extends FileImporter {
036
037    private static final ExtensionFileFilter FILE_FILTER = ExtensionFileFilter.newFilterWithArchiveExtensions(
038        "geojson", "geojson", tr("GeoJSON file") + " (*.geojson, *.geojson.gz, *.geojson.bz2, *.geojson.xz, *.geojson.zip)",
039        ExtensionFileFilter.AddArchiveExtension.NONE, Arrays.asList("gz", "bz", "bz2", "xz", "zip"));
040
041    /**
042     * Constructs a new GeoJSON File importer with an extension filter for .json and .geojson
043     */
044    public GeoJSONImporter() {
045        super(FILE_FILTER);
046    }
047
048    @Override
049    public void importData(final File file, final ProgressMonitor progressMonitor) {
050        progressMonitor.beginTask(tr("Loading json file…"));
051        progressMonitor.setTicksCount(2);
052        Logging.info("Parsing GeoJSON: {0}", file.getAbsolutePath());
053        try (InputStream fileInputStream = Compression.getUncompressedFileInputStream(file)) {
054            DataSet data = GeoJSONReader.parseDataSet(fileInputStream, progressMonitor);
055            progressMonitor.worked(1);
056            MainApplication.getLayerManager().addLayer(new OsmDataLayer(data, file.getName(), file));
057        } catch (IOException | IllegalArgumentException | IllegalDataException | JsonException e) {
058            Logging.error("Error while reading json file!");
059            Logging.error(e);
060            String message = tr("Error loading geojson file {0}", file.getAbsolutePath())
061                    + tr(" ({0})", Utils.getSizeString(file.length(), Locale.getDefault()));
062            GuiHelper.runInEDT(() -> JOptionPane.showMessageDialog(null, message, tr("Error"), JOptionPane.WARNING_MESSAGE));
063        } finally {
064            progressMonitor.finishTask();
065        }
066    }
067
068    /**
069     * Parse GeoJSON dataset.
070     * @param source geojson file
071     * @return GeoJSON dataset
072     * @throws IOException in case of I/O error
073     * @throws IllegalDataException if an error was found while parsing the data from the source
074     */
075    public DataSet parseDataSet(final String source) throws IOException, IllegalDataException {
076        try (CachedFile cf = new CachedFile(source)) {
077            InputStream fileInputStream = Compression.getUncompressedFileInputStream(cf.getFile()); // NOPMD
078            return GeoJSONReader.parseDataSet(fileInputStream, NullProgressMonitor.INSTANCE);
079        }
080    }
081}