From 677e0099afe5f2f927576aba37c79682a621736c Mon Sep 17 00:00:00 2001 From: neslihanturan Date: Wed, 5 Dec 2018 19:06:50 +0200 Subject: [PATCH] Search this area (#2051) * Recognize user is moving on the map and show a button * Use variable from strings xml instead of hardcoded string * Change search this area button location in xml file * Add location util file to convert mapbox LatLng to commons Latlng and viceversa * Populate places around searched area * Update narby map according to new points came from searched area * Add searchThisAreaMode boolean to stop nearby map updated when we try to search nearby areas. * Lock auto nearby operations during serch this area mode, with a more modular method and decrease code repetition * Add an if clausse to prevent multiple refresh view calls, while map is moving * Disable map gestures during search this area operation, re-eable them on operation is done * Add progress bar during search this area operation * Make sure you locked the map during search nearby map process * Implement recenter map view button * Fix logic problem and make sure you refreshed the view on coming back to previous position * Use custom refresh method instead * Use latest updated location from location manager isntead * Update ListFragment accordingly too * Do not update camera target according to bottom sheet status or do not follow users location with camera, if search this area mode is on * Add javadocs, sorry forgotten previously * Remove unused method * Threat both or search this area and regular search in same way * Make sure distances are correct * Seperate cutom location updates and current location updates from each other to continue other operations * Remove all logs, and make sure search this are button is not visible for no reason while around of current location is already loaded * Notify load attractions from location method about search status, current location of custom location * Make sure we calculate searched area and display search this area button when we are out of 3/4 of total searched area --- .../contributions/ContributionsFragment.java | 2 +- .../nrw/commons/nearby/NearbyController.java | 19 ++- .../nrw/commons/nearby/NearbyFragment.java | 114 +++++++++++++--- .../commons/nearby/NearbyListFragment.java | 13 ++ .../nrw/commons/nearby/NearbyMapFragment.java | 127 ++++++++++++++++-- .../free/nrw/commons/nearby/NearbyPlaces.java | 3 +- .../free/nrw/commons/utils/LocationUtils.java | 13 ++ app/src/main/res/layout/fragment_nearby.xml | 23 +++- app/src/main/res/values/strings.xml | 1 + 9 files changed, 283 insertions(+), 32 deletions(-) create mode 100644 app/src/main/java/fr/free/nrw/commons/utils/LocationUtils.java diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java index 50666e65a..c8f140575 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java @@ -622,7 +622,7 @@ public class ContributionsFragment curLatLng = locationManager.getLastLocation(); placesDisposable = Observable.fromCallable(() -> nearbyController - .loadAttractionsFromLocation(curLatLng, true)) // 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, diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java index a84e86218..abf02362f 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyController.java @@ -5,6 +5,7 @@ import android.content.SharedPreferences; import android.content.res.Resources; import android.graphics.Bitmap; import android.support.graphics.drawable.VectorDrawableCompat; +import android.util.Log; import com.mapbox.mapboxsdk.annotations.IconFactory; @@ -31,6 +32,8 @@ public class NearbyController { private static final int MAX_RESULTS = 1000; private final NearbyPlaces nearbyPlaces; private final SharedPreferences prefs; + public static double searchedRadius = 10.0; //in kilometers + public static LatLng currentLocation; @Inject public NearbyController(NearbyPlaces nearbyPlaces, @@ -44,18 +47,21 @@ public class NearbyController { * Prepares Place list to make their distance information update later. * * @param curLatLng current location for user + * @param latLangToSearchAround the location user wants to search around + * @param returnClosestResult if this search is done to find closest result or all results * @return NearbyPlacesInfo a variable holds Place list without distance information * and boundary coordinates of current Place List */ - public NearbyPlacesInfo loadAttractionsFromLocation(LatLng curLatLng, boolean returnClosestResult) throws IOException { - Timber.d("Loading attractions near %s", curLatLng); + public NearbyPlacesInfo loadAttractionsFromLocation(LatLng curLatLng, LatLng latLangToSearchAround, boolean returnClosestResult, boolean checkingAroundCurrentLocation) throws IOException { + + Timber.d("Loading attractions near %s", latLangToSearchAround); NearbyPlacesInfo nearbyPlacesInfo = new NearbyPlacesInfo(); - if (curLatLng == null) { + if (latLangToSearchAround == null) { Timber.d("Loading attractions neari, but curLatLng is null"); return null; } - List places = nearbyPlaces.getFromWikidataQuery(curLatLng, Locale.getDefault().getLanguage(), returnClosestResult); + List places = nearbyPlaces.getFromWikidataQuery(latLangToSearchAround, Locale.getDefault().getLanguage(), returnClosestResult); if (null != places && places.size() > 0) { LatLng[] boundaryCoordinates = {places.get(0).location, // south @@ -93,6 +99,11 @@ public class NearbyController { } nearbyPlacesInfo.placeList = places; nearbyPlacesInfo.boundaryCoordinates = boundaryCoordinates; + if (!returnClosestResult && checkingAroundCurrentLocation) { + // Do not update searched radius, if controller is used for nearby card notification + searchedRadius = nearbyPlaces.radius; + currentLocation = curLatLng; + } return nearbyPlacesInfo; } else { diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyFragment.java index 5cafedcbc..58943b0b5 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyFragment.java @@ -14,6 +14,7 @@ import android.support.design.widget.BottomSheetBehavior; import android.support.design.widget.Snackbar; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AlertDialog; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; @@ -64,8 +65,6 @@ public class NearbyFragment extends CommonsDaggerSupportFragment LinearLayout bottomSheetDetails; @BindView(R.id.transparentView) View transparentView; - @BindView(R.id.fab_recenter) - View fabRecenter; @Inject LocationServiceManager locationManager; @@ -87,16 +86,19 @@ public class NearbyFragment extends CommonsDaggerSupportFragment private LatLng curLatLng; private Disposable placesDisposable; + private Disposable placesDisposableCustom; private boolean lockNearbyView; //Determines if the nearby places needs to be refreshed public View view; private Snackbar snackbar; private LatLng lastKnownLocation; + private LatLng customLatLng; private final String NETWORK_INTENT_ACTION = "android.net.conn.CONNECTIVITY_CHANGE"; private BroadcastReceiver broadcastReceiver; private boolean onOrientationChanged = false; + private boolean populateForCurrentLocation = false; @Override public void onCreate(@Nullable Bundle savedInstanceState) { @@ -216,24 +218,27 @@ public class NearbyFragment extends CommonsDaggerSupportFragment @Override public void onLocationChangedSignificantly(LatLng latLng) { - refreshView(LOCATION_SIGNIFICANTLY_CHANGED); + refreshView(LOCATION_SIGNIFICANTLY_CHANGED); } @Override public void onLocationChangedSlightly(LatLng latLng) { - refreshView(LOCATION_SLIGHTLY_CHANGED); + refreshView(LOCATION_SLIGHTLY_CHANGED); } @Override public void onLocationChangedMedium(LatLng latLng) { // For nearby map actions, there are no differences between 500 meter location change (aka medium change) and slight change - refreshView(LOCATION_SLIGHTLY_CHANGED); + refreshView(LOCATION_SLIGHTLY_CHANGED); } @Override public void onWikidataEditSuccessful() { - refreshView(MAP_UPDATED); + // Do not refresh nearby map if we are checking other areas with search this area button + if (!nearbyMapFragment.searchThisAreaModeOn) { + refreshView(MAP_UPDATED); + } } /** @@ -241,7 +246,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment * * @param locationChangeType defines if location shanged significantly or slightly */ - private void refreshView(LocationServiceManager.LocationChangeType locationChangeType) { + public void refreshView(LocationServiceManager.LocationChangeType locationChangeType) { Timber.d("Refreshing nearby places"); if (lockNearbyView) { return; @@ -257,9 +262,11 @@ public class NearbyFragment extends CommonsDaggerSupportFragment if (curLatLng != null && curLatLng.equals(lastLocation) && !locationChangeType.equals(MAP_UPDATED)) { //refresh view only if location has changed + // Two exceptional cases to refresh nearby map manually. if (!onOrientationChanged) { return; } + } curLatLng = lastLocation; @@ -292,7 +299,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment bundle.putString("CurLatLng", gsonCurLatLng); placesDisposable = Observable.fromCallable(() -> nearbyController - .loadAttractionsFromLocation(curLatLng, false)) + .loadAttractionsFromLocation(curLatLng, curLatLng, false, true)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::populatePlaces, @@ -301,6 +308,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment showErrorMessage(getString(R.string.error_fetching_nearby_places)); progressBar.setVisibility(View.GONE); }); + } else if (locationChangeType .equals(LOCATION_SLIGHTLY_CHANGED)) { Gson gson = new GsonBuilder() @@ -308,7 +316,62 @@ public class NearbyFragment extends CommonsDaggerSupportFragment .create(); String gsonCurLatLng = gson.toJson(curLatLng); bundle.putString("CurLatLng", gsonCurLatLng); - updateMapFragment(true); + updateMapFragment(false,true, null, null); + } + + if (nearbyMapFragment != null) { + nearbyMapFragment.searchThisAreaButton.setVisibility(View.GONE); + } + } + + /** + * This method should be used with "Search this are button". This method will search nearby + * points around any custom location (target location when user clicked on search this area) + * button. It populates places for custom location. + * @param customLatLng Custom area which we will search around + */ + public void refreshViewForCustomLocation(LatLng customLatLng, boolean refreshForCurrentLocation) { + + if (customLatLng == null) { + // If null, return + return; + } + + populateForCurrentLocation = refreshForCurrentLocation; + this.customLatLng = customLatLng; + placesDisposableCustom = Observable.fromCallable(() -> nearbyController + .loadAttractionsFromLocation(curLatLng, customLatLng, false, populateForCurrentLocation)) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(this::populatePlacesFromCustomLocation, + throwable -> { + Timber.d(throwable); + showErrorMessage(getString(R.string.error_fetching_nearby_places)); + }); + + if (nearbyMapFragment != null) { + nearbyMapFragment.searchThisAreaButton.setVisibility(View.GONE); + } + } + + /** + * Populates places for custom location, should be used for finding nearby places around a + * location where you are not at. + * @param nearbyPlacesInfo This variable has place list information and distances. + */ + private void populatePlacesFromCustomLocation(NearbyController.NearbyPlacesInfo nearbyPlacesInfo) { + //NearbyMapFragment nearbyMapFragment = getMapFragment(); + if (nearbyMapFragment != null) { + nearbyMapFragment.searchThisAreaButtonProgressBar.setVisibility(View.GONE); + } + + if (nearbyMapFragment != null && curLatLng != null) { + if (!populateForCurrentLocation) { + nearbyMapFragment.updateMapSignificantlyForCustomLocation(customLatLng, nearbyPlacesInfo.placeList); + } else { + updateMapFragment(true,true, customLatLng, nearbyPlacesInfo); + } + updateListFragmentForCustomLocation(nearbyPlacesInfo.placeList); } } @@ -342,7 +405,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment } else { // There are fragments, just update the map and list Timber.d("Map fragment already exists, just update the map and list"); - updateMapFragment(false); + updateMapFragment(false,false, null, null); updateListFragment(); } } @@ -364,7 +427,11 @@ public class NearbyFragment extends CommonsDaggerSupportFragment } } - private void updateMapFragment(boolean isSlightUpdate) { + private void updateMapFragment(boolean updateViaButton, boolean isSlightUpdate, @Nullable LatLng customLatLng, @Nullable NearbyController.NearbyPlacesInfo nearbyPlacesInfo) { + + if (nearbyMapFragment.searchThisAreaModeOn) { + return; + } /* Significant update means updating nearby place markers. Slightly update means only updating current location marker and camera target. @@ -380,14 +447,14 @@ public class NearbyFragment extends CommonsDaggerSupportFragment * If we are close to nearby places boundaries, we need a significant update to * get new nearby places. Check order is south, north, west, east * */ - if (nearbyMapFragment.boundaryCoordinates != null + if (nearbyMapFragment.boundaryCoordinates != null && !nearbyMapFragment.searchThisAreaModeOn && (curLatLng.getLatitude() <= nearbyMapFragment.boundaryCoordinates[0].getLatitude() || curLatLng.getLatitude() >= nearbyMapFragment.boundaryCoordinates[1].getLatitude() || curLatLng.getLongitude() <= nearbyMapFragment.boundaryCoordinates[2].getLongitude() || curLatLng.getLongitude() >= nearbyMapFragment.boundaryCoordinates[3].getLongitude())) { // populate places placesDisposable = Observable.fromCallable(() -> nearbyController - .loadAttractionsFromLocation(curLatLng, false)) + .loadAttractionsFromLocation(curLatLng, curLatLng, false, updateViaButton)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::populatePlaces, @@ -397,11 +464,16 @@ public class NearbyFragment extends CommonsDaggerSupportFragment progressBar.setVisibility(View.GONE); }); nearbyMapFragment.setBundleForUpdtes(bundle); - nearbyMapFragment.updateMapSignificantly(); + nearbyMapFragment.updateMapSignificantlyForCurrentLocation(); updateListFragment(); return; } + if (updateViaButton) { + nearbyMapFragment.updateMapSignificantlyForCustomLocation(customLatLng, nearbyPlacesInfo.placeList); + return; + } + /* If this is the map update just after orientation change, then it is not a slight update anymore. We want to significantly update map after each orientation change @@ -416,7 +488,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment nearbyMapFragment.updateMapSlightly(); } else { nearbyMapFragment.setBundleForUpdtes(bundle); - nearbyMapFragment.updateMapSignificantly(); + nearbyMapFragment.updateMapSignificantlyForCurrentLocation(); updateListFragment(); } } else { @@ -433,6 +505,15 @@ public class NearbyFragment extends CommonsDaggerSupportFragment nearbyListFragment.updateNearbyListSignificantly(); } + /** + * Updates nearby list for custom location, will be used with search this area method. When you + * want to search for a place where you are not at. + * @param placeList List of places around your manually chosen target location from map. + */ + private void updateListFragmentForCustomLocation(List placeList) { + nearbyListFragment.updateNearbyListSignificantlyForCustomLocation(placeList); + } + /** * Calls fragment for map view. */ @@ -650,6 +731,9 @@ public class NearbyFragment extends CommonsDaggerSupportFragment if (placesDisposable != null) { placesDisposable.dispose(); } + if (placesDisposableCustom != null) { + placesDisposableCustom.dispose(); + } } @Override diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java index 3cf60c31d..5c6b6e871 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyListFragment.java @@ -98,6 +98,19 @@ public class NearbyListFragment extends DaggerFragment { } } + /** + * While nearby updates for current location held with bundle, automatically, custom updates are + * done by calling this methods, triddered by search this are button input from user. + * @param placeList + */ + public void updateNearbyListSignificantlyForCustomLocation(List placeList) { + try { + adapterFactory.updateAdapterData(placeList, (RVRendererAdapter) recyclerView.getAdapter()); + } catch (NullPointerException e) { + Timber.e("Null pointer exception from calling recyclerView.getAdapter()"); + } + } + private List getPlaceListFromBundle(Bundle bundle) { List placeList = Collections.emptyList(); diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java index c8c1d3ebd..6e92c9da2 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/NearbyMapFragment.java @@ -23,8 +23,10 @@ import android.view.View; import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.AnimationUtils; +import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.ProgressBar; import android.widget.TextView; import com.google.gson.Gson; @@ -60,10 +62,11 @@ import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.auth.LoginActivity; import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao; import fr.free.nrw.commons.contributions.ContributionController; +import fr.free.nrw.commons.location.LocationServiceManager; +import fr.free.nrw.commons.utils.LocationUtils; import fr.free.nrw.commons.utils.UriDeserializer; import fr.free.nrw.commons.utils.ViewUtil; import timber.log.Timber; -import uk.co.deanwild.materialshowcaseview.MaterialShowcaseView; import static android.app.Activity.RESULT_OK; import static android.content.pm.PackageManager.PERMISSION_GRANTED; @@ -115,16 +118,21 @@ public class NearbyMapFragment extends DaggerFragment { private Place place; private Marker selected; private Marker currentLocationMarker; - private MapboxMap mapboxMap; + public MapboxMap mapboxMap; private PolygonOptions currentLocationPolygonOptions; + public Button searchThisAreaButton; + public ProgressBar searchThisAreaButtonProgressBar; + private boolean isBottomListSheetExpanded; private final double CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT = 0.06; private final double CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE = 0.04; private boolean isMapReady; + public boolean searchThisAreaModeOn = false; private Bundle bundleForUpdtes;// Carry information from activity about changed nearby places and current location + private boolean searchedAroundCurrentLocation = true; @Inject @Named("prefs") @@ -246,8 +254,8 @@ public class NearbyMapFragment extends DaggerFragment { * called when user is out of boundaries (south, north, east or west) of markers drawn by * previous nearby call. */ - public void updateMapSignificantly() { - Timber.d("updateMapSignificantly called, bundle is:"+bundleForUpdtes); + public void updateMapSignificantlyForCurrentLocation() { + Timber.d("updateMapSignificantlyForCurrentLocation called, bundle is:"+bundleForUpdtes); if (mapboxMap != null) { if (bundleForUpdtes != null) { Gson gson = new GsonBuilder() @@ -271,10 +279,32 @@ public class NearbyMapFragment extends DaggerFragment { mapboxMap.clear(); addCurrentLocationMarker(mapboxMap); updateMapToTrackPosition(); - addNearbyMarkerstoMapBoxMap(); + // We are trying to find nearby places around our current location, thus custom parameter is nullified + addNearbyMarkerstoMapBoxMap(null); } } + /** + * Will be used for map vew updates for custom locations (ie. with search this area method). + * Clears the map, adds current location marker, adds nearby markers around custom location, + * re-enables map gestures which was locked during place load, remove progress bar. + * @param customLatLng custom location that we will search around + * @param placeList places around of custom location + */ + public void updateMapSignificantlyForCustomLocation(fr.free.nrw.commons.location.LatLng customLatLng, List placeList) { + List customBaseMarkerOptions = NearbyController + .loadAttractionsFromLocationToBaseMarkerOptions(curLatLng, // Curlatlang will be used to calculate distances + placeList, + getActivity()); + mapboxMap.clear(); + // We are trying to find nearby places around our custom searched area, thus custom parameter is nonnull + addNearbyMarkerstoMapBoxMap(customBaseMarkerOptions); + addCurrentLocationMarker(mapboxMap); + // Re-enable mapbox gestures on custom location markers load + mapboxMap.getUiSettings().setAllGesturesEnabled(true); + searchThisAreaButtonProgressBar.setVisibility(View.GONE); + } + // Only update current position marker and camera view private void updateMapToTrackPosition() { @@ -299,6 +329,9 @@ public class NearbyMapFragment extends DaggerFragment { // Make camera to follow user on location change CameraPosition position ; + + // Do not update camera position is search this area mode on + if (!searchThisAreaModeOn) { if (ViewUtil.isPortrait(getActivity())){ position = new CameraPosition.Builder() .target(isBottomListSheetExpanded ? @@ -323,10 +356,10 @@ public class NearbyMapFragment extends DaggerFragment { mapboxMap.animateCamera(CameraUpdateFactory .newCameraPosition(position), 1000); - + } } } - + private void initViews() { Timber.d("initViews called"); bottomSheetList = ((NearbyFragment)getParentFragment()).view.findViewById(R.id.bottom_sheet); @@ -366,6 +399,9 @@ public class NearbyMapFragment extends DaggerFragment { bookmarkButton = getActivity().findViewById(R.id.bookmarkButton); bookmarkButtonImage = getActivity().findViewById(R.id.bookmarkButtonImage); + searchThisAreaButton = ((NearbyFragment)getParentFragment()).view.findViewById(R.id.search_this_area_button); + searchThisAreaButtonProgressBar = ((NearbyFragment)getParentFragment()).view.findViewById(R.id.search_this_area_button_progres_bar); + } private void setListeners() { @@ -495,13 +531,77 @@ public class NearbyMapFragment extends DaggerFragment { @Override public void onMapReady(MapboxMap mapboxMap) { NearbyMapFragment.this.mapboxMap = mapboxMap; - updateMapSignificantly(); + addMapMovementListeners(); + updateMapSignificantlyForCurrentLocation(); } }); mapView.setStyleUrl("asset://mapstyle.json"); } } + private void addMapMovementListeners() { + + mapboxMap.addOnCameraMoveListener(new MapboxMap.OnCameraMoveListener() { + + @Override + public void onCameraMove() { + + if (NearbyController.currentLocation != null) { // If our nearby markers are calculated at least once + + if (searchThisAreaButton.getVisibility() == View.GONE) { + searchThisAreaButton.setVisibility(View.VISIBLE); + } + double distance = mapboxMap.getCameraPosition().target + .distanceTo(new LatLng(NearbyController.currentLocation.getLatitude() + , NearbyController.currentLocation.getLongitude())); + + if (distance > NearbyController.searchedRadius*1000*3/4) { //Convert to meter, and compare if our distance is bigger than 3/4 or our searched area + if (!searchThisAreaModeOn) { // If we are changing mode, then change click action + searchThisAreaModeOn = true; + searchThisAreaButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + searchThisAreaModeOn = true; + // Lock map operations during search this area operation + mapboxMap.getUiSettings().setAllGesturesEnabled(false); + searchThisAreaButtonProgressBar.setVisibility(View.VISIBLE); + searchThisAreaButton.setVisibility(View.GONE); + searchedAroundCurrentLocation = false; + ((NearbyFragment)getParentFragment()) + .refreshViewForCustomLocation(LocationUtils + .mapBoxLatLngToCommonsLatLng(mapboxMap.getCameraPosition().target), false); + } + }); + } + + } else { + if (searchThisAreaModeOn) { + searchThisAreaModeOn = false; // This flag will help us to understand should we folor users location or not + searchThisAreaButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + searchThisAreaModeOn = true; + // Lock map operations during search this area operation + mapboxMap.getUiSettings().setAllGesturesEnabled(false); + searchThisAreaButtonProgressBar.setVisibility(View.VISIBLE); + fabRecenter.callOnClick(); + searchThisAreaButton.setVisibility(View.GONE); + searchedAroundCurrentLocation = true; + ((NearbyFragment)getParentFragment()) + .refreshViewForCustomLocation(LocationUtils + .mapBoxLatLngToCommonsLatLng(mapboxMap.getCameraPosition().target), true); + } + }); + } + if (searchedAroundCurrentLocation) { + searchThisAreaButton.setVisibility(View.GONE); + } + } + } + } + }); + } + /** * onLogoutComplete is called after shared preferences and data stored in local database are cleared. */ @@ -554,10 +654,17 @@ public class NearbyMapFragment extends DaggerFragment { /** * Adds markers for nearby places to mapbox map */ - private void addNearbyMarkerstoMapBoxMap() { + private void addNearbyMarkerstoMapBoxMap(@Nullable List customNearbyBaseMarker) { + List baseMarkerOptions; Timber.d("addNearbyMarkerstoMapBoxMap is called"); + if (customNearbyBaseMarker != null) { + // If we try to update nearby points for a custom location choosen from map (we are not there) + baseMarkerOptions = customNearbyBaseMarker; + } else { + // If we try to display nearby markers around our curret location + baseMarkerOptions = this.baseMarkerOptions; + } mapboxMap.addMarkers(baseMarkerOptions); - mapboxMap.setOnInfoWindowCloseListener(marker -> { if (marker == selected) { bottomSheetDetailsBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); 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 6ca4af318..74af35de5 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 @@ -30,7 +30,7 @@ public class NearbyPlaces { private static final Uri WIKIDATA_QUERY_URL = Uri.parse("https://query.wikidata.org/sparql"); private static final Uri WIKIDATA_QUERY_UI_URL = Uri.parse("https://query.wikidata.org/"); private final String wikidataQuery; - private double radius = INITIAL_RADIUS; + public double radius = INITIAL_RADIUS; public NearbyPlaces() { try { @@ -55,6 +55,7 @@ public class NearbyPlaces { } else { MIN_RESULTS = 40; MAX_RADIUS = 300.0; // in kilometers + radius = INITIAL_RADIUS; } // increase the radius gradually to find a satisfactory number of nearby places diff --git a/app/src/main/java/fr/free/nrw/commons/utils/LocationUtils.java b/app/src/main/java/fr/free/nrw/commons/utils/LocationUtils.java new file mode 100644 index 000000000..58cd138a0 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/utils/LocationUtils.java @@ -0,0 +1,13 @@ +package fr.free.nrw.commons.utils; + +import fr.free.nrw.commons.location.LatLng; + +public class LocationUtils { + public static LatLng mapBoxLatLngToCommonsLatLng(com.mapbox.mapboxsdk.geometry.LatLng mapBoxLatLng) { + return new LatLng(mapBoxLatLng.getLatitude(), mapBoxLatLng.getLongitude(), 0); + } + + public static com.mapbox.mapboxsdk.geometry.LatLng comonsLatLngToMapBoxLatLng(LatLng commonsLatLng) { + return new com.mapbox.mapboxsdk.geometry.LatLng(commonsLatLng.getLatitude(), commonsLatLng.getLongitude()); + } +} diff --git a/app/src/main/res/layout/fragment_nearby.xml b/app/src/main/res/layout/fragment_nearby.xml index 4269f135b..8b50dfae5 100644 --- a/app/src/main/res/layout/fragment_nearby.xml +++ b/app/src/main/res/layout/fragment_nearby.xml @@ -19,7 +19,6 @@ android:gravity="center_vertical" android:orientation="horizontal"> - +