From eaf3d254aeb7b46246ae31707f150429cda7b455 Mon Sep 17 00:00:00 2001 From: Vivek Maskara Date: Sun, 12 Jan 2020 20:19:15 -0700 Subject: [PATCH 1/2] Suggest and auto fill title and description based on image location --- .../free/nrw/commons/nearby/NearbyPlaces.java | 2 +- .../repository/UploadRemoteDataSource.java | 28 ++++++++++++++++++- .../commons/repository/UploadRepository.java | 4 +++ .../UploadMediaDetailFragment.java | 24 ++++++++++++++++ .../UploadMediaDetailsContract.java | 2 ++ .../mediaDetails/UploadMediaPresenter.java | 17 ++++++++++- app/src/main/res/values/strings.xml | 3 ++ 7 files changed, 77 insertions(+), 3 deletions(-) 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 95cee7c513..b50c437817 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 @@ -91,7 +91,7 @@ List radiusExpander(LatLng curLatLng, String lang, boolean returnClosestR * @return list of places obtained * @throws IOException if query fails */ - private List getFromWikidataQuery(LatLng cur, String lang, double radius) throws IOException { + public List getFromWikidataQuery(LatLng cur, String lang, double radius) throws IOException { return okHttpJsonApiClient.getNearbyPlaces(cur, lang, radius).blockingSingle(); } } diff --git a/app/src/main/java/fr/free/nrw/commons/repository/UploadRemoteDataSource.java b/app/src/main/java/fr/free/nrw/commons/repository/UploadRemoteDataSource.java index d8f2a23223..a4646e2ed5 100644 --- a/app/src/main/java/fr/free/nrw/commons/repository/UploadRemoteDataSource.java +++ b/app/src/main/java/fr/free/nrw/commons/repository/UploadRemoteDataSource.java @@ -1,5 +1,6 @@ package fr.free.nrw.commons.repository; +import java.io.IOException; import java.util.Comparator; import java.util.List; @@ -10,6 +11,8 @@ import fr.free.nrw.commons.category.CategoryItem; import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.filepicker.UploadableFile; +import fr.free.nrw.commons.location.LatLng; +import fr.free.nrw.commons.nearby.NearbyPlaces; import fr.free.nrw.commons.nearby.Place; import fr.free.nrw.commons.upload.SimilarImageInterface; import fr.free.nrw.commons.upload.UploadController; @@ -24,16 +27,21 @@ @Singleton public class UploadRemoteDataSource { + private static final double NEARBY_RADIUS_IN_KILO_METERS = 5.0; // + private UploadModel uploadModel; private UploadController uploadController; private CategoriesModel categoriesModel; + private NearbyPlaces nearbyPlaces; @Inject public UploadRemoteDataSource(UploadModel uploadModel, UploadController uploadController, - CategoriesModel categoriesModel) { + CategoriesModel categoriesModel, + NearbyPlaces nearbyPlaces) { this.uploadModel = uploadModel; this.uploadController = uploadController; this.categoriesModel = categoriesModel; + this.nearbyPlaces = nearbyPlaces; } /** @@ -176,4 +184,22 @@ public Observable preProcessImage(UploadableFile uploadableFile, Pla public Single getImageQuality(UploadItem uploadItem, boolean shouldValidateTitle) { return uploadModel.getImageQuality(uploadItem, shouldValidateTitle); } + + /** + * gets nearby places matching with upload item's GPS location + * + * @param latitude + * @param longitude + * @return + */ + public Place getNearbyPlaces(double latitude, double longitude) { + try { + List fromWikidataQuery = nearbyPlaces.getFromWikidataQuery(new LatLng(latitude, longitude, 0.0f), + "en", + NEARBY_RADIUS_IN_KILO_METERS); + return fromWikidataQuery.size() > 0 ? fromWikidataQuery.get(0) : null; + } catch (IOException e) { + return null; + } + } } diff --git a/app/src/main/java/fr/free/nrw/commons/repository/UploadRepository.java b/app/src/main/java/fr/free/nrw/commons/repository/UploadRepository.java index 5d1749a13b..6ff5e5c35c 100644 --- a/app/src/main/java/fr/free/nrw/commons/repository/UploadRepository.java +++ b/app/src/main/java/fr/free/nrw/commons/repository/UploadRepository.java @@ -262,4 +262,8 @@ public String getValue(String key, String value) { public void setSelectedLicense(String licenseName) { localDataSource.setSelectedLicense(licenseName); } + + public Place checkNearbyPlaces(double decLatitude, double decLongitude) { + return remoteDataSource.getNearbyPlaces(decLatitude, decLongitude); + } } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java index a9d7c92978..c746bf10a6 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java @@ -1,5 +1,6 @@ package fr.free.nrw.commons.upload.mediaDetails; +import android.annotation.SuppressLint; import android.content.Context; import android.os.Bundle; import android.text.TextUtils; @@ -25,6 +26,7 @@ import org.apache.commons.lang3.StringUtils; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Locale; @@ -297,6 +299,28 @@ public void onImageProcessed(UploadItem uploadItem, Place place) { setDescriptionsInAdapter(descriptions); } + @SuppressLint("StringFormatInvalid") + @Override + public void onNearbyPlaceFound(UploadItem uploadItem, Place place) { + Timber.d("Place is %s", place.toString()); + DialogUtil.showAlertDialog(getActivity(), + getString(R.string.upload_nearby_place_found_title), + String.format(Locale.getDefault(), + getString(R.string.upload_nearby_place_found_description), + place.getName()), + () -> { + + }, + () -> { + etTitle.setText(place.getName()); + Description description = new Description(); + description.setLanguageCode("en"); + description.setDescriptionText(place.getLongDescription()); + descriptions = Arrays.asList(description); + setDescriptionsInAdapter(descriptions); + }); + } + @Override public void showProgress(boolean shouldShow) { callback.showProgress(shouldShow); diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailsContract.java b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailsContract.java index be4b5e08b2..b442d79396 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailsContract.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailsContract.java @@ -19,6 +19,8 @@ interface View extends SimilarImageInterface { void onImageProcessed(UploadItem uploadItem, Place place); + void onNearbyPlaceFound(UploadItem uploadItem, Place place); + void showProgress(boolean shouldShow); void onImageValidationSuccess(); diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.java b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.java index 6207e824de..4c95ae791e 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.java @@ -14,6 +14,7 @@ import fr.free.nrw.commons.upload.UploadModel.UploadItem; import fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailsContract.UserActionListener; import fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailsContract.View; +import io.reactivex.Observable; import io.reactivex.Scheduler; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; @@ -81,13 +82,27 @@ public void receiveImage(UploadableFile uploadableFile, String source, Place pla { view.onImageProcessed(uploadItem, place); GPSExtractor gpsCoords = uploadItem.getGpsCoords(); - view.showMapWithImageCoordinates((gpsCoords != null && gpsCoords.imageCoordsExists) ? true : false); + view.showMapWithImageCoordinates(gpsCoords != null && gpsCoords.imageCoordsExists); view.showProgress(false); + if (gpsCoords != null && gpsCoords.imageCoordsExists) { + checkNearbyPlaces(uploadItem); + } }, throwable -> Timber.e(throwable, "Error occurred in processing images")); compositeDisposable.add(uploadItemDisposable); } + private void checkNearbyPlaces(UploadItem uploadItem) { + Disposable checkNearbyPlaces = Observable.fromCallable(() -> repository + .checkNearbyPlaces(uploadItem.getGpsCoords().getDecLatitude(), + uploadItem.getGpsCoords().getDecLongitude())) + .subscribeOn(ioScheduler) + .observeOn(mainThreadScheduler) + .subscribe(place -> view.onNearbyPlaceFound(uploadItem, place), + throwable -> Timber.e(throwable, "Error occurred in processing images")); + compositeDisposable.add(checkNearbyPlaces); + } + /** * asks the repository to verify image quality * diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 843ec51492..f06dcdfd1d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -588,4 +588,7 @@ Upload your first media by tapping on the add button. Place type: Bridge, museum, hotel etc. Something went wrong with login, you must reset your password !! + + Nearby Place Found + Is this a photo of Place %1$s? From 6f906714af46501c48bd07f65c0e80464c7d59d8 Mon Sep 17 00:00:00 2001 From: Vivek Maskara Date: Sun, 12 Jan 2020 20:24:56 -0700 Subject: [PATCH 2/2] with java docs --- .../free/nrw/commons/repository/UploadRemoteDataSource.java | 5 +++-- .../fr/free/nrw/commons/repository/UploadRepository.java | 6 ++++++ .../upload/mediaDetails/UploadMediaDetailFragment.java | 6 +++++- .../commons/upload/mediaDetails/UploadMediaPresenter.java | 4 ++++ 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/repository/UploadRemoteDataSource.java b/app/src/main/java/fr/free/nrw/commons/repository/UploadRemoteDataSource.java index a4646e2ed5..047574a1a7 100644 --- a/app/src/main/java/fr/free/nrw/commons/repository/UploadRemoteDataSource.java +++ b/app/src/main/java/fr/free/nrw/commons/repository/UploadRemoteDataSource.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.util.Comparator; import java.util.List; +import java.util.Locale; import javax.inject.Inject; import javax.inject.Singleton; @@ -27,7 +28,7 @@ @Singleton public class UploadRemoteDataSource { - private static final double NEARBY_RADIUS_IN_KILO_METERS = 5.0; // + private static final double NEARBY_RADIUS_IN_KILO_METERS = 0.1; //100 meters private UploadModel uploadModel; private UploadController uploadController; @@ -195,7 +196,7 @@ public Single getImageQuality(UploadItem uploadItem, boolean shouldVali public Place getNearbyPlaces(double latitude, double longitude) { try { List fromWikidataQuery = nearbyPlaces.getFromWikidataQuery(new LatLng(latitude, longitude, 0.0f), - "en", + Locale.getDefault().getLanguage(), NEARBY_RADIUS_IN_KILO_METERS); return fromWikidataQuery.size() > 0 ? fromWikidataQuery.get(0) : null; } catch (IOException e) { diff --git a/app/src/main/java/fr/free/nrw/commons/repository/UploadRepository.java b/app/src/main/java/fr/free/nrw/commons/repository/UploadRepository.java index 6ff5e5c35c..0e84f9f379 100644 --- a/app/src/main/java/fr/free/nrw/commons/repository/UploadRepository.java +++ b/app/src/main/java/fr/free/nrw/commons/repository/UploadRepository.java @@ -263,6 +263,12 @@ public void setSelectedLicense(String licenseName) { localDataSource.setSelectedLicense(licenseName); } + /** + * Returns nearest place matching the passed latitude and longitude + * @param decLatitude + * @param decLongitude + * @return + */ public Place checkNearbyPlaces(double decLatitude, double decLongitude) { return remoteDataSource.getNearbyPlaces(decLatitude, decLongitude); } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java index c746bf10a6..1c6140b408 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaDetailFragment.java @@ -299,10 +299,14 @@ public void onImageProcessed(UploadItem uploadItem, Place place) { setDescriptionsInAdapter(descriptions); } + /** + * Shows popup if any nearby location needing pictures matches uploadable picture's GPS location + * @param uploadItem + * @param place + */ @SuppressLint("StringFormatInvalid") @Override public void onNearbyPlaceFound(UploadItem uploadItem, Place place) { - Timber.d("Place is %s", place.toString()); DialogUtil.showAlertDialog(getActivity(), getString(R.string.upload_nearby_place_found_title), String.format(Locale.getDefault(), diff --git a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.java b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.java index 4c95ae791e..3cab3c7537 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/mediaDetails/UploadMediaPresenter.java @@ -92,6 +92,10 @@ public void receiveImage(UploadableFile uploadableFile, String source, Place pla compositeDisposable.add(uploadItemDisposable); } + /** + * This method checks for the nearest location that needs images and suggests it to the user. + * @param uploadItem + */ private void checkNearbyPlaces(UploadItem uploadItem) { Disposable checkNearbyPlaces = Observable.fromCallable(() -> repository .checkNearbyPlaces(uploadItem.getGpsCoords().getDecLatitude(),