source: josm/trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackAction.java@ 9857

Last change on this file since 9857 was 9719, checked in by Don-vip, 8 years ago

DownloadWmsAlongTrackAction: add new unit test, error logs, fix infinite loop when tile loading errors occur (for example, with a bad TMS URL)

  • Property svn:eol-style set to native
File size: 5.5 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.layer.gpx;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.GraphicsEnvironment;
7import java.awt.GridBagLayout;
8import java.awt.event.ActionEvent;
9import java.io.IOException;
10import java.util.ArrayList;
11import java.util.List;
12
13import javax.swing.AbstractAction;
14import javax.swing.JLabel;
15import javax.swing.JOptionPane;
16import javax.swing.JPanel;
17
18import org.openstreetmap.josm.Main;
19import org.openstreetmap.josm.actions.AbstractMergeAction.LayerListCellRenderer;
20import org.openstreetmap.josm.data.coor.LatLon;
21import org.openstreetmap.josm.data.gpx.GpxData;
22import org.openstreetmap.josm.data.gpx.GpxTrack;
23import org.openstreetmap.josm.data.gpx.GpxTrackSegment;
24import org.openstreetmap.josm.data.gpx.WayPoint;
25import org.openstreetmap.josm.gui.ExtendedDialog;
26import org.openstreetmap.josm.gui.PleaseWaitRunnable;
27import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer;
28import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer.PrecacheTask;
29import org.openstreetmap.josm.gui.progress.ProgressTaskId;
30import org.openstreetmap.josm.gui.progress.ProgressTaskIds;
31import org.openstreetmap.josm.gui.widgets.JosmComboBox;
32import org.openstreetmap.josm.io.OsmTransferException;
33import org.openstreetmap.josm.tools.GBC;
34import org.openstreetmap.josm.tools.ImageProvider;
35import org.xml.sax.SAXException;
36
37/**
38 * Class downloading WMS and TMS along the GPX track.
39 * @since 5715
40 */
41public class DownloadWmsAlongTrackAction extends AbstractAction {
42
43 private final transient GpxData data;
44
45 /**
46 * @param data that represents GPX track, along which data should be downloaded
47 */
48 public DownloadWmsAlongTrackAction(final GpxData data) {
49 super(tr("Precache imagery tiles along this track"), ImageProvider.get("downloadalongtrack"));
50 this.data = data;
51 }
52
53 static class PrecacheWmsTask extends PleaseWaitRunnable {
54
55 private final AbstractTileSourceLayer layer;
56 private final List<LatLon> points;
57 private PrecacheTask precacheTask;
58
59 protected PrecacheWmsTask(AbstractTileSourceLayer layer, List<LatLon> points) {
60 super(tr("Precaching WMS"));
61 this.layer = layer;
62 this.points = points;
63 }
64
65 @Override
66 protected void realRun() throws SAXException, IOException, OsmTransferException {
67 precacheTask = layer.new PrecacheTask(progressMonitor);
68 layer.downloadAreaToCache(precacheTask, points, 0, 0);
69 while (!precacheTask.isFinished() && !progressMonitor.isCanceled()) {
70 synchronized (this) {
71 try {
72 wait(200);
73 } catch (InterruptedException ex) {
74 Main.warn("InterruptedException in "+getClass().getSimpleName()+" while precaching WMS");
75 }
76 }
77 }
78 }
79
80 @Override
81 protected void finish() {
82 // Do nothing
83 }
84
85 @Override
86 protected void cancel() {
87 precacheTask.cancel();
88 }
89
90 @Override
91 public ProgressTaskId canRunInBackground() {
92 return ProgressTaskIds.PRECACHE_WMS;
93 }
94 }
95
96 PrecacheWmsTask createTask() {
97 List<LatLon> points = new ArrayList<>();
98 for (GpxTrack trk : data.tracks) {
99 for (GpxTrackSegment segment : trk.getSegments()) {
100 for (WayPoint p : segment.getWayPoints()) {
101 points.add(p.getCoor());
102 }
103 }
104 }
105 for (WayPoint p : data.waypoints) {
106 points.add(p.getCoor());
107 }
108 AbstractTileSourceLayer layer = askedLayer();
109 return layer != null ? new PrecacheWmsTask(layer, points) : null;
110 }
111
112 @Override
113 public void actionPerformed(ActionEvent e) {
114 PrecacheWmsTask task = createTask();
115 if (task != null) {
116 Main.worker.execute(task);
117 }
118 }
119
120 protected AbstractTileSourceLayer askedLayer() {
121 if (!Main.isDisplayingMapView()) {
122 return null;
123 }
124 List<AbstractTileSourceLayer> targetLayers = Main.map.mapView.getLayersOfType(AbstractTileSourceLayer.class);
125 if (targetLayers.isEmpty()) {
126 if (!GraphicsEnvironment.isHeadless()) {
127 warnNoImageryLayers();
128 }
129 return null;
130 }
131 JosmComboBox<AbstractTileSourceLayer> layerList = new JosmComboBox<>(targetLayers.toArray(new AbstractTileSourceLayer[0]));
132 layerList.setRenderer(new LayerListCellRenderer());
133 layerList.setSelectedIndex(0);
134 JPanel pnl = new JPanel(new GridBagLayout());
135 pnl.add(new JLabel(tr("Please select the imagery layer.")), GBC.eol());
136 pnl.add(layerList, GBC.eol());
137 if (GraphicsEnvironment.isHeadless()) {
138 // return first layer in headless mode, for unit tests
139 return targetLayers.get(0);
140 }
141 ExtendedDialog ed = new ExtendedDialog(Main.parent, tr("Select imagery layer"), new String[]{tr("Download"), tr("Cancel")});
142 ed.setButtonIcons(new String[]{"dialogs/down", "cancel"});
143 ed.setContent(pnl);
144 ed.showDialog();
145 if (ed.getValue() != 1) {
146 return null;
147 }
148 return (AbstractTileSourceLayer) layerList.getSelectedItem();
149 }
150
151 protected void warnNoImageryLayers() {
152 JOptionPane.showMessageDialog(Main.parent, tr("There are no imagery layers."), tr("No imagery layers"), JOptionPane.WARNING_MESSAGE);
153 }
154}
Note: See TracBrowser for help on using the repository browser.