package com.mapbox.mapboxsdk.maps; import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Dialog; import android.app.Fragment; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.PointF; import android.graphics.RectF; import android.graphics.SurfaceTexture; import android.location.Location; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Bundle; import android.support.annotation.CallSuper; import android.support.annotation.FloatRange; import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; import android.support.v4.content.ContextCompat; import android.support.v4.view.GestureDetectorCompat; import android.support.v4.view.ScaleGestureDetectorCompat; import android.support.v7.app.AlertDialog; import android.text.TextUtils; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.util.Log; import android.view.GestureDetector; import android.view.InputDevice; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.ScaleGestureDetector; import android.view.Surface; import android.view.TextureView; import android.view.View; import android.view.ViewConfiguration; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ListView; import android.widget.ZoomButtonsController; 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.R; import com.mapbox.mapboxsdk.annotations.Annotation; import com.mapbox.mapboxsdk.annotations.Icon; import com.mapbox.mapboxsdk.annotations.IconFactory; import com.mapbox.mapboxsdk.annotations.InfoWindow; import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.Polygon; import com.mapbox.mapboxsdk.annotations.Polyline; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.constants.MyBearingTracking; import com.mapbox.mapboxsdk.constants.MyLocationTracking; import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.exceptions.IconBitmapChangedException; import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException; import com.mapbox.mapboxsdk.exceptions.TelemetryServiceNotConfiguredException; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.layers.CustomLayer; import com.mapbox.mapboxsdk.maps.widgets.CompassView; import com.mapbox.mapboxsdk.maps.widgets.UserLocationView; import com.mapbox.mapboxsdk.telemetry.MapboxEvent; import com.mapbox.mapboxsdk.telemetry.MapboxEventManager; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** *

* A {@code MapView} provides an embeddable map interface. * You use this class to display map information and to manipulate the map contents from your application. * You can center the map on a given coordinate, specify the size of the area you want to display, * and style the features of the map to fit your application's use case. *

*

* Use of {@code MapView} requires a Mapbox API access token. * Obtain an access token on the Mapbox account page. *

