|
11 | 11 | import fr.free.nrw.commons.explore.depictions.DepictsClient;
|
12 | 12 | import fr.free.nrw.commons.___location.LatLng;
|
13 | 13 | import fr.free.nrw.commons.nearby.Place;
|
| 14 | +import fr.free.nrw.commons.nearby.model.PlaceBindings; |
| 15 | +import fr.free.nrw.commons.nearby.model.ItemsClass; |
14 | 16 | import fr.free.nrw.commons.nearby.model.NearbyResponse;
|
15 | 17 | import fr.free.nrw.commons.nearby.model.NearbyResultItem;
|
16 | 18 | import fr.free.nrw.commons.profile.achievements.FeaturedImages;
|
|
27 | 29 | import java.util.ArrayList;
|
28 | 30 | import java.util.List;
|
29 | 31 | import java.util.Locale;
|
| 32 | +import java.util.regex.Matcher; |
| 33 | +import java.util.regex.Pattern; |
30 | 34 | import javax.inject.Inject;
|
31 | 35 | import javax.inject.Singleton;
|
32 | 36 | import okhttp3.HttpUrl;
|
@@ -393,6 +397,196 @@ public List<Place> getNearbyPlaces(
|
393 | 397 | throw new Exception(response.message());
|
394 | 398 | }
|
395 | 399 |
|
| 400 | + /** |
| 401 | + * Make API Call to get Places |
| 402 | + * |
| 403 | + * @param leftLatLng Left lat long |
| 404 | + * @param rightLatLng Right lat long |
| 405 | + * @return |
| 406 | + * @throws Exception |
| 407 | + */ |
| 408 | + @Nullable |
| 409 | + public String getPlacesAsKML(final LatLng leftLatLng, final LatLng rightLatLng) |
| 410 | + throws Exception { |
| 411 | + String kmlString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" + |
| 412 | + "<!--Created by wikidata-missing-pictures-offline -->\n" + |
| 413 | + "<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n" + |
| 414 | + " <Document>"; |
| 415 | + |
| 416 | + int increment = 1; |
| 417 | + double longitude = leftLatLng.getLongitude(); |
| 418 | + |
| 419 | + while (longitude <= rightLatLng.getLongitude()) { |
| 420 | + double NEXT_LONGITUDE = |
| 421 | + (increment + longitude) >= 0.0 && (increment + longitude) <= 1.0 ? 0.0 |
| 422 | + : increment + longitude; |
| 423 | + |
| 424 | + double latitude = leftLatLng.getLatitude(); |
| 425 | + |
| 426 | + while (latitude <= rightLatLng.getLatitude()) { |
| 427 | + double NEXT_LATITUDE = |
| 428 | + (increment + latitude) >= 0.0 && (increment + latitude) <= 1.0 ? 0.0 |
| 429 | + : increment + latitude; |
| 430 | + List<PlaceBindings> placeBindings = runQuery(new LatLng(latitude, longitude, 0), |
| 431 | + new LatLng(NEXT_LATITUDE, NEXT_LONGITUDE, 0)); |
| 432 | + if (placeBindings != null) { |
| 433 | + for (PlaceBindings item : placeBindings) { |
| 434 | + if (item.getItem() != null && item.getLabel() != null && item.getClas() != null) { |
| 435 | + String input = item.getLocation().getValue(); |
| 436 | + Pattern pattern = Pattern.compile( |
| 437 | + "Point\\(([-+]?[0-9]*\\.?[0-9]+) ([-+]?[0-9]*\\.?[0-9]+)\\)"); |
| 438 | + Matcher matcher = pattern.matcher(input); |
| 439 | + |
| 440 | + if (matcher.find()) { |
| 441 | + String longStr = matcher.group(1); |
| 442 | + String latStr = matcher.group(2); |
| 443 | + String itemUrl = item.getItem().getValue(); |
| 444 | + String itemName = item.getLabel().getValue().replace("&", "&"); |
| 445 | + String itemLatitude = latStr; |
| 446 | + String itemLongitude = longStr; |
| 447 | + String itemClass = item.getClas().getValue(); |
| 448 | + |
| 449 | + String formattedItemName = |
| 450 | + !itemClass.isEmpty() ? itemName + " (" + itemClass + ")" |
| 451 | + : itemName; |
| 452 | + |
| 453 | + String kmlEntry = "\n <Placemark>\n" + |
| 454 | + " <name>" + formattedItemName + "</name>\n" + |
| 455 | + " <description>" + itemUrl + "</description>\n" + |
| 456 | + " <Point>\n" + |
| 457 | + " <coordinates>" + itemLongitude + "," |
| 458 | + + itemLatitude |
| 459 | + + "</coordinates>\n" + |
| 460 | + " </Point>\n" + |
| 461 | + " </Placemark>"; |
| 462 | + kmlString = kmlString + kmlEntry; |
| 463 | + } else { |
| 464 | + Timber.e("No match found"); |
| 465 | + } |
| 466 | + } |
| 467 | + } |
| 468 | + } |
| 469 | + latitude += increment; |
| 470 | + } |
| 471 | + longitude += increment; |
| 472 | + } |
| 473 | + kmlString = kmlString + "\n </Document>\n" + |
| 474 | + "</kml>\n"; |
| 475 | + return kmlString; |
| 476 | + } |
| 477 | + |
| 478 | + /** |
| 479 | + * Make API Call to get Places |
| 480 | + * |
| 481 | + * @param leftLatLng Left lat long |
| 482 | + * @param rightLatLng Right lat long |
| 483 | + * @return |
| 484 | + * @throws Exception |
| 485 | + */ |
| 486 | + @Nullable |
| 487 | + public String getPlacesAsGPX(final LatLng leftLatLng, final LatLng rightLatLng) |
| 488 | + throws Exception { |
| 489 | + String gpxString = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" + |
| 490 | + "<gpx\n" + |
| 491 | + " version=\"1.0\"\n" + |
| 492 | + " creator=\"ExpertGPS 1.1 - https://www.topografix.com\"\n" + |
| 493 | + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + |
| 494 | + " xmlns=\"http://www.topografix.com/GPX/1/0\"\n" + |
| 495 | + " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd\">" |
| 496 | + + "\n<bounds minlat=\"$MIN_LATITUDE\" minlon=\"$MIN_LONGITUDE\" maxlat=\"$MAX_LATITUDE\" maxlon=\"$MAX_LONGITUDE\"/>"; |
| 497 | + |
| 498 | + int increment = 1; |
| 499 | + double longitude = leftLatLng.getLongitude(); |
| 500 | + |
| 501 | + while (longitude <= rightLatLng.getLongitude()) { |
| 502 | + double NEXT_LONGITUDE = |
| 503 | + (increment + longitude) >= 0.0 && (increment + longitude) <= 1.0 ? 0.0 |
| 504 | + : increment + longitude; |
| 505 | + |
| 506 | + double latitude = leftLatLng.getLatitude(); |
| 507 | + |
| 508 | + while (latitude <= rightLatLng.getLatitude()) { |
| 509 | + double NEXT_LATITUDE = |
| 510 | + (increment + latitude) >= 0.0 && (increment + latitude) <= 1.0 ? 0.0 |
| 511 | + : increment + latitude; |
| 512 | + List<PlaceBindings> placeBindings = runQuery(new LatLng(latitude, longitude, 0), |
| 513 | + new LatLng(NEXT_LATITUDE, NEXT_LONGITUDE, 0)); |
| 514 | + if (placeBindings != null) { |
| 515 | + for (PlaceBindings item : placeBindings) { |
| 516 | + if (item.getItem() != null && item.getLabel() != null && item.getClas() != null) { |
| 517 | + String input = item.getLocation().getValue(); |
| 518 | + Pattern pattern = Pattern.compile( |
| 519 | + "Point\\(([-+]?[0-9]*\\.?[0-9]+) ([-+]?[0-9]*\\.?[0-9]+)\\)"); |
| 520 | + Matcher matcher = pattern.matcher(input); |
| 521 | + |
| 522 | + if (matcher.find()) { |
| 523 | + String longStr = matcher.group(1); |
| 524 | + String latStr = matcher.group(2); |
| 525 | + String itemUrl = item.getItem().getValue(); |
| 526 | + String itemName = item.getLabel().getValue().replace("&", "&"); |
| 527 | + String itemLatitude = latStr; |
| 528 | + String itemLongitude = longStr; |
| 529 | + String itemClass = item.getClas().getValue(); |
| 530 | + |
| 531 | + String formattedItemName = |
| 532 | + !itemClass.isEmpty() ? itemName + " (" + itemClass + ")" |
| 533 | + : itemName; |
| 534 | + |
| 535 | + String gpxEntry = |
| 536 | + "\n <wpt lat=\"" + itemLatitude + "\" lon=\"" + itemLongitude |
| 537 | + + "\">\n" + |
| 538 | + " <name>" + itemName + "</name>\n" + |
| 539 | + " <url>" + itemUrl + "</url>\n" + |
| 540 | + " </wpt>"; |
| 541 | + gpxString = gpxString + gpxEntry; |
| 542 | + |
| 543 | + } else { |
| 544 | + Timber.e("No match found"); |
| 545 | + } |
| 546 | + } |
| 547 | + } |
| 548 | + } |
| 549 | + latitude += increment; |
| 550 | + } |
| 551 | + longitude += increment; |
| 552 | + } |
| 553 | + gpxString = gpxString + "\n</gpx>"; |
| 554 | + return gpxString; |
| 555 | + } |
| 556 | + |
| 557 | + private List<PlaceBindings> runQuery(final LatLng currentLatLng, final LatLng nextLatLng) |
| 558 | + throws IOException { |
| 559 | + |
| 560 | + final String wikidataQuery = FileUtils.readFromResource("/queries/places_query.rq"); |
| 561 | + final String query = wikidataQuery |
| 562 | + .replace("${LONGITUDE}", |
| 563 | + String.format(Locale.ROOT, "%.2f", currentLatLng.getLongitude())) |
| 564 | + .replace("${LATITUDE}", String.format(Locale.ROOT, "%.4f", currentLatLng.getLatitude())) |
| 565 | + .replace("${NEXT_LONGITUDE}", |
| 566 | + String.format(Locale.ROOT, "%.4f", nextLatLng.getLongitude())) |
| 567 | + .replace("${NEXT_LATITUDE}", |
| 568 | + String.format(Locale.ROOT, "%.4f", nextLatLng.getLatitude())); |
| 569 | + |
| 570 | + final HttpUrl.Builder urlBuilder = HttpUrl |
| 571 | + .parse(sparqlQueryUrl) |
| 572 | + .newBuilder() |
| 573 | + .addQueryParameter("query", query) |
| 574 | + .addQueryParameter("format", "json"); |
| 575 | + |
| 576 | + final Request request = new Request.Builder() |
| 577 | + .url(urlBuilder.build()) |
| 578 | + .build(); |
| 579 | + |
| 580 | + final Response response = okHttpClient.newCall(request).execute(); |
| 581 | + if (response.body() != null && response.isSuccessful()) { |
| 582 | + final String json = response.body().string(); |
| 583 | + final ItemsClass item = gson.fromJson(json, ItemsClass.class); |
| 584 | + return item.getResults().getBindings(); |
| 585 | + } else { |
| 586 | + return null; |
| 587 | + } |
| 588 | + } |
| 589 | + |
396 | 590 | /**
|
397 | 591 | * Make API Call to get Nearby Places Implementation does not expects a custom query
|
398 | 592 | *
|
|
0 commit comments