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