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

Last change on this file since 4579 was 4579, checked in by Don-vip, 12 years ago

Add Overpass API instances to supported OSM data servers

  • Property svn:eol-style set to native
File size: 7.9 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;
9
10import org.openstreetmap.josm.Main;
11import org.openstreetmap.josm.data.Bounds;
12import org.openstreetmap.josm.data.coor.LatLon;
13import org.openstreetmap.josm.data.osm.DataSet;
14import org.openstreetmap.josm.data.osm.DataSource;
15import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
16import org.openstreetmap.josm.gui.PleaseWaitRunnable;
17import org.openstreetmap.josm.gui.layer.Layer;
18import org.openstreetmap.josm.gui.layer.OsmDataLayer;
19import org.openstreetmap.josm.gui.progress.ProgressMonitor;
20import org.openstreetmap.josm.io.BoundingBoxDownloader;
21import org.openstreetmap.josm.io.OsmServerLocationReader;
22import org.openstreetmap.josm.io.OsmServerReader;
23import org.openstreetmap.josm.io.OsmTransferCanceledException;
24import org.openstreetmap.josm.io.OsmTransferException;
25import org.xml.sax.SAXException;
26
27/**
28 * Open the download dialog and download the data.
29 * Run in the worker thread.
30 */
31public class DownloadOsmTask extends AbstractDownloadTask {
32 protected Bounds currentBounds;
33 protected DataSet downloadedData;
34 protected DownloadTask downloadTask;
35
36 protected OsmDataLayer targetLayer;
37
38 protected void rememberDownloadedData(DataSet ds) {
39 this.downloadedData = ds;
40 }
41
42 public DataSet getDownloadedData() {
43 return downloadedData;
44 }
45
46 public Future<?> download(boolean newLayer, Bounds downloadArea, ProgressMonitor progressMonitor) {
47
48 downloadTask = new DownloadTask(newLayer,
49 new BoundingBoxDownloader(downloadArea), progressMonitor);
50 currentBounds = new Bounds(downloadArea);
51 // We need submit instead of execute so we can wait for it to finish and get the error
52 // message if necessary. If no one calls getErrorMessage() it just behaves like execute.
53 return Main.worker.submit(downloadTask);
54 }
55
56 /**
57 * Loads a given URL from the OSM Server
58 * @param True if the data should be saved to a new layer
59 * @param The URL as String
60 */
61 public Future<?> loadUrl(boolean new_layer, String url, ProgressMonitor progressMonitor) {
62 downloadTask = new DownloadTask(new_layer,
63 new OsmServerLocationReader(url),
64 progressMonitor);
65 currentBounds = null;
66 return Main.worker.submit(downloadTask);
67 }
68
69 /* (non-Javadoc)
70 * @see org.openstreetmap.josm.actions.downloadtasks.DownloadTask#acceptsUrl(java.lang.String)
71 */
72 @Override
73 public boolean acceptsUrl(String url) {
74 return url != null && (
75 url.matches("http://.*/api/0.6/(map|nodes?|ways?|relations?).*") // OSM API 0.6
76 || url.matches("http://.*/xapi\\?.*\\[@meta\\]") // Overpass API XAPI compatibility layer
77 );
78 }
79
80 public void cancel() {
81 if (downloadTask != null) {
82 downloadTask.cancel();
83 }
84 }
85
86 protected class DownloadTask extends PleaseWaitRunnable {
87 protected OsmServerReader reader;
88 protected DataSet dataSet;
89 protected boolean newLayer;
90
91 public DownloadTask(boolean newLayer, OsmServerReader reader, ProgressMonitor progressMonitor) {
92 super(tr("Downloading data"), progressMonitor, false);
93 this.reader = reader;
94 this.newLayer = newLayer;
95 }
96
97 protected DataSet parseDataSet() throws OsmTransferException {
98 return reader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
99 }
100
101 @Override public void realRun() throws IOException, SAXException, OsmTransferException {
102 try {
103 if (isCanceled())
104 return;
105 dataSet = parseDataSet();
106 } catch(Exception e) {
107 if (isCanceled()) {
108 System.out.println(tr("Ignoring exception because download has been canceled. Exception was: {0}", e.toString()));
109 return;
110 }
111 if (e instanceof OsmTransferCanceledException) {
112 setCanceled(true);
113 return;
114 } else if (e instanceof OsmTransferException) {
115 rememberException(e);
116 } else {
117 rememberException(new OsmTransferException(e));
118 }
119 DownloadOsmTask.this.setFailed(true);
120 }
121 }
122
123 protected OsmDataLayer getEditLayer() {
124 if (!Main.isDisplayingMapView()) return null;
125 return Main.map.mapView.getEditLayer();
126 }
127
128 protected int getNumDataLayers() {
129 int count = 0;
130 if (!Main.isDisplayingMapView()) return 0;
131 Collection<Layer> layers = Main.map.mapView.getAllLayers();
132 for (Layer layer : layers) {
133 if (layer instanceof OsmDataLayer) {
134 count++;
135 }
136 }
137 return count;
138 }
139
140 protected OsmDataLayer getFirstDataLayer() {
141 if (!Main.isDisplayingMapView()) return null;
142 Collection<Layer> layers = Main.map.mapView.getAllLayersAsList();
143 for (Layer layer : layers) {
144 if (layer instanceof OsmDataLayer)
145 return (OsmDataLayer) layer;
146 }
147 return null;
148 }
149
150 protected OsmDataLayer createNewLayer() {
151 return new OsmDataLayer(dataSet, OsmDataLayer.createNewName(), null);
152 }
153
154 @Override protected void finish() {
155 if (isFailed() || isCanceled())
156 return;
157 if (dataSet == null)
158 return; // user canceled download or error occurred
159 if (dataSet.allPrimitives().isEmpty()) {
160 rememberErrorMessage(tr("No data found in this area."));
161 // need to synthesize a download bounds lest the visual indication of downloaded
162 // area doesn't work
163 dataSet.dataSources.add(new DataSource(currentBounds != null ? currentBounds : new Bounds(new LatLon(0, 0)), "OpenStreetMap server"));
164 }
165
166 rememberDownloadedData(dataSet);
167 int numDataLayers = getNumDataLayers();
168 if (newLayer || numDataLayers == 0 || (numDataLayers > 1 && getEditLayer() == null)) {
169 // the user explicitly wants a new layer, we don't have any layer at all
170 // or it is not clear which layer to merge to
171 //
172 targetLayer = createNewLayer();
173 final boolean isDisplayingMapView = Main.isDisplayingMapView();
174
175 Main.main.addLayer(targetLayer);
176
177 // If the mapView is not there yet, we cannot calculate the bounds (see constructor of MapView).
178 // Otherwise jump to the current download.
179 if (isDisplayingMapView) {
180 computeBboxAndCenterScale();
181 }
182 } else {
183 targetLayer = getEditLayer();
184 if (targetLayer == null) {
185 targetLayer = getFirstDataLayer();
186 }
187 targetLayer.mergeFrom(dataSet);
188 computeBboxAndCenterScale();
189 targetLayer.onPostDownloadFromServer();
190 }
191 }
192
193 protected void computeBboxAndCenterScale() {
194 BoundingXYVisitor v = new BoundingXYVisitor();
195 if (currentBounds != null) {
196 v.visit(currentBounds);
197 } else {
198 v.computeBoundingBox(dataSet.getNodes());
199 }
200 Main.map.mapView.recalculateCenterScale(v);
201 }
202
203 @Override protected void cancel() {
204 setCanceled(true);
205 if (reader != null) {
206 reader.cancel();
207 }
208 }
209 }
210}
Note: See TracBrowser for help on using the repository browser.