mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
Made Nearby show all pins that could be presented on the screen, rather than a circle (#5553)
* Changed nearby from circle to rectangle * Fixed bug * Removed MAPBOX Token * Fixed minor issues * Fixed minor issues * Changed query files * Changed monuments query file * Fixed Unit Tests * Fixed failing tests * Fixed errors due to merging
This commit is contained in:
parent
f404ac9b47
commit
724e4db0fd
15 changed files with 576 additions and 219 deletions
|
|
@ -90,12 +90,20 @@ public class ContributionsFragment
|
|||
MediaDetailProvider,
|
||||
SensorEventListener,
|
||||
ICampaignsView, ContributionsContract.View, Callback {
|
||||
@Inject @Named("default_preferences") JsonKvStore store;
|
||||
@Inject NearbyController nearbyController;
|
||||
@Inject OkHttpJsonApiClient okHttpJsonApiClient;
|
||||
@Inject CampaignsPresenter presenter;
|
||||
@Inject LocationServiceManager locationManager;
|
||||
@Inject NotificationController notificationController;
|
||||
|
||||
@Inject
|
||||
@Named("default_preferences")
|
||||
JsonKvStore store;
|
||||
@Inject
|
||||
NearbyController nearbyController;
|
||||
@Inject
|
||||
OkHttpJsonApiClient okHttpJsonApiClient;
|
||||
@Inject
|
||||
CampaignsPresenter presenter;
|
||||
@Inject
|
||||
LocationServiceManager locationManager;
|
||||
@Inject
|
||||
NotificationController notificationController;
|
||||
|
||||
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
|
||||
|
|
@ -129,7 +137,9 @@ public class ContributionsFragment
|
|||
private SensorManager mSensorManager;
|
||||
private Sensor mLight;
|
||||
private float direction;
|
||||
private ActivityResultLauncher<String[]> nearbyLocationPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
|
||||
private ActivityResultLauncher<String[]> nearbyLocationPermissionLauncher = registerForActivityResult(
|
||||
new ActivityResultContracts.RequestMultiplePermissions(),
|
||||
new ActivityResultCallback<Map<String, Boolean>>() {
|
||||
@Override
|
||||
public void onActivityResult(Map<String, Boolean> result) {
|
||||
boolean areAllGranted = true;
|
||||
|
|
@ -175,7 +185,8 @@ public class ContributionsFragment
|
|||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
|
||||
binding = FragmentContributionsBinding.inflate(inflater, container, false);
|
||||
|
||||
|
|
@ -192,6 +203,7 @@ public class ContributionsFragment
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
mediaDetailPagerFragment = (MediaDetailPagerFragment) getChildFragmentManager()
|
||||
.findFragmentByTag(MEDIA_DETAIL_PAGER_FRAGMENT_TAG);
|
||||
|
|
@ -234,10 +246,13 @@ public class ContributionsFragment
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(@NonNull final Menu menu, @NonNull final MenuInflater inflater) {
|
||||
public void onCreateOptionsMenu(@NonNull final Menu menu,
|
||||
@NonNull final MenuInflater inflater) {
|
||||
|
||||
// Removing contributions menu items for ProfileActivity
|
||||
if (getActivity() instanceof ProfileActivity) { return; }
|
||||
if (getActivity() instanceof ProfileActivity) {
|
||||
return;
|
||||
}
|
||||
|
||||
inflater.inflate(R.menu.contribution_activity_notification_menu, menu);
|
||||
|
||||
|
|
@ -329,13 +344,15 @@ public class ContributionsFragment
|
|||
binding.cardViewNearby.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
showFragment(contributionsListFragment, CONTRIBUTION_LIST_FRAGMENT_TAG, mediaDetailPagerFragment);
|
||||
showFragment(contributionsListFragment, CONTRIBUTION_LIST_FRAGMENT_TAG,
|
||||
mediaDetailPagerFragment);
|
||||
}
|
||||
|
||||
private void showMediaDetailPagerFragment() {
|
||||
// hide nearby card view on media detail is visible
|
||||
setupViewForMediaDetails();
|
||||
showFragment(mediaDetailPagerFragment, MEDIA_DETAIL_PAGER_FRAGMENT_TAG, contributionsListFragment);
|
||||
showFragment(mediaDetailPagerFragment, MEDIA_DETAIL_PAGER_FRAGMENT_TAG,
|
||||
contributionsListFragment);
|
||||
}
|
||||
|
||||
private void setupViewForMediaDetails() {
|
||||
|
|
@ -363,7 +380,8 @@ public class ContributionsFragment
|
|||
showContributionsListFragment();
|
||||
}
|
||||
|
||||
showFragment(contributionsListFragment, CONTRIBUTION_LIST_FRAGMENT_TAG, mediaDetailPagerFragment);
|
||||
showFragment(contributionsListFragment, CONTRIBUTION_LIST_FRAGMENT_TAG,
|
||||
mediaDetailPagerFragment);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -517,7 +535,8 @@ public class ContributionsFragment
|
|||
}
|
||||
|
||||
private void displayYouWontSeeNearbyMessage() {
|
||||
ViewUtil.showLongToast(getActivity(), getResources().getString(R.string.unable_to_display_nearest_place));
|
||||
ViewUtil.showLongToast(getActivity(),
|
||||
getResources().getString(R.string.unable_to_display_nearest_place));
|
||||
store.putBoolean("doNotAskForLocationPermission", true);
|
||||
}
|
||||
|
||||
|
|
@ -525,7 +544,8 @@ public class ContributionsFragment
|
|||
private void updateClosestNearbyCardViewInfo() {
|
||||
curLatLng = locationManager.getLastLocation();
|
||||
compositeDisposable.add(Observable.fromCallable(() -> nearbyController
|
||||
.loadAttractionsFromLocation(curLatLng, curLatLng, true, false, false)) // thanks to boolean, it will only return closest result
|
||||
.loadAttractionsFromLocation(curLatLng, curLatLng, true,
|
||||
false)) // thanks to boolean, it will only return closest result
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(this::updateNearbyNotification,
|
||||
|
|
@ -535,8 +555,10 @@ public class ContributionsFragment
|
|||
}));
|
||||
}
|
||||
|
||||
private void updateNearbyNotification(@Nullable NearbyController.NearbyPlacesInfo nearbyPlacesInfo) {
|
||||
if (nearbyPlacesInfo != null && nearbyPlacesInfo.placeList != null && nearbyPlacesInfo.placeList.size() > 0) {
|
||||
private void updateNearbyNotification(
|
||||
@Nullable NearbyController.NearbyPlacesInfo nearbyPlacesInfo) {
|
||||
if (nearbyPlacesInfo != null && nearbyPlacesInfo.placeList != null
|
||||
&& nearbyPlacesInfo.placeList.size() > 0) {
|
||||
Place closestNearbyPlace = null;
|
||||
// Find the first nearby place that has no image and exists
|
||||
for (Place place : nearbyPlacesInfo.placeList) {
|
||||
|
|
@ -601,7 +623,8 @@ public class ContributionsFragment
|
|||
updateClosestNearbyCardViewInfo();
|
||||
}
|
||||
|
||||
@Override public void onViewCreated(@NonNull View view,
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
}
|
||||
|
|
@ -626,11 +649,13 @@ public class ContributionsFragment
|
|||
}
|
||||
}
|
||||
|
||||
@Override public void showMessage(String message) {
|
||||
@Override
|
||||
public void showMessage(String message) {
|
||||
Toast.makeText(getContext(), message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override public void showCampaigns(Campaign campaign) {
|
||||
@Override
|
||||
public void showCampaigns(Campaign campaign) {
|
||||
if (campaign != null && !isUserProfile) {
|
||||
if (binding!=null) {
|
||||
binding.campaignsView.setCampaign(campaign);
|
||||
|
|
@ -638,7 +663,8 @@ public class ContributionsFragment
|
|||
}
|
||||
}
|
||||
|
||||
@Override public void onDestroyView() {
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
presenter.onDetachView();
|
||||
}
|
||||
|
|
@ -652,6 +678,7 @@ public class ContributionsFragment
|
|||
|
||||
/**
|
||||
* Restarts the upload process for a contribution
|
||||
*
|
||||
* @param contribution
|
||||
*/
|
||||
public void restartUpload(Contribution contribution) {
|
||||
|
|
@ -659,6 +686,7 @@ public class ContributionsFragment
|
|||
contributionsPresenter.saveContribution(contribution);
|
||||
Timber.d("Restarting for %s", contribution.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retry upload when it is failed
|
||||
*
|
||||
|
|
@ -667,7 +695,8 @@ public class ContributionsFragment
|
|||
@Override
|
||||
public void retryUpload(Contribution contribution) {
|
||||
if (NetworkUtils.isInternetConnectionEstablished(getContext())) {
|
||||
if (contribution.getState() == STATE_PAUSED || contribution.getState()==Contribution.STATE_QUEUED_LIMITED_CONNECTION_MODE) {
|
||||
if (contribution.getState() == STATE_PAUSED
|
||||
|| contribution.getState() == Contribution.STATE_QUEUED_LIMITED_CONNECTION_MODE) {
|
||||
restartUpload(contribution);
|
||||
} else if (contribution.getState() == STATE_FAILED) {
|
||||
int retries = contribution.getRetries();
|
||||
|
|
@ -677,7 +706,8 @@ public class ContributionsFragment
|
|||
will never be successful */
|
||||
if (retries < MAX_RETRIES) {
|
||||
contribution.setRetries(retries + 1);
|
||||
Timber.d("Retried uploading %s %d times", contribution.getMedia().getFilename(), retries + 1);
|
||||
Timber.d("Retried uploading %s %d times", contribution.getMedia().getFilename(),
|
||||
retries + 1);
|
||||
restartUpload(contribution);
|
||||
} else {
|
||||
// TODO: Show the exact reason for failure
|
||||
|
|
@ -695,6 +725,7 @@ public class ContributionsFragment
|
|||
|
||||
/**
|
||||
* Pauses the upload
|
||||
*
|
||||
* @param contribution
|
||||
*/
|
||||
@Override
|
||||
|
|
@ -718,8 +749,8 @@ public class ContributionsFragment
|
|||
|
||||
/**
|
||||
* Replace whatever is in the current contributionsFragmentContainer view with
|
||||
* mediaDetailPagerFragment, and preserve previous state in back stack. Called when user selects a
|
||||
* contribution.
|
||||
* mediaDetailPagerFragment, and preserve previous state in back stack. Called when user selects
|
||||
* a contribution.
|
||||
*/
|
||||
@Override
|
||||
public void showDetail(int position, boolean isWikipediaButtonDisplayed) {
|
||||
|
|
@ -758,7 +789,8 @@ public class ContributionsFragment
|
|||
binding.cardViewNearby.setVisibility(View.GONE);
|
||||
}
|
||||
removeFragment(mediaDetailPagerFragment);
|
||||
showFragment(contributionsListFragment, CONTRIBUTION_LIST_FRAGMENT_TAG, mediaDetailPagerFragment);
|
||||
showFragment(contributionsListFragment, CONTRIBUTION_LIST_FRAGMENT_TAG,
|
||||
mediaDetailPagerFragment);
|
||||
if (isUserProfile) {
|
||||
// Fragment is associated with ProfileActivity
|
||||
// Enable ParentViewPager Scroll
|
||||
|
|
@ -768,7 +800,8 @@ public class ContributionsFragment
|
|||
}
|
||||
if (getActivity() instanceof MainActivity) {
|
||||
// Fragment is associated with MainActivity
|
||||
((BaseActivity) getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
||||
((BaseActivity) getActivity()).getSupportActionBar()
|
||||
.setDisplayHomeAsUpEnabled(false);
|
||||
((MainActivity) getActivity()).showTabs();
|
||||
}
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -272,13 +272,12 @@ public class OkHttpJsonApiClient {
|
|||
* @param cur Search lat long
|
||||
* @param language Language
|
||||
* @param radius Search Radius
|
||||
* @param shouldQueryForMonuments : Should we query for monuments
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Nullable
|
||||
public List<Place> getNearbyPlaces(final LatLng cur, final String language, final double radius,
|
||||
final boolean shouldQueryForMonuments, final String customQuery)
|
||||
final String customQuery)
|
||||
throws Exception {
|
||||
|
||||
Timber.d("Fetching nearby items at radius %s", radius);
|
||||
|
|
@ -286,10 +285,9 @@ public class OkHttpJsonApiClient {
|
|||
final String wikidataQuery;
|
||||
if (customQuery != null) {
|
||||
wikidataQuery = customQuery;
|
||||
} else if (!shouldQueryForMonuments) {
|
||||
wikidataQuery = FileUtils.readFromResource("/queries/nearby_query.rq");
|
||||
} else {
|
||||
wikidataQuery = FileUtils.readFromResource("/queries/nearby_query_monuments.rq");
|
||||
wikidataQuery = FileUtils.readFromResource(
|
||||
"/queries/radius_query_for_upload_wizard.rq");
|
||||
}
|
||||
final String query = wikidataQuery
|
||||
.replace("${RAD}", String.format(Locale.ROOT, "%.2f", radius))
|
||||
|
|
@ -307,6 +305,74 @@ public class OkHttpJsonApiClient {
|
|||
.url(urlBuilder.build())
|
||||
.build();
|
||||
|
||||
final Response response = okHttpClient.newCall(request).execute();
|
||||
if (response.body() != null && response.isSuccessful()) {
|
||||
final String json = response.body().string();
|
||||
final NearbyResponse nearbyResponse = gson.fromJson(json, NearbyResponse.class);
|
||||
final List<NearbyResultItem> bindings = nearbyResponse.getResults().getBindings();
|
||||
final List<Place> places = new ArrayList<>();
|
||||
for (final NearbyResultItem item : bindings) {
|
||||
final Place placeFromNearbyItem = Place.from(item);
|
||||
placeFromNearbyItem.setMonument(false);
|
||||
places.add(placeFromNearbyItem);
|
||||
}
|
||||
return places;
|
||||
}
|
||||
throw new Exception(response.message());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves nearby places based on screen coordinates and optional query parameters.
|
||||
*
|
||||
* @param screenTopRight The top right corner of the screen (latitude, longitude).
|
||||
* @param screenBottomLeft The bottom left corner of the screen (latitude, longitude).
|
||||
* @param language The language for the query.
|
||||
* @param shouldQueryForMonuments Flag indicating whether to include monuments in the query.
|
||||
* @param customQuery Optional custom SPARQL query to use instead of default
|
||||
* queries.
|
||||
* @return A list of nearby places.
|
||||
* @throws Exception If an error occurs during the retrieval process.
|
||||
*/
|
||||
@Nullable
|
||||
public List<Place> getNearbyPlaces(
|
||||
final fr.free.nrw.commons.location.LatLng screenTopRight,
|
||||
final fr.free.nrw.commons.location.LatLng screenBottomLeft, final String language,
|
||||
final boolean shouldQueryForMonuments, final String customQuery)
|
||||
throws Exception {
|
||||
|
||||
Timber.d("CUSTOM_SPARQL%s", String.valueOf(customQuery != null));
|
||||
|
||||
final String wikidataQuery;
|
||||
if (customQuery != null) {
|
||||
wikidataQuery = customQuery;
|
||||
} else if (!shouldQueryForMonuments) {
|
||||
wikidataQuery = FileUtils.readFromResource("/queries/rectangle_query_for_nearby.rq");
|
||||
} else {
|
||||
wikidataQuery = FileUtils.readFromResource(
|
||||
"/queries/rectangle_query_for_nearby_monuments.rq");
|
||||
}
|
||||
|
||||
final double westCornerLat = screenTopRight.getLatitude();
|
||||
final double westCornerLong = screenTopRight.getLongitude();
|
||||
final double eastCornerLat = screenBottomLeft.getLatitude();
|
||||
final double eastCornerLong = screenBottomLeft.getLongitude();
|
||||
|
||||
final String 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))
|
||||
.replace("${LANG}", language);
|
||||
final HttpUrl.Builder urlBuilder = HttpUrl
|
||||
.parse(sparqlQueryUrl)
|
||||
.newBuilder()
|
||||
.addQueryParameter("query", query)
|
||||
.addQueryParameter("format", "json");
|
||||
|
||||
final Request request = new Request.Builder()
|
||||
.url(urlBuilder.build())
|
||||
.build();
|
||||
|
||||
final Response response = okHttpClient.newCall(request).execute();
|
||||
if (response.body() != null && response.isSuccessful()) {
|
||||
final String json = response.body().string();
|
||||
|
|
@ -333,15 +399,13 @@ public class OkHttpJsonApiClient {
|
|||
* @param cur Search lat long
|
||||
* @param language Language
|
||||
* @param radius Search Radius
|
||||
* @param shouldQueryForMonuments : Should we query for monuments
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@Nullable
|
||||
public List<Place> getNearbyPlaces(final LatLng cur, final String language, final double radius,
|
||||
final boolean shouldQueryForMonuments)
|
||||
public List<Place> getNearbyPlaces(final LatLng cur, final String language, final double radius)
|
||||
throws Exception {
|
||||
return getNearbyPlaces(cur, language, radius, shouldQueryForMonuments, null);
|
||||
return getNearbyPlaces(cur, language, radius, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -43,31 +43,31 @@ public class NearbyController extends MapController {
|
|||
* @param searchLatLng the location user wants to search around
|
||||
* @param returnClosestResult if this search is done to find closest result or all results
|
||||
* @param customQuery if this search is done via an advanced query
|
||||
* @return NearbyPlacesInfo a variable holds Place list without distance information
|
||||
* and boundary coordinates of current Place List
|
||||
* @return NearbyPlacesInfo a variable holds Place list without distance information and
|
||||
* boundary coordinates of current Place List
|
||||
*/
|
||||
public NearbyPlacesInfo loadAttractionsFromLocation(final LatLng curLatLng, final LatLng searchLatLng,
|
||||
public NearbyPlacesInfo loadAttractionsFromLocation(final LatLng curLatLng,
|
||||
final LatLng searchLatLng,
|
||||
final boolean returnClosestResult, final boolean checkingAroundCurrentLocation,
|
||||
final boolean shouldQueryForMonuments, @Nullable final String customQuery) throws Exception {
|
||||
@Nullable final String customQuery) throws Exception {
|
||||
|
||||
Timber.d("Loading attractions near %s", searchLatLng);
|
||||
NearbyPlacesInfo nearbyPlacesInfo = new NearbyPlacesInfo();
|
||||
|
||||
if (searchLatLng == null) {
|
||||
Timber.d("Loading attractions nearby, but curLatLng is null");
|
||||
return null;
|
||||
}
|
||||
List<Place> places = nearbyPlaces
|
||||
.radiusExpander(searchLatLng, Locale.getDefault().getLanguage(), returnClosestResult,
|
||||
shouldQueryForMonuments, customQuery);
|
||||
customQuery);
|
||||
|
||||
if (null != places && places.size() > 0) {
|
||||
LatLng[] boundaryCoordinates = {places.get(0).location, // south
|
||||
LatLng[] boundaryCoordinates = {
|
||||
places.get(0).location, // south
|
||||
places.get(0).location, // north
|
||||
places.get(0).location, // west
|
||||
places.get(0).location};// east, init with a random location
|
||||
|
||||
|
||||
if (curLatLng != null) {
|
||||
Timber.d("Sorting places by distance...");
|
||||
final Map<Place, Double> distances = new HashMap<>();
|
||||
|
|
@ -118,6 +118,98 @@ public class NearbyController extends MapController {
|
|||
return nearbyPlacesInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares Place list to make their distance information update later.
|
||||
*
|
||||
* @param curLatLng The current latitude and longitude.
|
||||
* @param screenTopRight The top right corner of the screen (latitude,
|
||||
* longitude).
|
||||
* @param screenBottomLeft The bottom left corner of the screen (latitude,
|
||||
* longitude).
|
||||
* @param searchLatLng The latitude and longitude of the search location.
|
||||
* @param returnClosestResult Flag indicating whether to return the closest result.
|
||||
* @param checkingAroundCurrentLocation Flag indicating whether to check around the current
|
||||
* location.
|
||||
* @param shouldQueryForMonuments Flag indicating whether to include monuments in the
|
||||
* query.
|
||||
* @param customQuery Optional custom SPARQL query to use instead of default
|
||||
* queries.
|
||||
* @return An object containing information about nearby places.
|
||||
* @throws Exception If an error occurs during the retrieval process.
|
||||
*/
|
||||
public NearbyPlacesInfo loadAttractionsFromLocation(final LatLng curLatLng,
|
||||
final fr.free.nrw.commons.location.LatLng screenTopRight,
|
||||
final fr.free.nrw.commons.location.LatLng screenBottomLeft, final LatLng searchLatLng,
|
||||
final boolean returnClosestResult, final boolean checkingAroundCurrentLocation,
|
||||
final boolean shouldQueryForMonuments, @Nullable final String customQuery)
|
||||
throws Exception {
|
||||
|
||||
Timber.d("Loading attractions near %s", searchLatLng);
|
||||
NearbyPlacesInfo nearbyPlacesInfo = new NearbyPlacesInfo();
|
||||
|
||||
if (searchLatLng == null) {
|
||||
Timber.d("Loading attractions nearby, but curLatLng is null");
|
||||
return null;
|
||||
}
|
||||
|
||||
List<Place> places = nearbyPlaces.getFromWikidataQuery(screenTopRight, screenBottomLeft,
|
||||
Locale.getDefault().getLanguage(), shouldQueryForMonuments, customQuery);
|
||||
|
||||
if (null != places && places.size() > 0) {
|
||||
LatLng[] boundaryCoordinates = {
|
||||
places.get(0).location, // south
|
||||
places.get(0).location, // north
|
||||
places.get(0).location, // west
|
||||
places.get(0).location};// east, init with a random location
|
||||
|
||||
if (curLatLng != null) {
|
||||
Timber.d("Sorting places by distance...");
|
||||
final Map<Place, Double> distances = new HashMap<>();
|
||||
for (Place place : places) {
|
||||
distances.put(place, computeDistanceBetween(place.location, curLatLng));
|
||||
// Find boundaries with basic find max approach
|
||||
if (place.location.getLatitude() < boundaryCoordinates[0].getLatitude()) {
|
||||
boundaryCoordinates[0] = place.location;
|
||||
}
|
||||
if (place.location.getLatitude() > boundaryCoordinates[1].getLatitude()) {
|
||||
boundaryCoordinates[1] = place.location;
|
||||
}
|
||||
if (place.location.getLongitude() < boundaryCoordinates[2].getLongitude()) {
|
||||
boundaryCoordinates[2] = place.location;
|
||||
}
|
||||
if (place.location.getLongitude() > boundaryCoordinates[3].getLongitude()) {
|
||||
boundaryCoordinates[3] = place.location;
|
||||
}
|
||||
}
|
||||
Collections.sort(places,
|
||||
(lhs, rhs) -> {
|
||||
double lhsDistance = distances.get(lhs);
|
||||
double rhsDistance = distances.get(rhs);
|
||||
return (int) (lhsDistance - rhsDistance);
|
||||
}
|
||||
);
|
||||
}
|
||||
nearbyPlacesInfo.curLatLng = curLatLng;
|
||||
nearbyPlacesInfo.searchLatLng = searchLatLng;
|
||||
nearbyPlacesInfo.placeList = places;
|
||||
nearbyPlacesInfo.boundaryCoordinates = boundaryCoordinates;
|
||||
|
||||
// Returning closes result means we use the controller for nearby card. So no need to set search this area flags
|
||||
if (!returnClosestResult) {
|
||||
// To remember latest search either around user or any point on map
|
||||
latestSearchLocation = searchLatLng;
|
||||
latestSearchRadius = nearbyPlaces.radius * 1000; // to meter
|
||||
|
||||
// Our radius searched around us, will be used to understand when user search their own location, we will follow them
|
||||
if (checkingAroundCurrentLocation) {
|
||||
currentLocationSearchRadius = nearbyPlaces.radius * 1000; // to meter
|
||||
currentLocation = curLatLng;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nearbyPlacesInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares Place list to make their distance information update later.
|
||||
*
|
||||
|
|
@ -129,10 +221,10 @@ public class NearbyController extends MapController {
|
|||
*/
|
||||
public NearbyPlacesInfo loadAttractionsFromLocation(final LatLng curLatLng,
|
||||
final LatLng searchLatLng,
|
||||
final boolean returnClosestResult, final boolean checkingAroundCurrentLocation,
|
||||
final boolean shouldQueryForMonuments) throws Exception {
|
||||
final boolean returnClosestResult, final boolean checkingAroundCurrentLocation)
|
||||
throws Exception {
|
||||
return loadAttractionsFromLocation(curLatLng, searchLatLng, returnClosestResult,
|
||||
checkingAroundCurrentLocation, shouldQueryForMonuments, null);
|
||||
checkingAroundCurrentLocation, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -171,12 +263,14 @@ public class NearbyController extends MapController {
|
|||
|
||||
/**
|
||||
* Updates makerLabelList item isBookmarked value
|
||||
*
|
||||
* @param place place which is bookmarked
|
||||
* @param isBookmarked true is bookmarked, false if bookmark removed
|
||||
*/
|
||||
@MainThread
|
||||
public static void updateMarkerLabelListBookmark(Place place, boolean isBookmarked) {
|
||||
for (ListIterator<MarkerPlaceGroup> iter = markerLabelList.listIterator(); iter.hasNext();) {
|
||||
for (ListIterator<MarkerPlaceGroup> iter = markerLabelList.listIterator();
|
||||
iter.hasNext(); ) {
|
||||
MarkerPlaceGroup markerPlaceGroup = iter.next();
|
||||
if (markerPlaceGroup.getPlace().getWikiDataEntityId().equals(place.getWikiDataEntityId())) {
|
||||
iter.set(new MarkerPlaceGroup(isBookmarked, place));
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ public class NearbyPlaces {
|
|||
/**
|
||||
* Reads Wikidata query to check nearby wikidata items which needs picture, with a circular
|
||||
* search. As a point is center of a circle with a radius will be set later.
|
||||
*
|
||||
* @param okHttpJsonApiClient
|
||||
*/
|
||||
@Inject
|
||||
|
|
@ -36,6 +37,7 @@ public class NearbyPlaces {
|
|||
|
||||
/**
|
||||
* Expands the radius as needed for the Wikidata query
|
||||
*
|
||||
* @param curLatLng coordinates of search location
|
||||
* @param lang user's language
|
||||
* @param returnClosestResult true if only the nearest point is desired
|
||||
|
|
@ -43,8 +45,7 @@ public class NearbyPlaces {
|
|||
* @return list of places obtained
|
||||
*/
|
||||
List<Place> radiusExpander(final LatLng curLatLng, final String lang,
|
||||
final boolean returnClosestResult
|
||||
, final boolean shouldQueryForMonuments, @Nullable final String customQuery) throws Exception {
|
||||
final boolean returnClosestResult, @Nullable final String customQuery) throws Exception {
|
||||
|
||||
final int minResults;
|
||||
final double maxRadius;
|
||||
|
|
@ -65,7 +66,7 @@ public class NearbyPlaces {
|
|||
|
||||
// Increase the radius gradually to find a satisfactory number of nearby places
|
||||
while (radius <= maxRadius) {
|
||||
places = getFromWikidataQuery(curLatLng, lang, radius, shouldQueryForMonuments, customQuery);
|
||||
places = getFromWikidataQuery(curLatLng, lang, radius, customQuery);
|
||||
Timber.d("%d results at radius: %f", places.size(), radius);
|
||||
if (places.size() >= minResults) {
|
||||
break;
|
||||
|
|
@ -81,18 +82,41 @@ public class NearbyPlaces {
|
|||
|
||||
/**
|
||||
* Runs the Wikidata query to populate the Places around search location
|
||||
*
|
||||
* @param cur coordinates of search location
|
||||
* @param lang user's language
|
||||
* @param radius radius for search, as determined by radiusExpander()
|
||||
* @param shouldQueryForMonuments should the query include properites for monuments
|
||||
* @param customQuery
|
||||
* @return list of places obtained
|
||||
* @throws IOException if query fails
|
||||
*/
|
||||
public List<Place> getFromWikidataQuery(final LatLng cur, final String lang,
|
||||
final double radius, final boolean shouldQueryForMonuments,
|
||||
final double radius,
|
||||
@Nullable final String customQuery) throws Exception {
|
||||
return okHttpJsonApiClient
|
||||
.getNearbyPlaces(cur, lang, radius, shouldQueryForMonuments, customQuery);
|
||||
.getNearbyPlaces(cur, lang, radius, customQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a list of places from a Wikidata query based on screen coordinates and optional
|
||||
* parameters.
|
||||
*
|
||||
* @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.
|
||||
* @param shouldQueryForMonuments Flag indicating whether to include monuments in the query.
|
||||
* @param customQuery Optional custom SPARQL query to use instead of default
|
||||
* queries.
|
||||
* @return A list of places obtained from the Wikidata query.
|
||||
* @throws Exception If an error occurs during the retrieval process.
|
||||
*/
|
||||
public List<Place> getFromWikidataQuery(
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,6 +116,7 @@ import javax.inject.Inject;
|
|||
import javax.inject.Named;
|
||||
import kotlin.Unit;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.osmdroid.api.IGeoPoint;
|
||||
import org.osmdroid.events.MapEventsReceiver;
|
||||
import org.osmdroid.events.MapListener;
|
||||
import org.osmdroid.events.ScrollEvent;
|
||||
|
|
@ -489,7 +490,7 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
final AdvanceQueryFragment fragment = new AdvanceQueryFragment();
|
||||
final Bundle bundle = new Bundle();
|
||||
try {
|
||||
bundle.putString("query", FileUtils.readFromResource("/queries/nearby_query.rq"));
|
||||
bundle.putString("query", FileUtils.readFromResource("/queries/radius_query_for_upload_wizard.rq"));
|
||||
} catch (IOException e) {
|
||||
Timber.e(e);
|
||||
}
|
||||
|
|
@ -1119,11 +1120,52 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
|
||||
@Override
|
||||
public void populatePlaces(final fr.free.nrw.commons.location.LatLng curlatLng) {
|
||||
if (curlatLng.equals(getLastMapFocus())) { // Means we are checking around current location
|
||||
populatePlacesForCurrentLocation(getLastMapFocus(), curlatLng, null);
|
||||
IGeoPoint screenTopRight = mapView.getProjection().fromPixels(mapView.getWidth(), 0);
|
||||
IGeoPoint screenBottomLeft = mapView.getProjection().fromPixels(0, mapView.getHeight());
|
||||
fr.free.nrw.commons.location.LatLng screenTopRightLatLng = new fr.free.nrw.commons.location.LatLng(
|
||||
screenBottomLeft.getLatitude(), screenBottomLeft.getLongitude(), 0);
|
||||
fr.free.nrw.commons.location.LatLng screenBottomLeftLatLng = new fr.free.nrw.commons.location.LatLng(
|
||||
screenTopRight.getLatitude(), screenTopRight.getLongitude(), 0);
|
||||
|
||||
// When the nearby fragment is opened immediately upon app launch, the {screenTopRightLatLng}
|
||||
// and {screenBottomLeftLatLng} variables return {LatLng(0.0,0.0)} as output.
|
||||
// To address this issue, A small delta value {delta = 0.02} is used to adjust the latitude
|
||||
// and longitude values for {ZOOM_LEVEL = 14f}.
|
||||
// This adjustment helps in calculating the east and west corner LatLng accurately.
|
||||
// Note: This only happens when the nearby fragment is opened immediately upon app launch,
|
||||
// otherwise {screenTopRightLatLng} and {screenBottomLeftLatLng} are used to determine
|
||||
// the east and west corner LatLng.
|
||||
if (screenTopRightLatLng.getLatitude() == 0.0 && screenTopRightLatLng.getLongitude() == 0.0
|
||||
&& screenBottomLeftLatLng.getLatitude() == 0.0
|
||||
&& screenBottomLeftLatLng.getLongitude() == 0.0) {
|
||||
final double delta = 0.02;
|
||||
final double westCornerLat = curlatLng.getLatitude() - delta;
|
||||
final double westCornerLong = curlatLng.getLongitude() - delta;
|
||||
final double eastCornerLat = curlatLng.getLatitude() + delta;
|
||||
final double eastCornerLong = curlatLng.getLongitude() + delta;
|
||||
screenTopRightLatLng = new fr.free.nrw.commons.location.LatLng(westCornerLat,
|
||||
westCornerLong, 0);
|
||||
screenBottomLeftLatLng = new fr.free.nrw.commons.location.LatLng(eastCornerLat,
|
||||
eastCornerLong, 0);
|
||||
if (curlatLng.equals(
|
||||
getLastMapFocus())) { // Means we are checking around current location
|
||||
populatePlacesForCurrentLocation(getLastMapFocus(), screenTopRightLatLng,
|
||||
screenBottomLeftLatLng, curlatLng, null);
|
||||
} else {
|
||||
populatePlacesForAnotherLocation(getLastMapFocus(), curlatLng, null);
|
||||
populatePlacesForAnotherLocation(getLastMapFocus(), screenTopRightLatLng,
|
||||
screenBottomLeftLatLng, curlatLng, null);
|
||||
}
|
||||
} else {
|
||||
if (curlatLng.equals(
|
||||
getLastMapFocus())) { // Means we are checking around current location
|
||||
populatePlacesForCurrentLocation(getLastMapFocus(), screenTopRightLatLng,
|
||||
screenBottomLeftLatLng, curlatLng, null);
|
||||
} else {
|
||||
populatePlacesForAnotherLocation(getLastMapFocus(), screenTopRightLatLng,
|
||||
screenBottomLeftLatLng, curlatLng, null);
|
||||
}
|
||||
}
|
||||
|
||||
if (recenterToUserLocation) {
|
||||
recenterToUserLocation = false;
|
||||
}
|
||||
|
|
@ -1136,12 +1178,20 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
populatePlaces(curlatLng);
|
||||
return;
|
||||
}
|
||||
IGeoPoint screenTopRight = mapView.getProjection().fromPixels(mapView.getWidth(), 0);
|
||||
IGeoPoint screenBottomLeft = mapView.getProjection().fromPixels(0, mapView.getHeight());
|
||||
fr.free.nrw.commons.location.LatLng screenTopRightLatLng = new fr.free.nrw.commons.location.LatLng(
|
||||
screenBottomLeft.getLatitude(), screenBottomLeft.getLongitude(), 0);
|
||||
fr.free.nrw.commons.location.LatLng screenBottomLeftLatLng = new fr.free.nrw.commons.location.LatLng(
|
||||
screenTopRight.getLatitude(), screenTopRight.getLongitude(), 0);
|
||||
|
||||
if (curlatLng.equals(lastFocusLocation) || lastFocusLocation == null
|
||||
|| recenterToUserLocation) { // Means we are checking around current location
|
||||
populatePlacesForCurrentLocation(lastKnownLocation, curlatLng, customQuery);
|
||||
populatePlacesForCurrentLocation(lastKnownLocation, screenTopRightLatLng,
|
||||
screenBottomLeftLatLng, curlatLng, customQuery);
|
||||
} else {
|
||||
populatePlacesForAnotherLocation(lastKnownLocation, curlatLng, customQuery);
|
||||
populatePlacesForAnotherLocation(lastKnownLocation, screenTopRightLatLng,
|
||||
screenBottomLeftLatLng, curlatLng, customQuery);
|
||||
}
|
||||
if (recenterToUserLocation) {
|
||||
recenterToUserLocation = false;
|
||||
|
|
@ -1150,11 +1200,14 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
|
||||
private void populatePlacesForCurrentLocation(
|
||||
final fr.free.nrw.commons.location.LatLng curlatLng,
|
||||
final fr.free.nrw.commons.location.LatLng screenTopRight,
|
||||
final fr.free.nrw.commons.location.LatLng screenBottomLeft,
|
||||
final fr.free.nrw.commons.location.LatLng searchLatLng,
|
||||
@Nullable final String customQuery) {
|
||||
final Observable<NearbyController.NearbyPlacesInfo> nearbyPlacesInfoObservable = Observable
|
||||
.fromCallable(() -> nearbyController
|
||||
.loadAttractionsFromLocation(curlatLng, searchLatLng,
|
||||
.loadAttractionsFromLocation(curlatLng, screenTopRight, screenBottomLeft,
|
||||
searchLatLng,
|
||||
false, true, Utils.isMonumentsEnabled(new Date()), customQuery));
|
||||
|
||||
compositeDisposable.add(nearbyPlacesInfoObservable
|
||||
|
|
@ -1182,11 +1235,14 @@ public class NearbyParentFragment extends CommonsDaggerSupportFragment
|
|||
|
||||
private void populatePlacesForAnotherLocation(
|
||||
final fr.free.nrw.commons.location.LatLng curlatLng,
|
||||
final fr.free.nrw.commons.location.LatLng screenTopRight,
|
||||
final fr.free.nrw.commons.location.LatLng screenBottomLeft,
|
||||
final fr.free.nrw.commons.location.LatLng searchLatLng,
|
||||
@Nullable final String customQuery) {
|
||||
final Observable<NearbyPlacesInfo> nearbyPlacesInfoObservable = Observable
|
||||
.fromCallable(() -> nearbyController
|
||||
.loadAttractionsFromLocation(curlatLng, searchLatLng,
|
||||
.loadAttractionsFromLocation(curlatLng, screenTopRight, screenBottomLeft,
|
||||
searchLatLng,
|
||||
false, true, Utils.isMonumentsEnabled(new Date()), customQuery));
|
||||
|
||||
compositeDisposable.add(nearbyPlacesInfoObservable
|
||||
|
|
|
|||
|
|
@ -345,6 +345,7 @@ public class UploadRepository {
|
|||
|
||||
/**
|
||||
* Returns nearest place matching the passed latitude and longitude
|
||||
*
|
||||
* @param decLatitude
|
||||
* @param decLongitude
|
||||
* @return
|
||||
|
|
@ -355,7 +356,7 @@ public class UploadRepository {
|
|||
final List<Place> fromWikidataQuery = nearbyPlaces.getFromWikidataQuery(new LatLng(
|
||||
decLatitude, decLongitude, 0.0f),
|
||||
Locale.getDefault().getLanguage(),
|
||||
NEARBY_RADIUS_IN_KILO_METERS, false, null);
|
||||
NEARBY_RADIUS_IN_KILO_METERS, null);
|
||||
return (fromWikidataQuery != null && fromWikidataQuery.size() > 0) ? fromWikidataQuery
|
||||
.get(0) : null;
|
||||
} catch (final Exception e) {
|
||||
|
|
|
|||
|
|
@ -49,8 +49,10 @@ class FileProcessor @Inject constructor(
|
|||
/**
|
||||
* Processes filePath coordinates, either from EXIF data or user location
|
||||
*/
|
||||
fun processFileCoordinates(similarImageInterface: SimilarImageInterface,
|
||||
filePath: String?, inAppPictureLocation: LatLng?)
|
||||
fun processFileCoordinates(
|
||||
similarImageInterface: SimilarImageInterface,
|
||||
filePath: String?, inAppPictureLocation: LatLng?
|
||||
)
|
||||
: ImageCoordinates {
|
||||
val exifInterface: ExifInterface? = try {
|
||||
ExifInterface(filePath!!)
|
||||
|
|
@ -207,8 +209,7 @@ class FileProcessor @Inject constructor(
|
|||
okHttpJsonApiClient.getNearbyPlaces(
|
||||
imageCoordinates.latLng,
|
||||
Locale.getDefault().language,
|
||||
it,
|
||||
false
|
||||
it
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ public class FileUtils {
|
|||
/**
|
||||
* Read and return the content of a resource filePath as string.
|
||||
*
|
||||
* @param fileName asset filePath's path (e.g. "/queries/nearby_query.rq")
|
||||
* @param fileName asset filePath's path (e.g. "/queries/radius_query_for_upload_wizard.rq")
|
||||
* @return the content of the filePath
|
||||
*/
|
||||
public static String readFromResource(String fileName) throws IOException {
|
||||
|
|
|
|||
56
app/src/main/resources/queries/rectangle_query_for_nearby.rq
Normal file
56
app/src/main/resources/queries/rectangle_query_for_nearby.rq
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
SELECT
|
||||
?item
|
||||
(SAMPLE(?location) as ?location)
|
||||
(SAMPLE(?label) AS ?label)
|
||||
(SAMPLE(?description) AS ?description)
|
||||
(SAMPLE(?class) AS ?class)
|
||||
(SAMPLE(?classLabel) AS ?classLabel)
|
||||
(SAMPLE(?pic) AS ?pic)
|
||||
(SAMPLE(?destroyed) AS ?destroyed)
|
||||
(SAMPLE(?endTime) AS ?endTime)
|
||||
(SAMPLE(?wikipediaArticle) AS ?wikipediaArticle)
|
||||
(SAMPLE(?commonsArticle) AS ?commonsArticle)
|
||||
(SAMPLE(?commonsCategory) AS ?commonsCategory)
|
||||
WHERE {
|
||||
# Around given location
|
||||
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.
|
||||
}
|
||||
|
||||
OPTIONAL {
|
||||
?item p:P31/ps:P31 ?class.
|
||||
}
|
||||
|
||||
# Get picture
|
||||
OPTIONAL {?item wdt:P18 ?pic}
|
||||
|
||||
# Get existence
|
||||
OPTIONAL {?item wdt:P576 ?destroyed}
|
||||
OPTIONAL {?item wdt:P582 ?endTime}
|
||||
|
||||
# Get Commons category
|
||||
OPTIONAL {?item wdt:P373 ?commonsCategory}
|
||||
|
||||
# Get Wikipedia article
|
||||
OPTIONAL {
|
||||
?wikipediaArticle schema:about ?item.
|
||||
?wikipediaArticle schema:isPartOf <https://${LANG}.wikipedia.org/>.
|
||||
}
|
||||
|
||||
# Get Commons article
|
||||
OPTIONAL {
|
||||
?commonsArticle schema:about ?item.
|
||||
?commonsArticle schema:isPartOf <https://commons.wikimedia.org/>.
|
||||
}
|
||||
|
||||
# Labels and descriptions
|
||||
SERVICE wikibase:label {
|
||||
bd:serviceParam wikibase:language "${LANG},en,fr,de,es,ja,ru,it,zh,pt,ar,fa,pl,nl,id,uk,he,sv,cs,ko,vi,ca,no,fi,hu,tr,th,hi,bn,ceb,ro,sw,kk,da,eo,sr,lt,sk,bg,sl,eu,et,hr,ms,el,arz,ur,ta,te,nn,gl,az,af,bs,be,ml,ka,is,sq,uz,la,br,mk,lv,azb,mr,sh,tl,cy,ckb,ast,be-tarask,zh-yue,hy,pa,as,my,kn,ne,si,tt,ha,war,zh-min-nan,vo,min,lmo,ht,lb,gu,tg,sco,ku,new,bpy,nds,io,pms,su,oc,jv,nap,ba,scn,wa,bar,an,ksh,szl,fy,frr,als,ia,ga,yi,mg,gd,vec,ce,sa,mai,xmf,sd,wuu,mrj,mhr,km,roa-tara,am,roa-rup,map-bms,bh,mnw,shn,bcl,co,cv,dv,nds-nl,fo,hif,fur,gan,glk,hak,ilo,pam,csb,avk,lij,li,gv,mi,mt,nah,nrm,se,nov,qu,os,pi,pag,ps,pdc,rm,bat-smg,sc,to,tk,hsb,fiu-vro,vls,yo,diq,zh-classical,frp,lad,kw,mn,haw,ang,ln,ie,wo,tpi,ty,crh,nv,jbo,ay,pcd,zea,eml,ky,ig,or,cbk-zam,kg,arc,rmy,ab,gn,so,kab,ug,stq,udm,ext,mzn,pap,cu,sah,tet,sn,lo,pnb,iu,na,got,bo,dsb,chr,cdo,om,sm,ee,ti,av,bm,zu,pnt,cr,pih,ss,ve,bi,rw,ch,xh,kl,ik,bug,dz,ts,tn,kv,tum,xal,st,tw,bxr,ak,ny,fj,lbe,za,ks,ff,lg,sg,rn,chy,mwl,lez,bjn,gom,tyv,vep,nso,kbd,ltg,rue,pfl,gag,koi,krc,ace,olo,kaa,mdf,myv,srn,ady,jam,tcy,dty,atj,kbp,din,lfn,gor,inh,sat,hyw,nqo,ban,szy,awa,ary,lld,smn,skr,mad,dag,shi,nia,ki,gcr".
|
||||
?item rdfs:label ?label.
|
||||
?item schema:description ?description.
|
||||
?class rdfs:label ?classLabel.
|
||||
}
|
||||
}
|
||||
GROUP BY ?item
|
||||
|
|
@ -14,10 +14,10 @@ SELECT
|
|||
(SAMPLE(?monument) AS ?monument)
|
||||
WHERE {
|
||||
# Around given location
|
||||
SERVICE wikibase:around {
|
||||
SERVICE wikibase:box {
|
||||
?item wdt:P625 ?location.
|
||||
bd:serviceParam wikibase:center "Point(${LONG} ${LAT})"^^geo:wktLiteral. # Longitude latitude
|
||||
bd:serviceParam wikibase:radius "${RAD}". # Radius in kilometers.
|
||||
bd:serviceParam wikibase:cornerWest "Point(${LONG_WEST} ${LAT_WEST})"^^geo:wktLiteral.
|
||||
bd:serviceParam wikibase:cornerEast "Point(${LONG_EAST} ${LAT_EAST})"^^geo:wktLiteral.
|
||||
}
|
||||
|
||||
OPTIONAL {
|
||||
|
|
@ -62,7 +62,8 @@ class OkHttpJsonApiClientTests {
|
|||
fun testGetNearbyPlacesCustomQuery() {
|
||||
Mockito.`when`(response.message).thenReturn("test")
|
||||
try {
|
||||
okHttpJsonApiClient.getNearbyPlaces(latLng, "test", 10.0, true, "test")
|
||||
okHttpJsonApiClient.getNearbyPlaces(latLng, "test", 10.0, "test")
|
||||
okHttpJsonApiClient.getNearbyPlaces(latLng, latLng, "test", true, "test")
|
||||
} catch (e: Exception) {
|
||||
assert(e.message.equals("test"))
|
||||
}
|
||||
|
|
@ -75,7 +76,8 @@ class OkHttpJsonApiClientTests {
|
|||
fun testGetNearbyPlaces() {
|
||||
Mockito.`when`(response.message).thenReturn("test")
|
||||
try {
|
||||
okHttpJsonApiClient.getNearbyPlaces(latLng, "test", 10.0, true)
|
||||
okHttpJsonApiClient.getNearbyPlaces(latLng, "test", 10.0, null)
|
||||
okHttpJsonApiClient.getNearbyPlaces(latLng, latLng, "test", true, null)
|
||||
} catch (e: Exception) {
|
||||
assert(e.message.equals("test"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,12 @@ class NearbyControllerTest {
|
|||
@Mock
|
||||
private lateinit var nearbyPlaces: NearbyPlaces
|
||||
|
||||
@Mock
|
||||
private lateinit var screenTopRight: LatLng
|
||||
|
||||
@Mock
|
||||
private lateinit var screenBottomLeft: LatLng
|
||||
|
||||
@Mock
|
||||
private lateinit var searchLatLong: LatLng
|
||||
|
||||
|
|
@ -56,41 +62,48 @@ class NearbyControllerTest {
|
|||
|
||||
@Test
|
||||
fun testLoadAttractionsForLocationTest() {
|
||||
`when`(nearbyPlaces.radiusExpander(any(), any(), any(), any(), any()))
|
||||
`when`(nearbyPlaces.radiusExpander(any(), any(), any(), any()))
|
||||
.thenReturn(Collections.emptyList())
|
||||
nearbyController.loadAttractionsFromLocation(
|
||||
searchLatLong,
|
||||
currentLatLng,
|
||||
false,
|
||||
searchLatLong,
|
||||
false,
|
||||
true,
|
||||
customQuery
|
||||
)
|
||||
nearbyController.loadAttractionsFromLocation(
|
||||
currentLatLng,
|
||||
screenTopRight,
|
||||
screenBottomLeft,
|
||||
searchLatLong,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
customQuery
|
||||
)
|
||||
Mockito.verify(nearbyPlaces).radiusExpander(
|
||||
eq(currentLatLng),
|
||||
eq(searchLatLong),
|
||||
any(String::class.java),
|
||||
eq(false),
|
||||
eq(true),
|
||||
eq(customQuery)
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLoadAttractionsForLocationTestNoQuery() {
|
||||
`when`(nearbyPlaces.radiusExpander(any(), any(), any(), any(), anyOrNull()))
|
||||
`when`(nearbyPlaces.radiusExpander(any(), any(), any(), anyOrNull()))
|
||||
.thenReturn(Collections.emptyList())
|
||||
nearbyController.loadAttractionsFromLocation(
|
||||
searchLatLong,
|
||||
currentLatLng,
|
||||
searchLatLong,
|
||||
false,
|
||||
false,
|
||||
true
|
||||
true,
|
||||
null
|
||||
)
|
||||
Mockito.verify(nearbyPlaces).radiusExpander(
|
||||
eq(currentLatLng),
|
||||
eq(searchLatLong),
|
||||
any(String::class.java),
|
||||
eq(false),
|
||||
eq(true),
|
||||
eq(null)
|
||||
)
|
||||
}
|
||||
|
|
@ -102,8 +115,7 @@ class NearbyControllerTest {
|
|||
currentLatLng,
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
customQuery
|
||||
), null
|
||||
)
|
||||
|
|
@ -136,7 +148,7 @@ class NearbyControllerTest {
|
|||
`when`(
|
||||
nearbyPlaces.radiusExpander(
|
||||
searchLatLong, Locale.getDefault().language, false,
|
||||
false, customQuery
|
||||
customQuery
|
||||
)
|
||||
).thenReturn(mutableListOf(place1, place2))
|
||||
val result = nearbyController.loadAttractionsFromLocation(
|
||||
|
|
@ -144,6 +156,15 @@ class NearbyControllerTest {
|
|||
searchLatLong,
|
||||
false,
|
||||
true,
|
||||
customQuery
|
||||
)
|
||||
nearbyController.loadAttractionsFromLocation(
|
||||
currentLatLng,
|
||||
screenTopRight,
|
||||
screenBottomLeft,
|
||||
searchLatLong,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
customQuery
|
||||
)
|
||||
|
|
@ -178,7 +199,7 @@ class NearbyControllerTest {
|
|||
`when`(
|
||||
nearbyPlaces.radiusExpander(
|
||||
searchLatLong, Locale.getDefault().language, false,
|
||||
false, customQuery
|
||||
customQuery
|
||||
)
|
||||
).thenReturn(mutableListOf(place1, place2))
|
||||
val result = nearbyController.loadAttractionsFromLocation(
|
||||
|
|
@ -186,7 +207,6 @@ class NearbyControllerTest {
|
|||
searchLatLong,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
customQuery
|
||||
)
|
||||
assertEquals(result.curLatLng, currentLatLng)
|
||||
|
|
@ -220,7 +240,7 @@ class NearbyControllerTest {
|
|||
`when`(
|
||||
nearbyPlaces.radiusExpander(
|
||||
searchLatLong, Locale.getDefault().language, false,
|
||||
false, customQuery
|
||||
customQuery
|
||||
)
|
||||
).thenReturn(mutableListOf(place1, place2))
|
||||
val result = nearbyController.loadAttractionsFromLocation(
|
||||
|
|
@ -228,7 +248,6 @@ class NearbyControllerTest {
|
|||
searchLatLong,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
customQuery
|
||||
)
|
||||
assertEquals(result.curLatLng, currentLatLng)
|
||||
|
|
|
|||
|
|
@ -28,12 +28,11 @@ class NearbyPlacesTest {
|
|||
|
||||
@Test
|
||||
fun testRadiusExpander() {
|
||||
nearbyPlaces.radiusExpander(currentLatLong, "test", true, true, "test")
|
||||
nearbyPlaces.radiusExpander(currentLatLong, "test", true, "test")
|
||||
verify(okHttpJsonApiClient, times(5)).getNearbyPlaces(
|
||||
eq(currentLatLong),
|
||||
eq("test"),
|
||||
any(),
|
||||
eq(true),
|
||||
eq("test")
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -217,8 +217,10 @@ class UploadRepositoryUnitTest {
|
|||
|
||||
@Test
|
||||
fun testSetSelectedExistingDepictions() {
|
||||
assertEquals(repository.setSelectedExistingDepictions(listOf("")),
|
||||
uploadModel.setSelectedExistingDepictions(listOf("")))
|
||||
assertEquals(
|
||||
repository.setSelectedExistingDepictions(listOf("")),
|
||||
uploadModel.setSelectedExistingDepictions(listOf(""))
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -264,7 +266,7 @@ class UploadRepositoryUnitTest {
|
|||
nearbyPlaces.getFromWikidataQuery(
|
||||
LatLng(0.0, 0.0, 0.0f),
|
||||
java.util.Locale.getDefault().language, 0.1,
|
||||
false, null
|
||||
null
|
||||
)
|
||||
).thenReturn(listOf(place))
|
||||
assertEquals(
|
||||
|
|
@ -287,7 +289,7 @@ class UploadRepositoryUnitTest {
|
|||
nearbyPlaces.getFromWikidataQuery(
|
||||
LatLng(0.0, 0.0, 0.0f),
|
||||
java.util.Locale.getDefault().language, 0.1,
|
||||
false, null
|
||||
null
|
||||
)
|
||||
).thenThrow(Exception())
|
||||
assertEquals(
|
||||
|
|
@ -348,19 +350,25 @@ class UploadRepositoryUnitTest {
|
|||
|
||||
@Test
|
||||
fun testGetSelectedExistingCategories() {
|
||||
assertEquals(repository.selectedExistingCategories,
|
||||
categoriesModel.getSelectedExistingCategories())
|
||||
assertEquals(
|
||||
repository.selectedExistingCategories,
|
||||
categoriesModel.getSelectedExistingCategories()
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetSelectedExistingCategories() {
|
||||
assertEquals(repository.setSelectedExistingCategories(listOf("Test")),
|
||||
categoriesModel.setSelectedExistingCategories(mutableListOf("Test")))
|
||||
assertEquals(
|
||||
repository.setSelectedExistingCategories(listOf("Test")),
|
||||
categoriesModel.setSelectedExistingCategories(mutableListOf("Test"))
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testGetCategories() {
|
||||
assertEquals(repository.getCategories(listOf("Test")),
|
||||
categoriesModel.getCategoriesByName(mutableListOf("Test")))
|
||||
assertEquals(
|
||||
repository.getCategories(listOf("Test")),
|
||||
categoriesModel.getCategoriesByName(mutableListOf("Test"))
|
||||
)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue