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.GraphicsEnvironment; 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.JOptionPane; 014 015import org.openstreetmap.gui.jmapviewer.tilesources.AbstractTMSTileSource; 016import org.openstreetmap.josm.Main; 017import org.openstreetmap.josm.actions.AbstractMergeAction; 018import org.openstreetmap.josm.data.coor.LatLon; 019import org.openstreetmap.josm.data.gpx.GpxData; 020import org.openstreetmap.josm.data.gpx.GpxTrack; 021import org.openstreetmap.josm.data.gpx.GpxTrackSegment; 022import org.openstreetmap.josm.data.gpx.WayPoint; 023import org.openstreetmap.josm.gui.PleaseWaitRunnable; 024import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer; 025import org.openstreetmap.josm.gui.progress.ProgressTaskId; 026import org.openstreetmap.josm.gui.progress.ProgressTaskIds; 027import org.openstreetmap.josm.io.OsmTransferException; 028import org.openstreetmap.josm.tools.ImageProvider; 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"), ImageProvider.get("downloadalongtrack")); 044 this.data = data; 045 } 046 047 static class PrecacheWmsTask extends PleaseWaitRunnable { 048 049 private final AbstractTileSourceLayer<? extends AbstractTMSTileSource> layer; 050 private final List<LatLon> points; 051 private AbstractTileSourceLayer<? extends AbstractTMSTileSource>.PrecacheTask precacheTask; 052 053 protected PrecacheWmsTask(AbstractTileSourceLayer<? extends AbstractTMSTileSource> layer, List<LatLon> points) { 054 super(tr("Precaching WMS")); 055 this.layer = layer; 056 this.points = points; 057 } 058 059 @Override 060 protected void realRun() throws SAXException, IOException, OsmTransferException { 061 precacheTask = layer.downloadAreaToCache(progressMonitor, points, 0, 0); 062 synchronized (this) { 063 try { 064 while (!precacheTask.isFinished() && !progressMonitor.isCanceled()) { 065 wait(200); 066 } 067 } catch (InterruptedException ex) { 068 Main.warn("InterruptedException in "+getClass().getSimpleName()+" while precaching WMS"); 069 } 070 } 071 } 072 073 @Override 074 protected void finish() { 075 // Do nothing 076 } 077 078 @Override 079 protected void cancel() { 080 precacheTask.cancel(); 081 } 082 083 @Override 084 public ProgressTaskId canRunInBackground() { 085 return ProgressTaskIds.PRECACHE_WMS; 086 } 087 } 088 089 PrecacheWmsTask createTask() { 090 List<LatLon> points = new ArrayList<>(); 091 for (GpxTrack trk : data.tracks) { 092 for (GpxTrackSegment segment : trk.getSegments()) { 093 for (WayPoint p : segment.getWayPoints()) { 094 points.add(p.getCoor()); 095 } 096 } 097 } 098 for (WayPoint p : data.waypoints) { 099 points.add(p.getCoor()); 100 } 101 AbstractTileSourceLayer<? extends AbstractTMSTileSource> layer = askedLayer(); 102 return layer != null ? new PrecacheWmsTask(layer, points) : null; 103 } 104 105 @Override 106 public void actionPerformed(ActionEvent e) { 107 PrecacheWmsTask task = createTask(); 108 if (task != null) { 109 Main.worker.execute(task); 110 } 111 } 112 113 @SuppressWarnings({ "rawtypes", "unchecked" }) 114 protected AbstractTileSourceLayer<? extends AbstractTMSTileSource> askedLayer() { 115 if (!Main.isDisplayingMapView()) { 116 return null; 117 } 118 List<AbstractTileSourceLayer> targetLayers = Main.getLayerManager().getLayersOfType(AbstractTileSourceLayer.class); 119 if (targetLayers.isEmpty()) { 120 if (!GraphicsEnvironment.isHeadless()) { 121 warnNoImageryLayers(); 122 } 123 return null; 124 } 125 return AbstractMergeAction.askTargetLayer(targetLayers.toArray(new AbstractTileSourceLayer[0]), 126 tr("Please select the imagery layer."), 127 tr("Select imagery layer"), 128 tr("Download"), "dialogs/down"); 129 } 130 131 protected void warnNoImageryLayers() { 132 JOptionPane.showMessageDialog(Main.parent, tr("There are no imagery layers."), tr("No imagery layers"), JOptionPane.WARNING_MESSAGE); 133 } 134}