Nearby: Added binary search for loading pins

This commit is contained in:
savsch 2024-12-23 20:39:22 +05:30
parent df8a973079
commit 8f108d269b
4 changed files with 45 additions and 11 deletions

View file

@ -362,7 +362,7 @@ class OkHttpJsonApiClient @Inject constructor(
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")
.getAsJsonArray("bindings").get(0).getAsJsonObject().getAsJsonObject("itemCount")
.get("value").asInt
}
throw Exception(response.message)
@ -370,7 +370,7 @@ class OkHttpJsonApiClient @Inject constructor(
@Throws(Exception::class)
fun getNearbyItemCount(
center: LatLng, radius: Double
center: LatLng, radius: Float
): Int {
val wikidataQuery: String =
FileUtils.readFromResource("/queries/radius_query_for_item_count.rq")
@ -393,7 +393,7 @@ class OkHttpJsonApiClient @Inject constructor(
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")
.getAsJsonArray("bindings").get(0).getAsJsonObject().getAsJsonObject("itemCount")
.get("value").asInt
}
throw Exception(response.message)

View file

@ -1,5 +1,6 @@
package fr.free.nrw.commons.nearby;
import android.location.Location;
import androidx.annotation.Nullable;
import java.io.IOException;
import java.util.Collections;
@ -122,12 +123,46 @@ public class NearbyPlaces {
.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<Place>(); // TODO replace with actual method call
final int lowerLimit = 1000, upperLimit=1500;
final float[] results = new float[1];
Location.distanceBetween(centerPoint.getLatitude(), screenTopRight.getLongitude(),
centerPoint.getLatitude(), screenBottomLeft.getLongitude(), results);
final float longGap = results[0]/1000f;
Location.distanceBetween(screenTopRight.getLatitude(), centerPoint.getLongitude(),
screenBottomLeft.getLatitude(), centerPoint.getLongitude(), results);
final float latGap = results[0]/1000f;
if (Math.max(longGap,latGap)<100f){
final int itemCount = okHttpJsonApiClient.getNearbyItemCount(screenTopRight,
screenBottomLeft);
if(itemCount<upperLimit) {
return okHttpJsonApiClient.getNearbyPlaces(screenTopRight, screenBottomLeft, lang,
shouldQueryForMonuments, null);
}
}
int minRadius = 0, maxRadius = Math.round(Math.min(100f, Math.min(longGap, latGap)))*100;
int targetRadius = maxRadius/2;
while (minRadius<maxRadius) {
targetRadius = minRadius + (maxRadius - minRadius + 1) / 2;
final int itemCount = okHttpJsonApiClient.getNearbyItemCount(centerPoint,
targetRadius / 100f);
if (itemCount >= lowerLimit && itemCount < upperLimit){
break;
}
if (targetRadius>maxRadius/2 && itemCount<lowerLimit/5) {
minRadius = targetRadius + (maxRadius - targetRadius + 1) / 2;
continue;
}
if (itemCount<upperLimit) {
minRadius = targetRadius;
} else {
maxRadius = targetRadius - 1;
}
}
return new java.util.ArrayList<Place>(); // TODO make actual query
}
/**

View file

@ -1,9 +1,8 @@
SELECT (COUNT(DISTINCT ?item) AS ?count)
SELECT (COUNT(?item) AS ?itemCount)
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
}