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

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

fix #12071 - missing translated string

  • Property svn:eol-style set to native
File size: 9.2 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 * @return task name
117 */
118 protected String getTaskName() {
119 return tr("Contacting OSM Server...");
120 }
121
122 /**
123 * Builds the request part for the bounding box.
124 * @param lon1 left
125 * @param lat1 bottom
126 * @param lon2 right
127 * @param lat2 top
128 * @return "map?bbox=left,bottom,right,top"
129 */
130 protected String getRequestForBbox(double lon1, double lat1, double lon2, double lat2) {
131 return "map?bbox=" + lon1 + ',' + lat1 + ',' + lon2 + ',' + lat2;
132 }
133
134 /**
135 * Parse the given input source and return the dataset.
136 * @param source input stream
137 * @param progressMonitor progress monitor
138 * @return dataset
139 * @throws IllegalDataException if an error was found while parsing the OSM data
140 *
141 * @see OsmReader#parseDataSet(InputStream, ProgressMonitor)
142 */
143 protected DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException {
144 return OsmReader.parseDataSet(source, progressMonitor);
145 }
146
147 @Override
148 public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
149 progressMonitor.beginTask(getTaskName(), 10);
150 try {
151 DataSet ds = null;
152 progressMonitor.indeterminateSubTask(null);
153 if (crosses180th) {
154 // API 0.6 does not support requests crossing the 180th meridian, so make two requests
155 DataSet ds2 = null;
156
157 try (InputStream in = getInputStream(getRequestForBbox(lon1, lat1, 180.0, lat2),
158 progressMonitor.createSubTaskMonitor(9, false))) {
159 if (in == null)
160 return null;
161 ds = parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
162 }
163
164 try (InputStream in = getInputStream(getRequestForBbox(-180.0, lat1, lon2, lat2),
165 progressMonitor.createSubTaskMonitor(9, false))) {
166 if (in == null)
167 return null;
168 ds2 = parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
169 }
170 if (ds2 == null)
171 return null;
172 ds.mergeFrom(ds2);
173
174 } else {
175 // Simple request
176 try (InputStream in = getInputStream(getRequestForBbox(lon1, lat1, lon2, lat2),
177 progressMonitor.createSubTaskMonitor(9, false))) {
178 if (in == null)
179 return null;
180 ds = parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
181 }
182 }
183 return ds;
184 } catch (OsmTransferException e) {
185 throw e;
186 } catch (Exception e) {
187 throw new OsmTransferException(e);
188 } finally {
189 progressMonitor.finishTask();
190 activeConnection = null;
191 }
192 }
193
194 @Override
195 public List<Note> parseNotes(int noteLimit, int daysClosed, ProgressMonitor progressMonitor)
196 throws OsmTransferException, MoreNotesException {
197 progressMonitor.beginTask(tr("Downloading notes"));
198 CheckParameterUtil.ensureThat(noteLimit > 0, "Requested note limit is less than 1.");
199 // see result_limit in https://github.com/openstreetmap/openstreetmap-website/blob/master/app/controllers/notes_controller.rb
200 CheckParameterUtil.ensureThat(noteLimit <= 10000, "Requested note limit is over API hard limit of 10000.");
201 CheckParameterUtil.ensureThat(daysClosed >= -1, "Requested note limit is less than -1.");
202 String url = "notes?limit=" + noteLimit + "&closed=" + daysClosed + "&bbox=" + lon1 + ',' + lat1 + ',' + lon2 + ',' + lat2;
203 try {
204 InputStream is = getInputStream(url, progressMonitor.createSubTaskMonitor(1, false));
205 NoteReader reader = new NoteReader(is);
206 final List<Note> notes = reader.parse();
207 if (notes.size() == noteLimit) {
208 throw new MoreNotesException(notes, noteLimit);
209 }
210 return notes;
211 } catch (IOException e) {
212 throw new OsmTransferException(e);
213 } catch (SAXException e) {
214 throw new OsmTransferException(e);
215 } finally {
216 progressMonitor.finishTask();
217 }
218 }
219
220 /**
221 * Indicates that the number of fetched notes equals the specified limit. Thus there might be more notes to download.
222 */
223 public static class MoreNotesException extends RuntimeException {
224 /**
225 * The downloaded notes
226 */
227 public final transient List<Note> notes;
228 /**
229 * The download limit sent to the server.
230 */
231 public final int limit;
232
233 public MoreNotesException(List<Note> notes, int limit) {
234 this.notes = notes;
235 this.limit = limit;
236 }
237 }
238
239}
Note: See TracBrowser for help on using the repository browser.