source: josm/trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java@ 1879

Last change on this file since 1879 was 1879, checked in by Gubaer, 15 years ago

towards a fix for #3142: JOSM applet class no longer functional

  • Property svn:eol-style set to native
File size: 7.7 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.actions.downloadtasks;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.IOException;
7import java.util.Collection;
8import java.util.concurrent.Future;
9import java.util.logging.Logger;
10
11import javax.swing.JCheckBox;
12
13import org.openstreetmap.josm.Main;
14import org.openstreetmap.josm.actions.DownloadAction;
15import org.openstreetmap.josm.data.Bounds;
16import org.openstreetmap.josm.data.coor.LatLon;
17import org.openstreetmap.josm.data.osm.DataSet;
18import org.openstreetmap.josm.data.osm.DataSource;
19import org.openstreetmap.josm.gui.ExceptionDialogUtil;
20import org.openstreetmap.josm.gui.PleaseWaitRunnable;
21import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask;
22import org.openstreetmap.josm.gui.layer.Layer;
23import org.openstreetmap.josm.gui.layer.OsmDataLayer;
24import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
25import org.openstreetmap.josm.gui.progress.ProgressMonitor;
26import org.openstreetmap.josm.io.BoundingBoxDownloader;
27import org.openstreetmap.josm.io.OsmServerLocationReader;
28import org.openstreetmap.josm.io.OsmServerReader;
29import org.openstreetmap.josm.io.OsmTransferException;
30import org.xml.sax.SAXException;
31
32
33/**
34 * Open the download dialog and download the data.
35 * Run in the worker thread.
36 */
37public class DownloadOsmTask implements DownloadTask {
38 private static final Logger logger = Logger.getLogger(DownloadOsmTask.class.getName());
39
40 private static Bounds currentBounds;
41 private Future<Task> task = null;
42 private DataSet downloadedData;
43
44 private class Task extends PleaseWaitRunnable {
45 private OsmServerReader reader;
46 private DataSet dataSet;
47 private boolean newLayer;
48 private boolean cancelled;
49 private Exception lastException;
50
51 public Task(boolean newLayer, OsmServerReader reader, ProgressMonitor progressMonitor) {
52 super(tr("Downloading data"), progressMonitor, false);
53 this.reader = reader;
54 this.newLayer = newLayer;
55 }
56
57 @Override public void realRun() throws IOException, SAXException, OsmTransferException {
58 try {
59 dataSet = reader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
60 } catch(Exception e) {
61 if (cancelled) {
62 logger.warning(tr("Ignoring exception because download has been cancelled. Exception was: {0}" + e.toString()));
63 return;
64 }
65 if (e instanceof OsmTransferException) {
66 lastException = e;
67 } else {
68 lastException = new OsmTransferException(e);
69 }
70 }
71 }
72
73 protected OsmDataLayer getEditLayer() {
74 if (Main.map == null) return null;
75 if (Main.map.mapView == null) return null;
76 return Main.map.mapView.getEditLayer();
77 }
78
79 protected int getNumDataLayers() {
80 int count = 0;
81 if (Main.map == null) return 0;
82 if (Main.map.mapView == null) return 0;
83 Collection<Layer> layers = Main.map.mapView.getAllLayers();
84 for (Layer layer : layers) {
85 if (layer instanceof OsmDataLayer) {
86 count++;
87 }
88 }
89 return count;
90 }
91
92 protected OsmDataLayer getFirstDataLayer() {
93 if (Main.map == null) return null;
94 if (Main.map.mapView == null) return null;
95 Collection<Layer> layers = Main.map.mapView.getAllLayers();
96 for (Layer layer : layers) {
97 if (layer instanceof OsmDataLayer)
98 return (OsmDataLayer) layer;
99 }
100 return null;
101 }
102
103 @Override protected void finish() {
104 if (cancelled)
105 return;
106 if (lastException != null) {
107 ExceptionDialogUtil.explainException(lastException);
108 return;
109 }
110 if (dataSet == null)
111 return; // user canceled download or error occurred
112 if (dataSet.allPrimitives().isEmpty()) {
113 progressMonitor.setErrorMessage(tr("No data imported."));
114 // need to synthesize a download bounds lest the visual indication of downloaded
115 // area doesn't work
116 dataSet.dataSources.add(new DataSource(currentBounds, "OpenStreetMap server"));
117 }
118 rememberDownloadedData(dataSet);
119 int numDataLayers = getNumDataLayers();
120 if (newLayer || numDataLayers == 0 || (numDataLayers > 1 && getEditLayer() == null)) {
121 // the user explicitly wants a new layer, we don't have any layer at all
122 // or it is not clear which layer to merge to
123 //
124 OsmDataLayer layer = new OsmDataLayer(dataSet, OsmDataLayer.createNewName(), null);
125 Main.main.addLayer(layer);
126 } else {
127 OsmDataLayer target;
128 target = getEditLayer();
129 if (target == null) {
130 target = getFirstDataLayer();
131 }
132 target.mergeFrom(dataSet);
133 }
134 }
135
136 @Override protected void cancel() {
137 if (reader != null) {
138 reader.cancel();
139 }
140 }
141 }
142 private JCheckBox checkBox = new JCheckBox(tr("OpenStreetMap data"), true);
143
144 private void rememberDownloadedData(DataSet ds) {
145 this.downloadedData = ds;
146 }
147
148 public DataSet getDownloadedData() {
149 return downloadedData;
150 }
151
152 public void download(DownloadAction action, double minlat, double minlon,
153 double maxlat, double maxlon, ProgressMonitor progressMonitor) {
154 // Swap min and max if user has specified them the wrong way round
155 // (easy to do if you are crossing 0, for example)
156 // FIXME should perhaps be done in download dialog?
157 if (minlat > maxlat) {
158 double t = minlat; minlat = maxlat; maxlat = t;
159 }
160 if (minlon > maxlon) {
161 double t = minlon; minlon = maxlon; maxlon = t;
162 }
163
164 boolean newLayer = action != null
165 && (action.dialog == null || action.dialog.newLayer.isSelected());
166
167 Task t = new Task(newLayer,
168 new BoundingBoxDownloader(minlat, minlon, maxlat, maxlon), progressMonitor);
169 currentBounds = new Bounds(new LatLon(minlat, minlon), new LatLon(maxlat, maxlon));
170 // We need submit instead of execute so we can wait for it to finish and get the error
171 // message if necessary. If no one calls getErrorMessage() it just behaves like execute.
172 task = Main.worker.submit(t, t);
173 }
174
175 /**
176 * Loads a given URL from the OSM Server
177 * @param True if the data should be saved to a new layer
178 * @param The URL as String
179 */
180 public void loadUrl(boolean new_layer, String url) {
181 Task t = new Task(new_layer,
182 new OsmServerLocationReader(url),
183 NullProgressMonitor.INSTANCE);
184 task = Main.worker.submit(t, t);
185 }
186
187 public JCheckBox getCheckBox() {
188 return checkBox;
189 }
190
191 public String getPreferencesSuffix() {
192 return "osm";
193 }
194
195 /*
196 * (non-Javadoc)
197 * @see org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask#getErrorMessage()
198 */
199 public String getErrorMessage() {
200 if(task == null)
201 return "";
202
203 try {
204 Task t = task.get();
205 return t.getProgressMonitor().getErrorMessage() == null
206 ? ""
207 : t.getProgressMonitor().getErrorMessage();
208 } catch (Exception e) {
209 return "";
210 }
211 }
212}
Note: See TracBrowser for help on using the repository browser.