Skip to content

Commit 950539c

Browse files
Fixes Issue #5713: "Edit location" is hard to use (and confusing) (#5767)
* LocationPickerActivity.java: fix "Show in Map App" bug Once the "Show in Map App" button is pressed, the Map app will center on the current photo's EXIF location, if that data is available. If not, the map app will center on where the location picker's map is centered. Javadoc updated to reflect this small change. * LocationPickerActivity.java: add methods to easily move the map center Before this change, any time the map center had to move, several lines of code had to be written. This change creates several methods which move the map center to a specified location. By using these new methods, moving the map center only takes one simple method call. * LocationPickerActivity.java: add null check to method The original method did not include a null check for the input GeoPoint. This change includes a null check. If the input Geopoint is null, the method will simply return. * LocationPickerActivity.java: remove redundant method, renaming method Before this change, there were two methods with the same behavior. This change removes the newer method and renames the old method to the descriptive name the newer one had. Additionally, code which calls this method has been changed to reflect the new name. * LocationPickerActivity.java: rearrange method calls. Before this change, a method call to move the map to the device's GPS location was called at the very end of the map setup method. This would move the map away from the media's EXIF location data (if it was available). This change places the method call to move the map to the device's GPS location before the method call to move the map to the media's EXIF location (if the data is available). In short, if no exif data is available, the map attempts to move to the device's GPS location. If the exif location data does exist, the map will move to that location. * LocationPickerActivity.java: rewrite method scope, name, and documentation Before this commit, the method name was unclear and the documentation did not fully explain the method's behavior. Additionally, it was a public method. This commit renames the method (also changing calls to it), adds more documentation, and changes the method scope from public to private. * LocationPickerActivity.java: create method to move location picker map to device GPS location Before this method was created, several lines of code were required to move the location picker map to the device's GPS location. After this method was created, the location picker map can be moved to the GPS location in a single method call. * LocationPickerActivity.java: add code to move map to either EXIF or device GPS location Before this change, there was no explicit if check on whether there was EXIF data available before moving the location picker map. After this change, an explicit if check (which checks the activity name string) will move the location picker map to either the EXIF location (if that data is available) or to the device's GPS location (if EXIF data is not available). * LocationPickerActivity.java: refactor showInMapApp method Before this change, the showInMapApp method had correct behavior, but could be rewritten to become more clear. After this change, the showInMapApp code has been rewritten. Specifically, common code in an if statement has been factored out. * LocationPickerActivity.java: add null checks to showInMapApp Before this change, there was no null checks when accessing data from an object, which could create null pointer exceptions at runtime. After this change, null checks are introduced to make sure null pointer exceptions will not occur. * LocationPickerActivity.java: rewrite comments to clarify if statement Before this change, a comment in showInMapApp did not properly describe an if statement's intended behavior. After this change, the old comment was removed and 2 new comments were added in each part of the if statement to properly describe the intended behavior. * LocationPickerActivity.java: replace code with a method call Before this change, there was several lines of code which moved the map center to the EXIF location. After this change, the several lines of code have been replaced with a simpler method call which produces the same result. * LocationPickerActivity.java: remove redundant code Before this change, there was two sections of code which moved the map center to the same location. Both of these code sections occur very close to each other (one in onCreate(), the other in setupMapView()) After this change, the code section in onCreate() has been removed. With the map centering code only in the setupMapView() method. This change eliminates redundancy, reduces the amount of code in onCreate(), and makes this java file easier to understand. * content_location_picker.xml: adjust picker pin and shadow location Before this commit, the location picker pin and shadow graphics were incorrectly located on the screen. Specifically, the bottom of the pin was not located at the center of the view. Since pressing the checkmark button saves the location at the center of the view, users would most likely save the wrong location. After this commit, the location picker pin and shadow graphics have been moved upward. The shadow graphic is now located at the exact center of the view, and the bottom of the location picker pin is directly over the center as well. Users may now use the bottom of the pin as an accurate location picker. * LocationPickerActivity.java: fix bug with permissions menu moving map Prior to this change, if the menu asking for permissions to access the device's GPS was accepted, the map would automatically move to the most recent or current GPS location, rather than staying at the uploaded image's available EXIF location. After this change, the map will stay centered at the image's available EXIF location, as intended. The relevant method name and javadoc have been changed to more accurately describe the method's behavior. * LocationPickerActivity.java: fix map centering bug when editing location on already uploaded media Before this commit, when the user pressed the edit location icon on media which was already uploaded, the map would center on the device's current GPS location. After this commit, pressing the same edit location icon will now center the map on the location metadata. This is done by checking the activity string to see if the media is already uploaded. If so, a method is called to center the map on the media's location metadata. * LocationPickerActivity.java: replace references to EXIF in documentation Before this commit, there were several mentions of EXIF location data in the javadocs. It is not clear if this is correct, since many images have location data that is chosen by the user rather than derived from EXIF. After this commit, the more generic term "location metadata" is used in place of EXIF location data. Hopefully this change will help avoid confusion in the future. --------- Co-authored-by: Nicolas Raoul <nicolas.raoul@gmail.com>
1 parent f751ab4 commit 950539c

