source: josm/trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java@ 8787

Last change on this file since 8787 was 8787, checked in by simon04, 9 years ago

see #11428 - Change Overpass task name in progress monitor to "Contacting Server..."

  • Property svn:eol-style set to native
File size: 8.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.IOException;
7import java.io.InputStream;
8import java.util.List;
9
10import org.openstreetmap.josm.data.Bounds;
11import org.openstreetmap.josm.data.DataSource;
12import org.openstreetmap.josm.data.gpx.GpxData;
13import org.openstreetmap.josm.data.notes.Note;
14import org.openstreetmap.josm.data.osm.DataSet;
15import org.openstreetmap.josm.gui.progress.ProgressMonitor;
16import org.openstreetmap.josm.tools.CheckParameterUtil;
17import org.xml.sax.SAXException;
18
19/**
20 * Read content from OSM server for a given bounding box
21 * @since 627
22 */
23public class BoundingBoxDownloader extends OsmServerReader {
24
25 /**
26 * The boundings of the desired map data.
27 */
28 protected final double lat1;
29 protected final double lon1;
30 protected final double lat2;
31 protected final double lon2;
32 protected final boolean crosses180th;
33
34 /**
35 * Constructs a new {@code BoundingBoxDownloader}.
36 * @param downloadArea The area to download
37 */
38 public BoundingBoxDownloader(Bounds downloadArea) {
39 CheckParameterUtil.ensureParameterNotNull(downloadArea, "downloadArea");
40 this.lat1 = downloadArea.getMinLat();
41 this.lon1 = downloadArea.getMinLon();
42 this.lat2 = downloadArea.getMaxLat();
43 this.lon2 = downloadArea.getMaxLon();
44 this.crosses180th = downloadArea.crosses180thMeridian();
45 }
46
47 private GpxData downloadRawGps(Bounds b, ProgressMonitor progressMonitor) throws IOException, OsmTransferException, SAXException {
48 boolean done = false;
49 GpxData result = null;
50 String url = "trackpoints?bbox="+b.getMinLon()+","+b.getMinLat()+","+b.getMaxLon()+","+b.getMaxLat()+"&page=";
51 for (int i = 0; !done; ++i) {
52 progressMonitor.subTask(tr("Downloading points {0} to {1}...", i * 5000, (i + 1) * 5000));
53 try (InputStream in = getInputStream(url+i, progressMonitor.createSubTaskMonitor(1, true))) {
54 if (in == null) {
55 break;
56 }
57 progressMonitor.setTicks(0);
58 GpxReader reader = new GpxReader(in);
59 gpxParsedProperly = reader.parse(false);
60 GpxData currentGpx = reader.getGpxData();
61 if (result == null) {
62 result = currentGpx;
63 } else if (currentGpx.hasTrackPoints()) {
64 result.mergeFrom(currentGpx);
65 } else {
66 done = true;
67 }
68 }
69 activeConnection = null;
70 }
71 if (result != null) {
72 result.fromServer = true;
73 result.dataSources.add(new DataSource(b, "OpenStreetMap server"));
74 }
75 return result;
76 }
77
78 @Override
79 public GpxData parseRawGps(ProgressMonitor progressMonitor) throws OsmTransferException {
80 progressMonitor.beginTask("", 1);
81 try {
82 progressMonitor.indeterminateSubTask(getTaskName());
83 if (crosses180th) {
84 // API 0.6 does not support requests crossing the 180th meridian, so make two requests
85 GpxData result = downloadRawGps(new Bounds(lat1, lon1, lat2, 180.0), progressMonitor);
86 result.mergeFrom(downloadRawGps(new Bounds(lat1, -180.0, lat2, lon2), progressMonitor));
87 return result;
88 } else {
89 // Simple request
90 return downloadRawGps(new Bounds(lat1, lon1, lat2, lon2), progressMonitor);
91 }
92 } catch (IllegalArgumentException e) {
93 // caused by HttpUrlConnection in case of illegal stuff in the response
94 if (cancel)
95 return null;
96 throw new OsmTransferException("Illegal characters within the HTTP-header response.", e);
97 } catch (IOException e) {
98 if (cancel)
99 return null;
100 throw new OsmTransferException(e);
101 } catch (SAXException e) {
102 throw new OsmTransferException(e);
103 } catch (OsmTransferException e) {
104 throw e;
105 } catch (RuntimeException e) {
106 if (cancel)
107 return null;
108 throw e;
109 } finally {
110 progressMonitor.finishTask();
111 }
112 }
113
114 /**
115 * Returns the name of the download task to be displayed in the {@link ProgressMonitor}.
116 */
117 protected String getTaskName() {
118 return tr("Contacting OSM Server...");
119 }
120
121 /**
122 * Builds the request part for the bounding box.
123 */
124 protected String getRequestForBbox(double lon1, double lat1, double lon2, double lat2) {
125 return "map?bbox=" + lon1 + "," + lat1 + "," + lon2 + "," + lat2;
126 }
127
128 @Override
129 public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
130 progressMonitor.beginTask(getTaskName(), 10);
131 try {
132 DataSet ds = null;
133 progressMonitor.indeterminateSubTask(null);
134 if (crosses180th) {
135 // API 0.6 does not support requests crossing the 180th meridian, so make two requests
136 DataSet ds2 = null;
137
138 try (InputStream in = getInputStream(getRequestForBbox(lon1, lat1, 180.0, lat2),
139 progressMonitor.createSubTaskMonitor(9, false))) {
140 if (in == null)
141 return null;
142 ds = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
143 }
144
145 try (InputStream in = getInputStream(getRequestForBbox(-180.0, lat1, lon2, lat2),
146 progressMonitor.createSubTaskMonitor(9, false))) {
147 if (in == null)
148 return null;
149 ds2 = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
150 }
151 if (ds2 == null)
152 return null;
153 ds.mergeFrom(ds2);
154
155 } else {
156 // Simple request
157 try (InputStream in = getInputStream(getRequestForBbox(lon1, lat1, lon2, lat2),
158 progressMonitor.createSubTaskMonitor(9, false))) {
159 if (in == null)
160 return null;
161 ds = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
162 }
163 }
164 return ds;
165 } catch (OsmTransferException e) {
166 throw e;
167 } catch (Exception e) {
168 throw new OsmTransferException(e);
169 } finally {
170 progressMonitor.finishTask();
171 activeConnection = null;
172 }
173 }
174
175 @Override
176 public List<Note> parseNotes(int noteLimit, int daysClosed, ProgressMonitor progressMonitor)
177 throws OsmTransferException, MoreNotesException {
178 progressMonitor.beginTask("Downloading notes");
179 CheckParameterUtil.ensureThat(noteLimit > 0, "Requested note limit is less than 1.");
180 // see result_limit in https://github.com/openstreetmap/openstreetmap-website/blob/master/app/controllers/notes_controller.rb
181 CheckParameterUtil.ensureThat(noteLimit <= 10000, "Requested note limit is over API hard limit of 10000.");
182 CheckParameterUtil.ensureThat(daysClosed >= -1, "Requested note limit is less than -1.");
183 String url = "notes?limit=" + noteLimit + "&closed=" + daysClosed + "&bbox=" + lon1 + "," + lat1 + "," + lon2 + "," + lat2;
184 try {
185 InputStream is = getInputStream(url, progressMonitor.createSubTaskMonitor(1, false));
186 NoteReader reader = new NoteReader(is);
187 final List<Note> notes = reader.parse();
188 if (notes.size() == noteLimit) {
189 throw new MoreNotesException(notes, noteLimit);
190 }
191 return notes;
192 } catch (IOException e) {
193 throw new OsmTransferException(e);
194 } catch (SAXException e) {
195 throw new OsmTransferException(e);
196 } finally {
197 progressMonitor.finishTask();
198 }
199 }
200
201 /**
202 * Indicates that the number of fetched notes equals the specified limit. Thus there might be more notes to download.
203 */
204 public static class MoreNotesException extends RuntimeException {
205 /**
206 * The downloaded notes
207 */
208 public final transient List<Note> notes;
209 /**
210 * The download limit sent to the server.
211 */
212 public final int limit;
213
214 public MoreNotesException(List<Note> notes, int limit) {
215 this.notes = notes;
216 this.limit = limit;
217 }
218 }
219
220}
Note: See TracBrowser for help on using the repository browser.