mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
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:
parent
afdeaae075
commit
2290545bc9
7 changed files with 92 additions and 3 deletions
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue