mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Replaced mapbox to osmdroid (Upload Activity) (#5443)
* 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
This commit is contained in:
parent
11e7b1cde7
commit
6319da5445
9 changed files with 206 additions and 382 deletions
|
|
@ -1,21 +1,20 @@
|
|||
package fr.free.nrw.commons.LocationPicker;
|
||||
|
||||
import static com.mapbox.mapboxsdk.style.layers.Property.NONE;
|
||||
import static com.mapbox.mapboxsdk.style.layers.Property.VISIBLE;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconIgnorePlacement;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconImage;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.visibility;
|
||||
import static fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_LOCATION;
|
||||
import static fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_ZOOM;
|
||||
import static fr.free.nrw.commons.utils.MapUtils.ZOOM_LEVEL;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.location.Location;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.Html;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.animation.OvershootInterpolator;
|
||||
|
|
@ -28,32 +27,10 @@ import androidx.appcompat.app.ActionBar;
|
|||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.AppCompatTextView;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.lifecycle.Observer;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||
import com.mapbox.geojson.Point;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition.Builder;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponent;
|
||||
import com.mapbox.mapboxsdk.location.LocationComponentActivationOptions;
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngineCallback;
|
||||
import com.mapbox.mapboxsdk.location.engine.LocationEngineResult;
|
||||
import com.mapbox.mapboxsdk.location.modes.CameraMode;
|
||||
import com.mapbox.mapboxsdk.location.modes.RenderMode;
|
||||
import com.mapbox.mapboxsdk.location.permissions.PermissionsManager;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraIdleListener;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraMoveStartedListener;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.maps.Style;
|
||||
import com.mapbox.mapboxsdk.maps.UiSettings;
|
||||
import com.mapbox.mapboxsdk.style.layers.Layer;
|
||||
import com.mapbox.mapboxsdk.style.layers.SymbolLayer;
|
||||
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
|
||||
import fr.free.nrw.commons.MapStyle;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.Utils;
|
||||
import fr.free.nrw.commons.filepicker.Constants;
|
||||
|
|
@ -64,21 +41,24 @@ import fr.free.nrw.commons.location.LocationPermissionsHelper.LocationPermission
|
|||
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||
import fr.free.nrw.commons.theme.BaseActivity;
|
||||
import fr.free.nrw.commons.utils.SystemThemeUtils;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import timber.log.Timber;
|
||||
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
|
||||
import org.osmdroid.util.GeoPoint;
|
||||
import org.osmdroid.util.constants.GeoConstants;
|
||||
import org.osmdroid.views.CustomZoomButtonsController;
|
||||
import org.osmdroid.views.overlay.Marker;
|
||||
import org.osmdroid.views.overlay.Overlay;
|
||||
import org.osmdroid.views.overlay.ScaleDiskOverlay;
|
||||
import org.osmdroid.views.overlay.TilesOverlay;
|
||||
|
||||
/**
|
||||
* Helps to pick location and return the result with an intent
|
||||
*/
|
||||
public class LocationPickerActivity extends BaseActivity implements OnMapReadyCallback,
|
||||
OnCameraMoveStartedListener, OnCameraIdleListener, Observer<CameraPosition>, LocationPermissionCallback {
|
||||
public class LocationPickerActivity extends BaseActivity implements
|
||||
LocationPermissionCallback {
|
||||
|
||||
/**
|
||||
* DROPPED_MARKER_LAYER_ID : id for layer
|
||||
*/
|
||||
private static final String DROPPED_MARKER_LAYER_ID = "DROPPED_MARKER_LAYER_ID";
|
||||
/**
|
||||
* cameraPosition : position of picker
|
||||
*/
|
||||
|
|
@ -88,13 +68,9 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
*/
|
||||
private ImageView markerImage;
|
||||
/**
|
||||
* mapboxMap : map
|
||||
* mapView : OSM Map
|
||||
*/
|
||||
private MapboxMap mapboxMap;
|
||||
/**
|
||||
* mapView : view of the map
|
||||
*/
|
||||
private MapView mapView;
|
||||
private org.osmdroid.views.MapView mapView;
|
||||
/**
|
||||
* tvAttribution : credit
|
||||
*/
|
||||
|
|
@ -103,10 +79,6 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
* activity : activity key
|
||||
*/
|
||||
private String activity;
|
||||
/**
|
||||
* location : location
|
||||
*/
|
||||
private Location location;
|
||||
/**
|
||||
* modifyLocationButton : button for start editing location
|
||||
*/
|
||||
|
|
@ -123,10 +95,6 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
* fabCenterOnLocation: button for center on location;
|
||||
*/
|
||||
FloatingActionButton fabCenterOnLocation;
|
||||
/**
|
||||
* droppedMarkerLayer : Layer for static screen
|
||||
*/
|
||||
private Layer droppedMarkerLayer;
|
||||
/**
|
||||
* shadow : imageview of shadow
|
||||
*/
|
||||
|
|
@ -152,16 +120,19 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
@Inject
|
||||
SystemThemeUtils systemThemeUtils;
|
||||
private boolean isDarkTheme;
|
||||
private boolean moveToCurrentLocation;
|
||||
|
||||
@Inject
|
||||
LocationServiceManager locationManager;
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
@Override
|
||||
protected void onCreate(@Nullable final Bundle savedInstanceState) {
|
||||
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
isDarkTheme = systemThemeUtils.isDeviceInNightMode();
|
||||
moveToCurrentLocation = false;
|
||||
|
||||
getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
|
||||
final ActionBar actionBar = getSupportActionBar();
|
||||
|
|
@ -176,10 +147,6 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
activity = getIntent().getStringExtra(LocationPickerConstants.ACTIVITY_KEY);
|
||||
}
|
||||
|
||||
final LocationPickerViewModel viewModel = new ViewModelProvider(this)
|
||||
.get(LocationPickerViewModel.class);
|
||||
viewModel.getResult().observe(this, this);
|
||||
|
||||
bindViews();
|
||||
addBackButtonListener();
|
||||
addPlaceSelectedButton();
|
||||
|
|
@ -187,6 +154,31 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
getToolbarUI();
|
||||
addCenterOnGPSButton();
|
||||
|
||||
org.osmdroid.config.Configuration.getInstance().load(getApplicationContext(),
|
||||
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()));
|
||||
|
||||
mapView.setTileSource(TileSourceFactory.WIKIMEDIA);
|
||||
mapView.setTilesScaledToDpi(true);
|
||||
mapView.setMultiTouchControls(true);
|
||||
|
||||
org.osmdroid.config.Configuration.getInstance().getAdditionalHttpRequestProperties().put(
|
||||
"Referer", "http://maps.wikimedia.org/"
|
||||
);
|
||||
mapView.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
|
||||
mapView.getController().setZoom(ZOOM_LEVEL);
|
||||
mapView.setOnTouchListener((v, event) -> {
|
||||
if (event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
if (markerImage.getTranslationY() == 0) {
|
||||
markerImage.animate().translationY(-75)
|
||||
.setInterpolator(new OvershootInterpolator()).setDuration(250).start();
|
||||
}
|
||||
} else if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
markerImage.animate().translationY(0)
|
||||
.setInterpolator(new OvershootInterpolator()).setDuration(250).start();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if ("UploadActivity".equals(activity)) {
|
||||
placeSelectedButton.setVisibility(View.GONE);
|
||||
modifyLocationButton.setVisibility(View.VISIBLE);
|
||||
|
|
@ -195,10 +187,13 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
smallToolbarText.setText(getResources().
|
||||
getString(R.string.check_whether_location_is_correct));
|
||||
fabCenterOnLocation.setVisibility(View.GONE);
|
||||
markerImage.setVisibility(View.GONE);
|
||||
shadow.setVisibility(View.GONE);
|
||||
assert cameraPosition.target != null;
|
||||
showSelectedLocationMarker(new GeoPoint(cameraPosition.target.getLatitude(),
|
||||
cameraPosition.target.getLongitude()));
|
||||
}
|
||||
|
||||
mapView.onCreate(savedInstanceState);
|
||||
mapView.getMapAsync(this);
|
||||
setupMapView();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -209,6 +204,17 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
tvAttribution.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
|
||||
/**
|
||||
* For setting up Dark Theme
|
||||
*/
|
||||
private void darkThemeSetup() {
|
||||
if (isDarkTheme) {
|
||||
shadow.setColorFilter(Color.argb(255, 255, 255, 255));
|
||||
mapView.getOverlayManager().getTilesOverlay()
|
||||
.setColorFilter(TilesOverlay.INVERT_COLORS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clicking back button destroy locationPickerActivity
|
||||
*/
|
||||
|
|
@ -230,16 +236,6 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
shadow = findViewById(R.id.location_picker_image_view_shadow);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the listeners
|
||||
*/
|
||||
private void bindListeners() {
|
||||
mapboxMap.addOnCameraMoveStartedListener(
|
||||
this);
|
||||
mapboxMap.addOnCameraIdleListener(
|
||||
this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets toolbar color
|
||||
*/
|
||||
|
|
@ -250,49 +246,12 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
toolbar.setBackgroundColor(getResources().getColor(R.color.primaryColor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes action when map is ready to show
|
||||
* @param mapboxMap map
|
||||
*/
|
||||
@Override
|
||||
public void onMapReady(final MapboxMap mapboxMap) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
mapboxMap.setStyle(isDarkTheme ? MapStyle.DARK : MapStyle.STREETS, this::onStyleLoaded);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes dropped marker and layer
|
||||
* Handles camera position based on options
|
||||
* Enables location components
|
||||
*
|
||||
* @param style style
|
||||
*/
|
||||
private void onStyleLoaded(final Style style) {
|
||||
if (modifyLocationButton.getVisibility() == View.VISIBLE) {
|
||||
initDroppedMarker(style);
|
||||
adjustCameraBasedOnOptions();
|
||||
enableLocationComponent(style);
|
||||
if (style.getLayer(DROPPED_MARKER_LAYER_ID) != null) {
|
||||
final GeoJsonSource source = style.getSourceAs("dropped-marker-source-id");
|
||||
if (source != null) {
|
||||
source.setGeoJson(Point.fromLngLat(cameraPosition.target.getLongitude(),
|
||||
cameraPosition.target.getLatitude()));
|
||||
}
|
||||
droppedMarkerLayer = style.getLayer(DROPPED_MARKER_LAYER_ID);
|
||||
if (droppedMarkerLayer != null) {
|
||||
droppedMarkerLayer.setProperties(visibility(VISIBLE));
|
||||
markerImage.setVisibility(View.GONE);
|
||||
shadow.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
adjustCameraBasedOnOptions();
|
||||
enableLocationComponent(style);
|
||||
bindListeners();
|
||||
}
|
||||
|
||||
private void setupMapView() {
|
||||
adjustCameraBasedOnOptions();
|
||||
modifyLocationButton.setOnClickListener(v -> onClickModifyLocation());
|
||||
showInMapButton.setOnClickListener(v -> showInMap());
|
||||
darkThemeSetup();
|
||||
requestLocationPermissions();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -302,13 +261,16 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
placeSelectedButton.setVisibility(View.VISIBLE);
|
||||
modifyLocationButton.setVisibility(View.GONE);
|
||||
showInMapButton.setVisibility(View.GONE);
|
||||
droppedMarkerLayer.setProperties(visibility(NONE));
|
||||
markerImage.setVisibility(View.VISIBLE);
|
||||
shadow.setVisibility(View.VISIBLE);
|
||||
largeToolbarText.setText(getResources().getString(R.string.choose_a_location));
|
||||
smallToolbarText.setText(getResources().getString(R.string.pan_and_zoom_to_adjust));
|
||||
bindListeners();
|
||||
fabCenterOnLocation.setVisibility(View.VISIBLE);
|
||||
removeSelectedLocationMarker();
|
||||
if (cameraPosition.target != null) {
|
||||
mapView.getController().animateTo(new GeoPoint(cameraPosition.target.getLatitude(),
|
||||
cameraPosition.target.getLongitude()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -316,120 +278,20 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
*/
|
||||
public void showInMap() {
|
||||
Utils.handleGeoCoordinates(this,
|
||||
new fr.free.nrw.commons.location.LatLng(cameraPosition.target.getLatitude(),
|
||||
cameraPosition.target.getLongitude(), 0.0f));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize Dropped Marker and layer without showing
|
||||
* @param loadedMapStyle style
|
||||
*/
|
||||
private void initDroppedMarker(@NonNull final Style loadedMapStyle) {
|
||||
// Add the marker image to map
|
||||
loadedMapStyle.addImage("dropped-icon-image", BitmapFactory.decodeResource(
|
||||
getResources(), R.drawable.map_default_map_marker));
|
||||
loadedMapStyle.addSource(new GeoJsonSource("dropped-marker-source-id"));
|
||||
loadedMapStyle.addLayer(new SymbolLayer(DROPPED_MARKER_LAYER_ID,
|
||||
"dropped-marker-source-id").withProperties(
|
||||
iconImage("dropped-icon-image"),
|
||||
visibility(NONE),
|
||||
iconAllowOverlap(true),
|
||||
iconIgnorePlacement(true)
|
||||
));
|
||||
new fr.free.nrw.commons.location.LatLng(mapView.getMapCenter().getLatitude(),
|
||||
mapView.getMapCenter().getLongitude(), 0.0f));
|
||||
}
|
||||
|
||||
/**
|
||||
* move the location to the current media coordinates
|
||||
*/
|
||||
private void adjustCameraBasedOnOptions() {
|
||||
mapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables location components
|
||||
* @param loadedMapStyle Style
|
||||
*/
|
||||
@SuppressWarnings( {"MissingPermission"})
|
||||
private void enableLocationComponent(@NonNull final Style loadedMapStyle) {
|
||||
final UiSettings uiSettings = mapboxMap.getUiSettings();
|
||||
uiSettings.setAttributionEnabled(false);
|
||||
|
||||
// Check if permissions are enabled and if not request
|
||||
if (PermissionsManager.areLocationPermissionsGranted(this)) {
|
||||
|
||||
// Get an instance of the component
|
||||
final LocationComponent locationComponent = mapboxMap.getLocationComponent();
|
||||
|
||||
// Activate with options
|
||||
locationComponent.activateLocationComponent(
|
||||
LocationComponentActivationOptions.builder(this, loadedMapStyle).build());
|
||||
|
||||
// Enable to make component visible
|
||||
locationComponent.setLocationComponentEnabled(true);
|
||||
|
||||
// Set the component's camera mode
|
||||
locationComponent.setCameraMode(CameraMode.NONE);
|
||||
|
||||
// Set the component's render mode
|
||||
locationComponent.setRenderMode(RenderMode.NORMAL);
|
||||
|
||||
// Get the component's location engine to receive user's last location
|
||||
locationComponent.getLocationEngine().getLastLocation(
|
||||
new LocationEngineCallback<LocationEngineResult>() {
|
||||
@Override
|
||||
public void onSuccess(LocationEngineResult result) {
|
||||
location = result.getLastLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(@NonNull Exception exception) {
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
} else {
|
||||
requestLocationPermissions();
|
||||
if (cameraPosition.target != null) {
|
||||
mapView.getController().setCenter(new GeoPoint(cameraPosition.target.getLatitude(),
|
||||
cameraPosition.target.getLongitude()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Acts on camera moving
|
||||
* @param reason int
|
||||
*/
|
||||
@Override
|
||||
public void onCameraMoveStarted(final int reason) {
|
||||
Timber.v("Map camera has begun moving.");
|
||||
if (markerImage.getTranslationY() == 0) {
|
||||
markerImage.animate().translationY(-75)
|
||||
.setInterpolator(new OvershootInterpolator()).setDuration(250).start();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Acts on camera idle
|
||||
*/
|
||||
@Override
|
||||
public void onCameraIdle() {
|
||||
Timber.v("Map camera is now idling.");
|
||||
markerImage.animate().translationY(0)
|
||||
.setInterpolator(new OvershootInterpolator()).setDuration(250).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes action on camera position
|
||||
* @param position position of picker
|
||||
*/
|
||||
@Override
|
||||
public void onChanged(@Nullable CameraPosition position) {
|
||||
if (position == null) {
|
||||
position = new Builder()
|
||||
.target(new LatLng(mapboxMap.getCameraPosition().target.getLatitude(),
|
||||
mapboxMap.getCameraPosition().target.getLongitude()))
|
||||
.zoom(16).build();
|
||||
}
|
||||
cameraPosition = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the preferable location
|
||||
*/
|
||||
|
|
@ -444,23 +306,60 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
void placeSelected() {
|
||||
if (activity.equals("NoLocationUploadActivity")) {
|
||||
applicationKvStore.putString(LAST_LOCATION,
|
||||
mapboxMap.getCameraPosition().target.getLatitude()
|
||||
mapView.getMapCenter().getLatitude()
|
||||
+ ","
|
||||
+ mapboxMap.getCameraPosition().target.getLongitude());
|
||||
applicationKvStore.putString(LAST_ZOOM, mapboxMap.getCameraPosition().zoom + "");
|
||||
+ mapView.getMapCenter().getLongitude());
|
||||
applicationKvStore.putString(LAST_ZOOM, mapView.getZoomLevel() + "");
|
||||
}
|
||||
final Intent returningIntent = new Intent();
|
||||
returningIntent.putExtra(LocationPickerConstants.MAP_CAMERA_POSITION,
|
||||
mapboxMap.getCameraPosition());
|
||||
new CameraPosition(new LatLng(mapView.getMapCenter().getLatitude(),
|
||||
mapView.getMapCenter().getLongitude()), 14f, 0, 0));
|
||||
setResult(AppCompatActivity.RESULT_OK, returningIntent);
|
||||
finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Center the camera on the last saved location
|
||||
*/
|
||||
private void addCenterOnGPSButton(){
|
||||
private void addCenterOnGPSButton() {
|
||||
fabCenterOnLocation = findViewById(R.id.center_on_gps);
|
||||
fabCenterOnLocation.setOnClickListener(view -> requestLocationPermissions());
|
||||
fabCenterOnLocation.setOnClickListener(view -> {
|
||||
moveToCurrentLocation = true;
|
||||
requestLocationPermissions();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds selected location marker on the map
|
||||
*/
|
||||
private void showSelectedLocationMarker(GeoPoint point) {
|
||||
Drawable icon = ContextCompat.getDrawable(this, R.drawable.map_default_map_marker);
|
||||
Marker marker = new Marker(mapView);
|
||||
marker.setPosition(point);
|
||||
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
|
||||
marker.setIcon(icon);
|
||||
marker.setInfoWindow(null);
|
||||
mapView.getOverlays().add(marker);
|
||||
mapView.invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes selected location marker from the map
|
||||
*/
|
||||
private void removeSelectedLocationMarker() {
|
||||
List<Overlay> overlays = mapView.getOverlays();
|
||||
for (int i = 0; i < overlays.size(); i++) {
|
||||
if (overlays.get(i) instanceof Marker) {
|
||||
Marker item = (Marker) overlays.get(i);
|
||||
if (cameraPosition.target.getLatitude() == item.getPosition().getLatitude()
|
||||
&& cameraPosition.target.getLongitude() == item.getPosition().getLongitude()) {
|
||||
mapView.getOverlays().remove(i);
|
||||
mapView.invalidate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -478,13 +377,16 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
);
|
||||
LocationPermissionsHelper locationPermissionsHelper = new LocationPermissionsHelper(
|
||||
this, locationManager, this);
|
||||
locationPermissionsHelper.handleLocationPermissions(locationAccessDialog, locationOffDialog);
|
||||
locationPermissionsHelper.handleLocationPermissions(locationAccessDialog,
|
||||
locationOffDialog);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(final int requestCode, @NonNull final String[] permissions,
|
||||
public void onRequestPermissionsResult(final int requestCode,
|
||||
@NonNull final String[] permissions,
|
||||
@NonNull final int[] grantResults) {
|
||||
if (requestCode == Constants.RequestCodes.LOCATION && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
if (requestCode == Constants.RequestCodes.LOCATION
|
||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
onLocationPermissionGranted();
|
||||
} else {
|
||||
onLocationPermissionDenied("");
|
||||
|
|
@ -492,12 +394,6 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart() {
|
||||
super.onStart();
|
||||
mapView.onStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
|
@ -510,30 +406,6 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
mapView.onStop();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(final @NotNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLocationPermissionDenied(String toastMessage) {
|
||||
//do nothing
|
||||
|
|
@ -541,19 +413,49 @@ public class LocationPickerActivity extends BaseActivity implements OnMapReadyCa
|
|||
|
||||
@Override
|
||||
public void onLocationPermissionGranted() {
|
||||
if (mapboxMap.getStyle() != null) {
|
||||
enableLocationComponent(mapboxMap.getStyle());
|
||||
}
|
||||
fr.free.nrw.commons.location.LatLng currLocation = locationManager.getLastLocation();
|
||||
if (currLocation != null) {
|
||||
final CameraPosition position;
|
||||
position = new CameraPosition.Builder()
|
||||
.target(new com.mapbox.mapboxsdk.geometry.LatLng(currLocation.getLatitude(),
|
||||
currLocation.getLongitude(), 0)) // Sets the new camera position
|
||||
.zoom(mapboxMap.getCameraPosition().zoom) // Same zoom level
|
||||
.build();
|
||||
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(position), 1000);
|
||||
GeoPoint currLocationGeopoint = new GeoPoint(currLocation.getLatitude(),
|
||||
currLocation.getLongitude());
|
||||
addLocationMarker(currLocationGeopoint);
|
||||
if (moveToCurrentLocation) {
|
||||
mapView.getController().setCenter(currLocationGeopoint);
|
||||
mapView.getController().animateTo(currLocationGeopoint);
|
||||
moveToCurrentLocation = false;
|
||||
}
|
||||
markerImage.setTranslationY(0);
|
||||
}
|
||||
}
|
||||
|
||||
private void addLocationMarker(GeoPoint geoPoint) {
|
||||
if (moveToCurrentLocation) {
|
||||
mapView.getOverlays().clear();
|
||||
}
|
||||
ScaleDiskOverlay diskOverlay =
|
||||
new ScaleDiskOverlay(this,
|
||||
geoPoint, 2000, GeoConstants.UnitOfMeasure.foot);
|
||||
Paint circlePaint = new Paint();
|
||||
circlePaint.setColor(Color.rgb(128, 128, 128));
|
||||
circlePaint.setStyle(Paint.Style.STROKE);
|
||||
circlePaint.setStrokeWidth(2f);
|
||||
diskOverlay.setCirclePaint2(circlePaint);
|
||||
Paint diskPaint = new Paint();
|
||||
diskPaint.setColor(Color.argb(40, 128, 128, 128));
|
||||
diskPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
diskOverlay.setCirclePaint1(diskPaint);
|
||||
diskOverlay.setDisplaySizeMin(900);
|
||||
diskOverlay.setDisplaySizeMax(1700);
|
||||
mapView.getOverlays().add(diskOverlay);
|
||||
org.osmdroid.views.overlay.Marker startMarker = new org.osmdroid.views.overlay.Marker(
|
||||
mapView);
|
||||
startMarker.setPosition(geoPoint);
|
||||
startMarker.setAnchor(org.osmdroid.views.overlay.Marker.ANCHOR_CENTER,
|
||||
org.osmdroid.views.overlay.Marker.ANCHOR_BOTTOM);
|
||||
startMarker.setIcon(
|
||||
ContextCompat.getDrawable(this, R.drawable.current_location_marker));
|
||||
startMarker.setTitle("Your Location");
|
||||
startMarker.setTextLabelFontSize(24);
|
||||
mapView.getOverlays().add(startMarker);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 4.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.7 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 6 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB |
18
app/src/main/res/drawable/map_default_map_marker.xml
Normal file
18
app/src/main/res/drawable/map_default_map_marker.xml
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="32dp"
|
||||
android:height="44dp"
|
||||
android:viewportWidth="32"
|
||||
android:viewportHeight="44">
|
||||
<path
|
||||
android:pathData="M17.431,42.146C16.502,43.187 14.927,43.187 13.998,42.146C9.202,36.77 -3.689,20.865 1.017,9.968C6.757,-3.323 24.672,-3.323 30.412,9.968C35.118,20.865 22.227,36.77 17.431,42.146Z"
|
||||
android:fillColor="#023E5A"/>
|
||||
<path
|
||||
android:pathData="M15.714,41.066C15.714,41.066 -1.998,22.695 2.976,10.924C7.95,-0.848 23.477,-0.848 28.452,10.924C33.426,22.695 15.714,41.066 15.714,41.066Z"
|
||||
android:fillColor="#2CB7A9"/>
|
||||
<path
|
||||
android:pathData="M15.505,15.505m-6.286,0a6.286,6.286 0,1 1,12.571 0a6.286,6.286 0,1 1,-12.571 0"
|
||||
android:fillColor="#003B59"/>
|
||||
<path
|
||||
android:pathData="M15.505,15.505m-4.19,0a4.19,4.19 0,1 1,8.381 0a4.19,4.19 0,1 1,-8.381 0"
|
||||
android:fillColor="#F84D4D"/>
|
||||
</vector>
|
||||
|
|
@ -22,17 +22,15 @@
|
|||
android:id="@+id/location_picker_image_view_shadow"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/location_picker_image_view_shadow"
|
||||
android:elevation="1dp"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/map_view"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/location_picker_image_view_marker"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
app:srcCompat="@drawable/map_default_map_marker_shadow"
|
||||
android:contentDescription="@string/location_picker_image_view_shadow" />
|
||||
app:srcCompat="@drawable/map_default_map_marker_shadow" />
|
||||
|
||||
<com.mapbox.mapboxsdk.maps.MapView
|
||||
<org.osmdroid.views.MapView
|
||||
android:id="@+id/map_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
|
|
@ -40,9 +38,9 @@
|
|||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
|
||||
</com.mapbox.mapboxsdk.maps.MapView>
|
||||
|
||||
<include layout="@layout/bottom_container_location_picker"/>
|
||||
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ import org.junit.runner.RunWith
|
|||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.*
|
||||
import org.mockito.MockitoAnnotations
|
||||
import org.osmdroid.api.IMapController
|
||||
import org.osmdroid.util.GeoPoint
|
||||
import org.powermock.reflect.Whitebox
|
||||
import org.robolectric.Robolectric
|
||||
import org.robolectric.RobolectricTestRunner
|
||||
|
|
@ -54,7 +56,7 @@ class LocationPickerActivityUnitTests {
|
|||
private lateinit var applicationKvStore: JsonKvStore
|
||||
|
||||
@Mock
|
||||
private lateinit var mapboxMap: MapboxMap
|
||||
private lateinit var mapView: org.osmdroid.views.MapView
|
||||
|
||||
@Mock
|
||||
private lateinit var cameraPosition: CameraPosition
|
||||
|
|
@ -68,9 +70,6 @@ class LocationPickerActivityUnitTests {
|
|||
@Mock
|
||||
private lateinit var showInMapButton: TextView
|
||||
|
||||
@Mock
|
||||
private lateinit var droppedMarkerLayer: Layer
|
||||
|
||||
@Mock
|
||||
private lateinit var markerImage: ImageView
|
||||
|
||||
|
|
@ -89,22 +88,18 @@ class LocationPickerActivityUnitTests {
|
|||
@Mock
|
||||
private lateinit var tvAttribution: AppCompatTextView
|
||||
|
||||
@Mock
|
||||
private lateinit var style: Style
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
context = RuntimeEnvironment.getApplication().applicationContext
|
||||
activity = Robolectric.buildActivity(LocationPickerActivity::class.java).get()
|
||||
|
||||
Whitebox.setInternalState(activity, "mapboxMap", mapboxMap)
|
||||
Whitebox.setInternalState(activity, "mapView", mapView)
|
||||
Whitebox.setInternalState(activity, "applicationKvStore", applicationKvStore)
|
||||
Whitebox.setInternalState(activity, "cameraPosition", cameraPosition)
|
||||
Whitebox.setInternalState(activity, "modifyLocationButton", modifyLocationButton)
|
||||
Whitebox.setInternalState(activity, "placeSelectedButton", placeSelectedButton)
|
||||
Whitebox.setInternalState(activity, "showInMapButton", showInMapButton)
|
||||
Whitebox.setInternalState(activity, "droppedMarkerLayer", droppedMarkerLayer)
|
||||
Whitebox.setInternalState(activity, "markerImage", markerImage)
|
||||
Whitebox.setInternalState(activity, "shadow", shadow)
|
||||
Whitebox.setInternalState(activity, "largeToolbarText", largeToolbarText)
|
||||
|
|
@ -119,42 +114,6 @@ class LocationPickerActivityUnitTests {
|
|||
Assert.assertNotNull(activity)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testBindListeners() {
|
||||
val method: Method = LocationPickerActivity::class.java.getDeclaredMethod(
|
||||
"bindListeners"
|
||||
)
|
||||
method.isAccessible = true
|
||||
method.invoke(activity)
|
||||
verify(mapboxMap, times(1)).addOnCameraMoveStartedListener(activity)
|
||||
verify(mapboxMap, times(1)).addOnCameraIdleListener(activity)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnMapReady() {
|
||||
val method: Method = LocationPickerActivity::class.java.getDeclaredMethod(
|
||||
"onMapReady",
|
||||
MapboxMap::class.java
|
||||
)
|
||||
method.isAccessible = true
|
||||
try {
|
||||
method.invoke(activity, mapboxMap)
|
||||
fail("Expected an exception to be thrown")
|
||||
} catch (e: InvocationTargetException) {
|
||||
assertTrue((e.targetException is MapboxConfigurationException) ||
|
||||
(e.targetException is ExceptionInInitializerError))
|
||||
if (e.targetException is MapboxConfigurationException) {
|
||||
assertEquals(
|
||||
"\nUsing MapView requires calling Mapbox.getInstance(Context context, String apiKey,"
|
||||
+ " WellKnownTileServer wellKnownTileServer) before inflating or creating the view.",
|
||||
e.targetException.message
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testAddCredits() {
|
||||
|
|
@ -167,49 +126,6 @@ class LocationPickerActivityUnitTests {
|
|||
verify(tvAttribution).movementMethod = any()
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testAdjustCameraBasedOnOptions() {
|
||||
val method: Method = LocationPickerActivity::class.java.getDeclaredMethod(
|
||||
"adjustCameraBasedOnOptions"
|
||||
)
|
||||
method.isAccessible = true
|
||||
method.invoke(activity)
|
||||
verify(mapboxMap, times(1))
|
||||
.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnChanged() {
|
||||
val method: Method = LocationPickerActivity::class.java.getDeclaredMethod(
|
||||
"onChanged",
|
||||
CameraPosition::class.java
|
||||
)
|
||||
method.isAccessible = true
|
||||
method.invoke(activity, mock(CameraPosition::class.java))
|
||||
verify(mapboxMap, times(0)).cameraPosition
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnStyleLoaded() {
|
||||
whenever(modifyLocationButton.visibility).thenReturn(View.INVISIBLE)
|
||||
whenever(mapboxMap.uiSettings).thenReturn(mock(UiSettings::class.java))
|
||||
val method: Method = LocationPickerActivity::class.java.getDeclaredMethod(
|
||||
"onStyleLoaded",
|
||||
Style::class.java
|
||||
)
|
||||
method.isAccessible = true
|
||||
method.invoke(activity, style)
|
||||
verify(modifyLocationButton, times(1)).visibility
|
||||
verify(mapboxMap, times(1))
|
||||
.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))
|
||||
verify(mapboxMap, times(1)).uiSettings
|
||||
verify(mapboxMap, times(1)).addOnCameraMoveStartedListener(activity)
|
||||
verify(mapboxMap, times(1)).addOnCameraIdleListener(activity)
|
||||
}
|
||||
|
||||
@Test
|
||||
@Throws(Exception::class)
|
||||
fun testOnClickModifyLocation() {
|
||||
|
|
@ -223,12 +139,9 @@ class LocationPickerActivityUnitTests {
|
|||
verify(showInMapButton, times(1)).visibility = View.GONE
|
||||
verify(markerImage, times(1)).visibility = View.VISIBLE
|
||||
verify(shadow, times(1)).visibility = View.VISIBLE
|
||||
verify(droppedMarkerLayer, times(1)).setProperties(any())
|
||||
verify(largeToolbarText, times(1)).text = "Choose a location"
|
||||
verify(smallToolbarText, times(1)).text = "Pan and zoom to adjust"
|
||||
verify(fabCenterOnLocation, times(1)).visibility = View.VISIBLE
|
||||
verify(mapboxMap, times(1)).addOnCameraMoveStartedListener(activity)
|
||||
verify(mapboxMap, times(1)).addOnCameraIdleListener(activity)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -236,27 +149,20 @@ class LocationPickerActivityUnitTests {
|
|||
fun testPlaceSelected() {
|
||||
Shadows.shadowOf(Looper.getMainLooper()).idle()
|
||||
Whitebox.setInternalState(activity,"activity", "NoLocationUploadActivity")
|
||||
val position = CameraPosition.Builder().target(
|
||||
LatLng(
|
||||
51.50550,
|
||||
-0.07520,
|
||||
0.0
|
||||
)
|
||||
).zoom(15.0).build()
|
||||
`when`(mapboxMap.cameraPosition).thenReturn(position)
|
||||
val position = GeoPoint(51.50550, -0.07520)
|
||||
val method: Method = LocationPickerActivity::class.java.getDeclaredMethod(
|
||||
"placeSelected"
|
||||
)
|
||||
`when`(mapView.mapCenter).thenReturn(position)
|
||||
`when`(mapView.zoomLevel).thenReturn(15)
|
||||
method.isAccessible = true
|
||||
method.invoke(activity)
|
||||
verify(applicationKvStore, times(1))
|
||||
.putString(LAST_LOCATION, position.target!!.latitude.toString()
|
||||
+ ","
|
||||
+ position.target!!.longitude
|
||||
)
|
||||
verify(applicationKvStore, times(1))
|
||||
.putString(LAST_ZOOM, position.zoom.toString())
|
||||
verify(mapboxMap, times(4)).cameraPosition
|
||||
verify(applicationKvStore, times(1)).putString(
|
||||
LAST_LOCATION,
|
||||
position.latitude.toString() + "," + position.longitude.toString()
|
||||
)
|
||||
verify(applicationKvStore, times(1)).putString(LAST_ZOOM, mapView.zoomLevel.toString())
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue