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

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

Allow JOSM to load remote .osm files

  • Property svn:eol-style set to native
File size: 8.1 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://.*/interpreter\\?data=.*") // Overpass API
77 || url.matches("http://.*/xapi\\?.*\\[@meta\\].*") // Overpass API XAPI compatibility layer
78 || url.matches("http://.*/.*\\.osm") // Remote .osm files
79 );
80 }
81
82 public void cancel() {
83 if (downloadTask != null) {
84 downloadTask.cancel();
85 }
86 }
87
88 protected class DownloadTask extends PleaseWaitRunnable {
89 protected OsmServerReader reader;
90 protected DataSet dataSet;
91 protected boolean newLayer;
92
93 public DownloadTask(boolean newLayer, OsmServerReader reader, ProgressMonitor progressMonitor) {
94 super(tr("Downloading data"), progressMonitor, false);
95 this.reader = reader;
96 this.newLayer = newLayer;
97 }
98
99 protected DataSet parseDataSet() throws OsmTransferException {
100 return reader.parseOsm(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
101 }
102
103 @Override public void realRun() throws IOException, SAXException, OsmTransferException {
104 try {
105 if (isCanceled())
106 return;
107 dataSet = parseDataSet();
108 } catch(Exception e) {
109 if (isCanceled()) {
110 System.out.println(tr("Ignoring exception because download has been canceled. Exception was: {0}", e.toString()));
111 return;
112 }
113 if (e instanceof OsmTransferCanceledException) {
114 setCanceled(true);
115 return;
116 } else if (e instanceof OsmTransferException) {
117 rememberException(e);
118 } else {
119 rememberException(new OsmTransferException(e));
120 }
121 DownloadOsmTask.this.setFailed(true);
122 }
123 }
124
125 protected OsmDataLayer getEditLayer() {
126 if (!Main.isDisplayingMapView()) return null;
127 return Main.map.mapView.getEditLayer();
128 }
129
130 protected int getNumDataLayers() {
131 int count = 0;
132 if (!Main.isDisplayingMapView()) return 0;
133 Collection<Layer> layers = Main.map.mapView.getAllLayers();
134 for (Layer layer : layers) {
135 if (layer instanceof OsmDataLayer) {
136 count++;
137 }
138 }
139 return count;
140 }
141
142 protected OsmDataLayer getFirstDataLayer() {
143 if (!Main.isDisplayingMapView()) return null;
144 Collection<Layer> layers = Main.map.mapView.getAllLayersAsList();
145 for (Layer layer : layers) {
146 if (layer instanceof OsmDataLayer)
147 return (OsmDataLayer) layer;
148 }
149 return null;
150 }
151
152 protected OsmDataLayer createNewLayer() {
153 return new OsmDataLayer(dataSet, OsmDataLayer.createNewName(), null);
154 }
155
156 @Override protected void finish() {
157 if (isFailed() || isCanceled())
158 return;
159 if (dataSet == null)
160 return; // user canceled download or error occurred
161 if (dataSet.allPrimitives().isEmpty()) {
162 rememberErrorMessage(tr("No data found in this area."));
163 // need to synthesize a download bounds lest the visual indication of downloaded
164 // area doesn't work
165 dataSet.dataSources.add(new DataSource(currentBounds != null ? currentBounds : new Bounds(new LatLon(0, 0)), "OpenStreetMap server"));
166 }
167
168 rememberDownloadedData(dataSet);
169 int numDataLayers = getNumDataLayers();
170 if (newLayer || numDataLayers == 0 || (numDataLayers > 1 && getEditLayer() == null)) {
171 // the user explicitly wants a new layer, we don't have any layer at all
172 // or it is not clear which layer to merge to
173 //
174 targetLayer = createNewLayer();
175 final boolean isDisplayingMapView = Main.isDisplayingMapView();
176
177 Main.main.addLayer(targetLayer);
178
179 // If the mapView is not there yet, we cannot calculate the bounds (see constructor of MapView).
180 // Otherwise jump to the current download.
181 if (isDisplayingMapView) {
182 computeBboxAndCenterScale();
183 }
184 } else {
185 targetLayer = getEditLayer();
186 if (targetLayer == null) {
187 targetLayer = getFirstDataLayer();
188 }
189 targetLayer.mergeFrom(dataSet);
190 computeBboxAndCenterScale();
191 targetLayer.onPostDownloadFromServer();
192 }
193 }
194
195 protected void computeBboxAndCenterScale() {
196 BoundingXYVisitor v = new BoundingXYVisitor();
197 if (currentBounds != null) {
198 v.visit(currentBounds);
199 } else {
200 v.computeBoundingBox(dataSet.getNodes());
201 }
202 Main.map.mapView.recalculateCenterScale(v);
203 }
204
205 @Override protected void cancel() {
206 setCanceled(true);
207 if (reader != null) {
208 reader.cancel();
209 }
210 }
211 }
212}
Note: See TracBrowser for help on using the repository browser.