* Warning: Please note that you are responsible for getting permission to use the map data, * and for ensuring your use adheres to the relevant terms of use. * * @see MapView#setAccessToken(String) */ public class MapView extends FrameLayout { private MapboxMap mMapboxMap; private List mIcons; private NativeMapView mNativeMapView; private CompassView mCompassView; private ImageView mLogoView; private ImageView mAttributionsView; private UserLocationView mUserLocationView; private CopyOnWriteArrayList mOnMapChangedListener; private ZoomButtonsController mZoomButtonsController; private ConnectivityReceiver mConnectivityReceiver; private float mScreenDensity = 1.0f; private TrackballLongPressTimeOut mCurrentTrackballLongPressTimeOut; private GestureDetectorCompat mGestureDetector; private ScaleGestureDetector mScaleGestureDetector; private RotateGestureDetector mRotateGestureDetector; private ShoveGestureDetector mShoveGestureDetector; private boolean mTwoTap = false; private boolean mZoomStarted = false; private boolean mQuickZoom = false; private boolean mScrollInProgress = false; private int mContentPaddingLeft; private int mContentPaddingTop; private int mContentPaddingRight; private int mContentPaddingBottom; private String mStyleUrl; private List mOnMapReadyCallbackList; private boolean mInitialLoad; private boolean mDestroyed; @UiThread public MapView(@NonNull Context context) { super(context); initialize(context, MapboxMapOptions.createFromAttributes(context, null)); } @UiThread public MapView(@NonNull Context context, @Nullable AttributeSet attrs) { super(context, attrs); initialize(context, MapboxMapOptions.createFromAttributes(context, attrs)); } @UiThread public MapView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); initialize(context, MapboxMapOptions.createFromAttributes(context, attrs)); } @UiThread public MapView(@NonNull Context context, @Nullable MapboxMapOptions options) { super(context); initialize(context, options); } private void initialize(@NonNull Context context, @NonNull MapboxMapOptions options) { mInitialLoad = true; mOnMapReadyCallbackList = new ArrayList<>(); mOnMapChangedListener = new CopyOnWriteArrayList<>(); mMapboxMap = new MapboxMap(this); mIcons = new ArrayList<>(); View view = LayoutInflater.from(context).inflate(R.layout.mapview_internal, this); if (!isInEditMode()) { setWillNotDraw(false); } // Reference the TextureView TextureView textureView = (TextureView) view.findViewById(R.id.textureView); textureView.setSurfaceTextureListener(new SurfaceTextureListener()); // Check if we are in Android Studio UI editor to avoid error in layout preview if (isInEditMode()) { return; } mNativeMapView = new NativeMapView(this); // Ensure this view is interactable setClickable(true); setLongClickable(true); setFocusable(true); setFocusableInTouchMode(true); requestFocus(); // Touch gesture detectors mGestureDetector = new GestureDetectorCompat(context, new GestureListener()); mGestureDetector.setIsLongpressEnabled(true); mScaleGestureDetector = new ScaleGestureDetector(context, new ScaleGestureListener()); ScaleGestureDetectorCompat.setQuickScaleEnabled(mScaleGestureDetector, true); mRotateGestureDetector = new RotateGestureDetector(context, new RotateGestureListener()); mShoveGestureDetector = new ShoveGestureDetector(context, new ShoveGestureListener()); mZoomButtonsController = new ZoomButtonsController(this); mZoomButtonsController.setZoomSpeed(MapboxConstants.ANIMATION_DURATION); mZoomButtonsController.setOnZoomListener(new OnZoomListener()); // Connectivity onConnectivityChanged(isConnected()); mUserLocationView = (UserLocationView) view.findViewById(R.id.userLocationView); mUserLocationView.setMapboxMap(mMapboxMap); mCompassView = (CompassView) view.findViewById(R.id.compassView); mCompassView.setMapboxMap(mMapboxMap); mLogoView = (ImageView) view.findViewById(R.id.logoView); // Setup Attributions control mAttributionsView = (ImageView) view.findViewById(R.id.attributionView); mAttributionsView.setOnClickListener(new AttributionOnClickListener(this)); mScreenDensity = context.getResources().getDisplayMetrics().density; setInitialState(options); // Shows the zoom controls if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH)) { mMapboxMap.getUiSettings().setZoomControlsEnabled(true); } } private void setInitialState(MapboxMapOptions options) { mMapboxMap.setDebugActive(options.getDebugActive()); CameraPosition position = options.getCamera(); if (position != null) { mMapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(position)); } String accessToken = options.getAccessToken(); if (!TextUtils.isEmpty(accessToken)) { mMapboxMap.setAccessToken(accessToken); } String style = options.getStyle(); if (!TextUtils.isEmpty(style)) { mMapboxMap.setStyleUrl(style); } mMapboxMap.setMyLocationEnabled(options.getLocationEnabled()); // Enable gestures UiSettings uiSettings = mMapboxMap.getUiSettings(); uiSettings.setZoomGesturesEnabled(options.getZoomGesturesEnabled()); uiSettings.setScrollGesturesEnabled(options.getScrollGesturesEnabled()); uiSettings.setRotateGesturesEnabled(options.getRotateGesturesEnabled()); uiSettings.setTiltGesturesEnabled(options.getTiltGesturesEnabled()); uiSettings.setZoomControlsEnabled(options.getZoomControlsEnabled()); // Zoom mMapboxMap.setMaxZoom(options.getMaxZoom()); mMapboxMap.setMinZoom(options.getMinZoom()); // 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]); } // 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]); } // 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]); } } // // Lifecycle events // /** *

* You must call this method from the parent's {@link android.app.Activity#onCreate(Bundle)} or * {@link android.app.Fragment#onCreate(Bundle)}. *

