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

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

fix potential NPEs and Sonar issues related to serialization

  • Property svn:eol-style set to native
File size: 8.3 KB
RevLine 
[6380]1// License: GPL. For details, see LICENSE file.
[444]2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.IOException;
7import java.io.InputStream;
[7531]8import java.util.List;
[444]9
[2327]10import org.openstreetmap.josm.data.Bounds;
[7575]11import org.openstreetmap.josm.data.DataSource;
[1811]12import org.openstreetmap.josm.data.gpx.GpxData;
[7531]13import org.openstreetmap.josm.data.notes.Note;
[444]14import org.openstreetmap.josm.data.osm.DataSet;
[1811]15import org.openstreetmap.josm.gui.progress.ProgressMonitor;
[6474]16import org.openstreetmap.josm.tools.CheckParameterUtil;
[444]17import org.xml.sax.SAXException;
18
[6244]19/**
20 * Read content from OSM server for a given bounding box
21 * @since 627
22 */
[444]23public class BoundingBoxDownloader extends OsmServerReader {
24
[1169]25 /**
26 * The boundings of the desired map data.
27 */
[5097]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;
[444]33
[6244]34 /**
35 * Constructs a new {@code BoundingBoxDownloader}.
36 * @param downloadArea The area to download
37 */
[2327]38 public BoundingBoxDownloader(Bounds downloadArea) {
[6474]39 CheckParameterUtil.ensureParameterNotNull(downloadArea, "downloadArea");
[6203]40 this.lat1 = downloadArea.getMinLat();
41 this.lon1 = downloadArea.getMinLon();
42 this.lat2 = downloadArea.getMaxLat();
43 this.lon2 = downloadArea.getMaxLon();
[4580]44 this.crosses180th = downloadArea.crosses180thMeridian();
[1169]45 }
[444]46
[7575]47 private GpxData downloadRawGps(Bounds b, ProgressMonitor progressMonitor) throws IOException, OsmTransferException, SAXException {
[4580]48 boolean done = false;
49 GpxData result = null;
[7575]50 String url = "trackpoints?bbox="+b.getMinLon()+","+b.getMinLat()+","+b.getMaxLon()+","+b.getMaxLat()+"&page=";
[4580]51 for (int i = 0;!done;++i) {
52 progressMonitor.subTask(tr("Downloading points {0} to {1}...", i * 5000, ((i + 1) * 5000)));
[7033]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 }
[4580]68 }
69 activeConnection = null;
70 }
[7033]71 if (result != null) {
72 result.fromServer = true;
[7575]73 result.dataSources.add(new DataSource(b, "OpenStreetMap server"));
[7033]74 }
[4580]75 return result;
76 }
[6070]77
[4521]78 @Override
79 public GpxData parseRawGps(ProgressMonitor progressMonitor) throws OsmTransferException {
[1811]80 progressMonitor.beginTask("", 1);
[1169]81 try {
[1811]82 progressMonitor.indeterminateSubTask(tr("Contacting OSM Server..."));
[4580]83 if (crosses180th) {
84 // API 0.6 does not support requests crossing the 180th meridian, so make two requests
[7575]85 GpxData result = downloadRawGps(new Bounds(lat1, lon1, lat2, 180.0), progressMonitor);
86 result.mergeFrom(downloadRawGps(new Bounds(lat1, -180.0, lat2, lon2), progressMonitor));
[4580]87 return result;
88 } else {
89 // Simple request
[7575]90 return downloadRawGps(new Bounds(lat1, lon1, lat2, lon2), progressMonitor);
[1169]91 }
92 } catch (IllegalArgumentException e) {
93 // caused by HttpUrlConnection in case of illegal stuff in the response
94 if (cancel)
95 return null;
[4521]96 throw new OsmTransferException("Illegal characters within the HTTP-header response.", e);
[1169]97 } catch (IOException e) {
98 if (cancel)
99 return null;
[4521]100 throw new OsmTransferException(e);
[1169]101 } catch (SAXException e) {
[4521]102 throw new OsmTransferException(e);
[1835]103 } catch (OsmTransferException e) {
104 throw e;
[2676]105 } catch (RuntimeException e) {
[1169]106 if (cancel)
107 return null;
[2676]108 throw e;
[1811]109 } finally {
110 progressMonitor.finishTask();
[1169]111 }
112 }
[444]113
[5097]114 protected String getRequestForBbox(double lon1, double lat1, double lon2, double lat2) {
115 return "map?bbox=" + lon1 + "," + lat1 + "," + lon2 + "," + lat2;
116 }
117
[1670]118 @Override
[1811]119 public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
120 progressMonitor.beginTask(tr("Contacting OSM Server..."), 10);
[1169]121 try {
[4580]122 DataSet ds = null;
[1811]123 progressMonitor.indeterminateSubTask(null);
[4580]124 if (crosses180th) {
125 // API 0.6 does not support requests crossing the 180th meridian, so make two requests
[7033]126 DataSet ds2 = null;
[4580]127
[7033]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 }
[4580]139 if (ds2 == null)
140 return null;
141 ds.mergeFrom(ds2);
[6070]142
[4580]143 } else {
144 // Simple request
[7033]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 }
[4580]150 }
151 return ds;
[1670]152 } catch(OsmTransferException e) {
[1169]153 throw e;
154 } catch (Exception e) {
[1670]155 throw new OsmTransferException(e);
[1811]156 } finally {
157 progressMonitor.finishTask();
[1879]158 activeConnection = null;
[1169]159 }
160 }
[7531]161
162 @Override
[8218]163 public List<Note> parseNotes(int noteLimit, int daysClosed, ProgressMonitor progressMonitor) throws OsmTransferException, MoreNotesException {
[7531]164 progressMonitor.beginTask("Downloading notes");
[8218]165 CheckParameterUtil.ensureThat(noteLimit > 0, "Requested note limit is less than 1.");
[8230]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.");
[8218]168 CheckParameterUtil.ensureThat(daysClosed >= 0, "Requested note limit is less than 0.");
169 String url = "notes?limit=" + noteLimit + "&closed=" + daysClosed + "&bbox=" + lon1 + "," + lat1 + "," + lon2 + "," + lat2;
[7531]170 try {
171 InputStream is = getInputStream(url, progressMonitor.createSubTaskMonitor(1, false));
172 NoteReader reader = new NoteReader(is);
[8216]173 final List<Note> notes = reader.parse();
174 if (notes.size() == noteLimit) {
[8217]175 throw new MoreNotesException(notes, noteLimit);
[8216]176 }
177 return notes;
[7531]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
[8216]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 /**
[8217]192 * The downloaded notes
193 */
[8308]194 public final transient List<Note> notes;
[8217]195 /**
[8216]196 * The download limit sent to the server.
197 */
198 public final int limit;
199
[8217]200 public MoreNotesException(List<Note> notes, int limit) {
201 this.notes = notes;
[8216]202 this.limit = limit;
203 }
204 }
205
[444]206}
Note: See TracBrowser for help on using the repository browser.