Replace Mapbox with OSMDroid (Explore Activity) (#5475)

* Fixed Grey empty screen at Upload wizard caption step after denying files permission

* Empty commit

* Fixed loop issue

* Created docs for earlier commits

* Fixed javadoc

* Fixed spaces

* Added added basic features to OSM Maps

* Added search location feature

* Added filter to Open Street Maps

* Fixed chipGroup in Open Street Maps

* Removed mapBox code

* Removed mapBox's code

* Reformat code

* Reformatted code

* Removed rotation feature to map

* Removed rotation files and Fixed Marker click problem

* Ignored failing tests

* Added voice input feature

* Fixed test cases

* Changed caption and description text

* Replaced mapbox to osmdroid in upload activity

* Fixed Unit Tests

* Made selected marker to be fixed on map

* Changed color of map marker

* Fixes #5439 by capitalizing first letter of voice input

* Made UI changes in UploadMediaDetailAdapter

* Added javadoc

* Replaced Mapbox with OSMDroid in explore activity

---------

Co-authored-by: Nicolas Raoul <nicolas.raoul@gmail.com>
This commit is contained in:
Kanahia 2024-01-27 18:09:08 +05:30 committed by GitHub
parent 02ce017c98
commit 96b2608eb1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 631 additions and 561 deletions

View file

@ -14,32 +14,27 @@ public class ExploreMapContract {
interface View {
boolean isNetworkConnectionEstablished();
void populatePlaces(LatLng curlatLng,LatLng searchLatLng);
void populatePlaces(LatLng curlatLng);
void checkPermissionsAndPerformAction();
void recenterMap(LatLng curLatLng);
void showLocationOffDialog();
void openLocationSettings();
void hideBottomDetailsSheet();
void displayBottomSheetWithInfo(Marker marker);
void addOnCameraMoveListener();
LatLng getMapCenter();
LatLng getMapFocus();
LatLng getLastMapFocus();
void addMarkersToMap(final List<NearbyBaseMarker> nearbyBaseMarkers);
void clearAllMarkers();
void addSearchThisAreaButtonAction();
void setSearchThisAreaButtonVisibility(boolean isVisible);
void setProgressBarVisibility(boolean isVisible);
boolean isDetailsBottomSheetVisible();
boolean isSearchThisAreaButtonVisible();
void addCurrentLocationMarker(LatLng curLatLng);
void updateMapToTrackPosition(LatLng curLatLng);
Context getContext();
LatLng getCameraTarget();
void centerMapToPlace(Place placeToCenter);
LatLng getLastLocation();
com.mapbox.mapboxsdk.geometry.LatLng getLastFocusLocation();
boolean isCurrentLocationMarkerVisible();
void setProjectorLatLngBounds();
void disableFABRecenter();
void enableFABRecenter();
void addNearbyMarkersToMapBoxMap(final List<NearbyBaseMarker> nearbyBaseMarkers, final Marker selectedMarker);
void setMapBoundaries(CameraUpdate cameaUpdate);
void setFABRecenterAction(android.view.View.OnClickListener onClickListener);
boolean backButtonClicked();
}
@ -51,9 +46,6 @@ public class ExploreMapContract {
void detachView();
void setActionListeners(JsonKvStore applicationKvStore);
boolean backButtonClicked();
void onCameraMove(com.mapbox.mapboxsdk.geometry.LatLng latLng);
void markerUnselected();
void markerSelected(Marker marker);
}
}

View file

@ -33,6 +33,7 @@ import javax.inject.Inject;
import timber.log.Timber;
public class ExploreMapController extends MapController {
private final ExploreMapCalls exploreMapCalls;
public LatLng latestSearchLocation; // Can be current and camera target on search this area button is used
public LatLng currentLocation; // current location of user
@ -46,13 +47,18 @@ public class ExploreMapController extends MapController {
}
/**
* Takes location as parameter and returns ExplorePlaces info that holds curLatLng, mediaList, explorePlaceList and boundaryCoordinates
* @param curLatLng is current geolocation
* @param searchLatLng is the location that we want to search around
* @param checkingAroundCurrentLocation is a boolean flag. True if we want to check around current location, false if another location
* @return explorePlacesInfo info that holds curLatLng, mediaList, explorePlaceList and boundaryCoordinates
* Takes location as parameter and returns ExplorePlaces info that holds curLatLng, mediaList,
* explorePlaceList and boundaryCoordinates
*
* @param curLatLng is current geolocation
* @param searchLatLng is the location that we want to search around
* @param checkingAroundCurrentLocation is a boolean flag. True if we want to check around
* current location, false if another location
* @return explorePlacesInfo info that holds curLatLng, mediaList, explorePlaceList and
* boundaryCoordinates
*/
public ExplorePlacesInfo loadAttractionsFromLocation(LatLng curLatLng, LatLng searchLatLng, boolean checkingAroundCurrentLocation) {
public ExplorePlacesInfo loadAttractionsFromLocation(LatLng curLatLng, LatLng searchLatLng,
boolean checkingAroundCurrentLocation) {
if (searchLatLng == null) {
Timber.d("Loading attractions explore map, but search is null");
@ -74,18 +80,23 @@ public class ExploreMapController extends MapController {
Timber.d("Sorting places by distance...");
final Map<Media, Double> distances = new HashMap<>();
for (Media media : mediaList) {
distances.put(media, computeDistanceBetween(media.getCoordinates(), searchLatLng));
distances.put(media,
computeDistanceBetween(media.getCoordinates(), searchLatLng));
// Find boundaries with basic find max approach
if (media.getCoordinates().getLatitude() < boundaryCoordinates[0].getLatitude()) {
if (media.getCoordinates().getLatitude()
< boundaryCoordinates[0].getLatitude()) {
boundaryCoordinates[0] = media.getCoordinates();
}
if (media.getCoordinates().getLatitude() > boundaryCoordinates[1].getLatitude()) {
if (media.getCoordinates().getLatitude()
> boundaryCoordinates[1].getLatitude()) {
boundaryCoordinates[1] = media.getCoordinates();
}
if (media.getCoordinates().getLongitude() < boundaryCoordinates[2].getLongitude()) {
if (media.getCoordinates().getLongitude()
< boundaryCoordinates[2].getLongitude()) {
boundaryCoordinates[2] = media.getCoordinates();
}
if (media.getCoordinates().getLongitude() > boundaryCoordinates[3].getLongitude()) {
if (media.getCoordinates().getLongitude()
> boundaryCoordinates[3].getLongitude()) {
boundaryCoordinates[3] = media.getCoordinates();
}
}
@ -96,7 +107,8 @@ public class ExploreMapController extends MapController {
// Sets latestSearchRadius to maximum distance among boundaries and search location
for (LatLng bound : boundaryCoordinates) {
double distance = LocationUtils.commonsLatLngToMapBoxLatLng(bound).distanceTo(LocationUtils.commonsLatLngToMapBoxLatLng(latestSearchLocation));
double distance = LocationUtils.commonsLatLngToMapBoxLatLng(bound)
.distanceTo(LocationUtils.commonsLatLngToMapBoxLatLng(latestSearchLocation));
if (distance > latestSearchRadius) {
latestSearchRadius = distance;
}
@ -115,6 +127,7 @@ public class ExploreMapController extends MapController {
/**
* Loads attractions from location for map view, we need to return places in Place data type
*
* @return baseMarkerOptions list that holds nearby places with their icons
*/
public static List<NearbyBaseMarker> loadAttractionsFromLocationToBaseMarkerOptions(
@ -123,7 +136,6 @@ public class ExploreMapController extends MapController {
Context context,
NearbyBaseMarkerThumbCallback callback,
Marker selectedMarker,
boolean shouldTrackPosition,
ExplorePlacesInfo explorePlacesInfo) {
List<NearbyBaseMarker> baseMarkerOptions = new ArrayList<>();
@ -145,7 +157,8 @@ public class ExploreMapController extends MapController {
String distance = formatDistanceBetween(curLatLng, explorePlace.location);
explorePlace.setDistance(distance);
nearbyBaseMarker.title(explorePlace.name.substring(5, explorePlace.name.lastIndexOf(".")));
nearbyBaseMarker.title(
explorePlace.name.substring(5, explorePlace.name.lastIndexOf(".")));
nearbyBaseMarker.position(
new com.mapbox.mapboxsdk.geometry.LatLng(
explorePlace.location.getLatitude(),
@ -160,12 +173,15 @@ public class ExploreMapController extends MapController {
.into(new CustomTarget<Bitmap>() {
// We add icons to markers when bitmaps are ready
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
public void onResourceReady(@NonNull Bitmap resource,
@Nullable Transition<? super Bitmap> transition) {
nearbyBaseMarker.setIcon(IconFactory.getInstance(context).fromBitmap(
ImageUtils.addRedBorder(resource, 6, context)));
baseMarkerOptions.add(nearbyBaseMarker);
if (baseMarkerOptions.size() == placeList.size()) { // if true, we added all markers to list and can trigger thumbs ready callback
callback.onNearbyBaseMarkerThumbsReady(baseMarkerOptions, explorePlacesInfo, selectedMarker, shouldTrackPosition);
if (baseMarkerOptions.size()
== placeList.size()) { // if true, we added all markers to list and can trigger thumbs ready callback
callback.onNearbyBaseMarkerThumbsReady(baseMarkerOptions,
explorePlacesInfo, selectedMarker);
}
}
@ -177,10 +193,13 @@ public class ExploreMapController extends MapController {
@Override
public void onLoadFailed(@Nullable final Drawable errorDrawable) {
super.onLoadFailed(errorDrawable);
nearbyBaseMarker.setIcon(IconFactory.getInstance(context).fromResource(R.drawable.image_placeholder_96));
nearbyBaseMarker.setIcon(IconFactory.getInstance(context)
.fromResource(R.drawable.image_placeholder_96));
baseMarkerOptions.add(nearbyBaseMarker);
if (baseMarkerOptions.size() == placeList.size()) { // if true, we added all markers to list and can trigger thumbs ready callback
callback.onNearbyBaseMarkerThumbsReady(baseMarkerOptions, explorePlacesInfo, selectedMarker, shouldTrackPosition);
if (baseMarkerOptions.size()
== placeList.size()) { // if true, we added all markers to list and can trigger thumbs ready callback
callback.onNearbyBaseMarkerThumbsReady(baseMarkerOptions,
explorePlacesInfo, selectedMarker);
}
}
});
@ -190,7 +209,9 @@ public class ExploreMapController extends MapController {
}
interface NearbyBaseMarkerThumbCallback {
// Callback to notify thumbnails of explore markers are added as icons and ready
void onNearbyBaseMarkerThumbsReady(List<NearbyBaseMarker> baseMarkers, ExplorePlacesInfo explorePlacesInfo, Marker selectedMarker, boolean shouldTrackPosition);
void onNearbyBaseMarkerThumbsReady(List<NearbyBaseMarker> baseMarkers,
ExplorePlacesInfo explorePlacesInfo, Marker selectedMarker);
}
}

View file

@ -1,9 +1,11 @@
package fr.free.nrw.commons.explore.map;
import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED;
import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.MAP_UPDATED;
import static fr.free.nrw.commons.location.LocationServiceManager.LocationChangeType.SEARCH_CUSTOM_AREA;
import android.location.Location;
import android.view.View;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
@ -25,9 +27,9 @@ import timber.log.Timber;
public class ExploreMapPresenter
implements ExploreMapContract.UserActions,
NearbyBaseMarkerThumbCallback {
BookmarkLocationsDao bookmarkLocationDao;
private boolean isNearbyLocked;
private boolean placesLoadedOnce;
private LatLng curLatLng;
private ExploreMapController exploreMapController;
@ -54,7 +56,7 @@ public class ExploreMapPresenter
);
private ExploreMapContract.View exploreMapFragmentView = DUMMY;
public ExploreMapPresenter(BookmarkLocationsDao bookmarkLocationDao){
public ExploreMapPresenter(BookmarkLocationsDao bookmarkLocationDao) {
this.bookmarkLocationDao = bookmarkLocationDao;
}
@ -71,14 +73,6 @@ public class ExploreMapPresenter
return;
}
LatLng lastLocation = exploreMapFragmentView.getLastLocation();
curLatLng = lastLocation;
if (curLatLng == null) {
Timber.d("Skipping update of nearby places as location is unavailable");
return;
}
/**
* Significant changed - Markers and current location will be updated together
* Slightly changed - Only current position marker will be updated
@ -87,24 +81,21 @@ public class ExploreMapPresenter
Timber.d("LOCATION_SIGNIFICANTLY_CHANGED");
lockUnlockNearby(true);
exploreMapFragmentView.setProgressBarVisibility(true);
exploreMapFragmentView.populatePlaces(curLatLng, lastLocation);
exploreMapFragmentView.populatePlaces(exploreMapFragmentView.getMapCenter());
} else if (locationChangeType.equals(SEARCH_CUSTOM_AREA)) {
Timber.d("SEARCH_CUSTOM_AREA");
lockUnlockNearby(true);
exploreMapFragmentView.setProgressBarVisibility(true);
exploreMapFragmentView.populatePlaces(curLatLng, exploreMapFragmentView.getCameraTarget());
exploreMapFragmentView.populatePlaces(exploreMapFragmentView.getMapFocus());
} else { // Means location changed slightly, ie user is walking or driving.
Timber.d("Means location changed slightly");
if (exploreMapFragmentView.isCurrentLocationMarkerVisible()){ // Means user wants to see their live location
exploreMapFragmentView.recenterMap(curLatLng);
}
}
}
/**
* Nearby updates takes time, since they are network operations. During update time, we don't
* want to get any other calls from user. So locking nearby.
*
* @param isNearbyLocked true means lock, false means unlock
*/
@Override
@ -143,29 +134,10 @@ public class ExploreMapPresenter
return exploreMapFragmentView.backButtonClicked();
}
@Override
public void onCameraMove(com.mapbox.mapboxsdk.geometry.LatLng latLng) {
exploreMapFragmentView.setProjectorLatLngBounds();
// If our nearby markers are calculated at least once
if (exploreMapController.latestSearchLocation != null) {
double distance = latLng.distanceTo
(LocationUtils.commonsLatLngToMapBoxLatLng(exploreMapController.latestSearchLocation));
if (exploreMapFragmentView.isNetworkConnectionEstablished()) {
if (distance > exploreMapController.latestSearchRadius && exploreMapController.latestSearchRadius != 0) {
exploreMapFragmentView.setSearchThisAreaButtonVisibility(true);
} else {
exploreMapFragmentView.setSearchThisAreaButtonVisibility(false);
}
}
} else {
exploreMapFragmentView.setSearchThisAreaButtonVisibility(false);
}
}
public void onMapReady(ExploreMapController exploreMapController) {
this.exploreMapController = exploreMapController;
exploreMapFragmentView.addSearchThisAreaButtonAction();
if(null != exploreMapFragmentView) {
if (null != exploreMapFragmentView) {
exploreMapFragmentView.addSearchThisAreaButtonAction();
initializeMapOperations();
}
@ -177,66 +149,49 @@ public class ExploreMapPresenter
exploreMapFragmentView.addSearchThisAreaButtonAction();
}
public Observable<ExplorePlacesInfo> loadAttractionsFromLocation(LatLng curLatLng, LatLng searchLatLng, boolean checkingAroundCurrent) {
public Observable<ExplorePlacesInfo> loadAttractionsFromLocation(LatLng curLatLng,
LatLng searchLatLng, boolean checkingAroundCurrent) {
return Observable
.fromCallable(() -> exploreMapController
.loadAttractionsFromLocation(curLatLng, searchLatLng,checkingAroundCurrent));
.loadAttractionsFromLocation(curLatLng, searchLatLng, checkingAroundCurrent));
}
/**
* Populates places for custom location, should be used for finding nearby places around a
* location where you are not at.
*
* @param explorePlacesInfo This variable has placeToCenter list information and distances.
*/
public void updateMapMarkers(
MapController.ExplorePlacesInfo explorePlacesInfo, Marker selectedMarker, boolean shouldTrackPosition) {
exploreMapFragmentView.setMapBoundaries(CameraUpdateFactory.newLatLngBounds(getLatLngBounds(explorePlacesInfo.boundaryCoordinates), 50));
prepareNearbyBaseMarkers(explorePlacesInfo, selectedMarker, shouldTrackPosition);
MapController.ExplorePlacesInfo explorePlacesInfo, Marker selectedMarker) {
if (explorePlacesInfo.mediaList != null) {
prepareNearbyBaseMarkers(explorePlacesInfo, selectedMarker);
} else {
//TODO: SHOW SNACKBAR
lockUnlockNearby(false); // So that new location updates wont come
exploreMapFragmentView.setProgressBarVisibility(false);
}
}
void prepareNearbyBaseMarkers(MapController.ExplorePlacesInfo explorePlacesInfo, Marker selectedMarker, boolean shouldTrackPosition) {
void prepareNearbyBaseMarkers(MapController.ExplorePlacesInfo explorePlacesInfo,
Marker selectedMarker) {
exploreMapController
.loadAttractionsFromLocationToBaseMarkerOptions(explorePlacesInfo.curLatLng, // Curlatlang will be used to calculate distances
.loadAttractionsFromLocationToBaseMarkerOptions(explorePlacesInfo.curLatLng,
// Curlatlang will be used to calculate distances
explorePlacesInfo.explorePlaceList,
exploreMapFragmentView.getContext(),
this,
selectedMarker,
shouldTrackPosition,
explorePlacesInfo);
}
@Override
public void onNearbyBaseMarkerThumbsReady(List<NearbyBaseMarker> baseMarkers, ExplorePlacesInfo explorePlacesInfo, Marker selectedMarker, boolean shouldTrackPosition) {
if(null != exploreMapFragmentView) {
exploreMapFragmentView.addNearbyMarkersToMapBoxMap(baseMarkers, selectedMarker);
exploreMapFragmentView.addCurrentLocationMarker(explorePlacesInfo.curLatLng);
if(shouldTrackPosition){
exploreMapFragmentView.updateMapToTrackPosition(explorePlacesInfo.curLatLng);
}
public void onNearbyBaseMarkerThumbsReady(List<NearbyBaseMarker> baseMarkers,
ExplorePlacesInfo explorePlacesInfo, Marker selectedMarker) {
if (null != exploreMapFragmentView) {
exploreMapFragmentView.addMarkersToMap(baseMarkers);
lockUnlockNearby(false); // So that new location updates wont come
exploreMapFragmentView.setProgressBarVisibility(false);
handleCenteringTaskIfAny();
}
}
private LatLngBounds getLatLngBounds(LatLng[] boundaries) {
LatLngBounds latLngBounds = new LatLngBounds.Builder()
.include(LocationUtils.commonsLatLngToMapBoxLatLng(boundaries[0]))
.include(LocationUtils.commonsLatLngToMapBoxLatLng(boundaries[1]))
.include(LocationUtils.commonsLatLngToMapBoxLatLng(boundaries[2]))
.include(LocationUtils.commonsLatLngToMapBoxLatLng(boundaries[3]))
.build();
return latLngBounds;
}
/**
* Some centering task may need to wait for map to be ready, if they are requested before
* map is ready. So we will remember it when the map is ready
*/
private void handleCenteringTaskIfAny() {
if (!placesLoadedOnce) {
placesLoadedOnce = true;
exploreMapFragmentView.centerMapToPlace(null);
}
}
@ -245,7 +200,7 @@ public class ExploreMapPresenter
// Lock map operations during search this area operation
exploreMapFragmentView.setSearchThisAreaButtonVisibility(false);
if (searchCloseToCurrentLocation()){
if (searchCloseToCurrentLocation()) {
updateMap(LOCATION_SIGNIFICANTLY_CHANGED);
} else {
updateMap(SEARCH_CUSTOM_AREA);
@ -254,40 +209,29 @@ public class ExploreMapPresenter
}
/**
* Returns true if search this area button is used around our current location, so that
* we can continue following our current location again
* Returns true if search this area button is used around our current location, so that we can
* continue following our current location again
*
* @return Returns true if search this area button is used around our current location
*/
public boolean searchCloseToCurrentLocation() {
if (null == exploreMapFragmentView.getLastFocusLocation() || exploreMapController.latestSearchRadius == 0) {
if (null == exploreMapFragmentView.getLastMapFocus()) {
return true;
}
double distance = LocationUtils.commonsLatLngToMapBoxLatLng(exploreMapFragmentView.getCameraTarget())
.distanceTo(exploreMapFragmentView.getLastFocusLocation());
if (distance > exploreMapController.currentLocationSearchRadius * 3 / 4) {
Location mylocation = new Location("");
Location dest_location = new Location("");
dest_location.setLatitude(exploreMapFragmentView.getMapFocus().getLatitude());
dest_location.setLongitude(exploreMapFragmentView.getMapFocus().getLongitude());
mylocation.setLatitude(exploreMapFragmentView.getLastMapFocus().getLatitude());
mylocation.setLongitude(exploreMapFragmentView.getLastMapFocus().getLongitude());
Float distance = mylocation.distanceTo(dest_location);
if (distance > 2000.0 * 3 / 4) {
return false;
} else {
return true;
}
}
@Override
public void markerUnselected() {
exploreMapFragmentView.hideBottomDetailsSheet();
}
@Override
public void markerSelected(Marker marker) {
exploreMapFragmentView.displayBottomSheetWithInfo(marker);
}
public boolean areLocationsClose(LatLng cameraTarget, LatLng lastKnownLocation) {
double distance = LocationUtils.commonsLatLngToMapBoxLatLng(cameraTarget)
.distanceTo(LocationUtils.commonsLatLngToMapBoxLatLng(lastKnownLocation));
if (distance > exploreMapController.currentLocationSearchRadius * 3 / 4) {
return false;
} else {
return true;
}
}
}