* You must set a valid access token with {@link MapView#setAccessToken(String)} before you this method * or an exception will be thrown. * * @param savedInstanceState Pass in the parent's savedInstanceState. * @see MapView#setAccessToken(String) */ @UiThread public void onCreate(@Nullable Bundle savedInstanceState) { // Force a check for an access token validateAccessToken(getAccessToken()); if (savedInstanceState != null && savedInstanceState.getBoolean(MapboxConstants.STATE_HAS_SAVED_STATE)) { // Get previous camera position CameraPosition cameraPosition = savedInstanceState.getParcelable(MapboxConstants.STATE_CAMERA_POSITION); if (cameraPosition != null) { mMapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); } UiSettings uiSettings = mMapboxMap.getUiSettings(); uiSettings.setZoomGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_ENABLED)); uiSettings.setScrollGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_SCROLL_ENABLED)); uiSettings.setRotateGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ROTATE_ENABLED)); uiSettings.setTiltGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_TILT_ENABLED)); uiSettings.setZoomControlsEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_CONTROLS_ENABLED)); // Compass uiSettings.setCompassEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_COMPASS_ENABLED)); uiSettings.setCompassGravity(savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_GRAVITY)); uiSettings.setCompassMargins(savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_LEFT) , savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_TOP) , savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_RIGHT) , savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_BOTTOM)); // Logo uiSettings.setLogoEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_LOGO_ENABLED)); uiSettings.setLogoGravity(savedInstanceState.getInt(MapboxConstants.STATE_LOGO_GRAVITY)); uiSettings.setLogoMargins(savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_LEFT) , savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_TOP) , savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_RIGHT) , savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_BOTTOM)); // Attribution uiSettings.setAttributionEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ATTRIBUTION_ENABLED)); uiSettings.setAttributionGravity(savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_GRAVITY)); uiSettings.setAttributionMargins(savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_LEFT) , savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_TOP) , savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_RIGHT) , savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_BOTTOM)); mMapboxMap.setDebugActive(savedInstanceState.getBoolean(MapboxConstants.STATE_DEBUG_ACTIVE)); mMapboxMap.setStyleUrl(savedInstanceState.getString(MapboxConstants.STATE_STYLE_URL)); setAccessToken(savedInstanceState.getString(MapboxConstants.STATE_ACCESS_TOKEN)); mNativeMapView.setDefaultTransitionDuration( savedInstanceState.getLong(MapboxConstants.STATE_DEFAULT_TRANSITION_DURATION)); // User location try { //noinspection ResourceType mMapboxMap.setMyLocationEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED)); } catch (SecurityException ignore) { // User did not accept location permissions } TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings(); //noinspection ResourceType trackingSettings.setMyLocationTrackingMode(savedInstanceState.getInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, MyLocationTracking.TRACKING_NONE)); //noinspection ResourceType trackingSettings.setMyBearingTrackingMode(savedInstanceState.getInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, MyBearingTracking.NONE)); } else if (savedInstanceState == null) { // Force a check for Telemetry validateTelemetryServiceConfigured(); // Start Telemetry (authorization determined in initial MapboxEventManager constructor) MapboxEventManager eventManager = MapboxEventManager.getMapboxEventManager(); eventManager.initialize(getContext(), getAccessToken()); } // Initialize EGL mNativeMapView.initializeDisplay(); mNativeMapView.initializeContext(); // Add annotation deselection listener addOnMapChangedListener(new OnMapChangedListener() { @Override public void onMapChanged(@MapChange int change) { if (change == DID_FINISH_LOADING_MAP) { reloadIcons(); reloadMarkers(); adjustTopOffsetPixels(); if (mInitialLoad) { mInitialLoad = false; if (mOnMapReadyCallbackList.size() > 0) { Iterator iterator = mOnMapReadyCallbackList.iterator(); while (iterator.hasNext()) { OnMapReadyCallback callback = iterator.next(); callback.onMapReady(mMapboxMap); iterator.remove(); } } } } } }); // Fire MapLoad if (savedInstanceState == null) { Hashtable evt = new Hashtable<>(); evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_LOAD); evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate()); MapboxEventManager.getMapboxEventManager().pushEvent(evt); } } /** * You must call this method from the parent's {@link android.app.Activity#onSaveInstanceState(Bundle)} * or {@link android.app.Fragment#onSaveInstanceState(Bundle)}. * * @param outState Pass in the parent's outState. */ @UiThread public void onSaveInstanceState(@NonNull Bundle outState) { outState.putBoolean(MapboxConstants.STATE_HAS_SAVED_STATE, true); outState.putParcelable(MapboxConstants.STATE_CAMERA_POSITION, mMapboxMap.getCameraPosition()); outState.putBoolean(MapboxConstants.STATE_DEBUG_ACTIVE, mMapboxMap.isDebugActive()); outState.putString(MapboxConstants.STATE_STYLE_URL, mStyleUrl); outState.putString(MapboxConstants.STATE_ACCESS_TOKEN, mMapboxMap.getAccessToken()); outState.putLong(MapboxConstants.STATE_DEFAULT_TRANSITION_DURATION, mNativeMapView.getDefaultTransitionDuration()); outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED, mMapboxMap.isMyLocationEnabled()); // TrackingSettings TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings(); outState.putInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, trackingSettings.getMyLocationTrackingMode()); outState.putInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, trackingSettings.getMyBearingTrackingMode()); // UiSettings UiSettings uiSettings = mMapboxMap.getUiSettings(); outState.putBoolean(MapboxConstants.STATE_ZOOM_ENABLED, uiSettings.isZoomGesturesEnabled()); outState.putBoolean(MapboxConstants.STATE_SCROLL_ENABLED, uiSettings.isScrollGesturesEnabled()); outState.putBoolean(MapboxConstants.STATE_ROTATE_ENABLED, uiSettings.isRotateGesturesEnabled()); outState.putBoolean(MapboxConstants.STATE_TILT_ENABLED, uiSettings.isTiltGesturesEnabled()); outState.putBoolean(MapboxConstants.STATE_ZOOM_CONTROLS_ENABLED, uiSettings.isZoomControlsEnabled()); // UiSettings - Compass outState.putBoolean(MapboxConstants.STATE_COMPASS_ENABLED, uiSettings.isCompassEnabled()); outState.putInt(MapboxConstants.STATE_COMPASS_GRAVITY, uiSettings.getCompassGravity()); outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_LEFT, uiSettings.getCompassMarginLeft()); outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_TOP, uiSettings.getCompassMarginTop()); outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_BOTTOM, uiSettings.getCompassMarginBottom()); outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_RIGHT, uiSettings.getCompassMarginRight()); // UiSettings - Logo outState.putInt(MapboxConstants.STATE_LOGO_GRAVITY, uiSettings.getLogoGravity()); outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_LEFT, uiSettings.getLogoMarginLeft()); outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_TOP, uiSettings.getCompassMarginTop()); outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_RIGHT, uiSettings.getLogoMarginRight()); outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_BOTTOM, uiSettings.getLogoMarginBottom()); outState.putBoolean(MapboxConstants.STATE_LOGO_ENABLED, uiSettings.isLogoEnabled()); // UiSettings - Attribution outState.putInt(MapboxConstants.STATE_ATTRIBUTION_GRAVITY, uiSettings.getAttributionGravity()); outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_LEFT, uiSettings.getAttributionMarginLeft()); outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_TOP, uiSettings.getAttributionMarginTop()); outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_RIGHT, uiSettings.getAttributionMarginRight()); outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_BOTTOM, uiSettings.getAttributionMarginBottom()); outState.putBoolean(MapboxConstants.STATE_ATTRIBUTION_ENABLED, uiSettings.isAttributionEnabled()); } /** * You must call this method from the parent's {@link Activity#onDestroy()} or {@link Fragment#onDestroy()}. */ @UiThread public void onDestroy() { mDestroyed = true; mNativeMapView.terminateContext(); mNativeMapView.terminateDisplay(); mNativeMapView.destroySurface(); mNativeMapView.destroy(); mNativeMapView = null; } /** * You must call this method from the parent's {@link Activity#onStart()} or {@link Fragment#onStart()}. */ @UiThread public void onStart() { mUserLocationView.onStart(); } /** * You must call this method from the parent's {@link Activity#onStop()} or {@link Fragment#onStop()} */ @UiThread public void onStop() { mUserLocationView.onStop(); } /** * You must call this method from the parent's {@link Activity#onPause()} or {@link Fragment#onPause()}. */ @UiThread public void onPause() { // Register for connectivity changes getContext().unregisterReceiver(mConnectivityReceiver); mConnectivityReceiver = null; mUserLocationView.onPause(); mNativeMapView.pause(); } /** * You must call this method from the parent's {@link Activity#onResume()} or {@link Fragment#onResume()}. */ @UiThread public void onResume() { // Register for connectivity changes mConnectivityReceiver = new ConnectivityReceiver(); getContext().registerReceiver(mConnectivityReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); mNativeMapView.resume(); mNativeMapView.update(); mUserLocationView.onResume(); if (mStyleUrl == null) { // user has failed to supply a style url setStyleUrl(Style.MAPBOX_STREETS); } } /** * You must call this method from the parent's {@link Activity#onLowMemory()} or {@link Fragment#onLowMemory()}. */ @UiThread public void onLowMemory() { mNativeMapView.onLowMemory(); } // Called when debug mode is enabled to update a FPS counter // Called via JNI from NativeMapView // Forward to any listener protected void onFpsChanged(final double fps) { post(new Runnable() { @Override public void run() { MapboxMap.OnFpsChangedListener listener = mMapboxMap.getOnFpsChangedListener(); if (listener != null) { listener.onFpsChanged(fps); } } }); } // // LatLng / CenterCoordinate // LatLng getLatLng() { return mNativeMapView.getLatLng(); } // // Pitch / Tilt // double getTilt() { return mNativeMapView.getPitch(); } void setTilt(Double pitch, @Nullable Long duration) { long actualDuration = 0; if (duration != null) { actualDuration = duration; } mNativeMapView.setPitch(pitch, actualDuration); } // // Direction // double getDirection() { double direction = -mNativeMapView.getBearing(); while (direction > 360) { direction -= 360; } while (direction < 0) { direction += 360; } return direction; } void setDirection(@FloatRange(from = MapboxConstants.MINIMUM_DIRECTION, to = MapboxConstants.MAXIMUM_DIRECTION) double direction) { if (mDestroyed) { return; } setDirection(direction, false); } void setDirection(@FloatRange(from = MapboxConstants.MINIMUM_DIRECTION, to = MapboxConstants.MAXIMUM_DIRECTION) double direction, boolean animated) { if (mDestroyed) { return; } long duration = animated ? MapboxConstants.ANIMATION_DURATION : 0; mNativeMapView.cancelTransitions(); // Out of range directions are normalised in setBearing mNativeMapView.setBearing(-direction, duration); } void resetNorth() { if (mDestroyed) { return; } mNativeMapView.cancelTransitions(); mNativeMapView.resetNorth(); } // // Content padding // int getContentPaddingLeft() { return mContentPaddingLeft; } int getContentPaddingTop() { return mContentPaddingTop; } int getContentPaddingRight() { return mContentPaddingRight; } int getContentPaddingBottom() { return mContentPaddingBottom; } // // Zoom // double getZoom() { if (mDestroyed) { return 0; } return mNativeMapView.getZoom(); } void setMinZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double minZoom) { if (mDestroyed) { return; } mNativeMapView.setMinZoom(minZoom); } double getMinZoom() { if (mDestroyed) { return 0; } return mNativeMapView.getMinZoom(); } void setMaxZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double maxZoom) { if (mDestroyed) { return; } mNativeMapView.setMaxZoom(maxZoom); } double getMaxZoom() { if (mDestroyed) { return 0; } return mNativeMapView.getMaxZoom(); } // Zoom in or out private void zoom(boolean zoomIn) { zoom(zoomIn, -1.0f, -1.0f); } private void zoom(boolean zoomIn, float x, float y) { // Cancel any animation mNativeMapView.cancelTransitions(); if (zoomIn) { mNativeMapView.scaleBy(2.0, x / mScreenDensity, y / mScreenDensity, MapboxConstants.ANIMATION_DURATION); } else { mNativeMapView.scaleBy(0.5, x / mScreenDensity, y / mScreenDensity, MapboxConstants.ANIMATION_DURATION); } } // // Debug // boolean isDebugActive() { if (mDestroyed) { return false; } return mNativeMapView.getDebug(); } void setDebugActive(boolean debugActive) { if (mDestroyed) { return; } mNativeMapView.setDebug(debugActive); } void cycleDebugOptions() { if (mDestroyed) { return; } mNativeMapView.cycleDebugOptions(); } // // Styling // /** *

* Loads a new map style from the specified URL. *

* {@code url} can take the following forms: *
    *
  • {@code Style.*}: load one of the bundled styles in {@link Style}.
  • *
  • {@code mapbox://styles//