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

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

fix #9434 - Robustness in hash URLs parsing

  • Property svn:eol-style set to native
File size: 5.9 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;
8
9import org.openstreetmap.josm.data.Bounds;
10import org.openstreetmap.josm.data.gpx.GpxData;
11import org.openstreetmap.josm.data.osm.DataSet;
12import org.openstreetmap.josm.gui.progress.ProgressMonitor;
13import org.openstreetmap.josm.tools.CheckParameterUtil;
14import org.openstreetmap.josm.tools.Utils;
15import org.xml.sax.SAXException;
16
17/**
18 * Read content from OSM server for a given bounding box
19 * @since 627
20 */
21public class BoundingBoxDownloader extends OsmServerReader {
22
23 /**
24 * The boundings of the desired map data.
25 */
26 protected final double lat1;
27 protected final double lon1;
28 protected final double lat2;
29 protected final double lon2;
30 protected final boolean crosses180th;
31
32 /**
33 * Constructs a new {@code BoundingBoxDownloader}.
34 * @param downloadArea The area to download
35 */
36 public BoundingBoxDownloader(Bounds downloadArea) {
37 CheckParameterUtil.ensureParameterNotNull(downloadArea, "downloadArea");
38 this.lat1 = downloadArea.getMinLat();
39 this.lon1 = downloadArea.getMinLon();
40 this.lat2 = downloadArea.getMaxLat();
41 this.lon2 = downloadArea.getMaxLon();
42 this.crosses180th = downloadArea.crosses180thMeridian();
43 }
44
45 private GpxData downloadRawGps(String url, ProgressMonitor progressMonitor) throws IOException, OsmTransferException, SAXException {
46 boolean done = false;
47 GpxData result = null;
48 for (int i = 0;!done;++i) {
49 progressMonitor.subTask(tr("Downloading points {0} to {1}...", i * 5000, ((i + 1) * 5000)));
50 InputStream in = getInputStream(url+i, progressMonitor.createSubTaskMonitor(1, true));
51 if (in == null) {
52 break;
53 }
54 progressMonitor.setTicks(0);
55 GpxReader reader = new GpxReader(in);
56 gpxParsedProperly = reader.parse(false);
57 GpxData currentGpx = reader.getGpxData();
58 if (result == null) {
59 result = currentGpx;
60 } else if (currentGpx.hasTrackPoints()) {
61 result.mergeFrom(currentGpx);
62 } else{
63 done = true;
64 }
65 Utils.close(in);
66 activeConnection = null;
67 }
68 result.fromServer = true;
69 return result;
70 }
71
72 @Override
73 public GpxData parseRawGps(ProgressMonitor progressMonitor) throws OsmTransferException {
74 progressMonitor.beginTask("", 1);
75 try {
76 progressMonitor.indeterminateSubTask(tr("Contacting OSM Server..."));
77 if (crosses180th) {
78 // API 0.6 does not support requests crossing the 180th meridian, so make two requests
79 GpxData result = downloadRawGps("trackpoints?bbox="+lon1+","+lat1+",180.0,"+lat2+"&page=", progressMonitor);
80 result.mergeFrom(downloadRawGps("trackpoints?bbox=-180.0,"+lat1+","+lon2+","+lat2+"&page=", progressMonitor));
81 return result;
82 } else {
83 // Simple request
84 return downloadRawGps("trackpoints?bbox="+lon1+","+lat1+","+lon2+","+lat2+"&page=", progressMonitor);
85 }
86 } catch (IllegalArgumentException e) {
87 // caused by HttpUrlConnection in case of illegal stuff in the response
88 if (cancel)
89 return null;
90 throw new OsmTransferException("Illegal characters within the HTTP-header response.", e);
91 } catch (IOException e) {
92 if (cancel)
93 return null;
94 throw new OsmTransferException(e);
95 } catch (SAXException e) {
96 throw new OsmTransferException(e);
97 } catch (OsmTransferException e) {
98 throw e;
99 } catch (RuntimeException e) {
100 if (cancel)
101 return null;
102 throw e;
103 } finally {
104 progressMonitor.finishTask();
105 }
106 }
107
108 protected String getRequestForBbox(double lon1, double lat1, double lon2, double lat2) {
109 return "map?bbox=" + lon1 + "," + lat1 + "," + lon2 + "," + lat2;
110 }
111
112 @Override
113 public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
114 progressMonitor.beginTask(tr("Contacting OSM Server..."), 10);
115 InputStream in = null;
116 try {
117 DataSet ds = null;
118 progressMonitor.indeterminateSubTask(null);
119 if (crosses180th) {
120 // API 0.6 does not support requests crossing the 180th meridian, so make two requests
121 in = getInputStream(getRequestForBbox(lon1, lat1, 180.0, lat2), progressMonitor.createSubTaskMonitor(9, false));
122 if (in == null)
123 return null;
124 ds = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
125
126 in = getInputStream(getRequestForBbox(-180.0, lat1, lon2, lat2), progressMonitor.createSubTaskMonitor(9, false));
127 if (in == null)
128 return null;
129 DataSet ds2 = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
130 if (ds2 == null)
131 return null;
132 ds.mergeFrom(ds2);
133
134 } else {
135 // Simple request
136 in = getInputStream(getRequestForBbox(lon1, lat1, lon2, lat2), progressMonitor.createSubTaskMonitor(9, false));
137 if (in == null)
138 return null;
139 ds = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
140 }
141 return ds;
142 } catch(OsmTransferException e) {
143 throw e;
144 } catch (Exception e) {
145 throw new OsmTransferException(e);
146 } finally {
147 progressMonitor.finishTask();
148 Utils.close(in);
149 activeConnection = null;
150 }
151 }
152}
Note: See TracBrowser for help on using the repository browser.