| 287 | | /** |
| 288 | | * invokes a Multi Get for a set of ids and a given {@link OsmPrimitiveType}. |
| 289 | | * The retrieved primitives are merged to {@link #outputDataSet}. |
| 290 | | * |
| 291 | | * @param type the type |
| 292 | | * @param pkg the package of ids |
| 293 | | * @exception OsmTransferException thrown if an error occurs while communicating with the API server |
| 294 | | * |
| 295 | | */ |
| 296 | | protected void multiGetIdPackage(OsmPrimitiveType type, Set<Long> pkg, ProgressMonitor progressMonitor) throws OsmTransferException { |
| 297 | | String request = buildRequestString(type, pkg); |
| 298 | | final InputStream in = getInputStream(request, NullProgressMonitor.INSTANCE); |
| 299 | | if (in == null) return; |
| 300 | | progressMonitor.subTask(tr("Downloading OSM data...")); |
| 301 | | try { |
| 302 | | DataSet loaded = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(pkg.size(), false)); |
| 303 | | rememberNodesOfIncompleteWaysToLoad(loaded); |
| 304 | | merge(loaded); |
| 305 | | } catch(Exception e) { |
| 306 | | throw new OsmTransferException(e); |
| 307 | | } |
| 308 | | } |
| 309 | | |
| 310 | | /** |
| 311 | | * invokes a Multi Get for a single id and a given {@link OsmPrimitiveType}. |
| 312 | | * The retrieved primitive is merged to {@link #outputDataSet}. |
| 313 | | * |
| 314 | | * @param type the type |
| 315 | | * @param id the id |
| 316 | | * @exception OsmTransferException thrown if an error occurs while communicating with the API server |
| 317 | | * |
| 318 | | */ |
| 319 | | protected void singleGetId(OsmPrimitiveType type, long id, ProgressMonitor progressMonitor) throws OsmTransferException { |
| 320 | | String request = buildRequestString(type, id); |
| 321 | | final InputStream in = getInputStream(request, NullProgressMonitor.INSTANCE); |
| 322 | | if (in == null) |
| 323 | | return; |
| 324 | | progressMonitor.subTask(tr("Downloading OSM data...")); |
| 325 | | try { |
| 326 | | DataSet loaded = OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false)); |
| 327 | | rememberNodesOfIncompleteWaysToLoad(loaded); |
| 328 | | merge(loaded); |
| 329 | | } catch(Exception e) { |
| 330 | | throw new OsmTransferException(e); |
| 331 | | } |
| 332 | | } |
| 333 | | |
| 334 | | /** |
| 335 | | * invokes a sequence of Multi Gets for individual ids in a set of ids and a given {@link OsmPrimitiveType}. |
| 336 | | * The retrieved primitives are merged to {@link #outputDataSet}. |
| 337 | | * |
| 338 | | * This method is used if one of the ids in pkg doesn't exist (the server replies with return code 404). |
| 339 | | * If the set is fetched with this method it is possible to find out which of the ids doesn't exist. |
| 340 | | * Unfortunatelly, the server does not provide an error header or an error body for a 404 reply. |
| 341 | | * |
| 342 | | * @param type the type |
| 343 | | * @param pkg the set of ids |
| 344 | | * @exception OsmTransferException thrown if an error occurs while communicating with the API server |
| 345 | | * |
| 346 | | */ |
| 347 | | protected void singleGetIdPackage(OsmPrimitiveType type, Set<Long> pkg, ProgressMonitor progressMonitor) throws OsmTransferException { |
| 348 | | for (long id : pkg) { |
| 349 | | try { |
| 350 | | String msg = ""; |
| 351 | | switch(type) { |
| 352 | | case NODE: msg = tr("Fetching node with id {0} from ''{1}''", id, OsmApi.getOsmApi().getBaseUrl()); break; |
| 353 | | case WAY: msg = tr("Fetching way with id {0} from ''{1}''", id, OsmApi.getOsmApi().getBaseUrl()); break; |
| 354 | | case RELATION: msg = tr("Fetching relation with id {0} from ''{1}''", id, OsmApi.getOsmApi().getBaseUrl()); break; |
| 355 | | } |
| 356 | | progressMonitor.setCustomText(msg); |
| 357 | | singleGetId(type, id, progressMonitor); |
| 358 | | } catch(OsmApiException e) { |
| 359 | | if (e.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) { |
| 360 | | System.out.println(tr("Server replied with response code 404 for id {0}. Skipping.", Long.toString(id))); |
| 361 | | missingPrimitives.add(new SimplePrimitiveId(id, type)); |
| 362 | | continue; |
| 363 | | } |
| 364 | | throw e; |
| 365 | | } |
| 366 | | } |
| 367 | | } |
| 368 | | |
| | 410 | |
| | 411 | protected static class FetchResult { |
| | 412 | public final DataSet dataSet; |
| | 413 | public final Set<PrimitiveId> missingPrimitives; |
| | 414 | public FetchResult(DataSet dataSet, Set<PrimitiveId> missingPrimitives) { |
| | 415 | this.dataSet = dataSet; |
| | 416 | this.missingPrimitives = missingPrimitives; |
| | 417 | } |
| | 418 | } |
| | 419 | |
| | 420 | protected static class Fetcher extends OsmServerReader implements Callable<FetchResult> { |
| | 421 | |
| | 422 | private final Set<Long> pkg; |
| | 423 | private final OsmPrimitiveType type; |
| | 424 | private final ProgressMonitor progressMonitor; |
| | 425 | |
| | 426 | public Fetcher(OsmPrimitiveType type, Set<Long> extractIdPackage, ProgressMonitor progressMonitor) { |
| | 427 | this.pkg = extractIdPackage; |
| | 428 | this.type = type; |
| | 429 | this.progressMonitor = progressMonitor; |
| | 430 | } |
| | 431 | |
| | 432 | @Override |
| | 433 | public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException { |
| | 434 | return fetch(progressMonitor).dataSet; |
| | 435 | } |
| | 436 | |
| | 437 | @Override |
| | 438 | public FetchResult call() throws Exception { |
| | 439 | return fetch(progressMonitor); |
| | 440 | } |
| | 441 | |
| | 442 | private FetchResult fetch(ProgressMonitor progressMonitor) throws OsmTransferException { |
| | 443 | try { |
| | 444 | return multiGetIdPackage(type, pkg, progressMonitor); |
| | 445 | } catch (OsmApiException e) { |
| | 446 | if (e.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) { |
| | 447 | System.out.println(tr("Server replied with response code 404, retrying with an individual request for each object.")); |
| | 448 | return singleGetIdPackage(type, pkg, progressMonitor); |
| | 449 | } else { |
| | 450 | throw e; |
| | 451 | } |
| | 452 | } |
| | 453 | } |
| | 454 | |
| | 455 | /** |
| | 456 | * invokes a Multi Get for a set of ids and a given {@link OsmPrimitiveType}. |
| | 457 | * The retrieved primitives are merged to {@link #outputDataSet}. |
| | 458 | * |
| | 459 | * @param type the type |
| | 460 | * @param pkg the package of ids |
| | 461 | * @exception OsmTransferException thrown if an error occurs while communicating with the API server |
| | 462 | * |
| | 463 | */ |
| | 464 | protected FetchResult multiGetIdPackage(OsmPrimitiveType type, Set<Long> pkg, ProgressMonitor progressMonitor) throws OsmTransferException { |
| | 465 | String request = buildRequestString(type, pkg); |
| | 466 | final InputStream in = getInputStream(request, NullProgressMonitor.INSTANCE); |
| | 467 | if (in == null) return null; |
| | 468 | progressMonitor.subTask(tr("Downloading OSM data...")); |
| | 469 | try { |
| | 470 | return new FetchResult(OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(pkg.size(), false)), null); |
| | 471 | } catch (Exception e) { |
| | 472 | throw new OsmTransferException(e); |
| | 473 | } |
| | 474 | } |
| | 475 | |
| | 476 | /** |
| | 477 | * invokes a Multi Get for a single id and a given {@link OsmPrimitiveType}. |
| | 478 | * The retrieved primitive is merged to {@link #outputDataSet}. |
| | 479 | * |
| | 480 | * @param type the type |
| | 481 | * @param id the id |
| | 482 | * @exception OsmTransferException thrown if an error occurs while communicating with the API server |
| | 483 | * |
| | 484 | */ |
| | 485 | protected DataSet singleGetId(OsmPrimitiveType type, long id, ProgressMonitor progressMonitor) throws OsmTransferException { |
| | 486 | String request = buildRequestString(type, id); |
| | 487 | final InputStream in = getInputStream(request, NullProgressMonitor.INSTANCE); |
| | 488 | if (in == null) return null; |
| | 489 | progressMonitor.subTask(tr("Downloading OSM data...")); |
| | 490 | try { |
| | 491 | return OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false)); |
| | 492 | } catch (Exception e) { |
| | 493 | throw new OsmTransferException(e); |
| | 494 | } |
| | 495 | } |
| | 496 | |
| | 497 | /** |
| | 498 | * invokes a sequence of Multi Gets for individual ids in a set of ids and a given {@link OsmPrimitiveType}. |
| | 499 | * The retrieved primitives are merged to {@link #outputDataSet}. |
| | 500 | * |
| | 501 | * This method is used if one of the ids in pkg doesn't exist (the server replies with return code 404). |
| | 502 | * If the set is fetched with this method it is possible to find out which of the ids doesn't exist. |
| | 503 | * Unfortunatelly, the server does not provide an error header or an error body for a 404 reply. |
| | 504 | * |
| | 505 | * @param type the type |
| | 506 | * @param pkg the set of ids |
| | 507 | * @return |
| | 508 | * @exception OsmTransferException thrown if an error occurs while communicating with the API server |
| | 509 | * |
| | 510 | */ |
| | 511 | protected FetchResult singleGetIdPackage(OsmPrimitiveType type, Set<Long> pkg, ProgressMonitor progressMonitor) throws OsmTransferException { |
| | 512 | FetchResult result = new FetchResult(new DataSet(), new HashSet<PrimitiveId>()); |
| | 513 | String baseUrl = OsmApi.getOsmApi().getBaseUrl(); |
| | 514 | for (long id : pkg) { |
| | 515 | try { |
| | 516 | String msg = ""; |
| | 517 | switch (type) { |
| | 518 | case NODE: msg = tr("Fetching node with id {0} from ''{1}''", id, baseUrl); break; |
| | 519 | case WAY: msg = tr("Fetching way with id {0} from ''{1}''", id, baseUrl); break; |
| | 520 | case RELATION: msg = tr("Fetching relation with id {0} from ''{1}''", id, baseUrl); break; |
| | 521 | } |
| | 522 | progressMonitor.setCustomText(msg); |
| | 523 | result.dataSet.mergeFrom(singleGetId(type, id, progressMonitor)); |
| | 524 | } catch (OsmApiException e) { |
| | 525 | if (e.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) { |
| | 526 | System.out.println(tr("Server replied with response code 404 for id {0}. Skipping.", Long.toString(id))); |
| | 527 | result.missingPrimitives.add(new SimplePrimitiveId(id, type)); |
| | 528 | } else { |
| | 529 | throw e; |
| | 530 | } |
| | 531 | } |
| | 532 | } |
| | 533 | return result; |
| | 534 | } |
| | 535 | } |