File tree

2 files changed

+83
-36
lines changed

2 files changed

+83
-36
lines changed

app/src/main/java/fr/free/nrw/commons/LocationPicker/LocationPickerActivity.java

+80-34
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import fr.free.nrw.commons.Utils;
4141
import fr.free.nrw.commons.auth.SessionManager;
4242
import fr.free.nrw.commons.auth.csrf.CsrfTokenClient;
43-
import fr.free.nrw.commons.auth.csrf.InvalidLoginTokenException;
4443
import fr.free.nrw.commons.coordinates.CoordinateEditHelper;
4544
import fr.free.nrw.commons.filepicker.Constants;
4645
import fr.free.nrw.commons.kvstore.BasicKvStore;
@@ -237,15 +236,28 @@ protected void onCreate(@Nullable final Bundle savedInstanceState) {
237236
cameraPosition.getLongitude()));
238237
}
239238
setupMapView();
240-
241-
if("UploadActivity".equals(activity)){
242-
if(mapView != null && mapView.getController() != null && cameraPosition != null){
243-
GeoPoint cameraGeoPoint = new GeoPoint(cameraPosition.getLatitude(),
244-
cameraPosition.getLongitude());
245-
246-
mapView.getController().setCenter(cameraGeoPoint);
247-
mapView.getController().animateTo(cameraGeoPoint);
248-
}
239+
}
240+
241+
/**
242+
* Moves the center of the map to the specified coordinates
243+
*
244+
*/
245+
private void moveMapTo(double latitude, double longitude){
246+
if(mapView != null && mapView.getController() != null){
247+
GeoPoint point = new GeoPoint(latitude, longitude);
248+
249+
mapView.getController().setCenter(point);
250+
mapView.getController().animateTo(point);
251+
}
252+
}
253+
254+
/**
255+
* Moves the center of the map to the specified coordinates
256+
* @param point The GeoPoint object which contains the coordinates to move to
257+
*/
258+
private void moveMapTo(GeoPoint point){
259+
if(point != null){
260+
moveMapTo(point.getLatitude(), point.getLongitude());
249261
}
250262
}
251263

@@ -304,12 +316,20 @@ private void getToolbarUI() {
304316
}
305317

306318
private void setupMapView() {
307-
adjustCameraBasedOnOptions();
319+
requestLocationPermissions();
320+
321+
//If location metadata is available, move map to that location.
322+
if(activity.equals("UploadActivity") || activity.equals("MediaActivity")){
323+
moveMapToMediaLocation();
324+
} else {
325+
//If location metadata is not available, move map to device GPS location.
326+
moveMapToGPSLocation();
327+
}
328+
308329
modifyLocationButton.setOnClickListener(v -> onClickModifyLocation());
309330
removeLocationButton.setOnClickListener(v -> onClickRemoveLocation());
310-
showInMapButton.setOnClickListener(v -> showInMap());
331+
showInMapButton.setOnClickListener(v -> showInMapApp());
311332
darkThemeSetup();
312-
requestLocationPermissions();
313333
}
314334

