com.mapbox.mapboxsdk.maps.MapView Maven / Gradle / Ivy
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.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.graphics.drawable.ColorDrawable;
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.MapboxAccountManager;
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.MarkerView;
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.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
import com.mapbox.mapboxsdk.layers.CustomLayer;
import com.mapbox.mapboxsdk.location.LocationListener;
import com.mapbox.mapboxsdk.location.LocationServices;
import com.mapbox.mapboxsdk.maps.widgets.CompassView;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationView;
import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
import com.mapbox.mapboxsdk.telemetry.MapboxEvent;
import com.mapbox.mapboxsdk.telemetry.MapboxEventManager;
import com.mapbox.mapboxsdk.utils.ColorUtils;
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.
*/
public class MapView extends FrameLayout {
private MapboxMap mMapboxMap;
private boolean mInitialLoad;
private boolean mDestroyed;
private List mIcons;
private int mAverageIconHeight;
private int mAverageIconWidth;
private NativeMapView mNativeMapView;
private boolean mHasSurface = false;
private CompassView mCompassView;
private ImageView mLogoView;
private ImageView mAttributionsView;
private MyLocationView mMyLocationView;
private LocationListener mMyLocationListener;
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 StyleInitializer mStyleInitializer;
private List mOnMapReadyCallbackList;
@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<>();
mStyleInitializer = new StyleInitializer(context);
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());
mMyLocationView = (MyLocationView) view.findViewById(R.id.userLocationView);
mMyLocationView.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 = null;
if (MapboxAccountManager.getInstance() != null) {
accessToken = MapboxAccountManager.getInstance().getAccessToken();
} else {
accessToken = options.getAccessToken();
}
String style = options.getStyle();
if (!TextUtils.isEmpty(accessToken)) {
mMapboxMap.setAccessToken(accessToken);
if (style != null) {
setStyleUrl(style);
}
} else {
mStyleInitializer.setStyle(style, true);
}
// MyLocationView
MyLocationViewSettings myLocationViewSettings = mMapboxMap.getMyLocationViewSettings();
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());
mMapboxMap.setMyLocationEnabled(options.getLocationEnabled());
// Enable gestures
UiSettings uiSettings = mMapboxMap.getUiSettings();
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
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]);
} else {
int tenDp = (int) getResources().getDimension(R.dimen.ten_dp);
uiSettings.setCompassMargins(tenDp, tenDp, tenDp, tenDp);
}
// 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) getResources().getDimension(R.dimen.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 {
Resources resources = getResources();
int sevenDp = (int) resources.getDimension(R.dimen.seven_dp);
int seventySixDp = (int) resources.getDimension(R.dimen.seventy_six_dp);
uiSettings.setAttributionMargins(seventySixDp, sevenDp, sevenDp, sevenDp);
}
int attributionTintColor = options.getAttributionTintColor();
uiSettings.setAttributionTintColor(attributionTintColor != -1 ?
attributionTintColor : ColorUtils.getPrimaryColor(getContext()));
}
//
// 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
MapboxAccountManager.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.setZoomGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_ENABLED_CHANGE));
uiSettings.setScrollGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_SCROLL_ENABLED));
uiSettings.setScrollGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_SCROLL_ENABLED_CHANGE));
uiSettings.setRotateGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ROTATE_ENABLED));
uiSettings.setRotateGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_ROTATE_ENABLED_CHANGE));
uiSettings.setTiltGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_TILT_ENABLED));
uiSettings.setTiltGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_TILT_ENABLED_CHANGE));
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));
// 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) {
// Start Telemetry (authorization determined in initial MapboxEventManager constructor)
Log.i(MapView.class.getCanonicalName(), "MapView start Telemetry...");
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 == WILL_START_RENDERING_MAP && mInitialLoad) {
mInitialLoad = false;
reloadIcons();
reloadMarkers();
adjustTopOffsetPixels();
if (mOnMapReadyCallbackList.size() > 0) {
Iterator iterator = mOnMapReadyCallbackList.iterator();
while (iterator.hasNext()) {
OnMapReadyCallback callback = iterator.next();
callback.onMapReady(mMapboxMap);
iterator.remove();
}
}
} else if (change == REGION_IS_CHANGING || change == REGION_DID_CHANGE || change == DID_FINISH_LOADING_MAP) {
mMapboxMap.getMarkerViewManager().invalidateViewMarkers();
}
}
});
// 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, mStyleInitializer.getStyle());
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_ZOOM_ENABLED_CHANGE, uiSettings.isZoomGestureChangeAllowed());
outState.putBoolean(MapboxConstants.STATE_SCROLL_ENABLED, uiSettings.isScrollGesturesEnabled());
outState.putBoolean(MapboxConstants.STATE_SCROLL_ENABLED_CHANGE, uiSettings.isScrollGestureChangeAllowed());
outState.putBoolean(MapboxConstants.STATE_ROTATE_ENABLED, uiSettings.isRotateGesturesEnabled());
outState.putBoolean(MapboxConstants.STATE_ROTATE_ENABLED_CHANGE, uiSettings.isRotateGestureChangeAllowed());
outState.putBoolean(MapboxConstants.STATE_TILT_ENABLED, uiSettings.isTiltGesturesEnabled());
outState.putBoolean(MapboxConstants.STATE_TILT_ENABLED_CHANGE, uiSettings.isTiltGestureChangeAllowed());
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#onPause()} or {@link Fragment#onPause()}.
*/
@UiThread
public void onPause() {
// Register for connectivity changes
getContext().unregisterReceiver(mConnectivityReceiver);
mConnectivityReceiver = null;
mMyLocationView.onPause();
}
/**
* 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.update();
mMyLocationView.onResume();
if (mStyleInitializer.isDefaultStyle()) {
// user has failed to supply a style url
setStyleUrl(mStyleInitializer.getStyle());
}
}
/**
* 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) {
mMyLocationView.setTilt(pitch);
mNativeMapView.setPitch(pitch, 0);
}
//
// Direction
//
double getDirection() {
if (mDestroyed) {
return 0;
}
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;
}
int getContentWidth(){
return getWidth() - mContentPaddingLeft - mContentPaddingRight;
}
int getContentHeight(){
return getHeight() - mContentPaddingBottom - mContentPaddingTop;
}
//
// 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);
}
// work around to invalidate camera position
postDelayed(new ZoomInvalidator(mMapboxMap), 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/
/