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

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

code style - Useless parentheses around expressions should be removed to prevent any misunderstanding

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