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

Last change on this file since 7956 was 7575, checked in by Don-vip, 10 years ago

fix #7976 - Get downloaded gpx areas, on the same model as osm data

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