315335
/**
@@ -326,12 +346,7 @@ private void onClickModifyLocation() {
326346
smallToolbarText.setText(getResources().getString(R.string.pan_and_zoom_to_adjust));
327347
fabCenterOnLocation.setVisibility(View.VISIBLE);
328348
removeSelectedLocationMarker();
329-
if (cameraPosition != null && mapView != null) {
330-
if (mapView.getController() != null) {
331-
mapView.getController().animateTo(new GeoPoint(cameraPosition.getLatitude(),
332-
cameraPosition.getLongitude()));
333-
}
334-
}
349+
moveMapToMediaLocation();
335350
}
336351

337352
/**
@@ -364,21 +379,53 @@ private void removeLocationFromImage() {
364379
}
365380

366381
/**
367-
* Show the location in map app
382+
* Show the location in map app. Map will center on the location metadata, if available.
383+
* If there is no location metadata, the map will center on the commons app map center.
368384
*/
369-
public void showInMap() {
370-
Utils.handleGeoCoordinates(this,
371-
new fr.free.nrw.commons.location.LatLng(mapView.getMapCenter().getLatitude(),
372-
mapView.getMapCenter().getLongitude(), 0.0f));
385+
private void showInMapApp() {
386+
fr.free.nrw.commons.location.LatLng position = null;
387+
388+
if(activity.equals("UploadActivity") && cameraPosition != null){
389+
//location metadata is available
390+
position = new fr.free.nrw.commons.location.LatLng(cameraPosition.getLatitude(),
391+
cameraPosition.getLongitude(), 0.0f);
392+
} else if(mapView != null){
393+
//location metadata is not available
394+
position = new fr.free.nrw.commons.location.LatLng(mapView.getMapCenter().getLatitude(),
395+
mapView.getMapCenter().getLongitude(), 0.0f);
396+
}
397+
398+
if(position != null){
399+
Utils.handleGeoCoordinates(this, position);
400+
}
373401
}
374402

375403
/**
376-
* move the location to the current media coordinates
404+
* Moves the center of the map to the media's location, if that data
405+
* is available.
377406
*/
378-
private void adjustCameraBasedOnOptions() {
407+
private void moveMapToMediaLocation() {
379408
if (cameraPosition != null) {
380-
mapView.getController().setCenter(new GeoPoint(cameraPosition.getLatitude(),
381-
cameraPosition.getLongitude()));
409+
410+
GeoPoint point = new GeoPoint(cameraPosition.getLatitude(),
411+
cameraPosition.getLongitude());
412+
413+
moveMapTo(point);
414+
}
415+
}
416+
417+
/**
418+
* Moves the center of the map to the device's GPS location, if that data is available.
419+
*/
420+
private void moveMapToGPSLocation(){
421+
if(locationManager != null){
422+
fr.free.nrw.commons.location.LatLng location = locationManager.getLastLocation();
423+
424+
if(location != null){
425+
GeoPoint point = new GeoPoint(location.getLatitude(), location.getLongitude());
426+
427+
moveMapTo(point);
428+
}
382429
}
383430
}
384431

@@ -557,26 +604,25 @@ public void onLocationPermissionGranted() {
557604
locationManager.requestLocationUpdatesFromProvider(
558605
LocationManager.NETWORK_PROVIDER);
559606
locationManager.requestLocationUpdatesFromProvider(LocationManager.GPS_PROVIDER);
560-
getLocation();
607+
addMarkerAtGPSLocation();
561608
} else {
562-
getLocation();
609+
addMarkerAtGPSLocation();
563610
locationPermissionsHelper.showLocationOffDialog(this,
564611
R.string.ask_to_turn_location_on_text);
565612
}
566613
}
567614
}
568615

569616
/**
570-
* Gets new location if locations services are on, else gets last location
617+
* Adds a marker to the map at the most recent GPS location
618+
* (which may be the current GPS location).
571619
*/
572-
private void getLocation() {
620+
private void addMarkerAtGPSLocation() {
573621
fr.free.nrw.commons.location.LatLng currLocation = locationManager.getLastLocation();
574622
if (currLocation != null) {
575623
GeoPoint currLocationGeopoint = new GeoPoint(currLocation.getLatitude(),
576624
currLocation.getLongitude());
577625
addLocationMarker(currLocationGeopoint);
578-
mapView.getController().setCenter(currLocationGeopoint);
579-
mapView.getController().animateTo(currLocationGeopoint);
580626
markerImage.setTranslationY(0);
581627
}
582628
}

app/src/main/res/layout/content_location_picker.xml

+3-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
app:layout_constraintStart_toStartOf="parent"
1717
app:layout_constraintTop_toTopOf="parent"
1818
app:srcCompat="@drawable/map_default_map_marker"
19+
android:layout_marginBottom="45dp"
1920
android:contentDescription="@string/location_picker_image_view" />
2021

2122
<ImageView
@@ -24,10 +25,10 @@
2425
android:layout_height="wrap_content"
2526
android:contentDescription="@string/location_picker_image_view_shadow"
2627
android:elevation="1dp"
28+
app:layout_constraintBottom_toBottomOf="parent"
2729
app:layout_constraintEnd_toEndOf="parent"
28-
app:layout_constraintRight_toRightOf="parent"
2930
app:layout_constraintStart_toStartOf="parent"
30-
app:layout_constraintTop_toTopOf="@+id/location_picker_image_view_marker"
31+
app:layout_constraintTop_toTopOf="parent"
3132
app:srcCompat="@drawable/map_default_map_marker_shadow" />
3233

3334
<org.osmdroid.views.MapView

0 commit comments

Comments
 (0)