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; import com.mapbox.mapboxsdk.annotations.InfoWindow; import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.MarkerOptions; import com.mapbox.mapboxsdk.annotations.MarkerView; import com.mapbox.mapboxsdk.annotations.MarkerViewManager; import com.mapbox.mapboxsdk.annotations.Polygon; import com.mapbox.mapboxsdk.annotations.PolygonOptions; import com.mapbox.mapboxsdk.annotations.Polyline; import com.mapbox.mapboxsdk.annotations.PolylineOptions; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.camera.CameraUpdate; 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.geometry.LatLng; import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings; 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; import java.util.List; /** * The general class to interact with in the Android Mapbox SDK. It exposes the entry point for all * methods related to the MapView. You cannot instantiate {@link MapboxMap} object directly, rather, * you must obtain one from the getMapAsync() method on a MapFragment or MapView that you have * added to your application. *

* Note: Similar to a View object, a MapboxMap should only be read and modified from the main thread. *

*/ public final class MapboxMap { 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.OnFpsChangedListener onFpsChangedListener; private boolean myLocationEnabled; private double maxZoomLevel = -1; private double minZoomLevel = -1; 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; } 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 @Nullable @UiThread public Layer getLayer(@NonNull String layerId) { return nativeMapView.getLayer(layerId); } /** * Tries to cast the Layer to T, returns null if it's another type. * * @param layerId the layer id used to look up a layer * @param the generic attribute of a Layer * @return the casted Layer, null if another type */ @Nullable @UiThread public T getLayerAs(@NonNull String layerId) { try { //noinspection unchecked return (T) nativeMapView.getLayer(layerId); } catch (ClassCastException e) { Timber.e(String.format("Layer: %s is a different type: %s", layerId, e.getMessage())); return null; } } /** * Adds the layer to the map. The layer must be newly created and not added to the map before * * @param layer the layer to add */ @UiThread public void addLayer(@NonNull Layer layer) { addLayer(layer, null); } /** * Adds the layer to the map. The layer must be newly created and not added to the map before * * @param layer the layer to add * @param before the layer id to add this layer before */ @UiThread public void addLayer(@NonNull Layer layer, String before) { nativeMapView.addLayer(layer, before); } /** * Removes the layer. Any references to the layer become invalid and should not be used anymore * * @param layerId the layer to remove * @throws NoSuchLayerException */ @UiThread public void removeLayer(@NonNull String layerId) throws NoSuchLayerException { nativeMapView.removeLayer(layerId); } /** * Removes the layer. The reference is re-usable after this and can be re-added * * @param layer the layer to remove * @throws NoSuchLayerException */ @UiThread public void removeLayer(@NonNull Layer layer) throws NoSuchLayerException { nativeMapView.removeLayer(layer); } @Nullable @UiThread public Source getSource(@NonNull String sourceId) { return nativeMapView.getSource(sourceId); } /** * Tries to cast the Source to T, returns null if it's another type. * * @param sourceId the id used to look up a layer * @param the generic type of a Source * @return the casted Source, null if another type */ @Nullable @UiThread public T getSourceAs(@NonNull String sourceId) { try { //noinspection unchecked return (T) nativeMapView.getSource(sourceId); } catch (ClassCastException e) { Timber.e(String.format("Source: %s is a different type: %s", sourceId, e.getMessage())); return null; } } /** * Adds the source to the map. The source must be newly created and not added to the map before * * @param source the source to add */ @UiThread public void addSource(@NonNull Source source) { nativeMapView.addSource(source); } /** * Removes the source. Any references to the source become invalid and should not be used anymore * * @param sourceId the source to remove * @throws NoSuchSourceException */ @UiThread public void removeSource(@NonNull String sourceId) throws NoSuchSourceException { nativeMapView.removeSource(sourceId); } /** * Removes the source, preserving the reverence for re-use * * @param source the source to remove * @throws NoSuchSourceException */ @UiThread public void removeSource(@NonNull Source source) throws NoSuchSourceException { nativeMapView.removeSource(source); } /** * Add an image to be used int hte map's style * * @param name the name of the image * @param image the pre-multiplied Bitmap */ @UiThread public void addImage(@NonNull String name, @NonNull Bitmap image) { nativeMapView.addImage(name, image); } /** * Removes an image from the map's style * * @param name the name of the image to remove */ @UiThread public void removeImage(String name) { nativeMapView.removeImage(name); } // // MinZoom // /** *

* Sets the minimum zoom level the map can be displayed at. *

* * @param minZoom The new minimum zoom level. */ @UiThread public void setMinZoom( @FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double minZoom) { if ((minZoom < MapboxConstants.MINIMUM_ZOOM) || (minZoom > MapboxConstants.MAXIMUM_ZOOM)) { Timber.e("Not setting minZoom, value is in unsupported range: " + minZoom); return; } minZoomLevel = minZoom; nativeMapView.setMinZoom(minZoom); } /** *

* Gets the maximum zoom level the map can be displayed at. *

* * @return The minimum zoom level. */ @UiThread public double getMinZoom() { if (minZoomLevel == -1) { return minZoomLevel = nativeMapView.getMinZoom(); } return minZoomLevel; } // // MaxZoom // /** *

* Sets the maximum zoom level the map can be displayed at. *

* * @param maxZoom The new maximum zoom level. */ @UiThread public void setMaxZoom( @FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double maxZoom) { if ((maxZoom < MapboxConstants.MINIMUM_ZOOM) || (maxZoom > MapboxConstants.MAXIMUM_ZOOM)) { Timber.e("Not setting maxZoom, value is in unsupported range: " + maxZoom); return; } maxZoomLevel = maxZoom; nativeMapView.setMaxZoom(maxZoom); } /** *

* Gets the maximum zoom level the map can be displayed at. *

* * @return The maximum zoom level. */ @UiThread public double getMaxZoom() { if (maxZoomLevel == -1) { return maxZoomLevel = nativeMapView.getMaxZoom(); } return maxZoomLevel; } // // UiSettings // /** * Gets the user interface settings for the map. * * @return the UiSettings associated with this map */ public UiSettings getUiSettings() { return uiSettings; } // // TrackingSettings // /** * Gets the tracking interface settings for the map. * * @return the TrackingSettings asssociated with this map */ public TrackingSettings getTrackingSettings() { return trackingSettings; } // // MyLocationViewSettings // /** * Gets the settings of the user location for the map. * * @return the MyLocationViewSettings associated with this map */ public MyLocationViewSettings getMyLocationViewSettings() { return myLocationViewSettings; } // // Projection // /** * Get the Projection object that you can use to convert between screen coordinates and latitude/longitude * coordinates. * * @return the Projection associated with this map */ public Projection getProjection() { return projection; } // // Camera API // /** * Cancels ongoing animations. *

* This invokes the {@link CancelableCallback} for ongoing camera updates. *

*/ public void cancelTransitions() { transform.cancelTransitions(); } /** * Gets the current position of the camera. * The CameraPosition returned is a snapshot of the current position, and will not automatically update when the * camera moves. * * @return The current position of the Camera. */ public final CameraPosition getCameraPosition() { return transform.getCameraPosition(); } /** * Repositions the camera according to the cameraPosition. * The move is instantaneous, and a subsequent getCameraPosition() will reflect the new position. * See CameraUpdateFactory for a set of updates. * * @param cameraPosition the camera position to set */ public void setCameraPosition(@NonNull CameraPosition cameraPosition) { moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), null); } /** * Repositions the camera according to the instructions defined in the update. * The move is instantaneous, and a subsequent getCameraPosition() will reflect the new position. * See CameraUpdateFactory for a set of updates. * * @param update The change that should be applied to the camera. */ @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(); } /** * Repositions the camera according to the instructions defined in the update. * The move is instantaneous, and a subsequent getCameraPosition() will reflect the new position. * See CameraUpdateFactory for a set of updates. * * @param update The change that should be applied to the camera * @param callback the callback to be invoked when an animation finishes or is canceled */ @UiThread public final void moveCamera(final CameraUpdate update, final MapboxMap.CancelableCallback callback) { new Handler().post(new Runnable() { @Override public void run() { transform.moveCamera(MapboxMap.this, update, callback); } }); } /** * Gradually move the camera by the default duration, zoom will not be affected unless specified * within {@link CameraUpdate}. If {@link #getCameraPosition()} is called during the animation, * it will return the current location of the camera in flight. * * @param update The change that should be applied to the camera. * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates. */ @UiThread public final void easeCamera(CameraUpdate update) { easeCamera(update, MapboxConstants.ANIMATION_DURATION); } /** * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected * unless specified within {@link CameraUpdate}. If {@link #getCameraPosition()} is called * during the animation, it will return the current location of the camera in flight. * * @param update The change that should be applied to the camera. * @param durationMs The duration of the animation in milliseconds. This must be strictly * positive, otherwise an IllegalArgumentException will be thrown. * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates. */ @UiThread public final void easeCamera(CameraUpdate update, int durationMs) { easeCamera(update, durationMs, null); } /** * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected * unless specified within {@link CameraUpdate}. A callback can be used to be notified when * easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it * will return the current location of the camera in flight. *

* Note that this will cancel location tracking mode if enabled. *

* * @param update The change that should be applied to the camera. * @param durationMs The duration of the animation in milliseconds. This must be strictly * positive, otherwise an IllegalArgumentException will be thrown. * @param callback An optional callback to be notified from the main thread when the animation * stops. If the animation stops due to its natural completion, the callback * will be notified with onFinish(). If the animation stops due to interruption * by a later camera movement or a user gesture, onCancel() will be called. * Do not update or ease the camera from within onCancel(). * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates. */ @UiThread public final void easeCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) { easeCamera(update, durationMs, true, callback); } /** * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected * unless specified within {@link CameraUpdate}. A callback can be used to be notified when * easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it * will return the current location of the camera in flight. *

* Note that this will cancel location tracking mode if enabled. *

* * @param update The change that should be applied to the camera. * @param durationMs The duration of the animation in milliseconds. This must be strictly * positive, otherwise an IllegalArgumentException will be thrown. * @param easingInterpolator True for easing interpolator, false for linear. */ @UiThread public final void easeCamera(CameraUpdate update, int durationMs, boolean easingInterpolator) { easeCamera(update, durationMs, easingInterpolator, null); } /** * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected * unless specified within {@link CameraUpdate}. A callback can be used to be notified when * easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it * will return the current location of the camera in flight. *

* Note that this will cancel location tracking mode if enabled. *

* * @param update The change that should be applied to the camera. * @param durationMs The duration of the animation in milliseconds. This must be strictly * positive, otherwise an IllegalArgumentException will be thrown. * @param easingInterpolator True for easing interpolator, false for linear. * @param callback An optional callback to be notified from the main thread when the animation * stops. If the animation stops due to its natural completion, the callback * will be notified with onFinish(). If the animation stops due to interruption * by a later camera movement or a user gesture, onCancel() will be called. * Do not update or ease the camera from within onCancel(). */ @UiThread public final void easeCamera( CameraUpdate update, int durationMs, boolean easingInterpolator, final MapboxMap.CancelableCallback callback) { // dismiss tracking, moving camera is equal to a gesture easeCamera(update, durationMs, easingInterpolator, true, callback); } /** * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected * unless specified within {@link CameraUpdate}. A callback can be used to be notified when * easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it * will return the current location of the camera in flight. *

* Note that this will cancel location tracking mode if enabled. *

* * @param update The change that should be applied to the camera. * @param durationMs The duration of the animation in milliseconds. This must be strictly * positive, otherwise an IllegalArgumentException will be thrown. * @param resetTrackingMode True to reset tracking modes if required, false to ignore * @param easingInterpolator True for easing interpolator, false for linear. * @param callback An optional callback to be notified from the main thread when the animation * stops. If the animation stops due to its natural completion, the callback * will be notified with onFinish(). If the animation stops due to interruption * by a later camera movement or a user gesture, onCancel() will be called. * Do not update or ease the camera from within onCancel(). */ @UiThread public final void easeCamera(final CameraUpdate update, final int durationMs, final boolean easingInterpolator, final boolean resetTrackingMode, final MapboxMap.CancelableCallback callback) { new Handler().post(new Runnable() { @Override public void run() { transform.easeCamera(MapboxMap.this, update, durationMs, easingInterpolator, resetTrackingMode, callback); } }); } /** * Animate the camera to a new location defined within {@link CameraUpdate} using a transition * animation that evokes powered flight. The animation will last the default amount of time. * During the animation, a call to {@link #getCameraPosition()} returns an intermediate location * of the camera in flight. * * @param update The change that should be applied to the camera. * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates. */ @UiThread public final void animateCamera(CameraUpdate update) { animateCamera(update, MapboxConstants.ANIMATION_DURATION, null); } /** * Animate the camera to a new location defined within {@link CameraUpdate} using a transition * animation that evokes powered flight. The animation will last the default amount of time. A * callback can be used to be notified when animating the camera stops. During the animation, a * call to {@link #getCameraPosition()} returns an intermediate location of the camera in flight. * * @param update The change that should be applied to the camera. * @param callback The callback to invoke from the main thread when the animation stops. If the * animation completes normally, onFinish() is called; otherwise, onCancel() is * called. Do not update or animate the camera from within onCancel(). * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates. */ @UiThread public final void animateCamera(CameraUpdate update, MapboxMap.CancelableCallback callback) { animateCamera(update, MapboxConstants.ANIMATION_DURATION, callback); } /** * Animate the camera to a new location defined within {@link CameraUpdate} using a transition * animation that evokes powered flight. The animation will last a specified amount of time * given in milliseconds. During the animation, a call to {@link #getCameraPosition()} returns * an intermediate location of the camera in flight. * * @param update The change that should be applied to the camera. * @param durationMs The duration of the animation in milliseconds. This must be strictly * positive, otherwise an IllegalArgumentException will be thrown. * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates. */ @UiThread public final void animateCamera(CameraUpdate update, int durationMs) { animateCamera(update, durationMs, null); } /** * Animate the camera to a new location defined within {@link CameraUpdate} using a transition * animation that evokes powered flight. The animation will last a specified amount of time * given in milliseconds. A callback can be used to be notified when animating the camera stops. * During the animation, a call to {@link #getCameraPosition()} returns an intermediate location * of the camera in flight. * * @param update The change that should be applied to the camera. * @param durationMs The duration of the animation in milliseconds. This must be strictly * positive, otherwise an IllegalArgumentException will be thrown. * @param callback An optional callback to be notified from the main thread when the animation * stops. If the animation stops due to its natural completion, the callback * will be notified with onFinish(). If the animation stops due to interruption * by a later camera movement or a user gesture, onCancel() will be called. * Do not update or animate the camera from within onCancel(). If a callback * isn't required, leave it as null. * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates. */ @UiThread public final void animateCamera(final CameraUpdate update, final int durationMs, final MapboxMap.CancelableCallback callback) { new Handler().post(new Runnable() { @Override public void run() { transform.animateCamera(MapboxMap.this, update, durationMs, callback); } }); } /** * Invalidates the current camera position by reconstructing it from mbgl */ void invalidateCameraPosition() { CameraPosition cameraPosition = transform.invalidateCameraPosition(); if (cameraPosition != null) { transform.updateCameraPosition(cameraPosition); } } // // Reset North // /** * Resets the map view to face north. */ public void resetNorth() { transform.resetNorth(); } // // Debug // /** * Returns whether the map debug information is currently shown. * * @return If true, map debug information is currently shown. */ @UiThread public boolean isDebugActive() { return nativeMapView.getDebug(); } /** *

* Changes whether the map debug information is shown. *

* The default value is false. * * @param debugActive If true, map debug information is shown. */ @UiThread public void setDebugActive(boolean debugActive) { nativeMapView.setDebug(debugActive); } /** *

* Cycles through the map debug options. *

* The value of isDebugActive reflects whether there are * any map debug options enabled or disabled. * * @see #isDebugActive() */ @UiThread public void cycleDebugOptions() { nativeMapView.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//