From df8a97307929538195ab1431cd987b8d27759cbf Mon Sep 17 00:00:00 2001 From: savsch Date: Mon, 23 Dec 2024 18:46:24 +0530 Subject: [PATCH] Add query syntax and methods --- .../nrw/commons/mwapi/OkHttpJsonApiClient.kt | 69 +++++++++++++++++++ .../nrw/commons/nearby/NearbyController.java | 5 +- .../free/nrw/commons/nearby/NearbyPlaces.java | 16 ++++- .../queries/radius_query_for_item_count.rq | 9 +++ .../queries/rectangle_query_for_item_count.rq | 9 +++ 5 files changed, 103 insertions(+), 5 deletions(-) create mode 100644 app/src/main/resources/queries/radius_query_for_item_count.rq create mode 100644 app/src/main/resources/queries/rectangle_query_for_item_count.rq diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.kt b/app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.kt index 415d31671..d0138fb95 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.kt +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.kt @@ -2,6 +2,7 @@ package fr.free.nrw.commons.mwapi import android.text.TextUtils import com.google.gson.Gson +import com.google.gson.JsonParser import fr.free.nrw.commons.BuildConfig import fr.free.nrw.commons.campaigns.CampaignResponseDTO import fr.free.nrw.commons.explore.depictions.DepictsClient @@ -330,6 +331,74 @@ class OkHttpJsonApiClient @Inject constructor( throw Exception(response.message) } + @Throws(Exception::class) + fun getNearbyItemCount( + screenTopRight: LatLng, screenBottomLeft: LatLng + ): Int { + val wikidataQuery: String = + FileUtils.readFromResource("/queries/rectangle_query_for_item_count.rq") + + val westCornerLat = screenTopRight.latitude + val westCornerLong = screenTopRight.longitude + val eastCornerLat = screenBottomLeft.latitude + val eastCornerLong = screenBottomLeft.longitude + + val query = wikidataQuery + .replace("\${LAT_WEST}", String.format(Locale.ROOT, "%.4f", westCornerLat)) + .replace("\${LONG_WEST}", String.format(Locale.ROOT, "%.4f", westCornerLong)) + .replace("\${LAT_EAST}", String.format(Locale.ROOT, "%.4f", eastCornerLat)) + .replace("\${LONG_EAST}", String.format(Locale.ROOT, "%.4f", eastCornerLong)) + + val urlBuilder: HttpUrl.Builder = sparqlQueryUrl.toHttpUrlOrNull()!! + .newBuilder() + .addQueryParameter("query", query) + .addQueryParameter("format", "json") + + val request: Request = Request.Builder() + .url(urlBuilder.build()) + .build() + + val response = okHttpClient.newCall(request).execute() + if (response.body != null && response.isSuccessful) { + val json = response.body!!.string() + return JsonParser.parseString(json).getAsJsonObject().getAsJsonObject("results") + .getAsJsonArray("bindings").get(0).getAsJsonObject().getAsJsonObject("count") + .get("value").asInt + } + throw Exception(response.message) + } + + @Throws(Exception::class) + fun getNearbyItemCount( + center: LatLng, radius: Double + ): Int { + val wikidataQuery: String = + FileUtils.readFromResource("/queries/radius_query_for_item_count.rq") + + val query = wikidataQuery + .replace("\${LAT}", String.format(Locale.ROOT, "%.4f", center.latitude)) + .replace("\${LONG}", String.format(Locale.ROOT, "%.4f", center.longitude)) + .replace("\${RAD}", String.format(Locale.ROOT, "%.2f", radius)) + + val urlBuilder: HttpUrl.Builder = sparqlQueryUrl.toHttpUrlOrNull()!! + .newBuilder() + .addQueryParameter("query", query) + .addQueryParameter("format", "json") + + val request: Request = Request.Builder() + .url(urlBuilder.build()) + .build() + + val response = okHttpClient.newCall(request).execute() + if (response.body != null && response.isSuccessful) { + val json = response.body!!.string() + return JsonParser.parseString(json).getAsJsonObject().getAsJsonObject("results") + .getAsJsonArray("bindings").get(0).getAsJsonObject().getAsJsonObject("count") + .get("value").asInt + } + throw Exception(response.message) + } + @Throws(Exception::class) fun getNearbyPlaces( screenTopRight: LatLng, diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java index cc2442db6..403813519 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java @@ -196,8 +196,9 @@ public class NearbyController extends MapController { return null; } - List places = nearbyPlaces.getFromWikidataQuery(screenTopRight, screenBottomLeft, - Locale.getDefault().getLanguage(), shouldQueryForMonuments, customQuery); + List places = nearbyPlaces.getFromWikidataQuery(currentLatLng, screenTopRight, + screenBottomLeft, Locale.getDefault().getLanguage(), shouldQueryForMonuments, + customQuery); if (null != places && places.size() > 0) { LatLng[] boundaryCoordinates = { diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyPlaces.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyPlaces.java index 46f0a2a9e..3dd73b672 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyPlaces.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyPlaces.java @@ -101,6 +101,7 @@ public class NearbyPlaces { * Retrieves a list of places from a Wikidata query based on screen coordinates and optional * parameters. * + * @param centerPoint The center of the map, used for radius queries if required. * @param screenTopRight The top right corner of the screen (latitude, longitude). * @param screenBottomLeft The bottom left corner of the screen (latitude, longitude). * @param lang The language for the query. @@ -111,13 +112,22 @@ public class NearbyPlaces { * @throws Exception If an error occurs during the retrieval process. */ public List getFromWikidataQuery( + final fr.free.nrw.commons.location.LatLng centerPoint, final fr.free.nrw.commons.location.LatLng screenTopRight, final fr.free.nrw.commons.location.LatLng screenBottomLeft, final String lang, final boolean shouldQueryForMonuments, @Nullable final String customQuery) throws Exception { - return okHttpJsonApiClient - .getNearbyPlaces(screenTopRight, screenBottomLeft, lang, shouldQueryForMonuments, - customQuery); + if (customQuery != null){ + return okHttpJsonApiClient + .getNearbyPlaces(screenTopRight, screenBottomLeft, lang, shouldQueryForMonuments, + customQuery); + } + final double east = screenTopRight.getLongitude(); + final double west = screenBottomLeft.getLongitude(); + final double north = screenTopRight.getLatitude(); + final double south = screenBottomLeft.getLatitude(); + + return new java.util.ArrayList(); // TODO replace with actual method call } /** diff --git a/app/src/main/resources/queries/radius_query_for_item_count.rq b/app/src/main/resources/queries/radius_query_for_item_count.rq new file mode 100644 index 000000000..427b72795 --- /dev/null +++ b/app/src/main/resources/queries/radius_query_for_item_count.rq @@ -0,0 +1,9 @@ +SELECT (COUNT(?item) AS ?itemCount) +WHERE { + # Around given location. + SERVICE wikibase:around { + ?item wdt:P625 ?location. + bd:serviceParam wikibase:center "Point(${LONG} ${LAT})"^^geo:wktLiteral. + bd:serviceParam wikibase:radius "${RAD}" . # Radius in kilometers. + } +} \ No newline at end of file diff --git a/app/src/main/resources/queries/rectangle_query_for_item_count.rq b/app/src/main/resources/queries/rectangle_query_for_item_count.rq new file mode 100644 index 000000000..c7ff15f65 --- /dev/null +++ b/app/src/main/resources/queries/rectangle_query_for_item_count.rq @@ -0,0 +1,9 @@ +SELECT (COUNT(DISTINCT ?item) AS ?count) +WHERE { + SERVICE wikibase:box { + ?item wdt:P625 ?location. + bd:serviceParam wikibase:cornerWest "Point(${LONG_WEST} ${LAT_WEST})"^^geo:wktLiteral. + bd:serviceParam wikibase:cornerEast "Point(${LONG_EAST} ${LAT_EAST})"^^geo:wktLiteral. + } +} +&format=json \ No newline at end of file