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

Last change on this file since 8563 was 8540, checked in by Don-vip, 9 years ago

fix remaining checkstyle issues

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