[android] - Refactor dependencies, introduce focused components (#7189)
* [android] - refactor dependencies * ignore tests
This commit is contained in:
@@ -9,6 +9,7 @@ import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.mapbox.mapboxsdk.R;
|
||||
@@ -31,27 +32,31 @@ import java.util.Map;
|
||||
*/
|
||||
public class MarkerViewManager {
|
||||
|
||||
private Map<MarkerView, View> markerViewMap;
|
||||
private final ViewGroup markerViewContainer;
|
||||
private final Map<MarkerView, View> markerViewMap = new HashMap<>();
|
||||
private final List<MapboxMap.MarkerViewAdapter> markerViewAdapters = new ArrayList<>();
|
||||
|
||||
// TODO refactor MapboxMap out for Projection and Transform
|
||||
// Requires removing MapboxMap from Annotations by using Peer model from #6912
|
||||
private MapboxMap mapboxMap;
|
||||
private MapView mapView;
|
||||
private List<MapboxMap.MarkerViewAdapter> markerViewAdapters;
|
||||
|
||||
private long viewMarkerBoundsUpdateTime;
|
||||
private MapboxMap.OnMarkerViewClickListener onMarkerViewClickListener;
|
||||
private ImageMarkerViewAdapter defaultMarkerViewAdapter;
|
||||
|
||||
/**
|
||||
* Creates an instance of MarkerViewManager.
|
||||
*
|
||||
* @param mapboxMap the MapboxMap associated with the MarkerViewManager
|
||||
* @param mapView the MapView associated with the MarkerViewManager
|
||||
* @param container the ViewGroup associated with the MarkerViewManager
|
||||
*/
|
||||
public MarkerViewManager(@NonNull MapboxMap mapboxMap, @NonNull MapView mapView) {
|
||||
public MarkerViewManager(@NonNull ViewGroup container) {
|
||||
this.markerViewContainer = container;
|
||||
this.markerViewAdapters.add(new ImageMarkerViewAdapter(container.getContext()));
|
||||
}
|
||||
|
||||
// TODO refactor MapboxMap out for Projection and Transform
|
||||
// Requires removing MapboxMap from Annotations by using Peer model from #6912
|
||||
public void bind(MapboxMap mapboxMap){
|
||||
this.mapboxMap = mapboxMap;
|
||||
this.markerViewAdapters = new ArrayList<>();
|
||||
this.mapView = mapView;
|
||||
this.markerViewMap = new HashMap<>();
|
||||
this.defaultMarkerViewAdapter = new ImageMarkerViewAdapter(mapView.getContext());
|
||||
this.markerViewAdapters.add(defaultMarkerViewAdapter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -415,7 +420,7 @@ public class MarkerViewManager {
|
||||
* </p>
|
||||
*/
|
||||
public void invalidateViewMarkersInVisibleRegion() {
|
||||
RectF mapViewRect = new RectF(0, 0, mapView.getWidth(), mapView.getHeight());
|
||||
RectF mapViewRect = new RectF(0, 0, markerViewContainer.getWidth(), markerViewContainer.getHeight());
|
||||
List<MarkerView> markers = mapboxMap.getMarkerViewsInRect(mapViewRect);
|
||||
View convertView;
|
||||
|
||||
@@ -445,7 +450,7 @@ public class MarkerViewManager {
|
||||
|
||||
// Inflate View
|
||||
convertView = (View) adapter.getViewReusePool().acquire();
|
||||
final View adaptedView = adapter.getView(marker, convertView, mapView);
|
||||
final View adaptedView = adapter.getView(marker, convertView, markerViewContainer);
|
||||
if (adaptedView != null) {
|
||||
adaptedView.setRotationX(marker.getTilt());
|
||||
adaptedView.setRotation(marker.getRotation());
|
||||
@@ -464,7 +469,7 @@ public class MarkerViewManager {
|
||||
markerViewMap.put(marker, adaptedView);
|
||||
if (convertView == null) {
|
||||
adaptedView.setVisibility(View.GONE);
|
||||
mapView.getMarkerViewContainer().addView(adaptedView);
|
||||
markerViewContainer.addView(adaptedView);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -515,7 +520,7 @@ public class MarkerViewManager {
|
||||
for (final MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
|
||||
if (adapter.getMarkerClass().equals(marker.getClass())) {
|
||||
View convertView = (View) adapter.getViewReusePool().acquire();
|
||||
view = adapter.getView(marker, convertView, mapView);
|
||||
view = adapter.getView(marker, convertView, markerViewContainer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -523,7 +528,7 @@ public class MarkerViewManager {
|
||||
|
||||
if (view != null) {
|
||||
if (marker.getWidth() == 0) {
|
||||
if(view.getMeasuredWidth()==0) {
|
||||
if (view.getMeasuredWidth() == 0) {
|
||||
//Ensure the marker's view is measured first
|
||||
view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
|
||||
}
|
||||
@@ -546,6 +551,10 @@ public class MarkerViewManager {
|
||||
}
|
||||
}
|
||||
|
||||
public ViewGroup getMarkerViewContainer() {
|
||||
return markerViewContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default MarkerViewAdapter used for base class of {@link MarkerView} to adapt a MarkerView to
|
||||
* an ImageView.
|
||||
|
||||
@@ -257,7 +257,7 @@ public final class CameraUpdateFactory {
|
||||
float scaleX = (uiSettings.getWidth() - padding.left - padding.right) / width;
|
||||
float scaleY = (uiSettings.getHeight() - padding.top - padding.bottom) / height;
|
||||
minScale = scaleX < scaleY ? scaleX : scaleY;
|
||||
zoom = projection.calculateZoom(minScale);
|
||||
zoom = calculateZoom(mapboxMap, minScale);
|
||||
zoom = MathUtils.clamp(zoom, mapboxMap.getMinZoom(), mapboxMap.getMaxZoom());
|
||||
}
|
||||
|
||||
@@ -275,6 +275,16 @@ public final class CameraUpdateFactory {
|
||||
.bearing(0)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a zoom level based on minimum scale and current scale from MapView
|
||||
*
|
||||
* @param minScale The minimum scale to calculate the zoom level.
|
||||
* @return zoom level that fits the MapView.
|
||||
*/
|
||||
public double calculateZoom(MapboxMap mapboxMap, float minScale) {
|
||||
return Math.log(mapboxMap.getCameraPosition().zoom * minScale) / Math.log(2);
|
||||
}
|
||||
}
|
||||
|
||||
static final class CameraMoveUpdate implements CameraUpdate {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package com.mapbox.mapboxsdk.maps;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.LongSparseArray;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.Annotation;
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
|
||||
@@ -18,6 +20,7 @@ import com.mapbox.mapboxsdk.annotations.Polyline;
|
||||
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -32,30 +35,38 @@ import java.util.List;
|
||||
*/
|
||||
class AnnotationManager implements MapView.OnMapChangedListener {
|
||||
|
||||
private NativeMapView nativeMapView;
|
||||
private IconManager iconManager;
|
||||
private InfoWindowManager infoWindowManager;
|
||||
private MarkerViewManager markerViewManager;
|
||||
private final NativeMapView nativeMapView;
|
||||
private final MapView mapView;
|
||||
private final IconManager iconManager;
|
||||
private final InfoWindowManager infoWindowManager = new InfoWindowManager();
|
||||
private final MarkerViewManager markerViewManager;
|
||||
private final LongSparseArray<Annotation> annotations = new LongSparseArray<>();
|
||||
private final List<Marker> selectedMarkers = new ArrayList<>();
|
||||
|
||||
private LongSparseArray<Annotation> annotations;
|
||||
private List<Marker> selectedMarkers;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
private MapboxMap.OnMarkerClickListener onMarkerClickListener;
|
||||
private boolean isWaitingForRenderInvoke;
|
||||
|
||||
AnnotationManager(NativeMapView view, IconManager iconManager, InfoWindowManager manager) {
|
||||
AnnotationManager(NativeMapView view, MapView mapView, MarkerViewManager markerViewManager) {
|
||||
this.nativeMapView = view;
|
||||
this.iconManager = iconManager;
|
||||
this.infoWindowManager = manager;
|
||||
this.selectedMarkers = new ArrayList<>();
|
||||
this.annotations = new LongSparseArray<>();
|
||||
|
||||
this.mapView = mapView;
|
||||
this.iconManager = new IconManager(nativeMapView);
|
||||
this.markerViewManager = markerViewManager;
|
||||
if (view != null) {
|
||||
// null checking needed for unit tests
|
||||
view.addOnMapChangedListener(this);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO refactor MapboxMap out for Projection and Transform
|
||||
// Requires removing MapboxMap from Annotations by using Peer model from #6912
|
||||
AnnotationManager bind(MapboxMap mapboxMap) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
this.markerViewManager.bind(mapboxMap);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapChanged(@MapView.MapChange int change) {
|
||||
if (isWaitingForRenderInvoke && change == MapView.DID_FINISH_RENDERING_FRAME_FULLY_RENDERED) {
|
||||
@@ -280,7 +291,7 @@ class AnnotationManager implements MapView.OnMapChangedListener {
|
||||
onMarkerClickListener = listener;
|
||||
}
|
||||
|
||||
void selectMarker(@NonNull Marker marker, @NonNull MapboxMap mapboxMap) {
|
||||
void selectMarker(@NonNull Marker marker) {
|
||||
if (selectedMarkers.contains(marker)) {
|
||||
return;
|
||||
}
|
||||
@@ -303,7 +314,7 @@ class AnnotationManager implements MapView.OnMapChangedListener {
|
||||
}
|
||||
|
||||
if (infoWindowManager.isInfoWindowValidForMarker(marker) || infoWindowManager.getInfoWindowAdapter() != null) {
|
||||
infoWindowManager.add(marker.showInfoWindow(mapboxMap, mapboxMap.getMapView()));
|
||||
infoWindowManager.add(marker.showInfoWindow(mapboxMap, mapView));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -564,14 +575,11 @@ class AnnotationManager implements MapView.OnMapChangedListener {
|
||||
return polylines;
|
||||
}
|
||||
|
||||
//
|
||||
// MarkerViewManager
|
||||
//
|
||||
InfoWindowManager getInfoWindowManager() {
|
||||
return infoWindowManager;
|
||||
}
|
||||
|
||||
MarkerViewManager getMarkerViewManager(MapboxMap mapboxMap) {
|
||||
if (markerViewManager == null) {
|
||||
this.markerViewManager = new MarkerViewManager(mapboxMap, mapboxMap.getMapView());
|
||||
}
|
||||
MarkerViewManager getMarkerViewManager() {
|
||||
return markerViewManager;
|
||||
}
|
||||
|
||||
@@ -589,12 +597,13 @@ class AnnotationManager implements MapView.OnMapChangedListener {
|
||||
for (Marker marker : selectedMarkers) {
|
||||
if (marker.isInfoWindowShown()) {
|
||||
marker.hideInfoWindow();
|
||||
marker.showInfoWindow(mapboxMap, mapboxMap.getMapView());
|
||||
marker.showInfoWindow(mapboxMap, mapView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void reloadMarkers() {
|
||||
iconManager.reloadIcons();
|
||||
int count = annotations.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
Annotation annotation = annotations.get(i);
|
||||
@@ -606,4 +615,58 @@ class AnnotationManager implements MapView.OnMapChangedListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Click event
|
||||
//
|
||||
|
||||
boolean onTap(PointF tapPoint, float screenDensity) {
|
||||
float toleranceSides = 4 * screenDensity;
|
||||
float toleranceTopBottom = 10 * screenDensity;
|
||||
|
||||
RectF tapRect = new RectF(tapPoint.x - iconManager.getAverageIconWidth() / 2 - toleranceSides,
|
||||
tapPoint.y - iconManager.getAverageIconHeight() / 2 - toleranceTopBottom,
|
||||
tapPoint.x + iconManager.getAverageIconWidth() / 2 + toleranceSides,
|
||||
tapPoint.y + iconManager.getAverageIconHeight() / 2 + toleranceTopBottom);
|
||||
|
||||
List<Marker> nearbyMarkers = getMarkersInRect(tapRect);
|
||||
long newSelectedMarkerId = -1;
|
||||
|
||||
if (nearbyMarkers != null && nearbyMarkers.size() > 0) {
|
||||
Collections.sort(nearbyMarkers);
|
||||
for (Marker nearbyMarker : nearbyMarkers) {
|
||||
boolean found = false;
|
||||
for (Marker selectedMarker : selectedMarkers) {
|
||||
if (selectedMarker.equals(nearbyMarker)) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
newSelectedMarkerId = nearbyMarker.getId();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newSelectedMarkerId >= 0) {
|
||||
List<Annotation> annotations = getAnnotations();
|
||||
int count = annotations.size();
|
||||
for (int i = 0; i < count; i++) {
|
||||
Annotation annotation = annotations.get(i);
|
||||
if (annotation instanceof Marker) {
|
||||
if (annotation.getId() == newSelectedMarkerId) {
|
||||
if (selectedMarkers.isEmpty() || !selectedMarkers.contains(annotation)) {
|
||||
if (!(annotation instanceof MarkerView)) {
|
||||
selectMarker((Marker) annotation);
|
||||
} else {
|
||||
markerViewManager.onClickMarkerView((MarkerView) annotation);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.maps;
|
||||
|
||||
/**
|
||||
* Settings for the overlain views of a MapboxMap. Used by UiSettings.
|
||||
*/
|
||||
class CompassViewSettings extends ViewSettings{
|
||||
|
||||
private boolean fadeFacingNorth = true;
|
||||
|
||||
public CompassViewSettings() {
|
||||
super();
|
||||
}
|
||||
|
||||
public boolean isFadeFacingNorth() {
|
||||
return fadeFacingNorth;
|
||||
}
|
||||
|
||||
public void setFadeFacingNorth(boolean fadeFacingNorth) {
|
||||
this.fadeFacingNorth = fadeFacingNorth;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.mapbox.mapboxsdk.maps;
|
||||
|
||||
import android.graphics.PointF;
|
||||
|
||||
public interface FocalPointChangeListener {
|
||||
|
||||
void onFocalPointChanged(PointF pointF);
|
||||
}
|
||||
@@ -0,0 +1,601 @@
|
||||
package com.mapbox.mapboxsdk.maps;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PointF;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.view.GestureDetectorCompat;
|
||||
import android.support.v4.view.ScaleGestureDetectorCompat;
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ScaleGestureDetector;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
import com.almeros.android.multitouch.gesturedetectors.RotateGestureDetector;
|
||||
import com.almeros.android.multitouch.gesturedetectors.ShoveGestureDetector;
|
||||
import com.almeros.android.multitouch.gesturedetectors.TwoFingerGestureDetector;
|
||||
import com.mapbox.mapboxsdk.constants.MapboxConstants;
|
||||
import com.mapbox.mapboxsdk.telemetry.MapboxEvent;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Manages gestures events on a MapView.
|
||||
* <p>
|
||||
* Relies on gesture detection code in almeros.android.multitouch.gesturedetectors.
|
||||
* </p>
|
||||
*/
|
||||
final class MapGestureDetector {
|
||||
|
||||
private final Transform transform;
|
||||
private final Projection projection;
|
||||
private final UiSettings uiSettings;
|
||||
private final TrackingSettings trackingSettings;
|
||||
private final AnnotationManager annotationManager;
|
||||
|
||||
private final GestureDetectorCompat gestureDetector;
|
||||
private final ScaleGestureDetector scaleGestureDetector;
|
||||
private final RotateGestureDetector rotateGestureDetector;
|
||||
private final ShoveGestureDetector shoveGestureDetector;
|
||||
|
||||
private MapboxMap.OnMapClickListener onMapClickListener;
|
||||
private MapboxMap.OnMapLongClickListener onMapLongClickListener;
|
||||
private MapboxMap.OnFlingListener onFlingListener;
|
||||
private MapboxMap.OnScrollListener onScrollListener;
|
||||
|
||||
private PointF focalPoint;
|
||||
|
||||
private boolean twoTap = false;
|
||||
private boolean zoomStarted = false;
|
||||
private boolean dragStarted = false;
|
||||
private boolean quickZoom = false;
|
||||
private boolean scrollInProgress = false;
|
||||
|
||||
MapGestureDetector(Context context, Transform transform, Projection projection, UiSettings uiSettings,
|
||||
TrackingSettings trackingSettings, AnnotationManager annotationManager) {
|
||||
this.annotationManager = annotationManager;
|
||||
this.transform = transform;
|
||||
this.projection = projection;
|
||||
this.uiSettings = uiSettings;
|
||||
this.trackingSettings = trackingSettings;
|
||||
|
||||
// Touch gesture detectors
|
||||
gestureDetector = new GestureDetectorCompat(context, new GestureListener());
|
||||
gestureDetector.setIsLongpressEnabled(true);
|
||||
scaleGestureDetector = new ScaleGestureDetector(context, new ScaleGestureListener());
|
||||
ScaleGestureDetectorCompat.setQuickScaleEnabled(scaleGestureDetector, true);
|
||||
rotateGestureDetector = new RotateGestureDetector(context, new RotateGestureListener());
|
||||
shoveGestureDetector = new ShoveGestureDetector(context, new ShoveGestureListener());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the gesture focal point.
|
||||
* <p>
|
||||
* this is the center point used for calculate transformations from gestures, value is
|
||||
* overridden if end user provides his own through {@link UiSettings#setFocalPoint(PointF)}.
|
||||
* </p>
|
||||
*
|
||||
* @param focalPoint the center point for gestures
|
||||
*/
|
||||
void setFocalPoint(PointF focalPoint) {
|
||||
if (focalPoint == null) {
|
||||
// resetting focal point,
|
||||
if (uiSettings.getFocalPoint() != null) {
|
||||
// using user provided one to reset
|
||||
focalPoint = uiSettings.getFocalPoint();
|
||||
}
|
||||
}
|
||||
this.focalPoint = focalPoint;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called when user touches the screen, all positions are absolute.
|
||||
* <p>
|
||||
* Forwards event to the related gesture detectors.
|
||||
* </p>
|
||||
*
|
||||
* @param event the MotionEvent
|
||||
* @return True if touch event is handled
|
||||
*/
|
||||
boolean onTouchEvent(@NonNull MotionEvent event) {
|
||||
// Check and ignore non touch or left clicks
|
||||
if ((event.getButtonState() != 0) && (event.getButtonState() != MotionEvent.BUTTON_PRIMARY)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check two finger gestures first
|
||||
rotateGestureDetector.onTouchEvent(event);
|
||||
scaleGestureDetector.onTouchEvent(event);
|
||||
shoveGestureDetector.onTouchEvent(event);
|
||||
|
||||
// Handle two finger tap
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
// First pointer down
|
||||
transform.setGestureInProgress(true);
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_POINTER_DOWN:
|
||||
// Second pointer down
|
||||
twoTap = event.getPointerCount() == 2
|
||||
&& uiSettings.isZoomGesturesEnabled();
|
||||
if (twoTap) {
|
||||
// Confirmed 2nd Finger Down
|
||||
MapboxEvent.trackGestureEvent(projection, MapboxEvent.GESTURE_TWO_FINGER_SINGLETAP, event.getX(), event.getY(), transform.getZoom());
|
||||
}
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_POINTER_UP:
|
||||
// Second pointer up
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_UP:
|
||||
// First pointer up
|
||||
long tapInterval = event.getEventTime() - event.getDownTime();
|
||||
boolean isTap = tapInterval <= ViewConfiguration.getTapTimeout();
|
||||
boolean inProgress = rotateGestureDetector.isInProgress()
|
||||
|| scaleGestureDetector.isInProgress()
|
||||
|| shoveGestureDetector.isInProgress();
|
||||
|
||||
if (twoTap && isTap && !inProgress) {
|
||||
if (focalPoint != null) {
|
||||
transform.zoom(false, focalPoint.x, focalPoint.y);
|
||||
} else {
|
||||
PointF focalPoint = TwoFingerGestureDetector.determineFocalPoint(event);
|
||||
transform.zoom(false, focalPoint.x, focalPoint.y);
|
||||
}
|
||||
twoTap = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Scroll / Pan Has Stopped
|
||||
if (scrollInProgress) {
|
||||
MapboxEvent.trackGestureDragEndEvent(projection, event.getX(), event.getY(), transform.getZoom());
|
||||
scrollInProgress = false;
|
||||
}
|
||||
|
||||
twoTap = false;
|
||||
transform.setGestureInProgress(false);
|
||||
break;
|
||||
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
twoTap = false;
|
||||
transform.setGestureInProgress(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return gestureDetector.onTouchEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called for events that don't fit the other handlers.
|
||||
* <p>
|
||||
* Examples of such events are mouse scroll events, mouse moves, joystick & trackpad.
|
||||
* </p>
|
||||
*
|
||||
* @param event The MotionEvent occured
|
||||
* @return True is the event is handled
|
||||
*/
|
||||
boolean onGenericMotionEvent(MotionEvent event) {
|
||||
// Mouse events
|
||||
//if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { // this is not available before API 18
|
||||
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == InputDevice.SOURCE_CLASS_POINTER) {
|
||||
// Choose the action
|
||||
switch (event.getActionMasked()) {
|
||||
// Mouse scrolls
|
||||
case MotionEvent.ACTION_SCROLL:
|
||||
if (!uiSettings.isZoomGesturesEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
transform.cancelTransitions();
|
||||
|
||||
// Get the vertical scroll amount, one click = 1
|
||||
float scrollDist = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
|
||||
|
||||
// Scale the map by the appropriate power of two factor
|
||||
transform.zoomBy(Math.pow(2.0, scrollDist), event.getX(), event.getY());
|
||||
|
||||
return true;
|
||||
|
||||
default:
|
||||
// We are not interested in this event
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// We are not interested in this event
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Responsible for handling one finger gestures.
|
||||
*/
|
||||
private class GestureListener extends android.view.GestureDetector.SimpleOnGestureListener {
|
||||
|
||||
@Override
|
||||
public boolean onDown(MotionEvent event) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onDoubleTapEvent(MotionEvent e) {
|
||||
if (!uiSettings.isZoomGesturesEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (e.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (quickZoom) {
|
||||
// insert here?
|
||||
quickZoom = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Single finger double tap
|
||||
if (focalPoint != null) {
|
||||
// User provided focal point
|
||||
transform.zoom(true, focalPoint.x, focalPoint.y);
|
||||
} else {
|
||||
// Zoom in on gesture
|
||||
transform.zoom(true, e.getX(), e.getY());
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
MapboxEvent.trackGestureEvent(projection, MapboxEvent.GESTURE_DOUBLETAP, e.getX(), e.getY(), transform.getZoom());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapUp(MotionEvent motionEvent) {
|
||||
// Cancel any animation
|
||||
transform.cancelTransitions();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
|
||||
PointF tapPoint = new PointF(motionEvent.getX(), motionEvent.getY());
|
||||
boolean tapHandled = annotationManager.onTap(tapPoint, uiSettings.getPixelRatio());
|
||||
|
||||
if (!tapHandled) {
|
||||
if (uiSettings.isDeselectMarkersOnTap()) {
|
||||
// deselect any selected marker
|
||||
annotationManager.deselectMarkers();
|
||||
}
|
||||
|
||||
// notify app of map click
|
||||
if (onMapClickListener != null) {
|
||||
onMapClickListener.onMapClick(projection.fromScreenLocation(tapPoint));
|
||||
}
|
||||
}
|
||||
|
||||
MapboxEvent.trackGestureEvent(projection, MapboxEvent.GESTURE_SINGLETAP, motionEvent.getX(), motionEvent.getY(), transform.getZoom());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLongPress(MotionEvent motionEvent) {
|
||||
if (onMapLongClickListener != null && !quickZoom) {
|
||||
onMapLongClickListener.onMapLongClick(projection.fromScreenLocation(new PointF(motionEvent.getX(), motionEvent.getY())));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
|
||||
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
trackingSettings.resetTrackingModesIfRequired(true, false);
|
||||
|
||||
double decelerationRate = 1;
|
||||
|
||||
// Cancel any animation
|
||||
transform.cancelTransitions();
|
||||
|
||||
float screenDensity = uiSettings.getPixelRatio();
|
||||
double offsetX = velocityX * decelerationRate / 4 / screenDensity;
|
||||
double offsetY = velocityY * decelerationRate / 4 / screenDensity;
|
||||
|
||||
transform.setGestureInProgress(true);
|
||||
transform.moveBy(offsetX, offsetY, (long) (decelerationRate * 1000.0f));
|
||||
transform.setGestureInProgress(false);
|
||||
|
||||
if (onFlingListener != null) {
|
||||
onFlingListener.onFling();
|
||||
}
|
||||
|
||||
MapboxEvent.trackGestureEvent(projection, MapboxEvent.GESTURE_PAN_START, e1.getX(), e1.getY(), transform.getZoom());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called for drags
|
||||
@Override
|
||||
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
|
||||
if (!scrollInProgress) {
|
||||
scrollInProgress = true;
|
||||
}
|
||||
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dragStarted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// reset tracking if needed
|
||||
trackingSettings.resetTrackingModesIfRequired(true, false);
|
||||
// Cancel any animation
|
||||
transform.cancelTransitions();
|
||||
|
||||
// Scroll the map
|
||||
transform.moveBy(-distanceX, -distanceY, 0 /*no duration*/);
|
||||
|
||||
if (onScrollListener != null) {
|
||||
onScrollListener.onScroll();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for handling two finger gestures and double-tap drag gestures.
|
||||
*/
|
||||
private class ScaleGestureListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
|
||||
|
||||
long beginTime = 0;
|
||||
float scaleFactor = 1.0f;
|
||||
|
||||
// Called when two fingers first touch the screen
|
||||
@Override
|
||||
public boolean onScaleBegin(ScaleGestureDetector detector) {
|
||||
if (!uiSettings.isZoomGesturesEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
beginTime = detector.getEventTime();
|
||||
MapboxEvent.trackGestureEvent(projection, MapboxEvent.GESTURE_PINCH_START, detector.getFocusX(), detector.getFocusY(), transform.getZoom());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called when fingers leave screen
|
||||
@Override
|
||||
public void onScaleEnd(ScaleGestureDetector detector) {
|
||||
beginTime = 0;
|
||||
scaleFactor = 1.0f;
|
||||
zoomStarted = false;
|
||||
}
|
||||
|
||||
// Called each time a finger moves
|
||||
// Called for pinch zooms and quickzooms/quickscales
|
||||
@Override
|
||||
public boolean onScale(ScaleGestureDetector detector) {
|
||||
if (!uiSettings.isZoomGesturesEnabled()) {
|
||||
return super.onScale(detector);
|
||||
}
|
||||
|
||||
// If scale is large enough ignore a tap
|
||||
scaleFactor *= detector.getScaleFactor();
|
||||
if ((scaleFactor > 1.05f) || (scaleFactor < 0.95f)) {
|
||||
zoomStarted = true;
|
||||
}
|
||||
|
||||
// Ignore short touches in case it is a tap
|
||||
// Also ignore small scales
|
||||
long time = detector.getEventTime();
|
||||
long interval = time - beginTime;
|
||||
if (!zoomStarted && (interval <= ViewConfiguration.getTapTimeout())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!zoomStarted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (dragStarted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
transform.cancelTransitions();
|
||||
|
||||
// Gesture is a quickzoom if there aren't two fingers
|
||||
quickZoom = !twoTap;
|
||||
|
||||
// make an assumption here; if the zoom center is specified by the gesture, it's NOT going
|
||||
// to be in the center of the map. Therefore the zoom will translate the map center, so tracking
|
||||
// should be disabled.
|
||||
|
||||
trackingSettings.resetTrackingModesIfRequired(!quickZoom, false);
|
||||
// Scale the map
|
||||
if (focalPoint != null) {
|
||||
// arround user provided focal point
|
||||
transform.zoomBy(detector.getScaleFactor(), focalPoint.x, focalPoint.y);
|
||||
} else if (quickZoom) {
|
||||
// around center map
|
||||
transform.zoomBy(detector.getScaleFactor(), uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
|
||||
} else {
|
||||
// around gesture
|
||||
transform.zoomBy(detector.getScaleFactor(), detector.getFocusX(), detector.getFocusY());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for handling rotation gestures.
|
||||
*/
|
||||
private class RotateGestureListener extends RotateGestureDetector.SimpleOnRotateGestureListener {
|
||||
|
||||
long beginTime = 0;
|
||||
float totalAngle = 0.0f;
|
||||
boolean started = false;
|
||||
|
||||
// Called when two fingers first touch the screen
|
||||
@Override
|
||||
public boolean onRotateBegin(RotateGestureDetector detector) {
|
||||
if (!trackingSettings.isRotateGestureCurrentlyEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
beginTime = detector.getEventTime();
|
||||
MapboxEvent.trackGestureEvent(projection, MapboxEvent.GESTURE_ROTATION_START, detector.getFocusX(), detector.getFocusY(), transform.getZoom());
|
||||
return true;
|
||||
}
|
||||
|
||||
// Called when the fingers leave the screen
|
||||
@Override
|
||||
public void onRotateEnd(RotateGestureDetector detector) {
|
||||
beginTime = 0;
|
||||
totalAngle = 0.0f;
|
||||
started = false;
|
||||
}
|
||||
|
||||
// Called each time one of the two fingers moves
|
||||
// Called for rotation
|
||||
@Override
|
||||
public boolean onRotate(RotateGestureDetector detector) {
|
||||
if (!trackingSettings.isRotateGestureCurrentlyEnabled() || dragStarted) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If rotate is large enough ignore a tap
|
||||
// Also is zoom already started, don't rotate
|
||||
totalAngle += detector.getRotationDegreesDelta();
|
||||
if (!zoomStarted && ((totalAngle > 20.0f) || (totalAngle < -20.0f))) {
|
||||
started = true;
|
||||
}
|
||||
|
||||
// Ignore short touches in case it is a tap
|
||||
// Also ignore small rotate
|
||||
long time = detector.getEventTime();
|
||||
long interval = time - beginTime;
|
||||
if (!started && (interval <= ViewConfiguration.getTapTimeout())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!started) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
transform.cancelTransitions();
|
||||
|
||||
// rotation constitutes translation of anything except the center of
|
||||
// rotation, so cancel both location and bearing tracking if required
|
||||
|
||||
trackingSettings.resetTrackingModesIfRequired(true, true);
|
||||
|
||||
// Get rotate value
|
||||
double bearing = transform.getRawBearing();
|
||||
bearing += detector.getRotationDegreesDelta();
|
||||
|
||||
// Rotate the map
|
||||
if (focalPoint != null) {
|
||||
// User provided focal point
|
||||
transform.setBearing(bearing, focalPoint.x, focalPoint.y);
|
||||
} else {
|
||||
// around gesture
|
||||
transform.setBearing(bearing, detector.getFocusX(), detector.getFocusY());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible for handling 2 finger shove gestures.
|
||||
*/
|
||||
private class ShoveGestureListener implements ShoveGestureDetector.OnShoveGestureListener {
|
||||
|
||||
long beginTime = 0;
|
||||
float totalDelta = 0.0f;
|
||||
boolean started = false;
|
||||
|
||||
@Override
|
||||
public boolean onShoveBegin(ShoveGestureDetector detector) {
|
||||
if (!uiSettings.isTiltGesturesEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
beginTime = detector.getEventTime();
|
||||
MapboxEvent.trackGestureEvent(projection, MapboxEvent.GESTURE_PITCH_START, detector.getFocusX(), detector.getFocusY(), transform.getZoom());
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onShoveEnd(ShoveGestureDetector detector) {
|
||||
beginTime = 0;
|
||||
totalDelta = 0.0f;
|
||||
started = false;
|
||||
dragStarted = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onShove(ShoveGestureDetector detector) {
|
||||
if (!uiSettings.isTiltGesturesEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If tilt is large enough ignore a tap
|
||||
// Also if zoom already started, don't tilt
|
||||
totalDelta += detector.getShovePixelsDelta();
|
||||
if (!zoomStarted && ((totalDelta > 10.0f) || (totalDelta < -10.0f))) {
|
||||
started = true;
|
||||
}
|
||||
|
||||
// Ignore short touches in case it is a tap
|
||||
// Also ignore small tilt
|
||||
long time = detector.getEventTime();
|
||||
long interval = time - beginTime;
|
||||
if (!started && (interval <= ViewConfiguration.getTapTimeout())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!started) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
transform.cancelTransitions();
|
||||
|
||||
// Get tilt value (scale and clamp)
|
||||
double pitch = transform.getTilt();
|
||||
pitch -= 0.1 * detector.getShovePixelsDelta();
|
||||
pitch = Math.max(MapboxConstants.MINIMUM_TILT, Math.min(MapboxConstants.MAXIMUM_TILT, pitch));
|
||||
|
||||
// Tilt the map
|
||||
transform.setTilt(pitch);
|
||||
|
||||
dragStarted = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void setOnMapClickListener(MapboxMap.OnMapClickListener onMapClickListener) {
|
||||
this.onMapClickListener = onMapClickListener;
|
||||
}
|
||||
|
||||
void setOnMapLongClickListener(MapboxMap.OnMapLongClickListener onMapLongClickListener) {
|
||||
this.onMapLongClickListener = onMapLongClickListener;
|
||||
}
|
||||
|
||||
void setOnFlingListener(MapboxMap.OnFlingListener onFlingListener) {
|
||||
this.onFlingListener = onFlingListener;
|
||||
}
|
||||
|
||||
void setOnScrollListener(MapboxMap.OnScrollListener onScrollListener) {
|
||||
this.onScrollListener = onScrollListener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
package com.mapbox.mapboxsdk.maps;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.ViewConfiguration;
|
||||
|
||||
/**
|
||||
* Manages key events on a MapView.
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li> Uses {@link Transform} to change the map state</li>
|
||||
* <li> Uses {@link TrackingSettings} to verify validity of the current tracking mode.</li>
|
||||
* <li> Uses {@link UiSettings} to verify validity of user restricted movement.</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
*/
|
||||
final class MapKeyListener {
|
||||
|
||||
private final TrackingSettings trackingSettings;
|
||||
private final Transform transform;
|
||||
private final UiSettings uiSettings;
|
||||
|
||||
private TrackballLongPressTimeOut currentTrackballLongPressTimeOut;
|
||||
|
||||
MapKeyListener(@NonNull Transform transform, @NonNull TrackingSettings trackingSettings, @NonNull UiSettings uiSettings) {
|
||||
this.transform = transform;
|
||||
this.trackingSettings = trackingSettings;
|
||||
this.uiSettings = uiSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user presses a key, alse called for repeated keys held down.
|
||||
*
|
||||
* @param keyCode the id of the pressed key
|
||||
* @param event the related key event
|
||||
* @return true if the wevent is handled
|
||||
*/
|
||||
boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
|
||||
// If the user has held the scroll key down for a while then accelerate
|
||||
// the scroll speed
|
||||
double scrollDist = event.getRepeatCount() >= 5 ? 50.0 : 10.0;
|
||||
|
||||
// Check which key was pressed via hardware/real key code
|
||||
switch (keyCode) {
|
||||
// Tell the system to track these keys for long presses on
|
||||
// onKeyLongPress is fired
|
||||
case KeyEvent.KEYCODE_ENTER:
|
||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||
event.startTracking();
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
transform.cancelTransitions();
|
||||
|
||||
// Move left
|
||||
transform.moveBy(scrollDist, 0.0, 0 /*no animation*/);
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
transform.cancelTransitions();
|
||||
|
||||
// Move right
|
||||
transform.moveBy(-scrollDist, 0.0, 0 /*no animation*/);
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_UP:
|
||||
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
transform.cancelTransitions();
|
||||
|
||||
// Move up
|
||||
transform.moveBy(0.0, scrollDist, 0 /*no animation*/);
|
||||
return true;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
transform.cancelTransitions();
|
||||
|
||||
// Move down
|
||||
transform.moveBy(0.0, -scrollDist, 0 /*no animation*/);
|
||||
return true;
|
||||
|
||||
default:
|
||||
// We are not interested in this key
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user long presses a key that is being tracked.
|
||||
*
|
||||
* @param keyCode the id of the long pressed key
|
||||
* @param event the related key event
|
||||
* @return true if event is handled
|
||||
*/
|
||||
boolean onKeyLongPress(int keyCode, KeyEvent event) {
|
||||
// Check which key was pressed via hardware/real key code
|
||||
switch (keyCode) {
|
||||
// Tell the system to track these keys for long presses on
|
||||
// onKeyLongPress is fired
|
||||
case KeyEvent.KEYCODE_ENTER:
|
||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||
if (!uiSettings.isZoomGesturesEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Zoom out
|
||||
transform.zoom(false, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
|
||||
return true;
|
||||
|
||||
default:
|
||||
// We are not interested in this key
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the user releases a key.
|
||||
*
|
||||
* @param keyCode the id of the released key
|
||||
* @param event the related key event
|
||||
* @return true if the event is handled
|
||||
*/
|
||||
boolean onKeyUp(int keyCode, KeyEvent event) {
|
||||
// Check if the key action was canceled (used for virtual keyboards)
|
||||
if (event.isCanceled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check which key was pressed via hardware/real key code
|
||||
// Note if keyboard does not have physical key (ie primary non-shifted
|
||||
// key) then it will not appear here
|
||||
// Must use the key character map as physical to character is not
|
||||
// fixed/guaranteed
|
||||
switch (keyCode) {
|
||||
case KeyEvent.KEYCODE_ENTER:
|
||||
case KeyEvent.KEYCODE_DPAD_CENTER:
|
||||
if (!uiSettings.isZoomGesturesEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Zoom in
|
||||
transform.zoom(true, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
// We are not interested in this key
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called for trackball events, all motions are relative in device specific units.
|
||||
*
|
||||
* @param event the related motion event
|
||||
* @return true if the event is handled
|
||||
*/
|
||||
boolean onTrackballEvent(MotionEvent event) {
|
||||
// Choose the action
|
||||
switch (event.getActionMasked()) {
|
||||
// The trackball was rotated
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (!trackingSettings.isScrollGestureCurrentlyEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cancel any animation
|
||||
transform.cancelTransitions();
|
||||
|
||||
// Scroll the map
|
||||
transform.moveBy(-10.0 * event.getX(), -10.0 * event.getY(), 0 /*no animation*/);
|
||||
return true;
|
||||
|
||||
// Trackball was pushed in so start tracking and tell system we are
|
||||
// interested
|
||||
// We will then get the up action
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
// Set up a delayed callback to check if trackball is still
|
||||
// After waiting the system long press time out
|
||||
if (currentTrackballLongPressTimeOut != null) {
|
||||
currentTrackballLongPressTimeOut.cancel();
|
||||
currentTrackballLongPressTimeOut = null;
|
||||
}
|
||||
currentTrackballLongPressTimeOut = new TrackballLongPressTimeOut();
|
||||
new Handler().postDelayed(currentTrackballLongPressTimeOut,
|
||||
ViewConfiguration.getLongPressTimeout());
|
||||
return true;
|
||||
|
||||
// Trackball was released
|
||||
case MotionEvent.ACTION_UP:
|
||||
if (!uiSettings.isZoomGesturesEnabled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only handle if we have not already long pressed
|
||||
if (currentTrackballLongPressTimeOut != null) {
|
||||
// Zoom in
|
||||
transform.zoom(true, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
|
||||
}
|
||||
return true;
|
||||
|
||||
// Trackball was cancelled
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
if (currentTrackballLongPressTimeOut != null) {
|
||||
currentTrackballLongPressTimeOut.cancel();
|
||||
currentTrackballLongPressTimeOut = null;
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
// We are not interested in this event
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements the trackball long press time out callback
|
||||
*/
|
||||
private class TrackballLongPressTimeOut implements Runnable {
|
||||
|
||||
// Track if we have been cancelled
|
||||
private boolean cancelled;
|
||||
|
||||
TrackballLongPressTimeOut() {
|
||||
cancelled = false;
|
||||
}
|
||||
|
||||
// Cancel the timeout
|
||||
public void cancel() {
|
||||
cancelled = true;
|
||||
}
|
||||
|
||||
// Called when long press time out expires
|
||||
@Override
|
||||
public void run() {
|
||||
// Check if the trackball is still pressed
|
||||
if (!cancelled) {
|
||||
// Zoom out
|
||||
transform.zoom(false, uiSettings.getWidth() / 2, uiSettings.getHeight() / 2);
|
||||
|
||||
// Ensure the up action is not run
|
||||
currentTrackballLongPressTimeOut = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,20 +1,27 @@
|
||||
package com.mapbox.mapboxsdk.maps;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.PointF;
|
||||
import android.graphics.RectF;
|
||||
import android.location.Location;
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.FloatRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v4.util.Pools;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ZoomButtonsController;
|
||||
|
||||
import com.mapbox.mapboxsdk.MapboxAccountManager;
|
||||
import com.mapbox.mapboxsdk.R;
|
||||
import com.mapbox.mapboxsdk.annotations.Annotation;
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
|
||||
import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
|
||||
@@ -40,6 +47,7 @@ import com.mapbox.mapboxsdk.style.layers.Layer;
|
||||
import com.mapbox.mapboxsdk.style.layers.NoSuchLayerException;
|
||||
import com.mapbox.mapboxsdk.style.sources.NoSuchSourceException;
|
||||
import com.mapbox.mapboxsdk.style.sources.Source;
|
||||
import com.mapbox.mapboxsdk.utils.ColorUtils;
|
||||
import com.mapbox.services.commons.geojson.Feature;
|
||||
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
@@ -54,46 +62,134 @@ import java.util.List;
|
||||
* Note: Similar to a View object, a MapboxMap should only be read and modified from the main thread.
|
||||
* </p>
|
||||
*/
|
||||
public class MapboxMap {
|
||||
public final class MapboxMap {
|
||||
|
||||
private MapView mapView;
|
||||
private UiSettings uiSettings;
|
||||
private TrackingSettings trackingSettings;
|
||||
private MyLocationViewSettings myLocationViewSettings;
|
||||
private Projection projection;
|
||||
private Transform transform;
|
||||
private boolean myLocationEnabled;
|
||||
private final NativeMapView nativeMapView;
|
||||
private final UiSettings uiSettings;
|
||||
private final TrackingSettings trackingSettings;
|
||||
private final Projection projection;
|
||||
private final Transform transform;
|
||||
private final AnnotationManager annotationManager;
|
||||
private final MyLocationViewSettings myLocationViewSettings;
|
||||
private final OnRegisterTouchListener onRegisterTouchListener;
|
||||
|
||||
private MapboxMap.OnMapClickListener onMapClickListener;
|
||||
private MapboxMap.OnMapLongClickListener onMapLongClickListener;
|
||||
|
||||
|
||||
private MapboxMap.OnFlingListener onFlingListener;
|
||||
private MapboxMap.OnScrollListener onScrollListener;
|
||||
private MapboxMap.OnMyLocationTrackingModeChangeListener onMyLocationTrackingModeChangeListener;
|
||||
private MapboxMap.OnMyBearingTrackingModeChangeListener onMyBearingTrackingModeChangeListener;
|
||||
private MapboxMap.OnFpsChangedListener onFpsChangedListener;
|
||||
|
||||
private AnnotationManager annotationManager;
|
||||
private InfoWindowManager infoWindowManager;
|
||||
private boolean myLocationEnabled;
|
||||
|
||||
private double maxZoomLevel = -1;
|
||||
private double minZoomLevel = -1;
|
||||
|
||||
MapboxMap(@NonNull MapView mapView, IconManager iconManager) {
|
||||
this.mapView = mapView;
|
||||
uiSettings = new UiSettings(mapView);
|
||||
trackingSettings = new TrackingSettings(this.mapView, uiSettings);
|
||||
projection = new Projection(mapView);
|
||||
infoWindowManager = new InfoWindowManager();
|
||||
annotationManager = new AnnotationManager(mapView.getNativeMapView(), iconManager, infoWindowManager);
|
||||
MapboxMap(NativeMapView map, Transform transform, UiSettings ui, TrackingSettings tracking, MyLocationViewSettings myLocationView,
|
||||
Projection projection, OnRegisterTouchListener listener, AnnotationManager annotations) {
|
||||
this.nativeMapView = map;
|
||||
this.uiSettings = ui;
|
||||
this.trackingSettings = tracking;
|
||||
this.projection = projection;
|
||||
this.myLocationViewSettings = myLocationView;
|
||||
this.annotationManager = annotations.bind(this);
|
||||
this.transform = transform;
|
||||
this.onRegisterTouchListener = listener;
|
||||
}
|
||||
|
||||
// TODO inject NativeMapView https://github.com/mapbox/mapbox-gl-native/issues/4100
|
||||
NativeMapView nativeMapView = mapView.getNativeMapView();
|
||||
if (nativeMapView != null) {
|
||||
transform = new Transform(nativeMapView, this);
|
||||
nativeMapView.addOnMapChangedListener(new CameraInvalidator());
|
||||
void initialise(Context context, MapboxMapOptions options) {
|
||||
// TODO migrate code from this method to the classes they impact themselves
|
||||
setDebugActive(options.getDebugActive());
|
||||
|
||||
CameraPosition position = options.getCamera();
|
||||
if (position != null && !position.equals(CameraPosition.DEFAULT)) {
|
||||
transform.moveCamera(this, CameraUpdateFactory.newCameraPosition(position), null);
|
||||
myLocationViewSettings.setTilt(position.tilt);
|
||||
}
|
||||
|
||||
// api base url
|
||||
String apiBaseUrl = options.getApiBaseUrl();
|
||||
if (!TextUtils.isEmpty(apiBaseUrl)) {
|
||||
nativeMapView.setApiBaseUrl(apiBaseUrl);
|
||||
}
|
||||
|
||||
// access token
|
||||
String accessToken = options.getAccessToken();
|
||||
if (!TextUtils.isEmpty(accessToken)) {
|
||||
nativeMapView.setAccessToken(accessToken);
|
||||
}else{
|
||||
nativeMapView.setAccessToken(MapboxAccountManager.getInstance().getAccessToken());
|
||||
}
|
||||
|
||||
// style url
|
||||
String style = options.getStyle();
|
||||
if (!TextUtils.isEmpty(style)) {
|
||||
nativeMapView.setStyleUrl(style);
|
||||
}
|
||||
|
||||
// MyLocationView
|
||||
myLocationViewSettings.setForegroundDrawable(
|
||||
options.getMyLocationForegroundDrawable(), options.getMyLocationForegroundBearingDrawable());
|
||||
myLocationViewSettings.setForegroundTintColor(options.getMyLocationForegroundTintColor());
|
||||
myLocationViewSettings.setBackgroundDrawable(
|
||||
options.getMyLocationBackgroundDrawable(), options.getMyLocationBackgroundPadding());
|
||||
myLocationViewSettings.setBackgroundTintColor(options.getMyLocationBackgroundTintColor());
|
||||
myLocationViewSettings.setAccuracyAlpha(options.getMyLocationAccuracyAlpha());
|
||||
myLocationViewSettings.setAccuracyTintColor(options.getMyLocationAccuracyTintColor());
|
||||
setMyLocationEnabled(options.getLocationEnabled());
|
||||
|
||||
// Enable gestures
|
||||
uiSettings.setZoomGesturesEnabled(options.getZoomGesturesEnabled());
|
||||
uiSettings.setZoomGestureChangeAllowed(options.getZoomGesturesEnabled());
|
||||
uiSettings.setScrollGesturesEnabled(options.getScrollGesturesEnabled());
|
||||
uiSettings.setScrollGestureChangeAllowed(options.getScrollGesturesEnabled());
|
||||
uiSettings.setRotateGesturesEnabled(options.getRotateGesturesEnabled());
|
||||
uiSettings.setRotateGestureChangeAllowed(options.getRotateGesturesEnabled());
|
||||
uiSettings.setTiltGesturesEnabled(options.getTiltGesturesEnabled());
|
||||
uiSettings.setTiltGestureChangeAllowed(options.getTiltGesturesEnabled());
|
||||
|
||||
// Ui Controls
|
||||
uiSettings.setZoomControlsEnabled(options.getZoomControlsEnabled());
|
||||
|
||||
// Zoom
|
||||
setMaxZoom(options.getMaxZoom());
|
||||
setMinZoom(options.getMinZoom());
|
||||
|
||||
Resources resources = context.getResources();
|
||||
|
||||
// Compass
|
||||
uiSettings.setCompassEnabled(options.getCompassEnabled());
|
||||
uiSettings.setCompassGravity(options.getCompassGravity());
|
||||
int[] compassMargins = options.getCompassMargins();
|
||||
if (compassMargins != null) {
|
||||
uiSettings.setCompassMargins(compassMargins[0], compassMargins[1], compassMargins[2], compassMargins[3]);
|
||||
} else {
|
||||
int tenDp = (int) resources.getDimension(R.dimen.mapbox_ten_dp);
|
||||
uiSettings.setCompassMargins(tenDp, tenDp, tenDp, tenDp);
|
||||
}
|
||||
uiSettings.setCompassFadeFacingNorth(options.getCompassFadeFacingNorth());
|
||||
|
||||
// Logo
|
||||
uiSettings.setLogoEnabled(options.getLogoEnabled());
|
||||
uiSettings.setLogoGravity(options.getLogoGravity());
|
||||
int[] logoMargins = options.getLogoMargins();
|
||||
if (logoMargins != null) {
|
||||
uiSettings.setLogoMargins(logoMargins[0], logoMargins[1], logoMargins[2], logoMargins[3]);
|
||||
} else {
|
||||
int sixteenDp = (int) resources.getDimension(R.dimen.mapbox_sixteen_dp);
|
||||
uiSettings.setLogoMargins(sixteenDp, sixteenDp, sixteenDp, sixteenDp);
|
||||
}
|
||||
|
||||
// Attribution
|
||||
uiSettings.setAttributionEnabled(options.getAttributionEnabled());
|
||||
uiSettings.setAttributionGravity(options.getAttributionGravity());
|
||||
int[] attributionMargins = options.getAttributionMargins();
|
||||
if (attributionMargins != null) {
|
||||
uiSettings.setAttributionMargins(attributionMargins[0], attributionMargins[1], attributionMargins[2], attributionMargins[3]);
|
||||
} else {
|
||||
int sevenDp = (int) resources.getDimension(R.dimen.mapbox_seven_dp);
|
||||
int seventySixDp = (int) resources.getDimension(R.dimen.mapbox_seventy_six_dp);
|
||||
uiSettings.setAttributionMargins(seventySixDp, sevenDp, sevenDp, sevenDp);
|
||||
}
|
||||
|
||||
int attributionTintColor = options.getAttributionTintColor();
|
||||
uiSettings.setAttributionTintColor(attributionTintColor != -1
|
||||
? attributionTintColor : ColorUtils.getPrimaryColor(context));
|
||||
}
|
||||
|
||||
// Style
|
||||
@@ -101,7 +197,7 @@ public class MapboxMap {
|
||||
@Nullable
|
||||
@UiThread
|
||||
public Layer getLayer(@NonNull String layerId) {
|
||||
return getMapView().getNativeMapView().getLayer(layerId);
|
||||
return nativeMapView.getLayer(layerId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,7 +212,7 @@ public class MapboxMap {
|
||||
public <T extends Layer> T getLayerAs(@NonNull String layerId) {
|
||||
try {
|
||||
//noinspection unchecked
|
||||
return (T) getMapView().getNativeMapView().getLayer(layerId);
|
||||
return (T) nativeMapView.getLayer(layerId);
|
||||
} catch (ClassCastException e) {
|
||||
Timber.e(String.format("Layer: %s is a different type: %s", layerId, e.getMessage()));
|
||||
return null;
|
||||
@@ -141,7 +237,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void addLayer(@NonNull Layer layer, String before) {
|
||||
getMapView().getNativeMapView().addLayer(layer, before);
|
||||
nativeMapView.addLayer(layer, before);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,7 +248,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void removeLayer(@NonNull String layerId) throws NoSuchLayerException {
|
||||
getMapView().getNativeMapView().removeLayer(layerId);
|
||||
nativeMapView.removeLayer(layerId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -163,13 +259,13 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void removeLayer(@NonNull Layer layer) throws NoSuchLayerException {
|
||||
getMapView().getNativeMapView().removeLayer(layer);
|
||||
nativeMapView.removeLayer(layer);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@UiThread
|
||||
public Source getSource(@NonNull String sourceId) {
|
||||
return getMapView().getNativeMapView().getSource(sourceId);
|
||||
return nativeMapView.getSource(sourceId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -184,7 +280,7 @@ public class MapboxMap {
|
||||
public <T extends Source> T getSourceAs(@NonNull String sourceId) {
|
||||
try {
|
||||
//noinspection unchecked
|
||||
return (T) getMapView().getNativeMapView().getSource(sourceId);
|
||||
return (T) nativeMapView.getSource(sourceId);
|
||||
} catch (ClassCastException e) {
|
||||
Timber.e(String.format("Source: %s is a different type: %s", sourceId, e.getMessage()));
|
||||
return null;
|
||||
@@ -198,7 +294,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void addSource(@NonNull Source source) {
|
||||
getMapView().getNativeMapView().addSource(source);
|
||||
nativeMapView.addSource(source);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -209,7 +305,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void removeSource(@NonNull String sourceId) throws NoSuchSourceException {
|
||||
getMapView().getNativeMapView().removeSource(sourceId);
|
||||
nativeMapView.removeSource(sourceId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,7 +316,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void removeSource(@NonNull Source source) throws NoSuchSourceException {
|
||||
getMapView().getNativeMapView().removeSource(source);
|
||||
nativeMapView.removeSource(source);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,7 +327,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void addImage(@NonNull String name, @NonNull Bitmap image) {
|
||||
getMapView().getNativeMapView().addImage(name, image);
|
||||
nativeMapView.addImage(name, image);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,7 +337,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void removeImage(String name) {
|
||||
getMapView().getNativeMapView().removeImage(name);
|
||||
nativeMapView.removeImage(name);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -263,7 +359,7 @@ public class MapboxMap {
|
||||
return;
|
||||
}
|
||||
minZoomLevel = minZoom;
|
||||
mapView.setMinZoom(minZoom);
|
||||
nativeMapView.setMinZoom(minZoom);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,7 +372,7 @@ public class MapboxMap {
|
||||
@UiThread
|
||||
public double getMinZoom() {
|
||||
if (minZoomLevel == -1) {
|
||||
return minZoomLevel = mapView.getMinZoom();
|
||||
return minZoomLevel = nativeMapView.getMinZoom();
|
||||
}
|
||||
return minZoomLevel;
|
||||
}
|
||||
@@ -300,7 +396,7 @@ public class MapboxMap {
|
||||
return;
|
||||
}
|
||||
maxZoomLevel = maxZoom;
|
||||
mapView.setMaxZoom(maxZoom);
|
||||
nativeMapView.setMaxZoom(maxZoom);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,7 +409,7 @@ public class MapboxMap {
|
||||
@UiThread
|
||||
public double getMaxZoom() {
|
||||
if (maxZoomLevel == -1) {
|
||||
return maxZoomLevel = mapView.getMaxZoom();
|
||||
return maxZoomLevel = nativeMapView.getMaxZoom();
|
||||
}
|
||||
return maxZoomLevel;
|
||||
}
|
||||
@@ -354,9 +450,6 @@ public class MapboxMap {
|
||||
* @return the MyLocationViewSettings associated with this map
|
||||
*/
|
||||
public MyLocationViewSettings getMyLocationViewSettings() {
|
||||
if (myLocationViewSettings == null) {
|
||||
myLocationViewSettings = new MyLocationViewSettings(mapView, mapView.getUserLocationView());
|
||||
}
|
||||
return myLocationViewSettings;
|
||||
}
|
||||
|
||||
@@ -420,6 +513,9 @@ public class MapboxMap {
|
||||
@UiThread
|
||||
public final void moveCamera(CameraUpdate update) {
|
||||
moveCamera(update, null);
|
||||
// MapChange.REGION_DID_CHANGE_ANIMATED is not called for `jumpTo`
|
||||
// invalidate camera position to provide OnCameraChange event.
|
||||
invalidateCameraPosition();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -432,10 +528,10 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public final void moveCamera(final CameraUpdate update, final MapboxMap.CancelableCallback callback) {
|
||||
mapView.post(new Runnable() {
|
||||
new Handler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
transform.moveCamera(update, callback);
|
||||
transform.moveCamera(MapboxMap.this, update, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -559,10 +655,10 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public final void easeCamera(final CameraUpdate update, final int durationMs, final boolean easingInterpolator, final boolean resetTrackingMode, final MapboxMap.CancelableCallback callback) {
|
||||
mapView.post(new Runnable() {
|
||||
new Handler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
transform.easeCamera(update, durationMs, easingInterpolator, resetTrackingMode, callback);
|
||||
transform.easeCamera(MapboxMap.this, update, durationMs, easingInterpolator, resetTrackingMode, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -634,10 +730,10 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public final void animateCamera(final CameraUpdate update, final int durationMs, final MapboxMap.CancelableCallback callback) {
|
||||
mapView.post(new Runnable() {
|
||||
new Handler().post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
transform.animateCamera(update, durationMs, callback);
|
||||
transform.animateCamera(MapboxMap.this, update, durationMs, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -648,7 +744,7 @@ public class MapboxMap {
|
||||
void invalidateCameraPosition() {
|
||||
CameraPosition cameraPosition = transform.invalidateCameraPosition();
|
||||
if (cameraPosition != null) {
|
||||
mapView.updateCameraPosition(cameraPosition);
|
||||
transform.updateCameraPosition(cameraPosition);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -674,7 +770,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public boolean isDebugActive() {
|
||||
return mapView.isDebugActive();
|
||||
return nativeMapView.getDebug();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -687,21 +783,21 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void setDebugActive(boolean debugActive) {
|
||||
mapView.setDebugActive(debugActive);
|
||||
nativeMapView.setDebug(debugActive);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Cycles through the map debug options.
|
||||
* </p>
|
||||
* The value of {@link MapView#isDebugActive()} reflects whether there are
|
||||
* The value of isDebugActive reflects whether there are
|
||||
* any map debug options enabled or disabled.
|
||||
*
|
||||
* @see MapView#isDebugActive()
|
||||
* @see #isDebugActive()
|
||||
*/
|
||||
@UiThread
|
||||
public void cycleDebugOptions() {
|
||||
mapView.cycleDebugOptions();
|
||||
nativeMapView.cycleDebugOptions();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -739,7 +835,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void setStyleUrl(@NonNull String url) {
|
||||
mapView.setStyleUrl(url);
|
||||
nativeMapView.setStyleUrl(url);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -775,7 +871,7 @@ public class MapboxMap {
|
||||
@UiThread
|
||||
@NonNull
|
||||
public String getStyleUrl() {
|
||||
return mapView.getStyleUrl();
|
||||
return nativeMapView.getStyleUrl();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -797,7 +893,7 @@ public class MapboxMap {
|
||||
@Deprecated
|
||||
@UiThread
|
||||
public void setAccessToken(@NonNull String accessToken) {
|
||||
mapView.setAccessToken(accessToken);
|
||||
nativeMapView.setAccessToken(accessToken);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -815,17 +911,13 @@ public class MapboxMap {
|
||||
@UiThread
|
||||
@Nullable
|
||||
public String getAccessToken() {
|
||||
return mapView.getAccessToken();
|
||||
return nativeMapView.getAccessToken();
|
||||
}
|
||||
|
||||
//
|
||||
// Annotations
|
||||
//
|
||||
|
||||
void setTilt(double tilt) {
|
||||
mapView.setTilt(tilt);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Adds a marker to this map.
|
||||
@@ -1152,7 +1244,7 @@ public class MapboxMap {
|
||||
Timber.w("marker was null, so just returning");
|
||||
return;
|
||||
}
|
||||
annotationManager.selectMarker(marker, this);
|
||||
annotationManager.selectMarker(marker);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1189,7 +1281,7 @@ public class MapboxMap {
|
||||
* @return the associated MarkerViewManager
|
||||
*/
|
||||
public MarkerViewManager getMarkerViewManager() {
|
||||
return annotationManager.getMarkerViewManager(this);
|
||||
return annotationManager.getMarkerViewManager();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1208,7 +1300,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void setInfoWindowAdapter(@Nullable InfoWindowAdapter infoWindowAdapter) {
|
||||
infoWindowManager.setInfoWindowAdapter(infoWindowAdapter);
|
||||
annotationManager.getInfoWindowManager().setInfoWindowAdapter(infoWindowAdapter);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1219,7 +1311,7 @@ public class MapboxMap {
|
||||
@UiThread
|
||||
@Nullable
|
||||
public InfoWindowAdapter getInfoWindowAdapter() {
|
||||
return infoWindowManager.getInfoWindowAdapter();
|
||||
return annotationManager.getInfoWindowManager().getInfoWindowAdapter();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1229,7 +1321,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void setAllowConcurrentMultipleOpenInfoWindows(boolean allow) {
|
||||
infoWindowManager.setAllowConcurrentMultipleOpenInfoWindows(allow);
|
||||
annotationManager.getInfoWindowManager().setAllowConcurrentMultipleOpenInfoWindows(allow);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1239,12 +1331,12 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public boolean isAllowConcurrentMultipleOpenInfoWindows() {
|
||||
return infoWindowManager.isAllowConcurrentMultipleOpenInfoWindows();
|
||||
return annotationManager.getInfoWindowManager().isAllowConcurrentMultipleOpenInfoWindows();
|
||||
}
|
||||
|
||||
// Internal API
|
||||
List<InfoWindow> getInfoWindows() {
|
||||
return infoWindowManager.getInfoWindows();
|
||||
return annotationManager.getInfoWindowManager().getInfoWindows();
|
||||
}
|
||||
|
||||
AnnotationManager getAnnotationManager() {
|
||||
@@ -1279,7 +1371,7 @@ public class MapboxMap {
|
||||
* @param bottom The bottom margin in pixels.
|
||||
*/
|
||||
public void setPadding(int left, int top, int right, int bottom) {
|
||||
mapView.setContentPadding(left, top, right, bottom);
|
||||
projection.setContentPadding(new int[]{left, top, right, bottom}, myLocationViewSettings.getPadding());
|
||||
uiSettings.invalidate();
|
||||
}
|
||||
|
||||
@@ -1289,10 +1381,7 @@ public class MapboxMap {
|
||||
* @return An array with length 4 in the LTRB order.
|
||||
*/
|
||||
public int[] getPadding() {
|
||||
return new int[]{mapView.getContentPaddingLeft(),
|
||||
mapView.getContentPaddingTop(),
|
||||
mapView.getContentPaddingRight(),
|
||||
mapView.getContentPaddingBottom()};
|
||||
return projection.getContentPadding();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1334,12 +1423,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void setOnScrollListener(@Nullable OnScrollListener listener) {
|
||||
onScrollListener = listener;
|
||||
}
|
||||
|
||||
// used by MapView
|
||||
OnScrollListener getOnScrollListener() {
|
||||
return onScrollListener;
|
||||
onRegisterTouchListener.onRegisterScrollListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1350,12 +1434,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void setOnFlingListener(@Nullable OnFlingListener listener) {
|
||||
onFlingListener = listener;
|
||||
}
|
||||
|
||||
// used by MapView
|
||||
OnFlingListener getOnFlingListener() {
|
||||
return onFlingListener;
|
||||
onRegisterTouchListener.onRegisterFlingListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1366,12 +1445,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void setOnMapClickListener(@Nullable OnMapClickListener listener) {
|
||||
onMapClickListener = listener;
|
||||
}
|
||||
|
||||
// used by MapView
|
||||
OnMapClickListener getOnMapClickListener() {
|
||||
return onMapClickListener;
|
||||
onRegisterTouchListener.onRegisterMapClickListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1382,12 +1456,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void setOnMapLongClickListener(@Nullable OnMapLongClickListener listener) {
|
||||
onMapLongClickListener = listener;
|
||||
}
|
||||
|
||||
// used by MapView
|
||||
OnMapLongClickListener getOnMapLongClickListener() {
|
||||
return onMapLongClickListener;
|
||||
onRegisterTouchListener.onRegisterMapLongClickListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1398,7 +1467,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void setOnInfoWindowClickListener(@Nullable OnInfoWindowClickListener listener) {
|
||||
infoWindowManager.setOnInfoWindowClickListener(listener);
|
||||
getAnnotationManager().getInfoWindowManager().setOnInfoWindowClickListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1408,7 +1477,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public OnInfoWindowClickListener getOnInfoWindowClickListener() {
|
||||
return infoWindowManager.getOnInfoWindowClickListener();
|
||||
return getAnnotationManager().getInfoWindowManager().getOnInfoWindowClickListener();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1420,7 +1489,7 @@ public class MapboxMap {
|
||||
@UiThread
|
||||
public void setOnInfoWindowLongClickListener(@Nullable OnInfoWindowLongClickListener
|
||||
listener) {
|
||||
infoWindowManager.setOnInfoWindowLongClickListener(listener);
|
||||
getAnnotationManager().getInfoWindowManager().setOnInfoWindowLongClickListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1429,11 +1498,11 @@ public class MapboxMap {
|
||||
* @return Current active InfoWindow long Click Listener
|
||||
*/
|
||||
public OnInfoWindowLongClickListener getOnInfoWindowLongClickListener() {
|
||||
return infoWindowManager.getOnInfoWindowLongClickListener();
|
||||
return getAnnotationManager().getInfoWindowManager().getOnInfoWindowLongClickListener();
|
||||
}
|
||||
|
||||
public void setOnInfoWindowCloseListener(@Nullable OnInfoWindowCloseListener listener) {
|
||||
infoWindowManager.setOnInfoWindowCloseListener(listener);
|
||||
getAnnotationManager().getInfoWindowManager().setOnInfoWindowCloseListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1443,7 +1512,7 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public OnInfoWindowCloseListener getOnInfoWindowCloseListener() {
|
||||
return infoWindowManager.getOnInfoWindowCloseListener();
|
||||
return getAnnotationManager().getInfoWindowManager().getOnInfoWindowCloseListener();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1474,13 +1543,13 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void setMyLocationEnabled(boolean enabled) {
|
||||
if (!mapView.isPermissionsAccepted()) {
|
||||
if (!trackingSettings.isPermissionsAccepted()) {
|
||||
Timber.e("Could not activate user location tracking: "
|
||||
+ "user did not accept the permission or permissions were not requested.");
|
||||
return;
|
||||
}
|
||||
myLocationEnabled = enabled;
|
||||
mapView.setMyLocationEnabled(enabled);
|
||||
trackingSettings.setMyLocationEnabled(enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1491,7 +1560,7 @@ public class MapboxMap {
|
||||
@UiThread
|
||||
@Nullable
|
||||
public Location getMyLocation() {
|
||||
return mapView.getMyLocation();
|
||||
return trackingSettings.getMyLocation();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1504,7 +1573,7 @@ public class MapboxMap {
|
||||
@UiThread
|
||||
public void setOnMyLocationChangeListener(@Nullable MapboxMap.OnMyLocationChangeListener
|
||||
listener) {
|
||||
mapView.setOnMyLocationChangeListener(listener);
|
||||
trackingSettings.setOnMyLocationChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1514,15 +1583,8 @@ public class MapboxMap {
|
||||
* To unset the callback, use null.
|
||||
*/
|
||||
@UiThread
|
||||
public void setOnMyLocationTrackingModeChangeListener
|
||||
(@Nullable MapboxMap.OnMyLocationTrackingModeChangeListener listener) {
|
||||
onMyLocationTrackingModeChangeListener = listener;
|
||||
}
|
||||
|
||||
// used by MapView
|
||||
MapboxMap.OnMyLocationTrackingModeChangeListener getOnMyLocationTrackingModeChangeListener
|
||||
() {
|
||||
return onMyLocationTrackingModeChangeListener;
|
||||
public void setOnMyLocationTrackingModeChangeListener(@Nullable MapboxMap.OnMyLocationTrackingModeChangeListener listener) {
|
||||
trackingSettings.setOnMyLocationTrackingModeChangeListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1532,39 +1594,14 @@ public class MapboxMap {
|
||||
* To unset the callback, use null.
|
||||
*/
|
||||
@UiThread
|
||||
public void setOnMyBearingTrackingModeChangeListener
|
||||
(@Nullable OnMyBearingTrackingModeChangeListener listener) {
|
||||
onMyBearingTrackingModeChangeListener = listener;
|
||||
}
|
||||
|
||||
// used by MapView
|
||||
OnMyBearingTrackingModeChangeListener getOnMyBearingTrackingModeChangeListener() {
|
||||
return onMyBearingTrackingModeChangeListener;
|
||||
}
|
||||
|
||||
MapView getMapView() {
|
||||
return mapView;
|
||||
}
|
||||
|
||||
void setUiSettings(UiSettings uiSettings) {
|
||||
this.uiSettings = uiSettings;
|
||||
}
|
||||
|
||||
void setProjection(Projection projection) {
|
||||
this.projection = projection;
|
||||
public void setOnMyBearingTrackingModeChangeListener(@Nullable OnMyBearingTrackingModeChangeListener listener) {
|
||||
trackingSettings.setOnMyBearingTrackingModeChangeListener(listener);
|
||||
}
|
||||
|
||||
//
|
||||
// Invalidate
|
||||
//
|
||||
|
||||
/**
|
||||
* Triggers an invalidation of the map view.
|
||||
*/
|
||||
public void invalidate() {
|
||||
mapView.invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a snapshot of the map.
|
||||
*
|
||||
@@ -1573,7 +1610,8 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void snapshot(@NonNull SnapshotReadyCallback callback, @Nullable final Bitmap bitmap) {
|
||||
mapView.snapshot(callback, bitmap);
|
||||
// FIXME 12/02/2016
|
||||
//mapView.snapshot(callback, bitmap);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1583,7 +1621,8 @@ public class MapboxMap {
|
||||
*/
|
||||
@UiThread
|
||||
public void snapshot(@NonNull SnapshotReadyCallback callback) {
|
||||
mapView.snapshot(callback, null);
|
||||
// FIXME 12/02/2016
|
||||
//mapView.snapshot(callback, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1597,7 +1636,7 @@ public class MapboxMap {
|
||||
@NonNull
|
||||
public List<Feature> queryRenderedFeatures(@NonNull PointF coordinates, @Nullable String...
|
||||
layerIds) {
|
||||
return mapView.getNativeMapView().queryRenderedFeatures(coordinates, layerIds);
|
||||
return nativeMapView.queryRenderedFeatures(coordinates, layerIds);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1611,21 +1650,7 @@ public class MapboxMap {
|
||||
@NonNull
|
||||
public List<Feature> queryRenderedFeatures(@NonNull RectF coordinates, @Nullable String...
|
||||
layerIds) {
|
||||
return mapView.getNativeMapView().queryRenderedFeatures(coordinates, layerIds);
|
||||
}
|
||||
|
||||
//
|
||||
// Innner classes
|
||||
//
|
||||
|
||||
private class CameraInvalidator implements MapView.OnMapChangedListener {
|
||||
|
||||
@Override
|
||||
public void onMapChanged(@MapView.MapChange int change) {
|
||||
if (change == MapView.REGION_DID_CHANGE_ANIMATED) {
|
||||
invalidateCameraPosition();
|
||||
}
|
||||
}
|
||||
return nativeMapView.queryRenderedFeatures(coordinates, layerIds);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -1684,6 +1709,20 @@ public class MapboxMap {
|
||||
void onFpsChanged(double fps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface definition for a callback to be invoked when a user registers an listener that is
|
||||
* related to touch and click events.
|
||||
*/
|
||||
interface OnRegisterTouchListener {
|
||||
void onRegisterMapClickListener(OnMapClickListener listener);
|
||||
|
||||
void onRegisterMapLongClickListener(OnMapLongClickListener listener);
|
||||
|
||||
void onRegisterScrollListener(OnScrollListener listener);
|
||||
|
||||
void onRegisterFlingListener(OnFlingListener listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface definition for a callback to be invoked when the user clicks on the map view.
|
||||
*
|
||||
@@ -1939,7 +1978,7 @@ public class MapboxMap {
|
||||
/**
|
||||
* Interface definition for a callback to be invoked when the the My Location tracking mode changes.
|
||||
*
|
||||
* @see MapView#setMyLocationTrackingMode(int)
|
||||
* @see TrackingSettings#setMyLocationTrackingMode(int)
|
||||
*/
|
||||
public interface OnMyLocationTrackingModeChangeListener {
|
||||
|
||||
@@ -1954,7 +1993,7 @@ public class MapboxMap {
|
||||
/**
|
||||
* Interface definition for a callback to be invoked when the the My Location tracking mode changes.
|
||||
*
|
||||
* @see MapView#setMyLocationTrackingMode(int)
|
||||
* @see TrackingSettings#setMyLocationTrackingMode(int)
|
||||
*/
|
||||
public interface OnMyBearingTrackingModeChangeListener {
|
||||
|
||||
|
||||
@@ -9,14 +9,12 @@ import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.DisplayMetrics;
|
||||
import timber.log.Timber;
|
||||
import android.view.Surface;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.Icon;
|
||||
import com.mapbox.mapboxsdk.annotations.Marker;
|
||||
import com.mapbox.mapboxsdk.annotations.Polygon;
|
||||
import com.mapbox.mapboxsdk.annotations.Polyline;
|
||||
import com.mapbox.mapboxsdk.constants.MapboxConstants;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.geometry.ProjectedMeters;
|
||||
import com.mapbox.mapboxsdk.offline.OfflineManager;
|
||||
@@ -32,10 +30,13 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
// Class that wraps the native methods for convenience
|
||||
final class NativeMapView {
|
||||
|
||||
boolean destroyed = false;
|
||||
// Flag to indicating destroy was called
|
||||
private boolean destroyed = false;
|
||||
|
||||
// Holds the pointer to JNI NativeMapView
|
||||
private long nativeMapViewPtr = 0;
|
||||
@@ -43,8 +44,10 @@ final class NativeMapView {
|
||||
// Used for callbacks
|
||||
private MapView mapView;
|
||||
|
||||
// Device density
|
||||
private final float pixelRatio;
|
||||
|
||||
// Listeners for Map change events
|
||||
private CopyOnWriteArrayList<MapView.OnMapChangedListener> onMapChangedListeners;
|
||||
|
||||
//
|
||||
@@ -139,6 +142,9 @@ final class NativeMapView {
|
||||
}
|
||||
|
||||
public void resizeView(int width, int height) {
|
||||
width = (int) (width / pixelRatio);
|
||||
height = (int) (height / pixelRatio);
|
||||
|
||||
if (width < 0) {
|
||||
throw new IllegalArgumentException("width cannot be negative.");
|
||||
}
|
||||
@@ -208,6 +214,10 @@ final class NativeMapView {
|
||||
nativeSetStyleUrl(nativeMapViewPtr, url);
|
||||
}
|
||||
|
||||
public String getStyleUrl() {
|
||||
return nativeGetStyleUrl(nativeMapViewPtr);
|
||||
}
|
||||
|
||||
public void setStyleJson(String newStyleJson) {
|
||||
nativeSetStyleJson(nativeMapViewPtr, newStyleJson);
|
||||
}
|
||||
@@ -237,7 +247,7 @@ final class NativeMapView {
|
||||
}
|
||||
|
||||
public void moveBy(double dx, double dy, long duration) {
|
||||
nativeMoveBy(nativeMapViewPtr, dx, dy, duration);
|
||||
nativeMoveBy(nativeMapViewPtr, dx / pixelRatio, dy / pixelRatio, duration);
|
||||
}
|
||||
|
||||
public void setLatLng(LatLng latLng) {
|
||||
@@ -273,7 +283,7 @@ final class NativeMapView {
|
||||
}
|
||||
|
||||
public void scaleBy(double ds, double cx, double cy, long duration) {
|
||||
nativeScaleBy(nativeMapViewPtr, ds, cx, cy, duration);
|
||||
nativeScaleBy(nativeMapViewPtr, ds, cx / pixelRatio, cy / pixelRatio, duration);
|
||||
}
|
||||
|
||||
public void setScale(double scale) {
|
||||
@@ -285,7 +295,7 @@ final class NativeMapView {
|
||||
}
|
||||
|
||||
public void setScale(double scale, double cx, double cy, long duration) {
|
||||
nativeSetScale(nativeMapViewPtr, scale, cx, cy, duration);
|
||||
nativeSetScale(nativeMapViewPtr, scale, cx / pixelRatio, cy / pixelRatio, duration);
|
||||
}
|
||||
|
||||
public double getScale() {
|
||||
@@ -330,11 +340,15 @@ final class NativeMapView {
|
||||
|
||||
public void rotateBy(double sx, double sy, double ex, double ey,
|
||||
long duration) {
|
||||
nativeRotateBy(nativeMapViewPtr, sx, sy, ex, ey, duration);
|
||||
nativeRotateBy(nativeMapViewPtr, sx/pixelRatio, sy/pixelRatio, ex, ey, duration);
|
||||
}
|
||||
|
||||
public void setContentPadding(double top, double left, double bottom, double right) {
|
||||
nativeSetContentPadding(nativeMapViewPtr, top, left, bottom, right);
|
||||
public void setContentPadding(int[] padding) {
|
||||
nativeSetContentPadding(nativeMapViewPtr,
|
||||
padding[1] / pixelRatio,
|
||||
padding[0] / pixelRatio,
|
||||
padding[3] / pixelRatio,
|
||||
padding[2] / pixelRatio);
|
||||
}
|
||||
|
||||
public void setBearing(double degrees) {
|
||||
@@ -346,7 +360,7 @@ final class NativeMapView {
|
||||
}
|
||||
|
||||
public void setBearing(double degrees, double cx, double cy) {
|
||||
nativeSetBearingXY(nativeMapViewPtr, degrees, cx, cy);
|
||||
nativeSetBearingXY(nativeMapViewPtr, degrees, cx/pixelRatio, cy/pixelRatio);
|
||||
}
|
||||
|
||||
public double getBearing() {
|
||||
@@ -443,8 +457,8 @@ final class NativeMapView {
|
||||
nativeSetReachability(nativeMapViewPtr, status);
|
||||
}
|
||||
|
||||
public double getMetersPerPixelAtLatitude(double lat, double zoom) {
|
||||
return nativeGetMetersPerPixelAtLatitude(nativeMapViewPtr, lat, zoom);
|
||||
public double getMetersPerPixelAtLatitude(double lat) {
|
||||
return nativeGetMetersPerPixelAtLatitude(nativeMapViewPtr, lat, getZoom());
|
||||
}
|
||||
|
||||
public ProjectedMeters projectedMetersForLatLng(LatLng latLng) {
|
||||
@@ -456,11 +470,13 @@ final class NativeMapView {
|
||||
}
|
||||
|
||||
public PointF pixelForLatLng(LatLng latLng) {
|
||||
return nativePixelForLatLng(nativeMapViewPtr, latLng.getLatitude(), latLng.getLongitude());
|
||||
PointF pointF = nativePixelForLatLng(nativeMapViewPtr, latLng.getLatitude(), latLng.getLongitude());
|
||||
pointF.set(pointF.x * pixelRatio, pointF.y * pixelRatio);
|
||||
return pointF;
|
||||
}
|
||||
|
||||
public LatLng latLngForPixel(PointF pixel) {
|
||||
return nativeLatLngForPixel(nativeMapViewPtr, pixel.x, pixel.y);
|
||||
return nativeLatLngForPixel(nativeMapViewPtr, pixel.x / pixelRatio, pixel.y / pixelRatio);
|
||||
}
|
||||
|
||||
public double getTopOffsetPixelsForAnnotationSymbol(String symbolName) {
|
||||
@@ -636,6 +652,8 @@ final class NativeMapView {
|
||||
|
||||
private native void nativeSetStyleUrl(long nativeMapViewPtr, String url);
|
||||
|
||||
private native String nativeGetStyleUrl(long nativeMapViewPtr);
|
||||
|
||||
private native void nativeSetStyleJson(long nativeMapViewPtr, String newStyleJson);
|
||||
|
||||
private native String nativeGetStyleJson(long nativeMapViewPtr);
|
||||
@@ -782,6 +800,14 @@ final class NativeMapView {
|
||||
|
||||
private native void nativeSetAPIBaseURL(long nativeMapViewPtr, String baseUrl);
|
||||
|
||||
int getWidth() {
|
||||
return mapView.getWidth();
|
||||
}
|
||||
|
||||
int getHeight() {
|
||||
return mapView.getHeight();
|
||||
}
|
||||
|
||||
//
|
||||
// MapChangeEvents
|
||||
//
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.support.annotation.NonNull;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
|
||||
import com.mapbox.mapboxsdk.geometry.VisibleRegion;
|
||||
import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
|
||||
|
||||
/**
|
||||
* A projection is used to translate between on screen location and geographic coordinates on
|
||||
@@ -15,15 +16,33 @@ import com.mapbox.mapboxsdk.geometry.VisibleRegion;
|
||||
*/
|
||||
public class Projection {
|
||||
|
||||
private final MapView mapView;
|
||||
private final float screenDensity;
|
||||
private final PointF screenLocationPoint;
|
||||
private final NativeMapView nativeMapView;
|
||||
private int[] contentPadding;
|
||||
|
||||
Projection(@NonNull MapView mapView) {
|
||||
this.mapView = mapView;
|
||||
this.screenLocationPoint = new PointF();
|
||||
this.screenDensity = mapView.getContext() != null ? /* return default if unit test */
|
||||
mapView.getContext().getResources().getDisplayMetrics().density : 1.0f;
|
||||
Projection(@NonNull NativeMapView nativeMapView) {
|
||||
this.nativeMapView = nativeMapView;
|
||||
this.contentPadding = new int[]{0, 0, 0, 0};
|
||||
}
|
||||
|
||||
void setContentPadding(int[] contentPadding, int[] userLocationViewPadding) {
|
||||
this.contentPadding = contentPadding;
|
||||
|
||||
int[] padding = new int[]{
|
||||
contentPadding[0] + userLocationViewPadding[0],
|
||||
contentPadding[1] + userLocationViewPadding[1],
|
||||
contentPadding[2] + userLocationViewPadding[2],
|
||||
contentPadding[3] + userLocationViewPadding[3]
|
||||
};
|
||||
|
||||
nativeMapView.setContentPadding(padding);
|
||||
}
|
||||
|
||||
int[] getContentPadding() {
|
||||
return contentPadding;
|
||||
}
|
||||
|
||||
public void invalidateContentPadding(int[] userLocationViewPadding) {
|
||||
setContentPadding(contentPadding, userLocationViewPadding);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +56,7 @@ public class Projection {
|
||||
* @return The distance measured in meters.
|
||||
*/
|
||||
public double getMetersPerPixelAtLatitude(@FloatRange(from = -90, to = 90) double latitude) {
|
||||
return mapView.getMetersPerPixelAtLatitude(latitude);
|
||||
return nativeMapView.getMetersPerPixelAtLatitude(latitude);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,8 +69,7 @@ public class Projection {
|
||||
* the given screen point does not intersect the ground plane.
|
||||
*/
|
||||
public LatLng fromScreenLocation(PointF point) {
|
||||
screenLocationPoint.set(point.x / screenDensity, point.y / screenDensity);
|
||||
return mapView.fromNativeScreenLocation(screenLocationPoint);
|
||||
return nativeMapView.latLngForPixel(point);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,10 +81,10 @@ public class Projection {
|
||||
public VisibleRegion getVisibleRegion() {
|
||||
LatLngBounds.Builder builder = new LatLngBounds.Builder();
|
||||
|
||||
float left = mapView.getContentPaddingLeft();
|
||||
float right = mapView.getWidth() - mapView.getContentPaddingRight();
|
||||
float top = mapView.getContentPaddingTop();
|
||||
float bottom = mapView.getHeight() - mapView.getContentPaddingBottom();
|
||||
float left = contentPadding[0];
|
||||
float right = nativeMapView.getWidth() - contentPadding[2];
|
||||
float top = contentPadding[1];
|
||||
float bottom = nativeMapView.getHeight() - contentPadding[3];
|
||||
|
||||
LatLng topLeft = fromScreenLocation(new PointF(left, top));
|
||||
LatLng topRight = fromScreenLocation(new PointF(right, top));
|
||||
@@ -90,18 +108,14 @@ public class Projection {
|
||||
* @return A Point representing the screen location in screen pixels.
|
||||
*/
|
||||
public PointF toScreenLocation(LatLng location) {
|
||||
PointF pointF = mapView.toNativeScreenLocation(location);
|
||||
pointF.set(pointF.x * screenDensity, pointF.y * screenDensity);
|
||||
return pointF;
|
||||
return nativeMapView.pixelForLatLng(location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a zoom level based on minimum scale and current scale from MapView
|
||||
*
|
||||
* @param minScale The minimum scale to calculate the zoom level.
|
||||
* @return zoom level that fits the MapView.
|
||||
*/
|
||||
public double calculateZoom(float minScale) {
|
||||
return Math.log(mapView.getScale() * minScale) / Math.log(2);
|
||||
float getHeight() {
|
||||
return nativeMapView.getHeight();
|
||||
}
|
||||
|
||||
float getWidth() {
|
||||
return nativeMapView.getWidth();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,30 @@
|
||||
package com.mapbox.mapboxsdk.maps;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.PointF;
|
||||
import android.location.Location;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
|
||||
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
|
||||
import com.mapbox.mapboxsdk.location.LocationListener;
|
||||
import com.mapbox.mapboxsdk.location.LocationServices;
|
||||
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
|
||||
|
||||
/**
|
||||
* Settings for the user location and bearing tracking of a MapboxMap.
|
||||
*/
|
||||
public class TrackingSettings {
|
||||
public final class TrackingSettings {
|
||||
|
||||
private MapView mapView;
|
||||
private UiSettings uiSettings;
|
||||
private boolean dismissLocationTrackingOnGesture = true;
|
||||
private boolean dismissBearingTrackingOnGesture = true;
|
||||
private final MyLocationView myLocationView;
|
||||
private final UiSettings uiSettings;
|
||||
private final FocalPointChangeListener focalPointChangedListener;
|
||||
private LocationListener myLocationListener;
|
||||
|
||||
@MyLocationTracking.Mode
|
||||
private int myLocationTrackingMode;
|
||||
@@ -24,8 +32,14 @@ public class TrackingSettings {
|
||||
@MyBearingTracking.Mode
|
||||
private int myBearingTrackingMode;
|
||||
|
||||
TrackingSettings(@NonNull MapView mapView, UiSettings uiSettings) {
|
||||
this.mapView = mapView;
|
||||
private MapboxMap.OnMyLocationTrackingModeChangeListener onMyLocationTrackingModeChangeListener;
|
||||
private MapboxMap.OnMyBearingTrackingModeChangeListener onMyBearingTrackingModeChangeListener;
|
||||
private boolean dismissLocationTrackingOnGesture = true;
|
||||
private boolean dismissBearingTrackingOnGesture = true;
|
||||
|
||||
TrackingSettings(@NonNull MyLocationView myLocationView, UiSettings uiSettings, FocalPointChangeListener focalPointChangedListener) {
|
||||
this.myLocationView = myLocationView;
|
||||
this.focalPointChangedListener = focalPointChangedListener;
|
||||
this.uiSettings = uiSettings;
|
||||
}
|
||||
|
||||
@@ -45,7 +59,17 @@ public class TrackingSettings {
|
||||
@UiThread
|
||||
public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
|
||||
this.myLocationTrackingMode = myLocationTrackingMode;
|
||||
mapView.setMyLocationTrackingMode(myLocationTrackingMode);
|
||||
myLocationView.setMyLocationTrackingMode(myLocationTrackingMode);
|
||||
|
||||
if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
|
||||
focalPointChangedListener.onFocalPointChanged(new PointF(myLocationView.getCenterX(), myLocationView.getCenterY()));
|
||||
} else {
|
||||
focalPointChangedListener.onFocalPointChanged(null);
|
||||
}
|
||||
|
||||
if (onMyLocationTrackingModeChangeListener != null) {
|
||||
onMyLocationTrackingModeChangeListener.onMyLocationTrackingModeChange(myLocationTrackingMode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +103,10 @@ public class TrackingSettings {
|
||||
@UiThread
|
||||
public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
|
||||
this.myBearingTrackingMode = myBearingTrackingMode;
|
||||
mapView.setMyBearingTrackingMode(myBearingTrackingMode);
|
||||
myLocationView.setMyBearingTrackingMode(myBearingTrackingMode);
|
||||
if (onMyBearingTrackingModeChangeListener != null) {
|
||||
onMyBearingTrackingModeChangeListener.onMyBearingTrackingModeChange(myBearingTrackingMode);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -220,7 +247,7 @@ public class TrackingSettings {
|
||||
* @param translate
|
||||
* @param rotate
|
||||
*/
|
||||
public void resetTrackingModesIfRequired(boolean translate, boolean rotate) {
|
||||
void resetTrackingModesIfRequired(boolean translate, boolean rotate) {
|
||||
// if tracking is on, and we should dismiss tracking with gestures, and this is a scroll action, turn tracking off
|
||||
if (translate && !isLocationTrackingDisabled() && isDismissLocationTrackingOnGesture()) {
|
||||
setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
|
||||
@@ -232,7 +259,57 @@ public class TrackingSettings {
|
||||
}
|
||||
}
|
||||
|
||||
public void resetTrackingModesIfRequired(CameraPosition cameraPosition) {
|
||||
void resetTrackingModesIfRequired(CameraPosition cameraPosition) {
|
||||
resetTrackingModesIfRequired(cameraPosition.target != null, cameraPosition.bearing != -1);
|
||||
}
|
||||
|
||||
public void invalidateFocalPointForTracking(MyLocationView myLocationView) {
|
||||
if (!isLocationTrackingDisabled()) {
|
||||
focalPointChangedListener.onFocalPointChanged(new PointF(myLocationView.getCenterX(), myLocationView.getCenterY()));
|
||||
} else {
|
||||
focalPointChangedListener.onFocalPointChanged(null);
|
||||
}
|
||||
}
|
||||
|
||||
void setMyLocationEnabled(boolean enabled) {
|
||||
myLocationView.setEnabled(enabled);
|
||||
}
|
||||
|
||||
Location getMyLocation() {
|
||||
return myLocationView.getLocation();
|
||||
}
|
||||
|
||||
void setOnMyLocationChangeListener(@Nullable final MapboxMap.OnMyLocationChangeListener listener) {
|
||||
if (listener != null) {
|
||||
myLocationListener = new LocationListener() {
|
||||
@Override
|
||||
public void onLocationChanged(Location location) {
|
||||
if (listener != null) {
|
||||
listener.onMyLocationChange(location);
|
||||
}
|
||||
}
|
||||
};
|
||||
LocationServices.getLocationServices(myLocationView.getContext()).addLocationListener(myLocationListener);
|
||||
} else {
|
||||
LocationServices.getLocationServices(myLocationView.getContext()).removeLocationListener(myLocationListener);
|
||||
myLocationListener = null;
|
||||
}
|
||||
}
|
||||
|
||||
boolean isPermissionsAccepted() {
|
||||
return (ContextCompat.checkSelfPermission(myLocationView.getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) ||
|
||||
ContextCompat.checkSelfPermission(myLocationView.getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
void setOnMyLocationTrackingModeChangeListener(MapboxMap.OnMyLocationTrackingModeChangeListener onMyLocationTrackingModeChangeListener) {
|
||||
this.onMyLocationTrackingModeChangeListener = onMyLocationTrackingModeChangeListener;
|
||||
}
|
||||
|
||||
void setOnMyBearingTrackingModeChangeListener(MapboxMap.OnMyBearingTrackingModeChangeListener onMyBearingTrackingModeChangeListener) {
|
||||
this.onMyBearingTrackingModeChangeListener = onMyBearingTrackingModeChangeListener;
|
||||
}
|
||||
|
||||
MyLocationView getMyLocationView(){
|
||||
return myLocationView;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
package com.mapbox.mapboxsdk.maps;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
|
||||
import com.mapbox.mapboxsdk.annotations.MarkerViewManager;
|
||||
import com.mapbox.mapboxsdk.camera.CameraPosition;
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdate;
|
||||
import com.mapbox.mapboxsdk.constants.MapboxConstants;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -16,18 +21,23 @@ import static com.mapbox.mapboxsdk.maps.MapView.REGION_DID_CHANGE_ANIMATED;
|
||||
* Responsible for synchronising {@link CameraPosition} state and notifying {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraChangeListener}.
|
||||
* </p>
|
||||
*/
|
||||
class Transform {
|
||||
final class Transform implements MapView.OnMapChangedListener {
|
||||
|
||||
private NativeMapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
private final NativeMapView mapView;
|
||||
private final MarkerViewManager markerViewManager;
|
||||
private final TrackingSettings trackingSettings;
|
||||
private final MyLocationView myLocationView;
|
||||
|
||||
private CameraPosition cameraPosition;
|
||||
private MapboxMap.CancelableCallback cameraCancelableCallback;
|
||||
private MapboxMap.OnCameraChangeListener onCameraChangeListener;
|
||||
|
||||
Transform(NativeMapView mapView, MapboxMap mapboxMap) {
|
||||
Transform(NativeMapView mapView, MarkerViewManager markerViewManager, TrackingSettings trackingSettings) {
|
||||
this.mapView = mapView;
|
||||
this.mapboxMap = mapboxMap;
|
||||
this.markerViewManager = markerViewManager;
|
||||
this.trackingSettings = trackingSettings;
|
||||
this.myLocationView = trackingSettings.getMyLocationView();
|
||||
mapView.addOnMapChangedListener(this);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -43,25 +53,36 @@ class Transform {
|
||||
}
|
||||
|
||||
@UiThread
|
||||
final void moveCamera(CameraUpdate update, MapboxMap.CancelableCallback callback) {
|
||||
void updateCameraPosition(@NonNull CameraPosition position) {
|
||||
if (myLocationView != null) {
|
||||
myLocationView.setCameraPosition(position);
|
||||
}
|
||||
markerViewManager.setTilt((float) position.tilt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMapChanged(@MapView.MapChange int change) {
|
||||
if (change == MapView.REGION_DID_CHANGE_ANIMATED) {
|
||||
invalidateCameraPosition();
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
final void moveCamera(MapboxMap mapboxMap, CameraUpdate update, MapboxMap.CancelableCallback callback) {
|
||||
cameraPosition = update.getCameraPosition(mapboxMap);
|
||||
mapboxMap.getTrackingSettings().resetTrackingModesIfRequired(cameraPosition);
|
||||
trackingSettings.resetTrackingModesIfRequired(cameraPosition);
|
||||
cancelTransitions();
|
||||
mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom);
|
||||
|
||||
// MapChange.REGION_DID_CHANGE_ANIMATED is not called for `jumpTo`
|
||||
// invalidate camera position to provide OnCameraChange event.
|
||||
mapboxMap.invalidateCameraPosition();
|
||||
if (callback != null) {
|
||||
callback.onFinish();
|
||||
}
|
||||
}
|
||||
|
||||
@UiThread
|
||||
final void easeCamera(CameraUpdate update, int durationMs, boolean easingInterpolator, boolean resetTrackingMode, final MapboxMap.CancelableCallback callback) {
|
||||
final void easeCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, boolean easingInterpolator, boolean resetTrackingMode, final MapboxMap.CancelableCallback callback) {
|
||||
cameraPosition = update.getCameraPosition(mapboxMap);
|
||||
if (resetTrackingMode) {
|
||||
mapboxMap.getTrackingSettings().resetTrackingModesIfRequired(cameraPosition);
|
||||
trackingSettings.resetTrackingModesIfRequired(cameraPosition);
|
||||
}
|
||||
|
||||
cancelTransitions();
|
||||
@@ -83,9 +104,9 @@ class Transform {
|
||||
}
|
||||
|
||||
@UiThread
|
||||
final void animateCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
|
||||
final void animateCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
|
||||
cameraPosition = update.getCameraPosition(mapboxMap);
|
||||
mapboxMap.getTrackingSettings().resetTrackingModesIfRequired(cameraPosition);
|
||||
trackingSettings.resetTrackingModesIfRequired(cameraPosition);
|
||||
|
||||
cancelTransitions();
|
||||
if (callback != null) {
|
||||
@@ -140,4 +161,110 @@ class Transform {
|
||||
private long getDurationNano(long durationMs) {
|
||||
return durationMs > 0 ? TimeUnit.NANOSECONDS.convert(durationMs, TimeUnit.MILLISECONDS) : 0;
|
||||
}
|
||||
|
||||
//
|
||||
// non Camera API
|
||||
//
|
||||
|
||||
// Zoom in or out
|
||||
|
||||
double getZoom() {
|
||||
return cameraPosition.zoom;
|
||||
}
|
||||
|
||||
void zoom(boolean zoomIn) {
|
||||
zoom(zoomIn, -1.0f, -1.0f);
|
||||
}
|
||||
|
||||
void zoom(boolean zoomIn, float x, float y) {
|
||||
// Cancel any animation
|
||||
cancelTransitions();
|
||||
|
||||
if (zoomIn) {
|
||||
mapView.scaleBy(2.0, x, y, MapboxConstants.ANIMATION_DURATION);
|
||||
} else {
|
||||
mapView.scaleBy(0.5, x, y, MapboxConstants.ANIMATION_DURATION);
|
||||
}
|
||||
}
|
||||
|
||||
// Direction
|
||||
double getBearing() {
|
||||
double direction = -mapView.getBearing();
|
||||
|
||||
while (direction > 360) {
|
||||
direction -= 360;
|
||||
}
|
||||
while (direction < 0) {
|
||||
direction += 360;
|
||||
}
|
||||
|
||||
return direction;
|
||||
}
|
||||
|
||||
double getRawBearing(){
|
||||
return mapView.getBearing();
|
||||
}
|
||||
|
||||
void setBearing(double bearing) {
|
||||
if (myLocationView != null) {
|
||||
myLocationView.setBearing(bearing);
|
||||
}
|
||||
mapView.setBearing(bearing);
|
||||
}
|
||||
|
||||
void setBearing(double bearing, float focalX, float focalY) {
|
||||
if (myLocationView != null) {
|
||||
myLocationView.setBearing(bearing);
|
||||
}
|
||||
mapView.setBearing(bearing, focalX, focalY);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// LatLng / CenterCoordinate
|
||||
//
|
||||
|
||||
LatLng getLatLng() {
|
||||
return mapView.getLatLng();
|
||||
}
|
||||
|
||||
//
|
||||
// Pitch / Tilt
|
||||
//
|
||||
|
||||
double getTilt() {
|
||||
return mapView.getPitch();
|
||||
}
|
||||
|
||||
void setTilt(Double pitch) {
|
||||
if (myLocationView != null) {
|
||||
myLocationView.setTilt(pitch);
|
||||
}
|
||||
markerViewManager.setTilt(pitch.floatValue());
|
||||
mapView.setPitch(pitch, 0);
|
||||
}
|
||||
|
||||
//
|
||||
// Center coordinate
|
||||
//
|
||||
|
||||
LatLng getCenterCoordinate() {
|
||||
return mapView.getLatLng();
|
||||
}
|
||||
|
||||
void setCenterCoordinate(LatLng centerCoordinate) {
|
||||
mapView.setLatLng(centerCoordinate);
|
||||
}
|
||||
|
||||
void setGestureInProgress(boolean gestureInProgress) {
|
||||
mapView.setGestureInProgress(gestureInProgress);
|
||||
}
|
||||
|
||||
void zoomBy(double pow, float x, float y) {
|
||||
mapView.scaleBy(pow, x, y);
|
||||
}
|
||||
|
||||
void moveBy(double offsetX, double offsetY, long duration) {
|
||||
mapView.moveBy(offsetX, offsetY, duration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,23 +1,32 @@
|
||||
package com.mapbox.mapboxsdk.maps;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PointF;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.view.Gravity;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.mapbox.mapboxsdk.R;
|
||||
import com.mapbox.mapboxsdk.maps.widgets.CompassView;
|
||||
import com.mapbox.mapboxsdk.utils.ColorUtils;
|
||||
|
||||
/**
|
||||
* Settings for the user interface of a MapboxMap. To obtain this interface, call getUiSettings().
|
||||
*/
|
||||
public class UiSettings {
|
||||
public final class UiSettings {
|
||||
|
||||
private MapView mapView;
|
||||
|
||||
private CompassViewSettings compassSettings;
|
||||
private ViewSettings logoSettings;
|
||||
private ViewSettings attributionSettings;
|
||||
private final FocalPointChangeListener focalPointChangeListener;
|
||||
private final Projection projection;
|
||||
private final CompassView compassView;
|
||||
private final ImageView attributionsView;
|
||||
private final View logoView;
|
||||
private float pixelRatio;
|
||||
|
||||
private boolean rotateGesturesEnabled = true;
|
||||
private boolean rotateGestureChangeAllowed = true;
|
||||
@@ -35,13 +44,17 @@ public class UiSettings {
|
||||
|
||||
private boolean deselectMarkersOnTap = true;
|
||||
|
||||
private PointF focalPoint;
|
||||
private PointF userProvidedFocalPoint;
|
||||
|
||||
UiSettings(@NonNull MapView mapView) {
|
||||
this.mapView = mapView;
|
||||
this.compassSettings = new CompassViewSettings();
|
||||
this.logoSettings = new ViewSettings();
|
||||
this.attributionSettings = new ViewSettings();
|
||||
UiSettings(@NonNull Projection projection, @NonNull FocalPointChangeListener listener, @NonNull CompassView compassView, @NonNull ImageView attributionsView, @NonNull View logoView) {
|
||||
this.projection = projection;
|
||||
this.focalPointChangeListener = listener;
|
||||
this.compassView = compassView;
|
||||
this.attributionsView = attributionsView;
|
||||
this.logoView = logoView;
|
||||
if(logoView.getResources()!=null) {
|
||||
this.pixelRatio = logoView.getResources().getDisplayMetrics().density;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,8 +69,7 @@ public class UiSettings {
|
||||
* @param compassEnabled True to enable the compass; false to disable the compass.
|
||||
*/
|
||||
public void setCompassEnabled(boolean compassEnabled) {
|
||||
compassSettings.setEnabled(compassEnabled);
|
||||
mapView.setCompassEnabled(compassEnabled);
|
||||
compassView.setEnabled(compassEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,7 +78,7 @@ public class UiSettings {
|
||||
* @return True if the compass is enabled; false if the compass is disabled.
|
||||
*/
|
||||
public boolean isCompassEnabled() {
|
||||
return compassSettings.isEnabled();
|
||||
return compassView.isEnabled();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,8 +93,7 @@ public class UiSettings {
|
||||
*/
|
||||
@UiThread
|
||||
public void setCompassGravity(int gravity) {
|
||||
compassSettings.setGravity(gravity);
|
||||
mapView.setCompassGravity(gravity);
|
||||
setWidgetGravity(compassView, gravity);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,8 +105,7 @@ public class UiSettings {
|
||||
* @param compassFadeFacingNorth True to enable the fading animation; false to disable it
|
||||
*/
|
||||
public void setCompassFadeFacingNorth(boolean compassFadeFacingNorth) {
|
||||
compassSettings.setFadeFacingNorth(compassFadeFacingNorth);
|
||||
mapView.setCompassFadeFacingNorth(compassFadeFacingNorth);
|
||||
compassView.fadeCompassViewFacingNorth(compassFadeFacingNorth);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -103,8 +113,8 @@ public class UiSettings {
|
||||
*
|
||||
* @return True if the compass will fade, false if it remains visible
|
||||
*/
|
||||
public boolean isCompassFadeWhenFacingNorth(){
|
||||
return compassSettings.isFadeFacingNorth();
|
||||
public boolean isCompassFadeWhenFacingNorth() {
|
||||
return compassView.isFadeCompassViewFacingNorth();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,7 +123,7 @@ public class UiSettings {
|
||||
* @return The gravity
|
||||
*/
|
||||
public int getCompassGravity() {
|
||||
return compassSettings.getGravity();
|
||||
return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).gravity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -127,8 +137,7 @@ public class UiSettings {
|
||||
*/
|
||||
@UiThread
|
||||
public void setCompassMargins(int left, int top, int right, int bottom) {
|
||||
compassSettings.setMargins(new int[]{left, top, right, bottom});
|
||||
mapView.setCompassMargins(left, top, right, bottom);
|
||||
setWidgetMargins(compassView, left, top, right, bottom);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,7 +146,7 @@ public class UiSettings {
|
||||
* @return The left margin in pixels
|
||||
*/
|
||||
public int getCompassMarginLeft() {
|
||||
return compassSettings.getMargins()[0];
|
||||
return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).leftMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,7 +155,7 @@ public class UiSettings {
|
||||
* @return The top margin in pixels
|
||||
*/
|
||||
public int getCompassMarginTop() {
|
||||
return compassSettings.getMargins()[1];
|
||||
return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).topMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -155,7 +164,7 @@ public class UiSettings {
|
||||
* @return The right margin in pixels
|
||||
*/
|
||||
public int getCompassMarginRight() {
|
||||
return compassSettings.getMargins()[2];
|
||||
return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).rightMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,7 +173,7 @@ public class UiSettings {
|
||||
* @return The bottom margin in pixels
|
||||
*/
|
||||
public int getCompassMarginBottom() {
|
||||
return compassSettings.getMargins()[3];
|
||||
return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).bottomMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -176,8 +185,7 @@ public class UiSettings {
|
||||
* @param enabled True to enable the logo; false to disable the logo.
|
||||
*/
|
||||
public void setLogoEnabled(boolean enabled) {
|
||||
logoSettings.setEnabled(enabled);
|
||||
mapView.setLogoEnabled(enabled);
|
||||
logoView.setVisibility(enabled ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -186,7 +194,7 @@ public class UiSettings {
|
||||
* @return True if the logo is enabled; false if the logo is disabled.
|
||||
*/
|
||||
public boolean isLogoEnabled() {
|
||||
return logoSettings.isEnabled();
|
||||
return logoView.getVisibility() == View.VISIBLE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -200,8 +208,7 @@ public class UiSettings {
|
||||
* @see Gravity
|
||||
*/
|
||||
public void setLogoGravity(int gravity) {
|
||||
logoSettings.setGravity(gravity);
|
||||
mapView.setLogoGravity(gravity);
|
||||
setWidgetGravity(logoView, gravity);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,7 +217,7 @@ public class UiSettings {
|
||||
* @return The gravity
|
||||
*/
|
||||
public int getLogoGravity() {
|
||||
return logoSettings.getGravity();
|
||||
return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).gravity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -223,8 +230,7 @@ public class UiSettings {
|
||||
* @param bottom The bottom margin in pixels.
|
||||
*/
|
||||
public void setLogoMargins(int left, int top, int right, int bottom) {
|
||||
logoSettings.setMargins(new int[]{left, top, right, bottom});
|
||||
mapView.setLogoMargins(left, top, right, bottom);
|
||||
setWidgetMargins(logoView, left, top, right, bottom);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,7 +239,7 @@ public class UiSettings {
|
||||
* @return The left margin in pixels
|
||||
*/
|
||||
public int getLogoMarginLeft() {
|
||||
return logoSettings.getMargins()[0];
|
||||
return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).leftMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,7 +248,7 @@ public class UiSettings {
|
||||
* @return The top margin in pixels
|
||||
*/
|
||||
public int getLogoMarginTop() {
|
||||
return logoSettings.getMargins()[1];
|
||||
return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).topMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -251,7 +257,7 @@ public class UiSettings {
|
||||
* @return The right margin in pixels
|
||||
*/
|
||||
public int getLogoMarginRight() {
|
||||
return logoSettings.getMargins()[2];
|
||||
return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).rightMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,7 +266,7 @@ public class UiSettings {
|
||||
* @return The bottom margin in pixels
|
||||
*/
|
||||
public int getLogoMarginBottom() {
|
||||
return logoSettings.getMargins()[3];
|
||||
return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).bottomMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,8 +278,7 @@ public class UiSettings {
|
||||
* @param enabled True to enable the attribution; false to disable the attribution.
|
||||
*/
|
||||
public void setAttributionEnabled(boolean enabled) {
|
||||
attributionSettings.setEnabled(enabled);
|
||||
mapView.setAttributionEnabled(enabled ? View.VISIBLE : View.GONE);
|
||||
attributionsView.setVisibility(enabled ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -282,7 +287,7 @@ public class UiSettings {
|
||||
* @return True if the attribution is enabled; false if the attribution is disabled.
|
||||
*/
|
||||
public boolean isAttributionEnabled() {
|
||||
return attributionSettings.isEnabled();
|
||||
return attributionsView.getVisibility() == View.VISIBLE;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -295,8 +300,7 @@ public class UiSettings {
|
||||
* @see Gravity
|
||||
*/
|
||||
public void setAttributionGravity(int gravity) {
|
||||
attributionSettings.setGravity(gravity);
|
||||
mapView.setAttributionGravity(gravity);
|
||||
setWidgetGravity(attributionsView, gravity);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -305,7 +309,7 @@ public class UiSettings {
|
||||
* @return The gravity
|
||||
*/
|
||||
public int getAttributionGravity() {
|
||||
return attributionSettings.getGravity();
|
||||
return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).gravity;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -317,8 +321,7 @@ public class UiSettings {
|
||||
* @param bottom The bottom margin in pixels.
|
||||
*/
|
||||
public void setAttributionMargins(int left, int top, int right, int bottom) {
|
||||
attributionSettings.setMargins(new int[]{left, top, right, bottom});
|
||||
mapView.setAttributionMargins(left, top, right, bottom);
|
||||
setWidgetMargins(attributionsView, left, top, right, bottom);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -330,17 +333,12 @@ public class UiSettings {
|
||||
* @param tintColor Color to tint the attribution.
|
||||
*/
|
||||
public void setAttributionTintColor(@ColorInt int tintColor) {
|
||||
attributionSettings.setTintColor(tintColor);
|
||||
mapView.setAtttibutionTintColor(tintColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the tint color value of the attribution view.
|
||||
*
|
||||
* @return The tint color
|
||||
*/
|
||||
public int getAttributionTintColor() {
|
||||
return attributionSettings.getTintColor();
|
||||
// Check that the tint color being passed in isn't transparent.
|
||||
if (Color.alpha(tintColor) == 0) {
|
||||
ColorUtils.setTintList(attributionsView, ContextCompat.getColor(attributionsView.getContext(), R.color.mapbox_blue));
|
||||
} else {
|
||||
ColorUtils.setTintList(attributionsView, tintColor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -349,7 +347,7 @@ public class UiSettings {
|
||||
* @return The left margin in pixels
|
||||
*/
|
||||
public int getAttributionMarginLeft() {
|
||||
return attributionSettings.getMargins()[0];
|
||||
return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).leftMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -358,7 +356,7 @@ public class UiSettings {
|
||||
* @return The top margin in pixels
|
||||
*/
|
||||
public int getAttributionMarginTop() {
|
||||
return attributionSettings.getMargins()[1];
|
||||
return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).topMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -367,7 +365,7 @@ public class UiSettings {
|
||||
* @return The right margin in pixels
|
||||
*/
|
||||
public int getAttributionMarginRight() {
|
||||
return attributionSettings.getMargins()[2];
|
||||
return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).rightMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -376,7 +374,7 @@ public class UiSettings {
|
||||
* @return The bottom margin in pixels
|
||||
*/
|
||||
public int getAttributionMarginBottom() {
|
||||
return attributionSettings.getMargins()[3];
|
||||
return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).bottomMargin;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -593,8 +591,8 @@ public class UiSettings {
|
||||
* @param focalPoint the focal point to be used.
|
||||
*/
|
||||
public void setFocalPoint(@Nullable PointF focalPoint) {
|
||||
this.focalPoint = focalPoint;
|
||||
mapView.setFocalPoint(focalPoint);
|
||||
this.userProvidedFocalPoint = focalPoint;
|
||||
focalPointChangeListener.onFocalPointChanged(focalPoint);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -603,7 +601,7 @@ public class UiSettings {
|
||||
* @return The focal point
|
||||
*/
|
||||
public PointF getFocalPoint() {
|
||||
return focalPoint;
|
||||
return userProvidedFocalPoint;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -612,7 +610,7 @@ public class UiSettings {
|
||||
* @return height in pixels
|
||||
*/
|
||||
public float getHeight() {
|
||||
return mapView.getMeasuredHeight();
|
||||
return projection.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -621,15 +619,36 @@ public class UiSettings {
|
||||
* @return widht in pixels
|
||||
*/
|
||||
public float getWidth() {
|
||||
return mapView.getMeasuredWidth();
|
||||
return projection.getWidth();
|
||||
}
|
||||
|
||||
float getPixelRatio() {
|
||||
return pixelRatio;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidates the ViewSettings instances shown on top of the MapView
|
||||
*/
|
||||
public void invalidate() {
|
||||
mapView.setLogoMargins(getLogoMarginLeft(), getLogoMarginTop(), getLogoMarginRight(), getLogoMarginBottom());
|
||||
mapView.setCompassMargins(getCompassMarginLeft(), getCompassMarginTop(), getCompassMarginRight(), getCompassMarginBottom());
|
||||
mapView.setAttributionMargins(getAttributionMarginLeft(), getAttributionMarginTop(), getAttributionMarginRight(), getAttributionMarginBottom());
|
||||
setLogoMargins(getLogoMarginLeft(), getLogoMarginTop(), getLogoMarginRight(), getLogoMarginBottom());
|
||||
setCompassMargins(getCompassMarginLeft(), getCompassMarginTop(), getCompassMarginRight(), getCompassMarginBottom());
|
||||
setAttributionMargins(getAttributionMarginLeft(), getAttributionMarginTop(), getAttributionMarginRight(), getAttributionMarginBottom());
|
||||
}
|
||||
|
||||
private void setWidgetGravity(@NonNull final View view, int gravity) {
|
||||
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams();
|
||||
layoutParams.gravity = gravity;
|
||||
view.setLayoutParams(layoutParams);
|
||||
}
|
||||
|
||||
private void setWidgetMargins(@NonNull final View view, int left, int top, int right, int bottom) {
|
||||
int contentPadding[] = projection.getContentPadding();
|
||||
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams();
|
||||
left += contentPadding[0];
|
||||
top += contentPadding[1];
|
||||
right += contentPadding[2];
|
||||
bottom += contentPadding[3];
|
||||
layoutParams.setMargins(left, top, right, bottom);
|
||||
view.setLayoutParams(layoutParams);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
package com.mapbox.mapboxsdk.maps;
|
||||
|
||||
/**
|
||||
* Settings for the overlain views of a MapboxMap. Used by UiSettings.
|
||||
*/
|
||||
class ViewSettings {
|
||||
|
||||
private boolean enabled;
|
||||
private int gravity;
|
||||
private int[] margins;
|
||||
private int tintColor;
|
||||
|
||||
public ViewSettings() {
|
||||
margins = new int[4];
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public int getGravity() {
|
||||
return gravity;
|
||||
}
|
||||
|
||||
public void setGravity(int gravity) {
|
||||
this.gravity = gravity;
|
||||
}
|
||||
|
||||
public int[] getMargins() {
|
||||
return margins;
|
||||
}
|
||||
|
||||
public void setMargins(int[] margins) {
|
||||
this.margins = margins;
|
||||
}
|
||||
|
||||
public int getTintColor() {
|
||||
return tintColor;
|
||||
}
|
||||
|
||||
public void setTintColor(int tintColor) {
|
||||
this.tintColor = tintColor;
|
||||
}
|
||||
}
|
||||
@@ -61,6 +61,7 @@ public final class CompassView extends ImageView implements Runnable {
|
||||
setLayoutParams(lp);
|
||||
}
|
||||
|
||||
// TODO refactor MapboxMap and replace with interface
|
||||
public void setMapboxMap(@NonNull MapboxMap mapboxMap) {
|
||||
setOnClickListener(new CompassClickListener(mapboxMap, this));
|
||||
}
|
||||
@@ -121,6 +122,10 @@ public final class CompassView extends ImageView implements Runnable {
|
||||
fadeCompassViewFacingNorth = compassFadeFacingNorth;
|
||||
}
|
||||
|
||||
public boolean isFadeCompassViewFacingNorth(){
|
||||
return fadeCompassViewFacingNorth;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (isFacingNorth() && fadeCompassViewFacingNorth) {
|
||||
|
||||
@@ -379,6 +379,7 @@ public class MyLocationView extends View {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO refactor MapboxMap out
|
||||
public void setMapboxMap(MapboxMap mapboxMap) {
|
||||
this.mapboxMap = mapboxMap;
|
||||
this.projection = mapboxMap.getProjection();
|
||||
|
||||
@@ -4,14 +4,16 @@ import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.support.annotation.IntRange;
|
||||
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.Projection;
|
||||
import com.mapbox.mapboxsdk.maps.TrackingSettings;
|
||||
|
||||
/**
|
||||
* Settings to configure the visual appearance of the MyLocationView.
|
||||
*/
|
||||
public class MyLocationViewSettings {
|
||||
|
||||
private MapView mapView;
|
||||
private Projection projection;
|
||||
private TrackingSettings trackingSettings;
|
||||
private MyLocationView myLocationView;
|
||||
|
||||
//
|
||||
@@ -58,13 +60,14 @@ public class MyLocationViewSettings {
|
||||
/**
|
||||
* Creates an instance of MyLocationViewSettings
|
||||
*
|
||||
* @param mapView the MapView that hosts the MyLocationView
|
||||
* @param projection the MapView projection
|
||||
* @param myLocationView the MyLocationView to apply the settings to
|
||||
* @see MyLocationView
|
||||
*/
|
||||
public MyLocationViewSettings(MapView mapView, MyLocationView myLocationView) {
|
||||
this.mapView = mapView;
|
||||
public MyLocationViewSettings(Projection projection, MyLocationView myLocationView, TrackingSettings trackingSettings) {
|
||||
this.projection = projection;
|
||||
this.myLocationView = myLocationView;
|
||||
this.trackingSettings = trackingSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,7 +211,8 @@ public class MyLocationViewSettings {
|
||||
public void setPadding(int left, int top, int right, int bottom) {
|
||||
padding = new int[]{left, top, right, bottom};
|
||||
myLocationView.setContentPadding(padding);
|
||||
mapView.invalidateContentPadding();
|
||||
projection.invalidateContentPadding(padding);
|
||||
trackingSettings.invalidateFocalPointForTracking(myLocationView);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,4 +261,8 @@ public class MyLocationViewSettings {
|
||||
this.accuracyTintColor = accuracyTintColor;
|
||||
myLocationView.setAccuracyTint(accuracyTintColor);
|
||||
}
|
||||
|
||||
public void setTilt(double tilt) {
|
||||
myLocationView.setTilt(tilt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
package com.mapbox.mapboxsdk.telemetry;
|
||||
|
||||
import android.graphics.PointF;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.Projection;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Hashtable;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
/**
|
||||
* Constants for Telemetry Metadata
|
||||
@@ -53,7 +63,7 @@ public class MapboxEvent implements Serializable {
|
||||
public static final String ATTRIBUTE_VENDOR_ID = "vendorId";
|
||||
public static final String ATTRIBUTE_APP_BUNDLE_ID = "appBundleId";
|
||||
public static final String ATTRIBUTE_MODEL = "model";
|
||||
public static final String ATTRIBUTE_OPERATING_SYSTEM= "operatingSystem";
|
||||
public static final String ATTRIBUTE_OPERATING_SYSTEM = "operatingSystem";
|
||||
public static final String ATTRIBUTE_ORIENTATION = "orientation";
|
||||
public static final String ATTRIBUTE_BATTERY_LEVEL = "batteryLevel";
|
||||
public static final String ATTRIBUTE_PLUGGED_IN = "pluggedIn";
|
||||
@@ -63,4 +73,71 @@ public class MapboxEvent implements Serializable {
|
||||
public static final String ATTRIBUTE_CARRIER = "carrier";
|
||||
public static final String ATTRIBUTE_CELLULAR_NETWORK_TYPE = "cellularNetworkType";
|
||||
public static final String ATTRIBUTE_WIFI = "wifi";
|
||||
|
||||
/**
|
||||
* Helper method for tracking gesture events
|
||||
*
|
||||
* @param projection Projection of the Map object
|
||||
* @param gestureId Type of Gesture See {@see MapboxEvent#GESTURE_SINGLETAP MapboxEvent#GESTURE_DOUBLETAP MapboxEvent#GESTURE_TWO_FINGER_SINGLETAP MapboxEvent#GESTURE_QUICK_ZOOM MapboxEvent#GESTURE_PAN_START MapboxEvent#GESTURE_PINCH_START MapboxEvent#GESTURE_ROTATION_START MapboxEvent#GESTURE_PITCH_START}
|
||||
* @param xCoordinate Original x screen coordinate at start of gesture
|
||||
* @param yCoordinate Original y screen cooridnate at start of gesture
|
||||
* @param zoom Zoom level to be registered
|
||||
*/
|
||||
public static void trackGestureEvent(@NonNull Projection projection, @NonNull String gestureId, float xCoordinate, float yCoordinate, double zoom) {
|
||||
LatLng tapLatLng = projection.fromScreenLocation(new PointF(xCoordinate, yCoordinate));
|
||||
|
||||
// NaN and Infinite checks to prevent JSON errors at send to server time
|
||||
if (Double.isNaN(tapLatLng.getLatitude()) || Double.isNaN(tapLatLng.getLongitude())) {
|
||||
Timber.d("trackGestureEvent() has a NaN lat or lon. Returning.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Double.isInfinite(tapLatLng.getLatitude()) || Double.isInfinite(tapLatLng.getLongitude())) {
|
||||
Timber.d("trackGestureEvent() has an Infinite lat or lon. Returning.");
|
||||
return;
|
||||
}
|
||||
|
||||
Hashtable<String, Object> evt = new Hashtable<>();
|
||||
evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_CLICK);
|
||||
evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate());
|
||||
evt.put(MapboxEvent.KEY_GESTURE_ID, gestureId);
|
||||
evt.put(MapboxEvent.KEY_LATITUDE, tapLatLng.getLatitude());
|
||||
evt.put(MapboxEvent.KEY_LONGITUDE, tapLatLng.getLongitude());
|
||||
evt.put(MapboxEvent.KEY_ZOOM, zoom);
|
||||
|
||||
MapboxEventManager.getMapboxEventManager().pushEvent(evt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method for tracking DragEnd gesture event
|
||||
* See {@see MapboxEvent#TYPE_MAP_DRAGEND}
|
||||
*
|
||||
* @param projection projection of the Map object.
|
||||
* @param xCoordinate Original x screen coordinate at end of drag
|
||||
* @param yCoordinate Orginal y screen coordinate at end of drag
|
||||
* @param zoom Zoom level to be registered
|
||||
*/
|
||||
public static void trackGestureDragEndEvent(@NonNull Projection projection, float xCoordinate, float yCoordinate, double zoom) {
|
||||
LatLng tapLatLng = projection.fromScreenLocation(new PointF(xCoordinate, yCoordinate));
|
||||
|
||||
// NaN and Infinite checks to prevent JSON errors at send to server time
|
||||
if (Double.isNaN(tapLatLng.getLatitude()) || Double.isNaN(tapLatLng.getLongitude())) {
|
||||
Timber.d("trackGestureDragEndEvent() has a NaN lat or lon. Returning.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Double.isInfinite(tapLatLng.getLatitude()) || Double.isInfinite(tapLatLng.getLongitude())) {
|
||||
Timber.d("trackGestureDragEndEvent() has an Infinite lat or lon. Returning.");
|
||||
return;
|
||||
}
|
||||
|
||||
Hashtable<String, Object> evt = new Hashtable<>();
|
||||
evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_DRAGEND);
|
||||
evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate());
|
||||
evt.put(MapboxEvent.KEY_LATITUDE, tapLatLng.getLatitude());
|
||||
evt.put(MapboxEvent.KEY_LONGITUDE, tapLatLng.getLongitude());
|
||||
evt.put(MapboxEvent.KEY_ZOOM, zoom);
|
||||
|
||||
MapboxEventManager.getMapboxEventManager().pushEvent(evt);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user