| 1 | // License: GPL. Copyright 2007 by Immanuel Scholz and others |
|---|
| 2 | package org.openstreetmap.josm.io; |
|---|
| 3 | |
|---|
| 4 | import static org.openstreetmap.josm.tools.I18n.tr; |
|---|
| 5 | |
|---|
| 6 | import java.io.IOException; |
|---|
| 7 | import java.io.InputStream; |
|---|
| 8 | |
|---|
| 9 | import org.openstreetmap.josm.data.Bounds; |
|---|
| 10 | import org.openstreetmap.josm.data.gpx.GpxData; |
|---|
| 11 | import org.openstreetmap.josm.data.osm.DataSet; |
|---|
| 12 | import org.openstreetmap.josm.gui.progress.ProgressMonitor; |
|---|
| 13 | import org.xml.sax.SAXException; |
|---|
| 14 | |
|---|
| 15 | public class BoundingBoxDownloader extends OsmServerReader { |
|---|
| 16 | |
|---|
| 17 | /** |
|---|
| 18 | * The boundings of the desired map data. |
|---|
| 19 | */ |
|---|
| 20 | protected final double lat1; |
|---|
| 21 | protected final double lon1; |
|---|
| 22 | protected final double lat2; |
|---|
| 23 | protected final double lon2; |
|---|
| 24 | protected final boolean crosses180th; |
|---|
| 25 | |
|---|
| 26 | public BoundingBoxDownloader(Bounds downloadArea) { |
|---|
| 27 | this.lat1 = downloadArea.getMin().lat(); |
|---|
| 28 | this.lon1 = downloadArea.getMin().lon(); |
|---|
| 29 | this.lat2 = downloadArea.getMax().lat(); |
|---|
| 30 | this.lon2 = downloadArea.getMax().lon(); |
|---|
| 31 | this.crosses180th = downloadArea.crosses180thMeridian(); |
|---|
| 32 | } |
|---|
| 33 | |
|---|
| 34 | private GpxData downloadRawGps(String url, ProgressMonitor progressMonitor) throws IOException, OsmTransferException, SAXException { |
|---|
| 35 | boolean done = false; |
|---|
| 36 | GpxData result = null; |
|---|
| 37 | for (int i = 0;!done;++i) { |
|---|
| 38 | progressMonitor.subTask(tr("Downloading points {0} to {1}...", i * 5000, ((i + 1) * 5000))); |
|---|
| 39 | InputStream in = getInputStream(url+i, progressMonitor.createSubTaskMonitor(1, true)); |
|---|
| 40 | if (in == null) { |
|---|
| 41 | break; |
|---|
| 42 | } |
|---|
| 43 | progressMonitor.setTicks(0); |
|---|
| 44 | GpxReader reader = new GpxReader(in); |
|---|
| 45 | reader.parse(false); |
|---|
| 46 | GpxData currentGpx = reader.data; |
|---|
| 47 | if (result == null) { |
|---|
| 48 | result = currentGpx; |
|---|
| 49 | } else if (currentGpx.hasTrackPoints()) { |
|---|
| 50 | result.mergeFrom(currentGpx); |
|---|
| 51 | } else{ |
|---|
| 52 | done = true; |
|---|
| 53 | } |
|---|
| 54 | in.close(); |
|---|
| 55 | activeConnection = null; |
|---|
| 56 | } |
|---|
| 57 | result.fromServer = true; |
|---|
| 58 | return result; |
|---|
| 59 | } |
|---|
| 60 | |
|---|
| 61 | /** |
|---|
| 62 | * Retrieve raw gps waypoints from the server API. |
|---|
| 63 | * @return A list of all primitives retrieved. Currently, the list of lists |
|---|
| 64 | * contain only one list, since the server cannot distinguish between |
|---|
| 65 | * ways. |
|---|
| 66 | */ |
|---|
| 67 | @Override |
|---|
| 68 | public GpxData parseRawGps(ProgressMonitor progressMonitor) throws OsmTransferException { |
|---|
| 69 | progressMonitor.beginTask("", 1); |
|---|
| 70 | try { |
|---|
| 71 | progressMonitor.indeterminateSubTask(tr("Contacting OSM Server...")); |
|---|
| 72 | if (crosses180th) { |
|---|
| 73 | // API 0.6 does not support requests crossing the 180th meridian, so make two requests |
|---|
| 74 | GpxData result = downloadRawGps("trackpoints?bbox="+lon1+","+lat1+",180.0,"+lat2+"&page=", progressMonitor); |
|---|
| 75 | result.mergeFrom(downloadRawGps("trackpoints?bbox=-180.0,"+lat1+","+lon2+","+lat2+"&page=", progressMonitor)); |
|---|
| 76 | return result; |
|---|
| 77 | } else { |
|---|
| 78 | // Simple request |
|---|
| 79 | return downloadRawGps("trackpoints?bbox="+lon1+","+lat1+","+lon2+","+lat2+"&page=", progressMonitor); |
|---|
| 80 | } |
|---|
| 81 | } catch (IllegalArgumentException e) { |
|---|
| 82 | // caused by HttpUrlConnection in case of illegal stuff in the response |
|---|
| 83 | if (cancel) |
|---|
| 84 | return null; |
|---|
| 85 | throw new OsmTransferException("Illegal characters within the HTTP-header response.", e); |
|---|
| 86 | } catch (IOException e) { |
|---|
| 87 | if (cancel) |
|---|
| 88 | return null; |
|---|
| 89 | throw new OsmTransferException(e); |
|---|
| 90 | } catch (SAXException e) { |
|---|
| 91 | throw new OsmTransferException(e); |
|---|
| 92 | } catch (OsmTransferException e) { |
|---|
| 93 | throw e; |
|---|
| 94 | } catch (RuntimeException e) { |
|---|
| 95 | if (cancel) |
|---|
| 96 | return null; |
|---|
| 97 | throw e; |
|---|
| 98 | } finally { |
|---|
| 99 | progressMonitor.finishTask(); |
|---|
| 100 | } |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | protected String getRequestForBbox(double lon1, double lat1, double lon2, double lat2) { |
|---|
| 104 | return "map?bbox=" + lon1 + "," + lat1 + "," + lon2 + "," + lat2; |
|---|
| 105 | } |
|---|
| 106 | |
|---|
| 107 | /** |
|---|
| 108 | * Read the data from the osm server address. |
|---|
| 109 | * @return A data set containing all data retrieved from that url |
|---|
| 110 | */ |
|---|
| 111 | @Override |
|---|
| 112 | public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException { |
|---|
| 113 | progressMonitor.beginTask(tr("Contacting OSM Server..."), 10); |
|---|
| 114 | InputStream in = null; |
|---|
| 115 | try { |
|---|
| 116 | DataSet ds = null; |
|---|
| 117 | progressMonitor.indeterminateSubTask(null); |
|---|
| 118 | if (crosses180th) { |
|---|
| 119 | // API 0.6 does not support requests crossing the 180th meridian, so make two requests |
|---|
| 120 | in = getInputStream(getRequestForBbox(lon1, lat1, 180.0, lat2), progressMonitor.createSubTaskMonitor(9, false)); |
|---|
| 121 | if (in == null) |
|---|
| 122 | return null; |
|---|
| 123 | ds = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false)); |
|---|
| 124 | |
|---|
| 125 | in = getInputStream(getRequestForBbox(-180.0, lat1, lon2, lat2), progressMonitor.createSubTaskMonitor(9, false)); |
|---|
| 126 | if (in == null) |
|---|
| 127 | return null; |
|---|
| 128 | DataSet ds2 = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false)); |
|---|
| 129 | if (ds2 == null) |
|---|
| 130 | return null; |
|---|
| 131 | ds.mergeFrom(ds2); |
|---|
| 132 | |
|---|
| 133 | } else { |
|---|
| 134 | // Simple request |
|---|
| 135 | in = getInputStream(getRequestForBbox(lon1, lat1, lon2, lat2), progressMonitor.createSubTaskMonitor(9, false)); |
|---|
| 136 | if (in == null) |
|---|
| 137 | return null; |
|---|
| 138 | ds = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false)); |
|---|
| 139 | } |
|---|
| 140 | return ds; |
|---|
| 141 | } catch(OsmTransferException e) { |
|---|
| 142 | throw e; |
|---|
| 143 | } catch (Exception e) { |
|---|
| 144 | throw new OsmTransferException(e); |
|---|
| 145 | } finally { |
|---|
| 146 | progressMonitor.finishTask(); |
|---|
| 147 | if (in != null) { |
|---|
| 148 | try {in.close();} catch(IOException e) {} |
|---|
| 149 | } |
|---|
| 150 | activeConnection = null; |
|---|
| 151 | } |
|---|
| 152 | } |
|---|
| 153 | } |
|---|