source: josm/trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java@ 13691

Last change on this file since 13691 was 13572, checked in by Don-vip, 6 years ago

fix #15798 - support direct download of GPX files from HOT Tasking Manager

  • Property svn:eol-style set to native
File size: 9.4 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.Collections;
9import java.util.List;
10
11import org.openstreetmap.josm.data.gpx.GpxData;
12import org.openstreetmap.josm.data.notes.Note;
13import org.openstreetmap.josm.data.osm.DataSet;
14import org.openstreetmap.josm.gui.progress.ProgressMonitor;
15import org.openstreetmap.josm.tools.Utils;
16import org.xml.sax.SAXException;
17
18/**
19 * Read content from OSM server for a given URL
20 * @since 1146
21 */
22public class OsmServerLocationReader extends OsmServerReader {
23
24 // CHECKSTYLE.OFF: MethodParamPad
25 // CHECKSTYLE.OFF: SingleSpaceSeparator
26
27 /**
28 * Patterns for OSM data download URLs.
29 * @since 12679
30 */
31 public enum OsmUrlPattern {
32 OSM_API_URL ("https?://.*/api/0.6/(map|nodes?|ways?|relations?|\\*).*"),
33 OVERPASS_API_URL ("https?://.*/interpreter\\?data=.*"),
34 OVERPASS_API_XAPI_URL ("https?://.*/xapi(\\?.*\\[@meta\\]|_meta\\?).*"),
35 EXTERNAL_OSM_FILE ("https?://.*/.*\\.osm");
36
37 private final String urlPattern;
38
39 OsmUrlPattern(String urlPattern) {
40 this.urlPattern = urlPattern;
41 }
42
43 /**
44 * Returns the URL pattern.
45 * @return the URL pattern
46 */
47 public String pattern() {
48 return urlPattern;
49 }
50 }
51
52 /**
53 * Patterns for GPX download URLs.
54 * @since 12679
55 */
56 public enum GpxUrlPattern {
57 TRACE_ID ("https?://.*(osm|openstreetmap).org/trace/\\p{Digit}+/data"),
58 USER_TRACE_ID("https?://.*(osm|openstreetmap).org/user/[^/]+/traces/(\\p{Digit}+)"),
59 EDIT_TRACE_ID("https?://.*(osm|openstreetmap).org/edit/?\\?gpx=(\\p{Digit}+)(#.*)?"),
60
61 TRACKPOINTS_BBOX("https?://.*/api/0.6/trackpoints\\?bbox=.*,.*,.*,.*"),
62 TASKING_MANAGER("https?://.*/api/v\\p{Digit}+/project/\\p{Digit}+/tasks_as_gpx?.*"),
63
64 EXTERNAL_GPX_SCRIPT("https?://.*exportgpx.*"),
65 EXTERNAL_GPX_FILE ("https?://.*/(.*\\.gpx)");
66
67 private final String urlPattern;
68
69 GpxUrlPattern(String urlPattern) {
70 this.urlPattern = urlPattern;
71 }
72
73 /**
74 * Returns the URL pattern.
75 * @return the URL pattern
76 */
77 public String pattern() {
78 return urlPattern;
79 }
80 }
81
82 /**
83 * Patterns for Note download URLs.
84 * @since 12679
85 */
86 public enum NoteUrlPattern {
87 /** URL of OSM API Notes endpoint */
88 API_URL ("https?://.*/api/0.6/notes.*"),
89 /** URL of OSM API Notes compressed dump file */
90 DUMP_FILE("https?://.*/(.*\\.osn(\\.(gz|xz|bz2?|zip))?)");
91
92 private final String urlPattern;
93
94 NoteUrlPattern(String urlPattern) {
95 this.urlPattern = urlPattern;
96 }
97
98 /**
99 * Returns the URL pattern.
100 * @return the URL pattern
101 */
102 public String pattern() {
103 return urlPattern;
104 }
105 }
106
107 // CHECKSTYLE.ON: SingleSpaceSeparator
108 // CHECKSTYLE.ON: MethodParamPad
109
110 protected final String url;
111
112 /**
113 * Constructs a new {@code OsmServerLocationReader}.
114 * @param url The URL to fetch
115 */
116 public OsmServerLocationReader(String url) {
117 this.url = url;
118 }
119
120 protected abstract static class Parser<T> {
121 protected final ProgressMonitor progressMonitor;
122 protected final Compression compression;
123 protected InputStream in;
124
125 public Parser(ProgressMonitor progressMonitor, Compression compression) {
126 this.progressMonitor = progressMonitor;
127 this.compression = compression;
128 }
129
130 public abstract T parse() throws OsmTransferException, IllegalDataException, IOException, SAXException;
131 }
132
133 protected final <T> T doParse(Parser<T> parser, final ProgressMonitor progressMonitor) throws OsmTransferException {
134 progressMonitor.beginTask(tr("Contacting Server...", 10));
135 try {
136 return parser.parse();
137 } catch (OsmTransferException e) {
138 throw e;
139 } catch (IOException | SAXException | IllegalDataException e) {
140 if (cancel)
141 return null;
142 throw new OsmTransferException(e);
143 } finally {
144 progressMonitor.finishTask();
145 activeConnection = null;
146 Utils.close(parser.in);
147 parser.in = null;
148 }
149 }
150
151 @Override
152 public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
153 return parseOsm(progressMonitor, Compression.NONE);
154 }
155
156 @Override
157 public DataSet parseOsm(ProgressMonitor progressMonitor, Compression compression) throws OsmTransferException {
158 return doParse(new OsmParser(progressMonitor, compression), progressMonitor);
159 }
160
161 @Override
162 public DataSet parseOsmChange(ProgressMonitor progressMonitor) throws OsmTransferException {
163 return parseOsmChange(progressMonitor, Compression.NONE);
164 }
165
166 @Override
167 public DataSet parseOsmChange(ProgressMonitor progressMonitor, Compression compression) throws OsmTransferException {
168 return doParse(new OsmChangeParser(progressMonitor, compression), progressMonitor);
169 }
170
171 @Override
172 public GpxData parseRawGps(ProgressMonitor progressMonitor) throws OsmTransferException {
173 return parseRawGps(progressMonitor, Compression.NONE);
174 }
175
176 @Override
177 public GpxData parseRawGps(ProgressMonitor progressMonitor, Compression compression) throws OsmTransferException {
178 return doParse(new GpxParser(progressMonitor, compression), progressMonitor);
179 }
180
181 @Override
182 public List<Note> parseRawNotes(ProgressMonitor progressMonitor) throws OsmTransferException {
183 return parseRawNotes(progressMonitor, Compression.NONE);
184 }
185
186 @Override
187 public List<Note> parseRawNotes(ProgressMonitor progressMonitor, Compression compression) throws OsmTransferException {
188 return doParse(new NoteParser(progressMonitor, compression), progressMonitor);
189 }
190
191 protected class OsmParser extends Parser<DataSet> {
192 protected OsmParser(ProgressMonitor progressMonitor, Compression compression) {
193 super(progressMonitor, compression);
194 }
195
196 @Override
197 public DataSet parse() throws OsmTransferException, IllegalDataException, IOException {
198 in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
199 if (in == null)
200 return null;
201 progressMonitor.subTask(tr("Downloading OSM data..."));
202 return OsmReader.parseDataSet(compression.getUncompressedInputStream(in), progressMonitor.createSubTaskMonitor(1, false));
203 }
204 }
205
206 protected class OsmChangeParser extends Parser<DataSet> {
207 protected OsmChangeParser(ProgressMonitor progressMonitor, Compression compression) {
208 super(progressMonitor, compression);
209 }
210
211 @Override
212 public DataSet parse() throws OsmTransferException, IllegalDataException, IOException {
213 in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
214 if (in == null)
215 return null;
216 progressMonitor.subTask(tr("Downloading OSM data..."));
217 return OsmChangeReader.parseDataSet(compression.getUncompressedInputStream(in), progressMonitor.createSubTaskMonitor(1, false));
218 }
219 }
220
221 protected class GpxParser extends Parser<GpxData> {
222 protected GpxParser(ProgressMonitor progressMonitor, Compression compression) {
223 super(progressMonitor, compression);
224 }
225
226 @Override
227 public GpxData parse() throws OsmTransferException, IllegalDataException, IOException, SAXException {
228 in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(1, true), null, true);
229 if (in == null)
230 return null;
231 progressMonitor.subTask(tr("Downloading OSM data..."));
232 GpxReader reader = new GpxReader(compression.getUncompressedInputStream(in));
233 gpxParsedProperly = reader.parse(false);
234 GpxData result = reader.getGpxData();
235 result.fromServer = isGpxFromServer(url);
236 return result;
237 }
238 }
239
240 protected class NoteParser extends Parser<List<Note>> {
241
242 public NoteParser(ProgressMonitor progressMonitor, Compression compression) {
243 super(progressMonitor, compression);
244 }
245
246 @Override
247 public List<Note> parse() throws OsmTransferException, IllegalDataException, IOException, SAXException {
248 in = getInputStream(url, progressMonitor.createSubTaskMonitor(1, true));
249 if (in == null) {
250 return Collections.emptyList();
251 }
252 progressMonitor.subTask(tr("Downloading OSM notes..."));
253 NoteReader reader = new NoteReader(compression.getUncompressedInputStream(in));
254 return reader.parse();
255 }
256 }
257
258 /**
259 * Determines if the given URL denotes an OSM gpx-related API call.
260 * @param url The url to check
261 * @return true if the url matches "Trace ID" API call or "Trackpoints bbox" API call, false otherwise
262 * @see GpxData#fromServer
263 * @since 12679
264 */
265 public static final boolean isGpxFromServer(String url) {
266 return url != null && (url.matches(GpxUrlPattern.TRACE_ID.pattern()) || url.matches(GpxUrlPattern.TRACKPOINTS_BBOX.pattern()));
267 }
268}
Note: See TracBrowser for help on using the repository browser.