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.event.ActionEvent; 007import java.io.IOException; 008import java.util.ArrayList; 009import java.util.List; 010 011import javax.swing.AbstractAction; 012import javax.swing.JOptionPane; 013 014import org.openstreetmap.gui.jmapviewer.tilesources.AbstractTMSTileSource; 015import org.openstreetmap.josm.actions.AbstractMergeAction; 016import org.openstreetmap.josm.data.coor.LatLon; 017import org.openstreetmap.josm.data.gpx.GpxData; 018import org.openstreetmap.josm.data.gpx.IGpxTrack; 019import org.openstreetmap.josm.data.gpx.IGpxTrackSegment; 020import org.openstreetmap.josm.data.gpx.WayPoint; 021import org.openstreetmap.josm.gui.MainApplication; 022import org.openstreetmap.josm.gui.PleaseWaitRunnable; 023import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer; 024import org.openstreetmap.josm.gui.progress.ProgressTaskId; 025import org.openstreetmap.josm.gui.progress.ProgressTaskIds; 026import org.openstreetmap.josm.io.OsmTransferException; 027import org.openstreetmap.josm.tools.ImageProvider; 028import org.openstreetmap.josm.tools.Logging; 029import org.xml.sax.SAXException; 030 031/** 032 * Class downloading WMS and TMS along the GPX track. 033 * @since 5715 034 */ 035public class DownloadWmsAlongTrackAction extends AbstractAction { 036 037 private final transient GpxData data; 038 039 /** 040 * @param data that represents GPX track, along which data should be downloaded 041 */ 042 public DownloadWmsAlongTrackAction(final GpxData data) { 043 super(tr("Precache imagery tiles along this track")); 044 new ImageProvider("downloadalongtrack").getResource().attachImageIcon(this, true); 045 this.data = data; 046 } 047 048 static class PrecacheWmsTask extends PleaseWaitRunnable { 049 050 private final AbstractTileSourceLayer<? extends AbstractTMSTileSource> layer; 051 private final List<LatLon> points; 052 private AbstractTileSourceLayer<? extends AbstractTMSTileSource>.PrecacheTask precacheTask; 053 054 protected PrecacheWmsTask(AbstractTileSourceLayer<? extends AbstractTMSTileSource> layer, List<LatLon> points) { 055 super(tr("Precaching WMS")); 056 this.layer = layer; 057 this.points = points; 058 } 059 060 @Override 061 protected void realRun() throws SAXException, IOException, OsmTransferException { 062 precacheTask = layer.getDownloadAreaToCacheTask(progressMonitor, points, 0, 0); 063 precacheTask.run(); 064 synchronized (this) { 065 try { 066 while (!precacheTask.isFinished() && !progressMonitor.isCanceled()) { 067 wait(200); 068 } 069 } catch (InterruptedException ex) { 070 Logging.warn("InterruptedException in "+getClass().getSimpleName()+" while precaching WMS"); 071 Thread.currentThread().interrupt(); 072 } 073 } 074 } 075 076 @Override 077 protected void finish() { 078 // Do nothing 079 } 080 081 @Override 082 protected void cancel() { 083 precacheTask.cancel(); 084 } 085 086 @Override 087 public ProgressTaskId canRunInBackground() { 088 return ProgressTaskIds.PRECACHE_WMS; 089 } 090 } 091 092 PrecacheWmsTask createTask() { 093 List<LatLon> points = new ArrayList<>(); 094 for (IGpxTrack trk : data.tracks) { 095 for (IGpxTrackSegment segment : trk.getSegments()) { 096 for (WayPoint p : segment.getWayPoints()) { 097 points.add(p.getCoor()); 098 } 099 } 100 } 101 for (WayPoint p : data.waypoints) { 102 points.add(p.getCoor()); 103 } 104 AbstractTileSourceLayer<? extends AbstractTMSTileSource> layer = askedLayer(); 105 return layer != null ? new PrecacheWmsTask(layer, points) : null; 106 } 107 108 @Override 109 public void actionPerformed(ActionEvent e) { 110 PrecacheWmsTask task = createTask(); 111 if (task != null) { 112 MainApplication.worker.execute(task); 113 } 114 } 115 116 @SuppressWarnings({ "rawtypes", "unchecked" }) 117 protected AbstractTileSourceLayer<? extends AbstractTMSTileSource> askedLayer() { 118 List<AbstractTileSourceLayer> targetLayers = MainApplication.getLayerManager().getLayersOfType(AbstractTileSourceLayer.class); 119 if (targetLayers.isEmpty()) { 120 warnNoImageryLayers(); 121 return null; 122 } 123 return AbstractMergeAction.askTargetLayer(targetLayers.toArray(new AbstractTileSourceLayer[0]), 124 tr("Please select the imagery layer."), 125 tr("Select imagery layer"), 126 tr("Download"), "dialogs/down"); 127 } 128 129 protected void warnNoImageryLayers() { 130 JOptionPane.showMessageDialog(MainApplication.getMainFrame(), 131 tr("There are no imagery layers."), tr("No imagery layers"), JOptionPane.WARNING_MESSAGE); 132 } 133}