001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.actions;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.event.KeyEvent;
007import java.awt.geom.Path2D;
008import java.util.Collection;
009
010import javax.swing.JOptionPane;
011
012import org.openstreetmap.josm.data.osm.Node;
013import org.openstreetmap.josm.data.osm.OsmPrimitive;
014import org.openstreetmap.josm.data.osm.Way;
015import org.openstreetmap.josm.gui.MainApplication;
016import org.openstreetmap.josm.gui.PleaseWaitRunnable;
017import org.openstreetmap.josm.gui.help.HelpUtil;
018import org.openstreetmap.josm.gui.layer.gpx.DownloadAlongPanel;
019import org.openstreetmap.josm.tools.Shortcut;
020
021/**
022 * Calculate area around selected ways and split it into reasonable parts so
023 * that they can be downloaded.
024 *
025 */
026public class DownloadAlongWayAction extends DownloadAlongAction {
027
028    private static final String PREF_DOWNLOAD_ALONG_WAY_DISTANCE = "downloadAlongWay.distance";
029    private static final String PREF_DOWNLOAD_ALONG_WAY_AREA = "downloadAlongWay.area";
030
031    private static final String PREF_DOWNLOAD_ALONG_WAY_OSM = "downloadAlongWay.download.osm";
032    private static final String PREF_DOWNLOAD_ALONG_WAY_GPS = "downloadAlongWay.download.gps";
033
034    /**
035     * Create new {@link DownloadAlongWayAction}.
036     */
037    public DownloadAlongWayAction() {
038        super(tr("Download along..."), "download_along_way", tr("Download OSM data along the selected ways."),
039                Shortcut.registerShortcut("file:download_along", tr("File: {0}", tr("Download Along")),
040                        KeyEvent.VK_D, Shortcut.ALT_SHIFT), true);
041    }
042
043    @Override
044    protected PleaseWaitRunnable createTask() {
045        Collection<Way> selectedWays = getLayerManager().getEditDataSet().getSelectedWays();
046
047        if (selectedWays.isEmpty()) {
048            JOptionPane.showMessageDialog(MainApplication.getMainFrame(), tr("Please select 1 or more ways to download along"));
049            return null;
050        }
051
052        final DownloadAlongPanel panel = new DownloadAlongPanel(
053                PREF_DOWNLOAD_ALONG_WAY_OSM, PREF_DOWNLOAD_ALONG_WAY_GPS,
054                PREF_DOWNLOAD_ALONG_WAY_DISTANCE, PREF_DOWNLOAD_ALONG_WAY_AREA, null);
055
056        if (0 != panel.showInDownloadDialog(tr("Download from OSM along selected ways"), HelpUtil.ht("/Tools/DownloadAlong"))) {
057            return null;
058        }
059
060        // Convert OSM ways to Path2D
061        Path2D alongPath = new Path2D.Double();
062        for (Way way : selectedWays) {
063            boolean first = true;
064            for (Node p : way.getNodes()) {
065                if (first) {
066                    alongPath.moveTo(p.lon(), p.lat());
067                    first = false;
068                } else {
069                    alongPath.lineTo(p.lon(), p.lat());
070                }
071            }
072        }
073        return createCalcTask(alongPath, panel, tr("Download from OSM along selected ways"));
074
075    }
076
077    @Override
078    protected void updateEnabledState() {
079        if (getLayerManager().getEditDataSet() == null) {
080            setEnabled(false);
081        } else {
082            updateEnabledState(getLayerManager().getEditDataSet().getSelected());
083        }
084    }
085
086    @Override
087    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
088        setEnabled(selection.stream().anyMatch(Way.class::isInstance));
089    }
090}