Suggest and auto fill title and description based on image location (#3323)

* Suggest and auto fill title and description based on image location

* with java docs
This commit is contained in:
Vivek Maskara 2020-01-29 03:24:37 -07:00 committed by GitHub
parent afdeaae075
commit 2290545bc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 92 additions and 3 deletions

View file

@ -91,7 +91,7 @@ public class NearbyPlaces {
* @return list of places obtained * @return list of places obtained
* @throws IOException if query fails * @throws IOException if query fails
*/ */
private List<Place> getFromWikidataQuery(LatLng cur, String lang, double radius) throws IOException { public List<Place> getFromWikidataQuery(LatLng cur, String lang, double radius) throws IOException {
return okHttpJsonApiClient.getNearbyPlaces(cur, lang, radius).blockingSingle(); return okHttpJsonApiClient.getNearbyPlaces(cur, lang, radius).blockingSingle();
} }
} }

View file

@ -1,7 +1,9 @@
package fr.free.nrw.commons.repository; package fr.free.nrw.commons.repository;
import java.io.IOException;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Locale;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
@ -10,6 +12,8 @@ import fr.free.nrw.commons.category.CategoriesModel;
import fr.free.nrw.commons.category.CategoryItem; import fr.free.nrw.commons.category.CategoryItem;
import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.contributions.Contribution;
import fr.free.nrw.commons.filepicker.UploadableFile; 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.nearby.Place;
import fr.free.nrw.commons.upload.SimilarImageInterface; import fr.free.nrw.commons.upload.SimilarImageInterface;
import fr.free.nrw.commons.upload.UploadController; import fr.free.nrw.commons.upload.UploadController;
@ -24,16 +28,21 @@ import io.reactivex.Single;
@Singleton @Singleton
public class UploadRemoteDataSource { public class UploadRemoteDataSource {
private static final double NEARBY_RADIUS_IN_KILO_METERS = 0.1; //100 meters
private UploadModel uploadModel; private UploadModel uploadModel;
private UploadController uploadController; private UploadController uploadController;
private CategoriesModel categoriesModel; private CategoriesModel categoriesModel;
private NearbyPlaces nearbyPlaces;
@Inject @Inject
public UploadRemoteDataSource(UploadModel uploadModel, UploadController uploadController, public UploadRemoteDataSource(UploadModel uploadModel, UploadController uploadController,
CategoriesModel categoriesModel) { CategoriesModel categoriesModel,
NearbyPlaces nearbyPlaces) {
this.uploadModel = uploadModel; this.uploadModel = uploadModel;
this.uploadController = uploadController; this.uploadController = uploadController;
this.categoriesModel = categoriesModel; this.categoriesModel = categoriesModel;
this.nearbyPlaces = nearbyPlaces;
} }
/** /**
@ -176,4 +185,22 @@ public class UploadRemoteDataSource {
public Single<Integer> getImageQuality(UploadItem uploadItem, boolean shouldValidateTitle) { public Single<Integer> getImageQuality(UploadItem uploadItem, boolean shouldValidateTitle) {
return uploadModel.getImageQuality(uploadItem, 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<Place> fromWikidataQuery = nearbyPlaces.getFromWikidataQuery(new LatLng(latitude, longitude, 0.0f),
Locale.getDefault().getLanguage(),
NEARBY_RADIUS_IN_KILO_METERS);
return fromWikidataQuery.size() > 0 ? fromWikidataQuery.get(0) : null;
} catch (IOException e) {
return null;
}
}
} }

View file

@ -262,4 +262,14 @@ public class UploadRepository {
public void setSelectedLicense(String licenseName) { public void setSelectedLicense(String licenseName) {
localDataSource.setSelectedLicense(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);
}
} }

View file

@ -1,5 +1,6 @@
package fr.free.nrw.commons.upload.mediaDetails; package fr.free.nrw.commons.upload.mediaDetails;
import android.annotation.SuppressLint;
import android.content.Context; import android.content.Context;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
@ -25,6 +26,7 @@ import com.jakewharton.rxbinding2.widget.RxTextView;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
@ -297,6 +299,32 @@ public class UploadMediaDetailFragment extends UploadBaseFragment implements
setDescriptionsInAdapter(descriptions); 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) {
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 @Override
public void showProgress(boolean shouldShow) { public void showProgress(boolean shouldShow) {
callback.showProgress(shouldShow); callback.showProgress(shouldShow);

View file

@ -19,6 +19,8 @@ public interface UploadMediaDetailsContract {
void onImageProcessed(UploadItem uploadItem, Place place); void onImageProcessed(UploadItem uploadItem, Place place);
void onNearbyPlaceFound(UploadItem uploadItem, Place place);
void showProgress(boolean shouldShow); void showProgress(boolean shouldShow);
void onImageValidationSuccess(); void onImageValidationSuccess();

View file

@ -14,6 +14,7 @@ import fr.free.nrw.commons.upload.SimilarImageInterface;
import fr.free.nrw.commons.upload.UploadModel.UploadItem; 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.UserActionListener;
import fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailsContract.View; import fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailsContract.View;
import io.reactivex.Observable;
import io.reactivex.Scheduler; import io.reactivex.Scheduler;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
@ -81,13 +82,31 @@ public class UploadMediaPresenter implements UserActionListener, SimilarImageInt
{ {
view.onImageProcessed(uploadItem, place); view.onImageProcessed(uploadItem, place);
GPSExtractor gpsCoords = uploadItem.getGpsCoords(); GPSExtractor gpsCoords = uploadItem.getGpsCoords();
view.showMapWithImageCoordinates((gpsCoords != null && gpsCoords.imageCoordsExists) ? true : false); view.showMapWithImageCoordinates(gpsCoords != null && gpsCoords.imageCoordsExists);
view.showProgress(false); view.showProgress(false);
if (gpsCoords != null && gpsCoords.imageCoordsExists) {
checkNearbyPlaces(uploadItem);
}
}, },
throwable -> Timber.e(throwable, "Error occurred in processing images")); throwable -> Timber.e(throwable, "Error occurred in processing images"));
compositeDisposable.add(uploadItemDisposable); 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(),
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 * asks the repository to verify image quality
* *

View file

@ -588,4 +588,7 @@ Upload your first media by tapping on the add button.</string>
<string name="place_type">Place type:</string> <string name="place_type">Place type:</string>
<string name="nearby_search_hint">Bridge, museum, hotel etc.</string> <string name="nearby_search_hint">Bridge, museum, hotel etc.</string>
<string name="you_must_reset_your_passsword">Something went wrong with login, you must reset your password !!</string> <string name="you_must_reset_your_passsword">Something went wrong with login, you must reset your password !!</string>
<string name="upload_nearby_place_found_title">Nearby Place Found</string>
<string name="upload_nearby_place_found_description">Is this a photo of Place %1$s?</string>
</resources> </resources>