001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.layer.gpx;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.GridBagLayout;
007import java.awt.event.ActionEvent;
008import java.io.IOException;
009import java.util.ArrayList;
010import java.util.Collection;
011import java.util.List;
012
013import javax.swing.AbstractAction;
014import javax.swing.JLabel;
015import javax.swing.JOptionPane;
016import javax.swing.JPanel;
017
018import org.openstreetmap.josm.Main;
019import org.openstreetmap.josm.actions.AbstractMergeAction.LayerListCellRenderer;
020import org.openstreetmap.josm.data.coor.LatLon;
021import org.openstreetmap.josm.data.gpx.GpxData;
022import org.openstreetmap.josm.data.gpx.GpxTrack;
023import org.openstreetmap.josm.data.gpx.GpxTrackSegment;
024import org.openstreetmap.josm.data.gpx.WayPoint;
025import org.openstreetmap.josm.gui.ExtendedDialog;
026import org.openstreetmap.josm.gui.PleaseWaitRunnable;
027import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer;
028import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer.PrecacheTask;
029import org.openstreetmap.josm.gui.progress.ProgressTaskId;
030import org.openstreetmap.josm.gui.progress.ProgressTaskIds;
031import org.openstreetmap.josm.gui.widgets.JosmComboBox;
032import org.openstreetmap.josm.io.OsmTransferException;
033import org.openstreetmap.josm.tools.GBC;
034import org.openstreetmap.josm.tools.ImageProvider;
035import org.xml.sax.SAXException;
036
037/**
038 * Class downloading WMS and TMS along the GPX track
039 *
040 */
041public class DownloadWmsAlongTrackAction extends AbstractAction {
042
043    private final transient GpxData data;
044
045    /**
046     * @param data that represents GPX track, along which data should be downloaded
047     */
048    public DownloadWmsAlongTrackAction(final GpxData data) {
049        super(tr("Precache imagery tiles along this track"), ImageProvider.get("downloadalongtrack"));
050        this.data = data;
051    }
052
053    @Override
054    public void actionPerformed(ActionEvent e) {
055        final List<LatLon> points = new ArrayList<>();
056        for (GpxTrack trk : data.tracks) {
057            for (GpxTrackSegment segment : trk.getSegments()) {
058                for (WayPoint p : segment.getWayPoints()) {
059                    points.add(p.getCoor());
060                }
061            }
062        }
063        for (WayPoint p : data.waypoints) {
064            points.add(p.getCoor());
065        }
066        final AbstractTileSourceLayer layer = askedLayer();
067        if (layer != null) {
068            PleaseWaitRunnable task = new PleaseWaitRunnable(tr("Precaching WMS")) {
069                private PrecacheTask precacheTask;
070
071                @Override
072                protected void realRun() throws SAXException, IOException, OsmTransferException {
073                    precacheTask = layer.new PrecacheTask(progressMonitor);
074                    layer.downloadAreaToCache(precacheTask, points, 0, 0);
075                    while (!precacheTask.isFinished() && !progressMonitor.isCanceled()) {
076                        synchronized (this) {
077                            try {
078                                wait(200);
079                            } catch (InterruptedException ex) {
080                                Main.warn("InterruptedException in "+getClass().getSimpleName()+" while precaching WMS");
081                            }
082                        }
083                    }
084                }
085
086                @Override
087                protected void finish() {
088                }
089
090                @Override
091                protected void cancel() {
092                    precacheTask.cancel();
093                }
094
095                @Override
096                public ProgressTaskId canRunInBackground() {
097                    return ProgressTaskIds.PRECACHE_WMS;
098                }
099            };
100            Main.worker.execute(task);
101        }
102    }
103
104    protected AbstractTileSourceLayer askedLayer() {
105        Collection<AbstractTileSourceLayer> targetLayers = Main.map.mapView.getLayersOfType(AbstractTileSourceLayer.class);
106        if (targetLayers.isEmpty()) {
107            warnNoImageryLayers();
108            return null;
109        }
110        JosmComboBox<AbstractTileSourceLayer> layerList = new JosmComboBox<>(targetLayers.toArray(new AbstractTileSourceLayer[0]));
111        layerList.setRenderer(new LayerListCellRenderer());
112        layerList.setSelectedIndex(0);
113        JPanel pnl = new JPanel(new GridBagLayout());
114        pnl.add(new JLabel(tr("Please select the imagery layer.")), GBC.eol());
115        pnl.add(layerList, GBC.eol());
116        ExtendedDialog ed = new ExtendedDialog(Main.parent, tr("Select imagery layer"), new String[]{tr("Download"), tr("Cancel")});
117        ed.setButtonIcons(new String[]{"dialogs/down", "cancel"});
118        ed.setContent(pnl);
119        ed.showDialog();
120        if (ed.getValue() != 1) {
121            return null;
122        }
123        return (AbstractTileSourceLayer) layerList.getSelectedItem();
124    }
125
126    protected void warnNoImageryLayers() {
127        JOptionPane.showMessageDialog(Main.parent, tr("There are no imagery layers."), tr("No imagery layers"), JOptionPane.WARNING_MESSAGE);
128    }
129}