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.WMSLayer;
028import org.openstreetmap.josm.gui.layer.WMSLayer.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
037public class DownloadWmsAlongTrackAction extends AbstractAction {
038
039    private final GpxData data;
040
041    public DownloadWmsAlongTrackAction(final GpxData data) {
042        super(tr("Precache imagery tiles along this track"), ImageProvider.get("downloadalongtrack"));
043        this.data = data;
044    }
045
046    @Override
047    public void actionPerformed(ActionEvent e) {
048        final List<LatLon> points = new ArrayList<>();
049        for (GpxTrack trk : data.tracks) {
050            for (GpxTrackSegment segment : trk.getSegments()) {
051                for (WayPoint p : segment.getWayPoints()) {
052                    points.add(p.getCoor());
053                }
054            }
055        }
056        for (WayPoint p : data.waypoints) {
057            points.add(p.getCoor());
058        }
059        final WMSLayer layer = askWMSLayer();
060        if (layer != null) {
061            PleaseWaitRunnable task = new PleaseWaitRunnable(tr("Precaching WMS")) {
062                private PrecacheTask precacheTask;
063
064                @Override
065                protected void realRun() throws SAXException, IOException, OsmTransferException {
066                    precacheTask = new PrecacheTask(progressMonitor);
067                    layer.downloadAreaToCache(precacheTask, points, 0, 0);
068                    while (!precacheTask.isFinished() && !progressMonitor.isCanceled()) {
069                        synchronized (this) {
070                            try {
071                                wait(200);
072                            } catch (InterruptedException ex) {
073                                Main.warn("InterruptedException in "+getClass().getSimpleName()+" while precaching WMS");
074                            }
075                        }
076                    }
077                }
078
079                @Override
080                protected void finish() {
081                }
082
083                @Override
084                protected void cancel() {
085                    precacheTask.cancel();
086                }
087
088                @Override
089                public ProgressTaskId canRunInBackground() {
090                    return ProgressTaskIds.PRECACHE_WMS;
091                }
092            };
093            Main.worker.execute(task);
094        }
095    }
096
097    protected WMSLayer askWMSLayer() {
098        Collection<WMSLayer> targetLayers = Main.map.mapView.getLayersOfType(WMSLayer.class);
099        if (targetLayers.isEmpty()) {
100            warnNoImageryLayers();
101            return null;
102        }
103        JosmComboBox<WMSLayer> layerList = new JosmComboBox<>(targetLayers.toArray(new WMSLayer[0]));
104        layerList.setRenderer(new LayerListCellRenderer());
105        layerList.setSelectedIndex(0);
106        JPanel pnl = new JPanel(new GridBagLayout());
107        pnl.add(new JLabel(tr("Please select the imagery layer.")), GBC.eol());
108        pnl.add(layerList, GBC.eol());
109        ExtendedDialog ed = new ExtendedDialog(Main.parent, tr("Select imagery layer"), new String[]{tr("Download"), tr("Cancel")});
110        ed.setButtonIcons(new String[]{"dialogs/down", "cancel"});
111        ed.setContent(pnl);
112        ed.showDialog();
113        if (ed.getValue() != 1) {
114            return null;
115        }
116        return (WMSLayer) layerList.getSelectedItem();
117    }
118
119    protected void warnNoImageryLayers() {
120        JOptionPane.showMessageDialog(Main.parent, tr("There are no imagery layers."), tr("No imagery layers"), JOptionPane.WARNING_MESSAGE);
121    }
122}