summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps')
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdate.java12
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java387
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java20
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java795
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java694
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java116
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java6
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java27
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java20
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java121
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java207
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ViewSettings.java36
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java (renamed from platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CompassView.java)20
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/UserLocationView.java (renamed from platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UserLocationView.java)88
14 files changed, 1322 insertions, 1227 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdate.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdate.java
deleted file mode 100644
index 0f3e710134..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdate.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package com.mapbox.mapboxsdk.maps;
-
-import android.support.annotation.NonNull;
-
-import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.maps.MapboxMap;
-
-public interface CameraUpdate {
-
- CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap);
-
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java
deleted file mode 100644
index cad5152316..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CameraUpdateFactory.java
+++ /dev/null
@@ -1,387 +0,0 @@
-package com.mapbox.mapboxsdk.maps;
-
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.RectF;
-import android.support.annotation.IntDef;
-import android.support.annotation.NonNull;
-
-import com.mapbox.mapboxsdk.camera.CameraPosition;
-import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.geometry.LatLngBounds;
-import com.mapbox.mapboxsdk.utils.MathUtils;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-public class CameraUpdateFactory {
-
- /**
- * Returns a CameraUpdate that moves the camera to a specified CameraPosition.
- *
- * @param cameraPosition Camera Position to change to
- * @return CameraUpdate Final Camera Position data
- */
- public static CameraUpdate newCameraPosition(@NonNull CameraPosition cameraPosition) {
- return new CameraPositionUpdate(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom);
- }
-
- /**
- * Returns a CameraUpdate that moves the center of the screen to a latitude and longitude
- * specified by a LatLng object. This centers the camera on the LatLng object.
- *
- * @param latLng
- * @return
- */
- public static CameraUpdate newLatLng(@NonNull LatLng latLng) {
- return new CameraPositionUpdate(-1, latLng, -1, -1);
- }
-
- /**
- * Returns a CameraUpdate that transforms the camera such that the specified latitude/longitude
- * bounds are centered on screen at the greatest possible zoom level.
- * You can specify padding, in order to inset the bounding box from the map view's edges.
- * The returned CameraUpdate has a bearing of 0 and a tilt of 0.
- *
- * @param bounds
- * @param padding
- * @return
- */
- public static CameraUpdate newLatLngBounds(@NonNull LatLngBounds bounds, int padding) {
- return newLatLngBounds(bounds, padding, padding, padding, padding);
- }
-
-
- /**
- * Returns a CameraUpdate that transforms the camera such that the specified latitude/longitude
- * bounds are centered on screen at the greatest possible zoom level.
- * You can specify padding, in order to inset the bounding box from the map view's edges.
- * The returned CameraUpdate has a bearing of 0 and a tilt of 0.
- *
- * @param bounds
- * @param paddingLeft
- * @param paddingTop
- * @param paddingRight
- * @param paddingBottom
- * @return
- */
- public static CameraUpdate newLatLngBounds(@NonNull LatLngBounds bounds, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
- return new CameraBoundsUpdate(bounds, paddingLeft, paddingTop, paddingRight, paddingBottom);
- }
-
- /**
- * Returns a CameraUpdate that moves the center of the screen to a latitude and longitude specified by a LatLng object, and moves to the given zoom level.
- *
- * @param latLng
- * @param zoom
- * @return
- */
- public static CameraUpdate newLatLngZoom(@NonNull LatLng latLng, float zoom) {
- return new CameraPositionUpdate(-1, latLng, -1, zoom);
- }
-
- /**
- * Returns a CameraUpdate that scrolls the camera over the map, shifting the center of view by the specified number of pixels in the x and y directions.
- *
- * @param xPixel
- * @param yPixel
- * @return
- */
- public static CameraUpdate scrollBy(float xPixel, float yPixel) {
- return new CameraMoveUpdate(xPixel, yPixel);
- }
-
- /**
- * Returns a CameraUpdate that shifts the zoom level of the current camera viewpoint.
- *
- * @param amount
- * @param focus
- * @return
- */
- public static CameraUpdate zoomBy(float amount, Point focus) {
- return new ZoomUpdate(amount, focus.x, focus.y);
- }
-
- /**
- * Returns a CameraUpdate that shifts the zoom level of the current camera viewpoint.
- *
- * @param amount
- * @return
- */
- public static CameraUpdate zoomBy(float amount) {
- return new ZoomUpdate(ZoomUpdate.ZOOM_BY, amount);
- }
-
- /**
- * Returns a CameraUpdate that zooms in on the map by moving the viewpoint's height closer to the Earth's surface. The zoom increment is 1.0.
- *
- * @return
- */
- public static CameraUpdate zoomIn() {
- return new ZoomUpdate(ZoomUpdate.ZOOM_IN);
- }
-
- /**
- * Returns a CameraUpdate that zooms out on the map by moving the viewpoint's height farther away from the Earth's surface. The zoom increment is -1.0.
- *
- * @return
- */
- public static CameraUpdate zoomOut() {
- return new ZoomUpdate(ZoomUpdate.ZOOM_OUT);
- }
-
- /**
- * Returns a CameraUpdate that moves the camera viewpoint to a particular zoom level.
- *
- * @param zoom
- * @return
- */
- public static CameraUpdate zoomTo(float zoom) {
- return new ZoomUpdate(ZoomUpdate.ZOOM_TO, zoom);
- }
-
- //
- // CameraUpdate types
- //
-
- public static class CameraPositionUpdate implements CameraUpdate {
-
- private final float bearing;
- private final LatLng target;
- private final float tilt;
- private final float zoom;
-
- CameraPositionUpdate(float bearing, LatLng target, float tilt, float zoom) {
- this.bearing = bearing;
- this.target = target;
- this.tilt = tilt;
- this.zoom = zoom;
- }
-
- public LatLng getTarget() {
- return target;
- }
-
- public float getBearing() {
- return bearing;
- }
-
- public float getTilt() {
- return tilt;
- }
-
- public float getZoom() {
- return zoom;
- }
-
- @Override
- public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
- CameraPosition previousPosition = mapboxMap.getCameraPosition();
- if (target == null) {
- return new CameraPosition.Builder(true)
- .tilt(tilt)
- .zoom(zoom)
- .bearing(bearing)
- .target(previousPosition.target)
- .build();
- }
- return new CameraPosition.Builder(this).build();
- }
- }
-
- public static class CameraBoundsUpdate implements CameraUpdate {
-
- private LatLngBounds bounds;
- private RectF padding;
-
- public CameraBoundsUpdate(LatLngBounds bounds, RectF padding) {
- this.bounds = bounds;
- this.padding = padding;
- }
-
- public CameraBoundsUpdate(LatLngBounds bounds, int[] padding) {
- this(bounds, new RectF(padding[0], padding[1], padding[2], padding[3]));
- }
-
- public CameraBoundsUpdate(LatLngBounds bounds, int paddingLeft, int paddingTop, int paddingRight, int paddingBottom) {
- this(bounds, new int[]{paddingLeft, paddingTop, paddingRight, paddingBottom});
- }
-
- public LatLngBounds getBounds() {
- return bounds;
- }
-
- public RectF getPadding() {
- return padding;
- }
-
- @Override
- public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
- MapView mapView = mapboxMap.getMapView();
- RectF padding = getPadding();
-
- // Calculate the bounds of the possibly rotated shape with respect to the viewport.
- PointF nePixel = new PointF(-10000, -10000);
- PointF swPixel = new PointF(1000, 10000);
- float viewportHeight = mapView.getHeight();
- for (LatLng latLng : getBounds().toLatLngs()) {
- PointF pixel = mapView.toScreenLocation(latLng);
- swPixel.x = Math.min(swPixel.x, pixel.x);
- nePixel.x = Math.max(nePixel.x, pixel.x);
- swPixel.y = Math.min(swPixel.y, viewportHeight - pixel.y);
- nePixel.y = Math.max(nePixel.y, viewportHeight - pixel.y);
- }
-
- float width = nePixel.x - swPixel.x;
- float height = nePixel.y - swPixel.y;
-
- // Calculate the zoom level.
- float scaleX = (mapView.getWidth() - padding.left - padding.right) / width;
- float scaleY = (mapView.getHeight() - padding.top - padding.bottom) / height;
- float minScale = scaleX < scaleY ? scaleX : scaleY;
- double zoom = Math.log(mapView.getScale() * minScale) / Math.log(2);
- zoom = MathUtils.clamp(zoom, (float) mapView.getMinZoom(), (float) mapView.getMaxZoom());
-
- // Calculate the center point of a virtual bounds that is extended in all directions by padding.
- PointF paddedNEPixel = new PointF(nePixel.x + padding.right / minScale, nePixel.y + padding.top / minScale);
- PointF paddedSWPixel = new PointF(swPixel.x - padding.left / minScale, swPixel.y - padding.bottom / minScale);
- PointF centerPixel = new PointF((paddedNEPixel.x + paddedSWPixel.x) / 2, (paddedNEPixel.y + paddedSWPixel.y) / 2);
-
- centerPixel.y = viewportHeight - centerPixel.y;
-
- LatLng center = mapboxMap.getProjection().fromScreenLocation(centerPixel);
-
- return new CameraPosition.Builder()
- .target(center)
- .zoom((float) zoom)
- .tilt(0)
- .bearing(0)
- .build();
- }
- }
-
- public static class CameraMoveUpdate implements CameraUpdate {
-
- private float x;
- private float y;
-
- public CameraMoveUpdate(float x, float y) {
- this.x = x;
- this.y = y;
- }
-
- @Override
- public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
- MapView mapView = mapboxMap.getMapView();
-
- // Calculate the new center point
- float viewPortWidth = mapView.getWidth();
- float viewPortHeight = mapView.getHeight();
- PointF targetPoint = new PointF(viewPortWidth / 2 + x, viewPortHeight / 2 + y);
-
- // Convert point to LatLng
- LatLng latLng = mapView.fromScreenLocation(targetPoint);
-
- CameraPosition cameraPosition = mapboxMap.getCameraPosition();
- return new CameraPosition.Builder()
- .target(latLng)
- .zoom(cameraPosition.zoom)
- .tilt(cameraPosition.tilt)
- .bearing(cameraPosition.bearing)
- .build();
- }
- }
-
- public static class ZoomUpdate implements CameraUpdate {
-
- @IntDef({ZOOM_IN, ZOOM_OUT, ZOOM_BY, ZOOM_TO, ZOOM_TO_POINT})
- @Retention(RetentionPolicy.SOURCE)
- public @interface Type {
- }
-
- public static final int ZOOM_IN = 0;
- public static final int ZOOM_OUT = 1;
- public static final int ZOOM_BY = 2;
- public static final int ZOOM_TO = 3;
- public static final int ZOOM_TO_POINT = 4;
-
- @Type
- private final int type;
- private final float zoom;
- private float x;
- private float y;
-
- ZoomUpdate(@Type int type) {
- this.type = type;
- this.zoom = 0;
- }
-
- ZoomUpdate(@Type int type, float zoom) {
- this.type = type;
- this.zoom = zoom;
- }
-
- ZoomUpdate(float zoom, float x, float y) {
- this.type = ZOOM_TO_POINT;
- this.zoom = zoom;
- this.x = x;
- this.y = y;
- }
-
- public float getZoom() {
- return zoom;
- }
-
- @Type
- public int getType() {
- return type;
- }
-
- public float getX() {
- return x;
- }
-
- public float getY() {
- return y;
- }
-
- public float transformZoom(float currentZoom) {
- switch (getType()) {
- case CameraUpdateFactory.ZoomUpdate.ZOOM_IN:
- currentZoom++;
- break;
- case CameraUpdateFactory.ZoomUpdate.ZOOM_OUT:
- currentZoom--;
- if (currentZoom < 0) {
- currentZoom = 0;
- }
- break;
- case CameraUpdateFactory.ZoomUpdate.ZOOM_TO:
- currentZoom = getZoom();
- break;
- case CameraUpdateFactory.ZoomUpdate.ZOOM_BY:
- currentZoom = currentZoom + getZoom();
- break;
- case CameraUpdateFactory.ZoomUpdate.ZOOM_TO_POINT:
- currentZoom = currentZoom + getZoom();
- break;
- }
- return currentZoom;
- }
-
- @Override
- public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) {
- CameraPosition cameraPosition = mapboxMap.getCameraPosition();
- if (getType() != CameraUpdateFactory.ZoomUpdate.ZOOM_TO_POINT) {
- return new CameraPosition.Builder(cameraPosition)
- .zoom(transformZoom(cameraPosition.zoom))
- .build();
- } else {
- return new CameraPosition.Builder(cameraPosition)
- .zoom(transformZoom(cameraPosition.zoom))
- .target(mapboxMap.getProjection().fromScreenLocation(new PointF(getX(), getY())))
- .build();
- }
- }
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java
index 2789e85ed8..4b5aa0cbaf 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapFragment.java
@@ -2,6 +2,7 @@ package com.mapbox.mapboxsdk.maps;
import android.app.Fragment;
import android.os.Bundle;
+import android.os.Handler;
import android.support.annotation.NonNull;
import android.view.LayoutInflater;
import android.view.View;
@@ -29,18 +30,10 @@ public class MapFragment extends Fragment {
private MapView mMap;
- public static MapFragment newInstance(){
+ public static MapFragment newInstance() {
return new MapFragment();
}
- public static MapFragment newInstance(MapboxMapOptions mapboxMapOptions) {
- final MapFragment mapFragment = new MapFragment();
- Bundle bundle = new Bundle();
- bundle.putParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS, mapboxMapOptions);
- mapFragment.setArguments(bundle);
- return mapFragment;
- }
-
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
@@ -94,7 +87,12 @@ public class MapFragment extends Fragment {
}
@NonNull
- public void getMapAsync(@NonNull OnMapReadyCallback onMapReadyCallback){
- mMap.getMapAsync(onMapReadyCallback);
+ public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) {
+ new Handler().post(new Runnable() {
+ @Override
+ public void run() {
+ mMap.getMapAsync(onMapReadyCallback);
+ }
+ });
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
index bd0a010900..cb9459d5f2 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
@@ -10,7 +10,9 @@ 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.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -27,8 +29,8 @@ import android.support.annotation.FloatRange;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import android.support.annotation.RequiresPermission;
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;
@@ -47,44 +49,50 @@ 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.MarkerOptions;
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.annotations.IconFactory;
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 com.mapbox.mapboxsdk.utils.ApiAccess;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
+import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* <p>
@@ -111,7 +119,6 @@ public class MapView extends FrameLayout {
private static final float DIMENSION_SEVENTYSIX_DP = 76f;
private MapboxMap mMapboxMap;
- private List<Annotation> mAnnotations;
private List<Icon> mIcons;
private NativeMapView mNativeMapView;
@@ -120,7 +127,7 @@ public class MapView extends FrameLayout {
private ImageView mAttributionsView;
private UserLocationView mUserLocationView;
- private List<OnMapChangedListener> mOnMapChangedListener;
+ private CopyOnWriteArrayList<OnMapChangedListener> mOnMapChangedListener;
private ZoomButtonsController mZoomButtonsController;
private ConnectivityReceiver mConnectivityReceiver;
private float mScreenDensity = 1.0f;
@@ -133,13 +140,12 @@ public class MapView extends FrameLayout {
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;
-*/
@UiThread
public MapView(@NonNull Context context) {
@@ -160,11 +166,9 @@ public class MapView extends FrameLayout {
}
private void initialize(@NonNull Context context, @Nullable AttributeSet attrs) {
- mOnMapChangedListener = new ArrayList<>();
+ mOnMapChangedListener = new CopyOnWriteArrayList<>();
mMapboxMap = new MapboxMap(this);
- mAnnotations = new ArrayList<>();
mIcons = new ArrayList<>();
-
View view = LayoutInflater.from(context).inflate(R.layout.mapview_internal, this);
if (!isInEditMode()) {
@@ -200,7 +204,7 @@ public class MapView extends FrameLayout {
// Shows the zoom controls
if (!context.getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH)) {
- mMapboxMap.setZoomControlsEnabled(true);
+ mMapboxMap.getUiSettings().setZoomControlsEnabled(true);
}
mZoomButtonsController = new ZoomButtonsController(this);
mZoomButtonsController.setZoomSpeed(MapboxConstants.ANIMATION_DURATION);
@@ -210,9 +214,9 @@ public class MapView extends FrameLayout {
onConnectivityChanged(isConnected());
mUserLocationView = (UserLocationView) view.findViewById(R.id.userLocationView);
- mUserLocationView.setMapView(this);
+ mUserLocationView.setMapboxMap(mMapboxMap);
mCompassView = (CompassView) view.findViewById(R.id.compassView);
- mCompassView.setOnClickListener(new CompassView.CompassClickListener(this));
+ mCompassView.setOnClickListener(new CompassView.CompassClickListener(mMapboxMap));
mLogoView = (ImageView) view.findViewById(R.id.logoView);
// Setup Attributions control
@@ -232,13 +236,15 @@ public class MapView extends FrameLayout {
mMapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
// Access token
- if (typedArray.getString(R.styleable.MapView_access_token) != null) {
+ String accessToken = typedArray.getString(R.styleable.MapView_access_token);
+ if (accessToken != null) {
setAccessToken(typedArray.getString(R.styleable.MapView_access_token));
}
// Style url
- if (typedArray.getString(R.styleable.MapView_style_url) != null) {
- mMapboxMap.setStyleUrl(typedArray.getString(R.styleable.MapView_style_url));
+ String styleUrl = typedArray.getString(R.styleable.MapView_style_url);
+ if (styleUrl != null) {
+ mMapboxMap.setStyleUrl(styleUrl);
}
// Enable gestures
@@ -249,6 +255,10 @@ public class MapView extends FrameLayout {
uiSettings.setTiltGesturesEnabled(typedArray.getBoolean(R.styleable.MapView_tilt_enabled, true));
uiSettings.setZoomControlsEnabled(typedArray.getBoolean(R.styleable.MapView_zoom_controls_enabled, false));
+ // Zoom
+ uiSettings.setMaxZoom(typedArray.getFloat(R.styleable.MapView_zoom_max, (float) MapboxConstants.MAXIMUM_ZOOM));
+ uiSettings.setMinZoom(typedArray.getFloat(R.styleable.MapView_zoom_min, (float) MapboxConstants.MINIMUM_ZOOM));
+
// Compass
uiSettings.setCompassEnabled(typedArray.getBoolean(R.styleable.MapView_compass_enabled, true));
uiSettings.setCompassGravity(typedArray.getInt(R.styleable.MapView_compass_gravity, Gravity.TOP | Gravity.END));
@@ -274,13 +284,7 @@ public class MapView extends FrameLayout {
, (int) (typedArray.getDimension(R.styleable.MapView_attribution_margin_bottom, DIMENSION_SEVEN_DP) * mScreenDensity));
// User location
- try {
- //noinspection ResourceType
- mMapboxMap.setMyLocationEnabled(typedArray.getBoolean(R.styleable.MapView_my_location_enabled, false));
- } catch (SecurityException ignore) {
- // User did not accept location permissions
- }
-
+ mMapboxMap.setMyLocationEnabled(typedArray.getBoolean(R.styleable.MapView_my_location_enabled, false));
} finally {
typedArray.recycle();
}
@@ -303,7 +307,7 @@ public class MapView extends FrameLayout {
*/
@UiThread
public void onCreate(@Nullable Bundle savedInstanceState) {
- if (savedInstanceState != null) {
+ if (savedInstanceState != null && savedInstanceState.getBoolean(MapboxConstants.STATE_HAS_SAVED_STATE)) {
// Get previous camera position
CameraPosition cameraPosition = savedInstanceState.getParcelable(MapboxConstants.STATE_CAMERA_POSITION);
@@ -357,10 +361,17 @@ public class MapView extends FrameLayout {
// User did not accept location permissions
}
+ TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings();
//noinspection ResourceType
- mMapboxMap.setMyLocationTrackingMode(savedInstanceState.getInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, MyLocationTracking.TRACKING_NONE));
+ trackingSettings.setMyLocationTrackingMode(savedInstanceState.getInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, MyLocationTracking.TRACKING_NONE));
//noinspection ResourceType
- mMapboxMap.setMyBearingTrackingMode(savedInstanceState.getInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, MyBearingTracking.NONE));
+ trackingSettings.setMyBearingTrackingMode(savedInstanceState.getInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, MyBearingTracking.NONE));
+ } else {
+ // Force a check for Telemetry
+ validateTelemetryServiceConfigured();
+
+ // Start Telemetry (authorization determined in initial MapboxEventManager constructor)
+ MapboxEventManager.getMapboxEventManager(getContext()).isTelemetryEnabled();
}
// Force a check for an access token
@@ -381,6 +392,16 @@ public class MapView extends FrameLayout {
}
}
});
+
+ // Fire MapLoad
+ if (savedInstanceState == null) {
+ Hashtable<String, Object> evt = new Hashtable<>();
+ evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_LOAD);
+ evt.put(MapboxEvent.KEY_LATITUDE, mMapboxMap.getCameraPosition().target.getLatitude());
+ evt.put(MapboxEvent.KEY_LONGITUDE, mMapboxMap.getCameraPosition().target.getLongitude());
+ evt.put(MapboxEvent.KEY_ZOOM, mMapboxMap.getCameraPosition().zoom);
+ MapboxEventManager.getMapboxEventManager(getContext()).pushEvent(evt);
+ }
}
/**
@@ -392,14 +413,19 @@ public class MapView extends FrameLayout {
@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, mMapboxMap.getStyleUrl());
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());
- outState.putInt(MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, mMapboxMap.getMyLocationTrackingMode());
- outState.putInt(MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, mMapboxMap.getMyBearingTrackingMode());
+
+
+ // 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();
@@ -554,13 +580,13 @@ public class MapView extends FrameLayout {
}
//
- // Rotation
+ // Direction
//
/**
- * Returns the current heading of the map relative to true north.
+ * Returns the current direction of the map relative to true north.
*
- * @return The current heading measured in degrees.
+ * @return The current direction measured in degrees.
*/
@UiThread
@FloatRange(from = MapboxConstants.MINIMUM_DIRECTION, to = MapboxConstants.MAXIMUM_DIRECTION)
@@ -633,6 +659,46 @@ public class MapView extends FrameLayout {
}
//
+ // Content padding
+ //
+
+ /**
+ * Return The current content padding left of the map view viewport.
+ *
+ * @return The current content padding left
+ */
+ int getContentPaddingLeft() {
+ return mContentPaddingLeft;
+ }
+
+ /**
+ * Return The current content padding left of the map view viewport.
+ *
+ * @return The current content padding left
+ */
+ int getContentPaddingTop() {
+ return mContentPaddingTop;
+ }
+
+ /**
+ * Return The current content padding left of the map view viewport.
+ *
+ * @return The current content padding right
+ */
+ int getContentPaddingRight() {
+ return mContentPaddingRight;
+ }
+
+ /**
+ * Return The current content padding left of the map view viewport.
+ *
+ * @return The current content padding bottom
+ */
+ int getContentPaddingBottom() {
+ return mContentPaddingBottom;
+ }
+
+ //
// Zoom
//
@@ -647,51 +713,6 @@ public class MapView extends FrameLayout {
return mNativeMapView.getZoom();
}
-// /**
-// * Return The current content padding left of the map view viewport.
-// *
-// * @return The current content padding left
-// */
-///*
-// public int getContentPaddingLeft() {
-// return mContentPaddingLeft;
-// }
-//*/
-//
-// /**
-// * Return The current content padding left of the map view viewport.
-// *
-// * @return The current content padding left
-// */
-///*
-// public int getContentPaddingTop() {
-// return mContentPaddingTop;
-// }
-//*/
-//
-// /**
-// * Return The current content padding left of the map view viewport.
-// *
-// * @return The current content padding left
-// */
-///*
-// public int getContentPaddingRight() {
-// return mContentPaddingRight;
-// }
-//*/
-//
-// /**
-// * Return The current content padding left of the map view viewport.
-// *
-// * @param zoomLevel The new zoom level.
-// * @param animated If true, animates the change. If false, immediately changes the map.
-// * @see MapboxMap#MAXIMUM_ZOOM
-// */
-///*
-// public int getContentPaddingBottom() {
-// return mContentPaddingBottom;
-//*/
-
/**
* <p>
* Sets the minimum zoom level the map can be displayed at.
@@ -712,7 +733,7 @@ public class MapView extends FrameLayout {
* @return The minimum zoom level.
*/
@UiThread
- public double getMinZoom() {
+ double getMinZoom() {
return mNativeMapView.getMinZoom();
}
@@ -724,7 +745,7 @@ public class MapView extends FrameLayout {
* @param maxZoom The new maximum zoom level.
*/
@UiThread
- public void setMaxZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double maxZoom) {
+ void setMaxZoom(@FloatRange(from = MapboxConstants.MINIMUM_ZOOM, to = MapboxConstants.MAXIMUM_ZOOM) double maxZoom) {
mNativeMapView.setMaxZoom(maxZoom);
}
@@ -736,7 +757,7 @@ public class MapView extends FrameLayout {
* @return The maximum zoom level.
*/
@UiThread
- public double getMaxZoom() {
+ double getMaxZoom() {
return mNativeMapView.getMaxZoom();
}
@@ -866,6 +887,28 @@ public class MapView extends FrameLayout {
}
}
+ // Checks that TelemetryService has been configured by developer
+ private void validateTelemetryServiceConfigured() {
+
+ try {
+ // Check Implementing app's AndroidManifest.xml
+ PackageInfo packageInfo = getContext().getPackageManager().getPackageInfo(getContext().getPackageName(), PackageManager.GET_SERVICES);
+
+ if (packageInfo.services != null) {
+
+ for (ServiceInfo service : packageInfo.services) {
+ if (TextUtils.equals("com.mapbox.mapboxsdk.telemetry.TelemetryService", service.name)) {
+ return;
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ Log.w(TAG, "Error checking for Telemetry Service Config: " + e);
+ }
+ throw new TelemetryServiceNotConfiguredException();
+ }
+
/**
* <p>
* Sets the current Mapbox access token used to load map styles and tiles.
@@ -942,7 +985,25 @@ public class MapView extends FrameLayout {
// Annotations
//
- private void loadIcon(Icon icon) {
+ Icon loadIconForMarker(Marker marker) {
+ Icon icon = marker.getIcon();
+ if (icon == null) {
+ icon = IconFactory.getInstance(getContext()).defaultMarker();
+ marker.setIcon(icon);
+ }
+ if (!mIcons.contains(icon)) {
+ mIcons.add(icon);
+ loadIcon(icon);
+ } else {
+ Icon oldIcon = mIcons.get(mIcons.indexOf(icon));
+ if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
+ throw new IconBitmapChangedException();
+ }
+ }
+ return icon;
+ }
+
+ void loadIcon(Icon icon) {
Bitmap bitmap = icon.getBitmap();
String id = icon.getId();
if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) {
@@ -964,7 +1025,7 @@ public class MapView extends FrameLayout {
scale, buffer.array());
}
- private void reloadIcons() {
+ void reloadIcons() {
int count = mIcons.size();
for (int i = 0; i < count; i++) {
Icon icon = mIcons.get(i);
@@ -972,8 +1033,35 @@ public class MapView extends FrameLayout {
}
}
+ /**
+ * <p>
+ * Updates a marker on this map. Does nothing if the marker is already added.
+ * </p>
+ *
+ * @param updatedMarker An updated marker object.
+ */
+ @UiThread
+ void updateMarker(@NonNull Marker updatedMarker) {
+ if (updatedMarker == null) {
+ Log.w(TAG, "marker was null, doing nothing");
+ return;
+ }
+
+ if (updatedMarker.getId() == -1) {
+ Log.w(TAG, "marker has an id of -1, possibly was not added yet, doing nothing");
+ }
+
+ ensureIconLoaded(updatedMarker);
+ mNativeMapView.updateMarker(updatedMarker);
+ }
+
private Marker prepareMarker(MarkerOptions markerOptions) {
Marker marker = markerOptions.getMarker();
+ ensureIconLoaded(marker);
+ return marker;
+ }
+
+ private void ensureIconLoaded(Marker marker) {
Icon icon = marker.getIcon();
if (icon == null) {
icon = IconFactory.getInstance(getContext()).defaultMarker();
@@ -988,270 +1076,48 @@ public class MapView extends FrameLayout {
throw new IconBitmapChangedException();
}
}
- marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon));
- return marker;
- }
- /**
- * <p>
- * Adds a marker to this map.
- * </p>
- * The marker's icon is rendered on the map at the location {@code Marker.position}.
- * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
- *
- * @param markerOptions A marker options object that defines how to render the marker.
- * @return The {@code Marker} that was added to the map.
- */
- @UiThread
- @NonNull
- Marker addMarker(@NonNull MarkerOptions markerOptions) {
- if (markerOptions == null) {
- Log.w(TAG, "markerOptions was null, so just returning null");
- return null;
+ // this seems to be a costly operation according to the profiler so I'm trying to save some calls
+ Marker previousMarker = marker.getId() != -1 ? (Marker) mMapboxMap.getAnnotation(marker.getId()) : null;
+ if (previousMarker == null || previousMarker.getIcon() == null || previousMarker.getIcon() != marker.getIcon()) {
+ marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon));
}
-
- Marker marker = prepareMarker(markerOptions);
- long id = mNativeMapView.addMarker(marker);
- marker.setId(id); // the annotation needs to know its id
- marker.setMapboxMap(mMapboxMap); // the annotation needs to know which map view it is in
- mAnnotations.add(marker);
- return marker;
}
- /**
- * <p>
- * Adds multiple markers to this map.
- * </p>
- * The marker's icon is rendered on the map at the location {@code Marker.position}.
- * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet.
- *
- * @param markerOptionsList A list of marker options objects that defines how to render the markers.
- * @return A list of the {@code Marker}s that were added to the map.
- */
- @UiThread
- @NonNull
- List<Marker> addMarkers(@NonNull List<MarkerOptions> markerOptionsList) {
- if (markerOptionsList == null) {
- Log.w(TAG, "markerOptionsList was null, so just returning null");
- return null;
- }
-
- int count = markerOptionsList.size();
- List<Marker> markers = new ArrayList<>(count);
- for (int i = 0; i < count; i++) {
- MarkerOptions markerOptions = markerOptionsList.get(i);
- Marker marker = prepareMarker(markerOptions);
- markers.add(marker);
- }
-
- long[] ids = mNativeMapView.addMarkers(markers);
- Marker m;
- for (int i = 0; i < count; i++) {
- m = markers.get(i);
- m.setId(ids[i]);
- m.setMapboxMap(mMapboxMap);
- mAnnotations.add(m);
+ long addMarker(@NonNull Marker marker) {
+ if (mNativeMapView == null) {
+ return 0l;
}
-
- return new ArrayList<>(markers);
+ return mNativeMapView.addMarker(marker);
}
- /**
- * Adds a polyline to this map.
- *
- * @param polylineOptions A polyline options object that defines how to render the polyline.
- * @return The {@code Polyine} that was added to the map.
- */
- @UiThread
- @NonNull
- Polyline addPolyline(@NonNull PolylineOptions polylineOptions) {
- if (polylineOptions == null) {
- Log.w(TAG, "polylineOptions was null, so just returning null");
- return null;
- }
-
- Polyline polyline = polylineOptions.getPolyline();
- long id = mNativeMapView.addPolyline(polyline);
- polyline.setId(id);
- polyline.setMapboxMap(mMapboxMap);
- mAnnotations.add(polyline);
- return polyline;
+ long[] addMarkers(@NonNull List<Marker> markerList) {
+ return mNativeMapView.addMarkers(markerList);
}
- /**
- * Adds multiple polylines to this map.
- *
- * @param polylineOptionsList A list of polyline options objects that defines how to render the polylines.
- * @return A list of the {@code Polyline}s that were added to the map.
- */
- @UiThread
- @NonNull
- List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList) {
- if (polylineOptionsList == null) {
- Log.w(TAG, "polylineOptionsList was null, so just returning null");
- return null;
- }
-
- int count = polylineOptionsList.size();
- List<Polyline> polylines = new ArrayList<>(count);
- for (PolylineOptions options : polylineOptionsList) {
- polylines.add(options.getPolyline());
- }
-
- long[] ids = mNativeMapView.addPolylines(polylines);
-
- Polyline p;
- for (int i = 0; i < count; i++) {
- p = polylines.get(i);
- p.setId(ids[i]);
- p.setMapboxMap(mMapboxMap);
- mAnnotations.add(p);
- }
-
- return new ArrayList<>(polylines);
+ long addPolyline(@NonNull Polyline polyline) {
+ return mNativeMapView.addPolyline(polyline);
}
- /**
- * Adds a polygon to this map.
- *
- * @param polygonOptions A polygon options object that defines how to render the polygon.
- * @return The {@code Polygon} that was added to the map.
- */
- @UiThread
- @NonNull
- Polygon addPolygon(@NonNull PolygonOptions polygonOptions) {
- if (polygonOptions == null) {
- Log.w(TAG, "polygonOptions was null, so just returning null");
- return null;
- }
-
- Polygon polygon = polygonOptions.getPolygon();
- long id = mNativeMapView.addPolygon(polygon);
- polygon.setId(id);
- polygon.setMapboxMap(mMapboxMap);
- mAnnotations.add(polygon);
- return polygon;
+ long[] addPolylines(@NonNull List<Polyline> polylines) {
+ return mNativeMapView.addPolylines(polylines);
}
-
- /**
- * Adds multiple polygons to this map.
- *
- * @param polygonOptionsList A list of polygon options objects that defines how to render the polygons.
- * @return A list of the {@code Polygon}s that were added to the map.
- */
- @UiThread
- @NonNull
- List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList) {
- if (polygonOptionsList == null) {
- Log.w(TAG, "polygonOptionsList was null, so just returning null");
- return null;
- }
-
- int count = polygonOptionsList.size();
- List<Polygon> polygons = new ArrayList<>(count);
- for (PolygonOptions polygonOptions : polygonOptionsList) {
- polygons.add(polygonOptions.getPolygon());
- }
-
- long[] ids = mNativeMapView.addPolygons(polygons);
-
- Polygon p;
- for (int i = 0; i < count; i++) {
- p = polygons.get(i);
- p.setId(ids[i]);
- p.setMapboxMap(mMapboxMap);
- mAnnotations.add(p);
- }
-
- return new ArrayList<>(polygons);
+ long addPolygon(@NonNull Polygon polygon) {
+ return mNativeMapView.addPolygon(polygon);
}
-
- /**
- * <p>
- * Convenience method for removing a Marker from the map.
- * </p>
- * Calls removeAnnotation() internally
- *
- * @param marker Marker to remove
- */
- @UiThread
- void removeMarker(@NonNull Marker marker) {
- removeAnnotation(marker);
+ long[] addPolygons(@NonNull List<Polygon> polygons) {
+ return mNativeMapView.addPolygons(polygons);
}
- /**
- * Removes an annotation from the map.
- *
- * @param annotation The annotation object to remove.
- */
- @UiThread
- void removeAnnotation(@NonNull Annotation annotation) {
- if (annotation == null) {
- Log.w(TAG, "annotation was null, so just returning");
- return;
- }
-
- if (annotation instanceof Marker) {
- ((Marker) annotation).hideInfoWindow();
- }
- long id = annotation.getId();
+ void removeAnnotation(long id) {
mNativeMapView.removeAnnotation(id);
- mAnnotations.remove(annotation);
- }
-
- /**
- * Removes multiple annotations from the map.
- *
- * @param annotationList A list of annotation objects to remove.
- */
- @UiThread
- void removeAnnotations(@NonNull List<? extends Annotation> annotationList) {
- if (annotationList == null) {
- Log.w(TAG, "annotationList was null, so just returning");
- return;
- }
-
- int count = annotationList.size();
- long[] ids = new long[count];
- for (int i = 0; i < count; i++) {
- ids[i] = annotationList.get(i).getId();
- }
- mNativeMapView.removeAnnotations(ids);
}
- /**
- * Removes all annotations from the map.
- */
- @UiThread
- void removeAllAnnotations() {
- int count = mAnnotations.size();
- long[] ids = new long[mAnnotations.size()];
-
- for (int i = 0; i < count; i++) {
- Annotation annotation = mAnnotations.get(i);
- long id = annotation.getId();
- ids[i] = id;
- if (annotation instanceof Marker) {
- ((Marker) annotation).hideInfoWindow();
- }
- }
-
+ void removeAnnotations(@NonNull long[] ids) {
mNativeMapView.removeAnnotations(ids);
- mAnnotations.clear();
- }
-
- /**
- * Returns a list of all the annotations on the map.
- *
- * @return A list of all the annotation objects. The returned object is a copy so modifying this
- * list will not update the map.
- */
- @NonNull
- List<Annotation> getAllAnnotations() {
- return new ArrayList<>(mAnnotations);
}
private List<Marker> getMarkersInBounds(@NonNull LatLngBounds bbox) {
@@ -1269,9 +1135,10 @@ public class MapView extends FrameLayout {
}
List<Marker> annotations = new ArrayList<>(ids.length);
- int count = mAnnotations.size();
+ List<Annotation> annotationList = mMapboxMap.getAnnotations();
+ int count = annotationList.size();
for (int i = 0; i < count; i++) {
- Annotation annotation = mAnnotations.get(i);
+ Annotation annotation = annotationList.get(i);
if (annotation instanceof Marker && idsList.contains(annotation.getId())) {
annotations.add((Marker) annotation);
}
@@ -1280,7 +1147,7 @@ public class MapView extends FrameLayout {
return new ArrayList<>(annotations);
}
- private int getTopOffsetPixelsForIcon(Icon icon) {
+ int getTopOffsetPixelsForIcon(Icon icon) {
// This method will dead lock if map paused. Causes a freeze if you add a marker in an
// activity's onCreate()
if (mNativeMapView.isPaused()) {
@@ -1292,6 +1159,35 @@ public class MapView extends FrameLayout {
}
/**
+ * Sets the distance from the edges of the map view’s frame to the edges of the map
+ * view’s logical viewport.
+ * <p/>
+ * When the value of this property is equal to {0,0,0,0}, viewport
+ * properties such as `centerCoordinate` assume a viewport that matches the map
+ * view’s frame. Otherwise, those properties are inset, excluding part of the
+ * frame from the viewport. For instance, if the only the top edge is inset, the
+ * map center is effectively shifted downward.
+ *
+ * @param left The left margin in pixels.
+ * @param top The top margin in pixels.
+ * @param right The right margin in pixels.
+ * @param bottom The bottom margin in pixels.
+ */
+ @UiThread
+ void setContentPadding(int left, int top, int right, int bottom) {
+ if (left == mContentPaddingLeft && top == mContentPaddingTop && right == mContentPaddingRight && bottom == mContentPaddingBottom) {
+ return;
+ }
+
+ mContentPaddingLeft = left;
+ mContentPaddingTop = top;
+ mContentPaddingRight = right;
+ mContentPaddingBottom = bottom;
+
+ mNativeMapView.setContentPadding(top / mScreenDensity, left / mScreenDensity, bottom / mScreenDensity, right / mScreenDensity);
+ }
+
+ /**
* <p>
* Returns the distance spanned by one pixel at the specified latitude and current zoom level.
* </p>
@@ -1400,9 +1296,10 @@ public class MapView extends FrameLayout {
}
private void adjustTopOffsetPixels() {
- int count = mAnnotations.size();
+ List<Annotation> annotations = mMapboxMap.getAnnotations();
+ int count = annotations.size();
for (int i = 0; i < count; i++) {
- Annotation annotation = mAnnotations.get(i);
+ Annotation annotation = annotations.get(i);
if (annotation instanceof Marker) {
Marker marker = (Marker) annotation;
marker.setTopOffsetPixels(
@@ -1419,9 +1316,10 @@ public class MapView extends FrameLayout {
}
private void reloadMarkers() {
- int count = mAnnotations.size();
+ List<Annotation> annotations = mMapboxMap.getAnnotations();
+ int count = annotations.size();
for (int i = 0; i < count; i++) {
- Annotation annotation = mAnnotations.get(i);
+ Annotation annotation = annotations.get(i);
if (annotation instanceof Marker) {
Marker marker = (Marker) annotation;
mNativeMapView.removeAnnotation(annotation.getId());
@@ -1572,6 +1470,26 @@ public class MapView extends FrameLayout {
// Touch events
//
+ /**
+ * Helper method for tracking gesture events
+ * @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
+ */
+ private void trackGestureEvent(@NonNull String gestureId, @NonNull float xCoordinate, float yCoordinate) {
+
+ LatLng tapLatLng = fromScreenLocation(new PointF(xCoordinate, yCoordinate));
+
+ Hashtable<String, Object> evt = new Hashtable<>();
+ evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_CLICK);
+ 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, mMapboxMap.getCameraPosition().zoom);
+
+ MapboxEventManager.getMapboxEventManager(getContext()).pushEvent(evt);
+ }
+
// Called when user touches the screen, all positions are absolute
@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
@@ -1596,6 +1514,10 @@ public class MapView extends FrameLayout {
case MotionEvent.ACTION_POINTER_DOWN:
// Second pointer down
mTwoTap = event.getPointerCount() == 2;
+ if (mTwoTap) {
+ // Confirmed 2nd Finger Down
+ trackGestureEvent(MapboxEvent.GESTURE_TWO_FINGER_SINGLETAP, event.getX(), event.getY());
+ }
break;
case MotionEvent.ACTION_POINTER_UP:
@@ -1617,6 +1539,12 @@ public class MapView extends FrameLayout {
return true;
}
+ // Scroll / Pan Has Stopped
+ if (mScrollInProgress) {
+ trackGestureEvent(MapboxEvent.TYPE_MAP_DRAGEND, event.getX(), event.getY());
+ mScrollInProgress = false;
+ }
+
mTwoTap = false;
mNativeMapView.setGestureInProgress(false);
break;
@@ -1632,8 +1560,7 @@ public class MapView extends FrameLayout {
}
// This class handles one finger gestures
- private class GestureListener extends
- GestureDetector.SimpleOnGestureListener {
+ private class GestureListener extends GestureDetector.SimpleOnGestureListener {
// Must always return true otherwise all events are ignored
@Override
@@ -1665,16 +1592,20 @@ public class MapView extends FrameLayout {
}
// Single finger double tap
- if (mUserLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE) {
+ if (mMapboxMap.getTrackingSettings().isLocationTrackingDisabled()) {
// Zoom in on gesture
zoom(true, e.getX(), e.getY());
+ trackGestureEvent(MapboxEvent.GESTURE_QUICK_ZOOM, e.getX(), e.getY());
} else {
- // Zoom in on center map
- zoom(true, getWidth() / 2, getHeight() / 2);
+ // Zoom in on user location view
+ PointF centerPoint = mUserLocationView.getMarkerScreenPoint();
+ zoom(true, centerPoint.x, centerPoint.y);
}
break;
}
+ trackGestureEvent(MapboxEvent.GESTURE_DOUBLETAP, e.getX(), e.getY());
+
return true;
}
@@ -1725,9 +1656,10 @@ public class MapView extends FrameLayout {
}
if (newSelectedMarkerId >= 0) {
- int count = mAnnotations.size();
+ List<Annotation> annotations = mMapboxMap.getAnnotations();
+ int count = annotations.size();
for (int i = 0; i < count; i++) {
- Annotation annotation = mAnnotations.get(i);
+ Annotation annotation = annotations.get(i);
if (annotation instanceof Marker) {
if (annotation.getId() == newSelectedMarkerId) {
if (selectedMarkers.isEmpty() || !selectedMarkers.contains(annotation)) {
@@ -1749,6 +1681,8 @@ public class MapView extends FrameLayout {
}
}
+ trackGestureEvent(MapboxEvent.GESTURE_SINGLETAP, e.getX(), e.getY());
+
return true;
}
@@ -1771,7 +1705,9 @@ public class MapView extends FrameLayout {
}
// reset tracking modes if gesture occurs
- resetTrackingModes();
+ if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
+ resetTrackingModes();
+ }
// Fling the map
float ease = 0.25f;
@@ -1793,18 +1729,25 @@ public class MapView extends FrameLayout {
listener.onFling();
}
+ trackGestureEvent(MapboxEvent.GESTURE_PAN_START, e1.getX(), e1.getY());
return true;
}
// Called for drags
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+ Log.i(TAG, "onScroll() started");
+ if (!mScrollInProgress) {
+ mScrollInProgress = true;
+ }
if (!mMapboxMap.getUiSettings().isScrollGesturesEnabled()) {
return false;
}
- // reset tracking modes if gesture occurs
- resetTrackingModes();
+ if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
+ // reset tracking modes if gesture occurs
+ resetTrackingModes();
+ }
// Cancel any animation
mNativeMapView.cancelTransitions();
@@ -1817,6 +1760,7 @@ public class MapView extends FrameLayout {
listener.onScroll();
}
+ Log.i(TAG, "onScroll() done");
return true;
}
}
@@ -1834,10 +1778,13 @@ public class MapView extends FrameLayout {
return false;
}
- // reset tracking modes if gesture occurs
- resetTrackingModes();
+ if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
+ // reset tracking modes if gesture occurs
+ resetTrackingModes();
+ }
mBeginTime = detector.getEventTime();
+ trackGestureEvent(MapboxEvent.GESTURE_PINCH_START, detector.getFocusX(), detector.getFocusY());
return true;
}
@@ -1853,7 +1800,8 @@ public class MapView extends FrameLayout {
// Called for pinch zooms and quickzooms/quickscales
@Override
public boolean onScale(ScaleGestureDetector detector) {
- if (!mMapboxMap.getUiSettings().isZoomGesturesEnabled()) {
+ UiSettings uiSettings = mMapboxMap.getUiSettings();
+ if (!uiSettings.isZoomGesturesEnabled()) {
return false;
}
@@ -1881,13 +1829,21 @@ public class MapView extends FrameLayout {
// Gesture is a quickzoom if there aren't two fingers
mQuickZoom = !mTwoTap;
+ TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings();
+
// Scale the map
- if (mMapboxMap.getUiSettings().isScrollGesturesEnabled() && !mQuickZoom && mUserLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE) {
+ if (uiSettings.isScrollGesturesEnabled() && !mQuickZoom && trackingSettings.isLocationTrackingDisabled()) {
// around gesture
mNativeMapView.scaleBy(detector.getScaleFactor(), detector.getFocusX() / mScreenDensity, detector.getFocusY() / mScreenDensity);
} else {
- // around center map
- mNativeMapView.scaleBy(detector.getScaleFactor(), (getWidth() / 2) / mScreenDensity, (getHeight() / 2) / mScreenDensity);
+ if(trackingSettings.isLocationTrackingDisabled()) {
+ // around center map
+ mNativeMapView.scaleBy(detector.getScaleFactor(), (getWidth() / 2) / mScreenDensity, (getHeight() / 2) / mScreenDensity);
+ }else {
+ // around user location view
+ PointF centerPoint = mUserLocationView.getMarkerScreenPoint();
+ mNativeMapView.scaleBy(detector.getScaleFactor(), centerPoint.x / mScreenDensity, centerPoint.y / mScreenDensity);
+ }
}
return true;
}
@@ -1907,10 +1863,13 @@ public class MapView extends FrameLayout {
return false;
}
- // reset tracking modes if gesture occurs
- resetTrackingModes();
+ if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
+ // reset tracking modes if gesture occurs
+ resetTrackingModes();
+ }
mBeginTime = detector.getEventTime();
+ trackGestureEvent(MapboxEvent.GESTURE_ROTATION_START, detector.getFocusX(), detector.getFocusY());
return true;
}
@@ -1957,16 +1916,15 @@ public class MapView extends FrameLayout {
bearing += detector.getRotationDegreesDelta();
// Rotate the map
- if (mUserLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE) {
+ if (mMapboxMap.getTrackingSettings().isLocationTrackingDisabled()) {
// around gesture
mNativeMapView.setBearing(bearing,
detector.getFocusX() / mScreenDensity,
detector.getFocusY() / mScreenDensity);
} else {
- // around center map
- mNativeMapView.setBearing(bearing,
- (getWidth() / 2) / mScreenDensity,
- (getHeight() / 2) / mScreenDensity);
+ // around center userlocation
+ PointF centerPoint = mUserLocationView.getMarkerScreenPoint();
+ mNativeMapView.setBearing(bearing, centerPoint.x / mScreenDensity, centerPoint.y / mScreenDensity);
}
return true;
}
@@ -1986,10 +1944,13 @@ public class MapView extends FrameLayout {
return false;
}
- // reset tracking modes if gesture occurs
- resetTrackingModes();
+ if (mMapboxMap.getTrackingSettings().isDismissTrackingOnGesture()) {
+ // reset tracking modes if gesture occurs
+ resetTrackingModes();
+ }
mBeginTime = detector.getEventTime();
+ trackGestureEvent(MapboxEvent.GESTURE_PITCH_START, detector.getFocusX(), detector.getFocusY());
return true;
}
@@ -2056,8 +2017,6 @@ public class MapView extends FrameLayout {
if (!mMapboxMap.getUiSettings().isZoomGesturesEnabled()) {
return;
}
-
- // Zoom in or out
zoom(zoomIn);
}
}
@@ -2408,9 +2367,11 @@ public class MapView extends FrameLayout {
// Forward to any listeners
protected void onMapChanged(int mapChange) {
if (mOnMapChangedListener != null) {
- int count = mOnMapChangedListener.size();
- for (int i = 0; i < count; i++) {
- mOnMapChangedListener.get(i).onMapChanged(mapChange);
+ OnMapChangedListener listener;
+ final Iterator<OnMapChangedListener> iterator = mOnMapChangedListener.iterator();
+ while (iterator.hasNext()) {
+ listener = iterator.next();
+ listener.onMapChanged(mapChange);
}
}
}
@@ -2419,6 +2380,11 @@ public class MapView extends FrameLayout {
// User location
//
+ boolean isPermissionsAccepted() {
+ return (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) ||
+ ContextCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
+ }
+
/**
* <p>
* Enables or disables the my-location layer.
@@ -2433,9 +2399,6 @@ public class MapView extends FrameLayout {
* @throws SecurityException if no suitable permission is present
*/
@UiThread
- @RequiresPermission(anyOf = {
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION})
void setMyLocationEnabled(boolean enabled) {
mUserLocationView.setEnabled(enabled);
}
@@ -2473,19 +2436,13 @@ public class MapView extends FrameLayout {
* See {@link MyLocationTracking} for different values.
*
* @param myLocationTrackingMode The location tracking mode to be used.
- * @throws SecurityException if no suitable permission is present
* @see MyLocationTracking
*/
@UiThread
- @RequiresPermission(anyOf = {
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION})
void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
if (myLocationTrackingMode != MyLocationTracking.TRACKING_NONE && !mMapboxMap.isMyLocationEnabled()) {
- //noinspection ResourceType
mMapboxMap.setMyLocationEnabled(true);
}
-
mUserLocationView.setMyLocationTrackingMode(myLocationTrackingMode);
MapboxMap.OnMyLocationTrackingModeChangeListener listener = mMapboxMap.getOnMyLocationTrackingModeChangeListener();
if (listener != null) {
@@ -2494,19 +2451,6 @@ public class MapView extends FrameLayout {
}
/**
- * Returns the current user location tracking mode.
- *
- * @return The current user location tracking mode.
- * One of the values from {@link MyLocationTracking.Mode}.
- * @see MyLocationTracking.Mode
- */
- @UiThread
- @MyLocationTracking.Mode
- int getMyLocationTrackingMode() {
- return mUserLocationView.getMyLocationTrackingMode();
- }
-
- /**
* <p>
* Set the current my bearing tracking mode.
* </p>
@@ -2518,16 +2462,11 @@ public class MapView extends FrameLayout {
* See {@link MyBearingTracking} for different values.
*
* @param myBearingTrackingMode The bearing tracking mode to be used.
- * @throws SecurityException if no suitable permission is present
* @see MyBearingTracking
*/
@UiThread
- @RequiresPermission(anyOf = {
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION})
void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
if (myBearingTrackingMode != MyBearingTracking.NONE && !mMapboxMap.isMyLocationEnabled()) {
- //noinspection ResourceType
mMapboxMap.setMyLocationEnabled(true);
}
mUserLocationView.setMyBearingTrackingMode(myBearingTrackingMode);
@@ -2537,26 +2476,11 @@ public class MapView extends FrameLayout {
}
}
- /**
- * Returns the current user bearing tracking mode.
- * See {@link MyBearingTracking} for possible return values.
- *
- * @return the current user bearing tracking mode.
- * @see MyBearingTracking
- */
- @UiThread
- @MyLocationTracking.Mode
- int getMyBearingTrackingMode() {
- //noinspection ResourceType
- return mUserLocationView.getMyBearingTrackingMode();
- }
-
private void resetTrackingModes() {
try {
- //noinspection ResourceType
- setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
- //noinspection ResourceType
- setMyBearingTrackingMode(MyBearingTracking.NONE);
+ TrackingSettings trackingSettings = mMapboxMap.getTrackingSettings();
+ trackingSettings.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
+ trackingSettings.setMyBearingTrackingMode(MyBearingTracking.NONE);
} catch (SecurityException ignore) {
// User did not accept location permissions
}
@@ -2806,6 +2730,10 @@ public class MapView extends FrameLayout {
private void setWidgetMargins(@NonNull final View view, int left, int top, int right, int bottom) {
LayoutParams layoutParams = (LayoutParams) view.getLayoutParams();
+ left += mContentPaddingLeft;
+ top += mContentPaddingTop;
+ right += mContentPaddingRight;
+ bottom += mContentPaddingBottom;
layoutParams.setMargins(left, top, right, bottom);
view.setLayoutParams(layoutParams);
}
@@ -2813,9 +2741,11 @@ public class MapView extends FrameLayout {
private static class AttributionOnClickListener implements View.OnClickListener, DialogInterface.OnClickListener {
private static final int ATTRIBUTION_INDEX_IMPROVE_THIS_MAP = 2;
+ private static final int ATTRIBUTION_INDEX_TELEMETRY_SETTINGS = 3;
private MapView mMapView;
public AttributionOnClickListener(MapView mapView) {
+ super();
mMapView = mapView;
}
@@ -2825,7 +2755,7 @@ public class MapView extends FrameLayout {
Context context = v.getContext();
String[] items = context.getResources().getStringArray(R.array.attribution_names);
AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AttributionAlertDialogStyle);
- builder.setTitle(R.string.attributionsDialogTitle);
+ builder.setTitle(R.string.mapbox_attributionsDialogTitle);
builder.setAdapter(new ArrayAdapter<>(context, R.layout.attribution_list_item, items), this);
builder.show();
}
@@ -2833,7 +2763,49 @@ public class MapView extends FrameLayout {
// Called when someone selects an attribution, 'Improve this map' adds location data to the url
@Override
public void onClick(DialogInterface dialog, int which) {
- Context context = ((Dialog) dialog).getContext();
+ final Context context = ((Dialog) dialog).getContext();
+ if (which == ATTRIBUTION_INDEX_TELEMETRY_SETTINGS) {
+
+ int array = R.array.attribution_telemetry_options;
+ if (MapboxEventManager.getMapboxEventManager(context).isTelemetryEnabled()) {
+ array = R.array.attribution_telemetry_options_already_participating;
+ }
+ String[] items = context.getResources().getStringArray(array);
+ AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AttributionAlertDialogStyle);
+ builder.setTitle(R.string.mapbox_attributionTelemetryTitle);
+ LayoutInflater factory = LayoutInflater.from(context);
+ View content = factory.inflate(R.layout.attribution_telemetry_view, null);
+
+ ListView lv = (ListView) content.findViewById(R.id.telemetryOptionsList);
+ lv.setAdapter(new ArrayAdapter<String>(context, R.layout.attribution_list_item, items));
+ lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
+
+ builder.setView(content);
+ final AlertDialog telemDialog = builder.show();
+ lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+ switch (position) {
+ case 0:
+ String url = context.getResources().getStringArray(R.array.attribution_links)[3];
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.setData(Uri.parse(url));
+ context.startActivity(intent);
+ telemDialog.cancel();
+ return;
+ case 1:
+ MapboxEventManager.getMapboxEventManager(context).setTelemetryEnabled(false);
+ telemDialog.cancel();
+ return;
+ case 2:
+ MapboxEventManager.getMapboxEventManager(context).setTelemetryEnabled(true);
+ telemDialog.cancel();
+ return;
+ }
+ }
+ });
+ return;
+ }
String url = context.getResources().getStringArray(R.array.attribution_links)[which];
if (which == ATTRIBUTION_INDEX_IMPROVE_THIS_MAP) {
LatLng latLng = mMapView.getMapboxMap().getCameraPosition().target;
@@ -3044,4 +3016,5 @@ public class MapView extends FrameLayout {
void onMapChanged(@MapChange int change);
}
+
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
index 757a9bc3d9..40b75d3ce1 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
@@ -1,20 +1,21 @@
package com.mapbox.mapboxsdk.maps;
-import android.Manifest;
import android.content.Context;
import android.location.Location;
import android.os.Bundle;
-import android.support.annotation.FloatRange;
+import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
-import android.support.annotation.RequiresPermission;
import android.support.annotation.UiThread;
+import android.support.v4.util.LongSparseArray;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import com.mapbox.mapboxsdk.annotations.Annotation;
+import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
+import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.InfoWindow;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
@@ -23,6 +24,8 @@ 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;
@@ -39,10 +42,12 @@ public class MapboxMap {
private MapView mMapView;
private UiSettings mUiSettings;
+ private TrackingSettings mTrackingSettings;
private Projection mProjection;
private CameraPosition mCameraPosition;
private boolean mInvalidCameraPosition;
private String mStyleUrl;
+ private LongSparseArray<Annotation> mAnnotations;
private List<Marker> mSelectedMarkers;
private List<InfoWindow> mInfoWindows;
private MapboxMap.InfoWindowAdapter mInfoWindowAdapter;
@@ -54,17 +59,22 @@ public class MapboxMap {
private MapboxMap.OnMapLongClickListener mOnMapLongClickListener;
private MapboxMap.OnMarkerClickListener mOnMarkerClickListener;
private MapboxMap.OnInfoWindowClickListener mOnInfoWindowClickListener;
+ private MapboxMap.OnInfoWindowLongClickListener mOnInfoWindowLongClickListener;
+ private MapboxMap.OnInfoWindowCloseListener mOnInfoWindowCloseListener;
private MapboxMap.OnFlingListener mOnFlingListener;
private MapboxMap.OnScrollListener mOnScrollListener;
private MapboxMap.OnMyLocationTrackingModeChangeListener mOnMyLocationTrackingModeChangeListener;
private MapboxMap.OnMyBearingTrackingModeChangeListener mOnMyBearingTrackingModeChangeListener;
private MapboxMap.OnFpsChangedListener mOnFpsChangedListener;
+ private MapboxMap.OnCameraChangeListener mOnCameraChangeListener;
MapboxMap(@NonNull MapView mapView) {
mMapView = mapView;
mMapView.addOnMapChangedListener(new MapChangeCameraPositionListener());
mUiSettings = new UiSettings(mapView);
+ mTrackingSettings = new TrackingSettings(mMapView, mUiSettings);
mProjection = new Projection(mapView);
+ mAnnotations = new LongSparseArray<>();
mSelectedMarkers = new ArrayList<>();
mInfoWindows = new ArrayList<>();
}
@@ -83,6 +93,19 @@ public class MapboxMap {
}
//
+ // TrackingSettings
+ //
+
+ /**
+ * Gets the tracking interface settings for the map.
+ *
+ * @return
+ */
+ public TrackingSettings getTrackingSettings() {
+ return mTrackingSettings;
+ }
+
+ //
// Projection
//
@@ -105,14 +128,7 @@ public class MapboxMap {
*/
public final CameraPosition getCameraPosition() {
if (mInvalidCameraPosition) {
- // Camera position has changed, need to regenerate position
- mCameraPosition = new CameraPosition.Builder(true)
- .bearing((float) mMapView.getBearing())
- .target(mMapView.getLatLng())
- .tilt((float) mMapView.getTilt())
- .zoom((float) mMapView.getZoom())
- .build();
- mInvalidCameraPosition = false;
+ invalidateCameraPosition();
}
return mCameraPosition;
}
@@ -137,8 +153,26 @@ public class MapboxMap {
*/
@UiThread
public final void moveCamera(CameraUpdate update) {
+ moveCamera(update, 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, MapboxMap.CancelableCallback callback) {
mCameraPosition = update.getCameraPosition(this);
mMapView.jumpTo(mCameraPosition.bearing, mCameraPosition.target, mCameraPosition.tilt, mCameraPosition.zoom);
+ if (mOnCameraChangeListener != null) {
+ mOnCameraChangeListener.onCameraChange(mCameraPosition);
+ }
+ if (callback != null) {
+ callback.onFinish();
+ }
}
/**
@@ -175,7 +209,25 @@ public class MapboxMap {
@UiThread
public final void easeCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
mCameraPosition = update.getCameraPosition(this);
- mMapView.easeTo(mCameraPosition.bearing, mCameraPosition.target, getDurationNano(durationMs), mCameraPosition.tilt, mCameraPosition.zoom, callback);
+ mMapView.easeTo(mCameraPosition.bearing, mCameraPosition.target, getDurationNano(durationMs), mCameraPosition.tilt, mCameraPosition.zoom, new CancelableCallback() {
+ @Override
+ public void onCancel() {
+ if (callback != null) {
+ callback.onCancel();
+ }
+ }
+
+ @Override
+ public void onFinish() {
+ if (mOnCameraChangeListener != null) {
+ mOnCameraChangeListener.onCameraChange(mCameraPosition);
+ }
+
+ if (callback != null) {
+ callback.onFinish();
+ }
+ }
+ });
}
/**
@@ -227,7 +279,25 @@ public class MapboxMap {
@UiThread
public final void animateCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
mCameraPosition = update.getCameraPosition(this);
- mMapView.flyTo(mCameraPosition.bearing, mCameraPosition.target, getDurationNano(durationMs), mCameraPosition.tilt, mCameraPosition.zoom, callback);
+ mMapView.flyTo(mCameraPosition.bearing, mCameraPosition.target, getDurationNano(durationMs), mCameraPosition.tilt, mCameraPosition.zoom, new CancelableCallback() {
+ @Override
+ public void onCancel() {
+ if (callback != null) {
+ callback.onCancel();
+ }
+ }
+
+ @Override
+ public void onFinish() {
+ if (mOnCameraChangeListener != null) {
+ mOnCameraChangeListener.onCameraChange(mCameraPosition);
+ }
+
+ if (callback != null) {
+ callback.onFinish();
+ }
+ }
+ });
}
// internal time layer conversion
@@ -235,75 +305,34 @@ public class MapboxMap {
return durationMs > 0 ? TimeUnit.NANOSECONDS.convert(durationMs, TimeUnit.MILLISECONDS) : 0;
}
- //
- // ZOOM
- //
-
- /**
- * <p>
- * Sets the minimum zoom level the map can be displayed at.
- * </p>
- *
- * @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)) {
- Log.e(MapboxConstants.TAG, "Not setting minZoom, value is in unsupported range: " + minZoom);
- return;
+ private void invalidateCameraPosition() {
+ mInvalidCameraPosition = false;
+ mCameraPosition = new CameraPosition.Builder(true)
+ .bearing((float) mMapView.getBearing())
+ .target(mMapView.getLatLng())
+ .tilt((float) mMapView.getTilt())
+ .zoom((float) mMapView.getZoom())
+ .build();
+ if (mOnCameraChangeListener != null) {
+ mOnCameraChangeListener.onCameraChange(mCameraPosition);
}
- mMapView.setMinZoom(minZoom);
}
- /**
- * <p>
- * Gets the maximum zoom level the map can be displayed at.
- * </p>
- *
- * @return The minimum zoom level.
- */
- @UiThread
- public double getMinZoom() {
- return mMapView.getMinZoom();
- }
-
- /**
- * <p>
- * Sets the maximum zoom level the map can be displayed at.
- * </p>
- *
- * @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)) {
- Log.e(MapboxConstants.TAG, "Not setting maxZoom, value is in unsupported range: " + maxZoom);
- return;
- }
- mMapView.setMaxZoom(maxZoom);
- }
+ //
+ // Reset North
+ //
/**
- * <p>
- * Gets the maximum zoom level the map can be displayed at.
- * </p>
*
- * @return The maximum zoom level.
*/
- @UiThread
- public double getMaxZoom() {
- return mMapView.getMaxZoom();
+ public void resetNorth() {
+ mMapView.resetNorth();
}
//
// Manual zoom controls
//
- // used by UiSettings
- void setZoomControlsEnabled(boolean enabled) {
- mMapView.setZoomControlsEnabled(enabled);
- }
-
//
// Debug
//
@@ -468,7 +497,17 @@ public class MapboxMap {
@UiThread
@NonNull
public Marker addMarker(@NonNull MarkerOptions markerOptions) {
- return mMapView.addMarker(markerOptions);
+ return addMarker((BaseMarkerOptions) markerOptions);
+ }
+
+ @UiThread
+ @NonNull
+ public Marker addMarker(@NonNull BaseMarkerOptions markerOptions) {
+ Marker marker = prepareMarker(markerOptions);
+ long id = mMapView.addMarker(marker);
+ marker.setId(id);
+ mAnnotations.put(id, marker);
+ return marker;
}
/**
@@ -484,7 +523,50 @@ public class MapboxMap {
@UiThread
@NonNull
public List<Marker> addMarkers(@NonNull List<MarkerOptions> markerOptionsList) {
- return mMapView.addMarkers(markerOptionsList);
+ int count = markerOptionsList.size();
+ List<Marker> markers = new ArrayList<>(count);
+ MarkerOptions markerOptions;
+ Marker marker;
+ for (int i = 0; i < count; i++) {
+ markerOptions = markerOptionsList.get(i);
+ marker = prepareMarker(markerOptions);
+ markers.add(marker);
+ }
+
+ long[] ids = mMapView.addMarkers(markers);
+ long id = 0;
+ Marker m;
+
+ for (int i = 0; i < markers.size(); i++) {
+ m = markers.get(i);
+ m.setMapboxMap(this);
+ if (ids != null) {
+ id = ids[i];
+ } else {
+ //unit test
+ id++;
+ }
+ m.setId(id);
+ mAnnotations.put(id, m);
+ }
+ return markers;
+ }
+
+ /**
+ * <p>
+ * Updates a marker on this map. Does nothing if the marker is already added.
+ * </p>
+ *
+ * @param updatedMarker An updated marker object.
+ */
+ @UiThread
+ public void updateMarker(@NonNull Marker updatedMarker) {
+ mMapView.updateMarker(updatedMarker);
+
+ int index = mAnnotations.indexOfKey(updatedMarker.getId());
+ if (index > -1) {
+ mAnnotations.setValueAt(index, updatedMarker);
+ }
}
/**
@@ -496,7 +578,14 @@ public class MapboxMap {
@UiThread
@NonNull
public Polyline addPolyline(@NonNull PolylineOptions polylineOptions) {
- return mMapView.addPolyline(polylineOptions);
+ Polyline polyline = polylineOptions.getPolyline();
+ if (!polyline.getPoints().isEmpty()) {
+ long id = mMapView.addPolyline(polyline);
+ polyline.setMapboxMap(this);
+ polyline.setId(id);
+ mAnnotations.put(id, polyline);
+ }
+ return polyline;
}
/**
@@ -508,7 +597,33 @@ public class MapboxMap {
@UiThread
@NonNull
public List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList) {
- return mMapView.addPolylines(polylineOptionsList);
+ int count = polylineOptionsList.size();
+ Polyline polyline;
+ List<Polyline> polylines = new ArrayList<>(count);
+ for (PolylineOptions options : polylineOptionsList) {
+ polyline = options.getPolyline();
+ if (!polyline.getPoints().isEmpty()) {
+ polylines.add(polyline);
+ }
+ }
+
+ long[] ids = mMapView.addPolylines(polylines);
+ long id = 0;
+ Polyline p;
+
+ for (int i = 0; i < polylines.size(); i++) {
+ p = polylines.get(i);
+ p.setMapboxMap(this);
+ if (ids != null) {
+ id = ids[i];
+ } else {
+ // unit test
+ id++;
+ }
+ p.setId(id);
+ mAnnotations.put(id, p);
+ }
+ return polylines;
}
/**
@@ -520,7 +635,14 @@ public class MapboxMap {
@UiThread
@NonNull
public Polygon addPolygon(@NonNull PolygonOptions polygonOptions) {
- return mMapView.addPolygon(polygonOptions);
+ Polygon polygon = polygonOptions.getPolygon();
+ if (!polygon.getPoints().isEmpty()) {
+ long id = mMapView.addPolygon(polygon);
+ polygon.setId(id);
+ polygon.setMapboxMap(this);
+ mAnnotations.put(id, polygon);
+ }
+ return polygon;
}
/**
@@ -532,7 +654,32 @@ public class MapboxMap {
@UiThread
@NonNull
public List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList) {
- return mMapView.addPolygons(polygonOptionsList);
+ int count = polygonOptionsList.size();
+
+ Polygon polygon;
+ List<Polygon> polygons = new ArrayList<>(count);
+ for (PolygonOptions polygonOptions : polygonOptionsList) {
+ polygon = polygonOptions.getPolygon();
+ if (!polygon.getPoints().isEmpty()) {
+ polygons.add(polygon);
+ }
+ }
+
+ long[] ids = mMapView.addPolygons(polygons);
+ long id = 0;
+ for (int i = 0; i < polygons.size(); i++) {
+ polygon = polygons.get(i);
+ polygon.setMapboxMap(this);
+ if (ids != null) {
+ id = ids[i];
+ } else {
+ // unit test
+ id++;
+ }
+ polygon.setId(id);
+ mAnnotations.put(id, polygon);
+ }
+ return polygons;
}
/**
@@ -549,13 +696,55 @@ public class MapboxMap {
}
/**
+ * <p>
+ * Convenience method for removing a Polyline from the map.
+ * </p>
+ * Calls removeAnnotation() internally
+ *
+ * @param polyline Polyline to remove
+ */
+ @UiThread
+ public void removePolyline(@NonNull Polyline polyline) {
+ removeAnnotation(polyline);
+ }
+
+ /**
+ * <p>
+ * Convenience method for removing a Polygon from the map.
+ * </p>
+ * Calls removeAnnotation() internally
+ *
+ * @param polygon Polygon to remove
+ */
+ @UiThread
+ public void removePolygon(@NonNull Polygon polygon) {
+ removeAnnotation(polygon);
+ }
+
+ /**
* Removes an annotation from the map.
*
* @param annotation The annotation object to remove.
*/
@UiThread
public void removeAnnotation(@NonNull Annotation annotation) {
- mMapView.removeAnnotation(annotation);
+ if (annotation instanceof Marker) {
+ ((Marker) annotation).hideInfoWindow();
+ }
+ long id = annotation.getId();
+ mMapView.removeAnnotation(id);
+ mAnnotations.remove(id);
+ }
+
+ /**
+ * Removes an annotation from the map
+ *
+ * @param id The identifier associated to the annotation to be removed
+ */
+ @UiThread
+ public void removeAnnotation(long id) {
+ mMapView.removeAnnotation(id);
+ mAnnotations.remove(id);
}
/**
@@ -565,15 +754,49 @@ public class MapboxMap {
*/
@UiThread
public void removeAnnotations(@NonNull List<? extends Annotation> annotationList) {
- mMapView.removeAnnotations(annotationList);
+ int count = annotationList.size();
+ long[] ids = new long[count];
+ for (int i = 0; i < count; i++) {
+ Annotation annotation = annotationList.get(i);
+ if (annotation instanceof Marker) {
+ ((Marker) annotation).hideInfoWindow();
+ }
+ ids[i] = annotationList.get(i).getId();
+ }
+ mMapView.removeAnnotations(ids);
+ for (long id : ids) {
+ mAnnotations.remove(id);
+ }
}
/**
* Removes all annotations from the map.
*/
@UiThread
- public void removeAllAnnotations() {
- mMapView.removeAllAnnotations();
+ public void removeAnnotations() {
+ Annotation annotation;
+ int count = mAnnotations.size();
+ long[] ids = new long[count];
+ for (int i = 0; i < count; i++) {
+ ids[i] = mAnnotations.keyAt(i);
+ annotation = mAnnotations.get(ids[i]);
+ if (annotation instanceof Marker) {
+ ((Marker) annotation).hideInfoWindow();
+ }
+ }
+ mMapView.removeAnnotations(ids);
+ mAnnotations.clear();
+ }
+
+ /**
+ * Return a annotation based on its id.
+ *
+ * @return An annotation with a matched id, null is returned if no match was found.
+ */
+ @UiThread
+ @Nullable
+ public Annotation getAnnotation(long id) {
+ return mAnnotations.get(id);
}
/**
@@ -583,8 +806,69 @@ public class MapboxMap {
* list will not update the map.
*/
@NonNull
- public List<Annotation> getAllAnnotations() {
- return mMapView.getAllAnnotations();
+ public List<Annotation> getAnnotations() {
+ List<Annotation> annotations = new ArrayList<>();
+ for (int i = 0; i < mAnnotations.size(); i++) {
+ annotations.add(mAnnotations.get(mAnnotations.keyAt(i)));
+ }
+ return annotations;
+ }
+
+ /**
+ * Returns a list of all the markers on the map.
+ *
+ * @return A list of all the markers objects. The returned object is a copy so modifying this
+ * list will not update the map.
+ */
+ @NonNull
+ public List<Marker> getMarkers() {
+ List<Marker> markers = new ArrayList<>();
+ Annotation annotation;
+ for (int i = 0; i < mAnnotations.size(); i++) {
+ annotation = mAnnotations.get(mAnnotations.keyAt(i));
+ if (annotation instanceof Marker) {
+ markers.add((Marker) annotation);
+ }
+ }
+ return markers;
+ }
+
+ /**
+ * Returns a list of all the polygons on the map.
+ *
+ * @return A list of all the polygon objects. The returned object is a copy so modifying this
+ * list will not update the map.
+ */
+ @NonNull
+ public List<Polygon> getPolygons() {
+ List<Polygon> polygons = new ArrayList<>();
+ Annotation annotation;
+ for (int i = 0; i < mAnnotations.size(); i++) {
+ annotation = mAnnotations.get(mAnnotations.keyAt(i));
+ if (annotation instanceof Polygon) {
+ polygons.add((Polygon) annotation);
+ }
+ }
+ return polygons;
+ }
+
+ /**
+ * Returns a list of all the polylines on the map.
+ *
+ * @return A list of all the polylines objects. The returned object is a copy so modifying this
+ * list will not update the map.
+ */
+ @NonNull
+ public List<Polyline> getPolylines() {
+ List<Polyline> polylines = new ArrayList<>();
+ Annotation annotation;
+ for (int i = 0; i < mAnnotations.size(); i++) {
+ annotation = mAnnotations.get(mAnnotations.keyAt(i));
+ if (annotation instanceof Polyline) {
+ polylines.add((Polyline) annotation);
+ }
+ }
+ return polylines;
}
/**
@@ -670,11 +954,17 @@ public class MapboxMap {
* @return The currently selected marker.
*/
@UiThread
- @Nullable
public List<Marker> getSelectedMarkers() {
return mSelectedMarkers;
}
+ private Marker prepareMarker(BaseMarkerOptions markerOptions) {
+ Marker marker = markerOptions.getMarker();
+ Icon icon = mMapView.loadIconForMarker(marker);
+ marker.setTopOffsetPixels(mMapView.getTopOffsetPixelsForIcon(icon));
+ return marker;
+ }
+
//
// InfoWindow
//
@@ -735,10 +1025,58 @@ public class MapboxMap {
}
//
+ // Padding
+ //
+
+ /**
+ * Sets the distance from the edges of the map view’s frame to the edges of the map
+ * view’s logical viewport.
+ * <p/>
+ * When the value of this property is equal to {0,0,0,0}, viewport
+ * properties such as `centerCoordinate` assume a viewport that matches the map
+ * view’s frame. Otherwise, those properties are inset, excluding part of the
+ * frame from the viewport. For instance, if the only the top edge is inset, the
+ * map center is effectively shifted downward.
+ *
+ * @param left The left margin in pixels.
+ * @param top The top margin in pixels.
+ * @param right The right margin in pixels.
+ * @param bottom The bottom margin in pixels.
+ */
+ public void setPadding(int left, int top, int right, int bottom) {
+ mMapView.setContentPadding(left, top, right, bottom);
+ mUiSettings.invalidate();
+
+ moveCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition.Builder(mCameraPosition).build()));
+ }
+
+ /**
+ *
+ * @return
+ */
+ public int[] getPadding() {
+ return new int[]{mMapView.getContentPaddingLeft(),
+ mMapView.getContentPaddingTop(),
+ mMapView.getContentPaddingRight(),
+ mMapView.getContentPaddingBottom()};
+ }
+
+ //
// Map events
//
/**
+ * Sets a callback that's invoked on every change in camera position.
+ *
+ * @param listener The callback that's invoked on every camera change position.
+ * To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnCameraChangeListener(@Nullable OnCameraChangeListener listener) {
+ mOnCameraChangeListener = listener;
+ }
+
+ /**
* Sets a callback that's invoked on every frame rendered to the map view.
*
* @param listener The callback that's invoked on every frame rendered to the map view.
@@ -845,10 +1183,44 @@ public class MapboxMap {
*
* @return Current active InfoWindow Click Listener
*/
+ @UiThread
public OnInfoWindowClickListener getOnInfoWindowClickListener() {
return mOnInfoWindowClickListener;
}
+ /**
+ * Sets a callback that's invoked when a marker's info window is long pressed.
+ *
+ * @param listener The callback that's invoked when a marker's info window is long pressed. To unset the callback, use null.
+ */
+ @UiThread
+ public void setOnInfoWindowLongClickListener(@Nullable OnInfoWindowLongClickListener listener) {
+ mOnInfoWindowLongClickListener = listener;
+ }
+
+ /**
+ * Return the InfoWindow long click listener
+ *
+ * @return Current active InfoWindow long Click Listener
+ */
+ public OnInfoWindowLongClickListener getOnInfoWindowLongClickListener() {
+ return mOnInfoWindowLongClickListener;
+ }
+
+ public void setOnInfoWindowCloseListener(@Nullable OnInfoWindowCloseListener listener) {
+ mOnInfoWindowCloseListener = listener;
+ }
+
+ /**
+ * Return the InfoWindow close listener
+ *
+ * @return Current active InfoWindow Close Listener
+ */
+ @UiThread
+ public OnInfoWindowCloseListener getOnInfoWindowCloseListener() {
+ return mOnInfoWindowCloseListener;
+ }
+
//
// User location
//
@@ -874,13 +1246,14 @@ public class MapboxMap {
* or @link android.Manifest.permission#ACCESS_FINE_LOCATION.
*
* @param enabled True to enable; false to disable.
- * @throws SecurityException if no suitable permission is present
*/
@UiThread
- @RequiresPermission(anyOf = {
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION})
public void setMyLocationEnabled(boolean enabled) {
+ if (!mMapView.isPermissionsAccepted()) {
+ Log.e(MapboxConstants.TAG, "Could not activate user location tracking: " +
+ "user did not accept the permission or permissions were not requested.");
+ return;
+ }
mMyLocationEnabled = enabled;
mMapView.setMyLocationEnabled(enabled);
}
@@ -909,40 +1282,6 @@ public class MapboxMap {
}
/**
- * <p>
- * Set the current my location tracking mode.
- * </p>
- * <p>
- * Will enable my location if not active.
- * </p>
- * See {@link MyLocationTracking} for different values.
- *
- * @param myLocationTrackingMode The location tracking mode to be used.
- * @throws SecurityException if no suitable permission is present
- * @see MyLocationTracking
- */
- @UiThread
- @RequiresPermission(anyOf = {
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION})
- public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
- mMapView.setMyLocationTrackingMode(myLocationTrackingMode);
- }
-
- /**
- * Returns the current user location tracking mode.
- *
- * @return The current user location tracking mode.
- * One of the values from {@link MyLocationTracking.Mode}.
- * @see MyLocationTracking.Mode
- */
- @UiThread
- @MyLocationTracking.Mode
- public int getMyLocationTrackingMode() {
- return mMapView.getMyLocationTrackingMode();
- }
-
- /**
* Sets a callback that's invoked when the location tracking mode changes.
*
* @param listener The callback that's invoked when the location tracking mode changes.
@@ -959,42 +1298,6 @@ public class MapboxMap {
}
/**
- * <p>
- * Set the current my bearing tracking mode.
- * </p>
- * Shows the direction the user is heading.
- * <p>
- * When location tracking is disabled the direction of {@link UserLocationView} is rotated
- * When location tracking is enabled the {@link MapView} is rotated based on bearing value.
- * </p>
- * See {@link MyBearingTracking} for different values.
- *
- * @param myBearingTrackingMode The bearing tracking mode to be used.
- * @throws SecurityException if no suitable permission is present
- * @see MyBearingTracking
- */
- @UiThread
- @RequiresPermission(anyOf = {
- Manifest.permission.ACCESS_COARSE_LOCATION,
- Manifest.permission.ACCESS_FINE_LOCATION})
- public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
- mMapView.setMyBearingTrackingMode(myBearingTrackingMode);
- }
-
- /**
- * Returns the current user bearing tracking mode.
- * See {@link MyBearingTracking} for possible return values.
- *
- * @return the current user bearing tracking mode.
- * @see MyBearingTracking
- */
- @UiThread
- @MyLocationTracking.Mode
- public int getMyBearingTrackingMode() {
- return mMapView.getMyBearingTrackingMode();
- }
-
- /**
* Sets a callback that's invoked when the bearing tracking mode changes.
*
* @param listener The callback that's invoked when the bearing tracking mode changes.
@@ -1033,9 +1336,17 @@ public class MapboxMap {
return mMapView;
}
-//
-// Interfaces
-//
+ //
+ // Invalidate
+ //
+
+ public void invalidate(){
+ mMapView.update();
+ }
+
+ //
+ // Interfaces
+ //
/**
* Interface definition for a callback to be invoked when the map is flinged.
@@ -1062,6 +1373,20 @@ public class MapboxMap {
}
/**
+ * Interface definition for a callback to be invoked for when the camera changes position.
+ */
+ public interface OnCameraChangeListener {
+ /**
+ * Called after the camera position has changed. During an animation,
+ * this listener may not be notified of intermediate camera positions.
+ * It is always called for the final position in the animation.
+ *
+ * @param position The CameraPosition at the end of the last camera change.
+ */
+ void onCameraChange(CameraPosition position);
+ }
+
+ /**
* Interface definition for a callback to be invoked on every frame rendered to the map view.
*
* @see MapboxMap#setOnFpsChangedListener(OnFpsChangedListener)
@@ -1130,7 +1455,37 @@ public class MapboxMap {
* @param marker The marker of the info window the user clicked on.
* @return If true the listener has consumed the event and the info window will not be closed.
*/
- boolean onMarkerClick(@NonNull Marker marker);
+ boolean onInfoWindowClick(@NonNull Marker marker);
+ }
+
+ /**
+ * Callback interface for when the user long presses on a marker's info window.
+ *
+ * @see MapboxMap#setOnInfoWindowClickListener(OnInfoWindowClickListener)
+ */
+ public interface OnInfoWindowLongClickListener {
+
+ /**
+ * Called when the user makes a long-press gesture on the marker's info window.
+ *
+ * @param marker The marker were the info window is attached to
+ */
+ void onInfoWindowLongClick(Marker marker);
+ }
+
+ /**
+ * Callback interface for close events on a marker's info window.
+ *
+ * @see MapboxMap#setOnInfoWindowCloseListener(OnInfoWindowCloseListener)
+ */
+ public interface OnInfoWindowCloseListener {
+
+ /**
+ * Called when the marker's info window is closed.
+ *
+ * @param marker The marker of the info window that was closed.
+ */
+ void onInfoWindowClose(Marker marker);
}
/**
@@ -1169,7 +1524,7 @@ public class MapboxMap {
/**
* Interface definition for a callback to be invoked when the the My Location tracking mode changes.
*
- * @see MapboxMap#setMyLocationTrackingMode(int)
+ * @see MapView#setMyLocationTrackingMode(int)
*/
public interface OnMyLocationTrackingModeChangeListener {
@@ -1184,7 +1539,7 @@ public class MapboxMap {
/**
* Interface definition for a callback to be invoked when the the My Location tracking mode changes.
*
- * @see MapboxMap#setMyLocationTrackingMode(int)
+ * @see MapView#setMyLocationTrackingMode(int)
*/
public interface OnMyBearingTrackingModeChangeListener {
@@ -1212,13 +1567,20 @@ public class MapboxMap {
}
private class MapChangeCameraPositionListener implements MapView.OnMapChangedListener {
+
+ private static final long UPDATE_RATE_MS = 400;
+ private long mPreviousUpdateTimestamp = 0;
+
@Override
public void onMapChanged(@MapView.MapChange int change) {
- if (!mInvalidCameraPosition && (change == MapView.REGION_DID_CHANGE
- || change == MapView.REGION_DID_CHANGE_ANIMATED
- || change == MapView.REGION_WILL_CHANGE
- || change == MapView.REGION_WILL_CHANGE_ANIMATED)) {
+ if (change >= MapView.REGION_WILL_CHANGE && change <= MapView.REGION_DID_CHANGE_ANIMATED) {
mInvalidCameraPosition = true;
+ long currentTime = SystemClock.elapsedRealtime();
+ if (currentTime < mPreviousUpdateTimestamp) {
+ return;
+ }
+ invalidateCameraPosition();
+ mPreviousUpdateTimestamp = currentTime + UPDATE_RATE_MS;
}
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
deleted file mode 100644
index cb6407986e..0000000000
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java
+++ /dev/null
@@ -1,116 +0,0 @@
-package com.mapbox.mapboxsdk.maps;
-
-import android.content.Context;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.util.AttributeSet;
-
-import com.mapbox.mapboxsdk.camera.CameraPosition;
-
-/**
- * Builder for composing {@link MapboxMap} objects. These options can be used when adding a
- * map to your application programmatically (as opposed to via XML). If you are using a MapFragment,
- * you can pass these options in using the static factory method newInstance(MapboxMapOptions).
- * If you are using a MapView, you can pass these options in using the constructor MapView(Context, MapboxMapOptions).
- */
-public class MapboxMapOptions implements Parcelable {
-
- private MapboxMap mMapboxMap;
- private UiSettings mUiSettings;
-
- public MapboxMapOptions(MapboxMap mapboxMap) {
- mMapboxMap = mapboxMap;
- mUiSettings = mapboxMap.getUiSettings();
- }
-
- public MapboxMapOptions(Parcel in) {
- throw new UnsupportedOperationException();
- }
-
- public MapboxMapOptions camera(CameraPosition camera) {
- mMapboxMap.setCameraPosition(camera);
- return this;
- }
-
- public CameraPosition getCamera() {
- return mMapboxMap.getCameraPosition();
- }
-
- public MapboxMapOptions compassEnabled(boolean enabled) {
- mUiSettings.setCompassEnabled(enabled);
- return this;
- }
-
- public boolean getCompassEnabled() {
- return mUiSettings.isCompassEnabled();
- }
-
- public MapboxMapOptions rotateEnabled(boolean rotateEnabled) {
- mUiSettings.setRotateGesturesEnabled(rotateEnabled);
- return this;
- }
-
- public MapboxMapOptions rotateGesturesEnabled(boolean enabled) {
- mUiSettings.setRotateGesturesEnabled(enabled);
- return this;
- }
-
- public boolean getRotateGesturesEnabled() {
- return mUiSettings.isRotateGesturesEnabled();
- }
-
- public MapboxMapOptions scrollGesturesEnabled(boolean enabled) {
- mUiSettings.setScrollGesturesEnabled(enabled);
- return this;
- }
-
- public boolean getScrollGesturesEnabled() {
- return mUiSettings.isScrollGesturesEnabled();
- }
-
- public MapboxMapOptions tiltGesturesEnabled(boolean enabled) {
- mUiSettings.setTiltGesturesEnabled(enabled);
- return this;
- }
-
- public boolean getTiltGesturesEnabled() {
- return mUiSettings.isTiltGesturesEnabled();
- }
-
- public MapboxMapOptions zoomControlsEnabled(boolean enabled) {
- mUiSettings.setZoomControlsEnabled(enabled);
- return this;
- }
-
- public boolean getZoomControlsEnabled() {
- return mUiSettings.isZoomControlsEnabled();
- }
-
- public boolean getZoomGesturesEnabled() {
- return mUiSettings.isZoomGesturesEnabled();
- }
-
- public MapboxMapOptions createFromAttributes(Context context, AttributeSet attrs) {
- throw new UnsupportedOperationException();
- }
-
- public static final Parcelable.Creator<MapboxMapOptions> CREATOR = new Parcelable.Creator<MapboxMapOptions>() {
- public MapboxMapOptions createFromParcel(Parcel in) {
- return new MapboxMapOptions(in);
- }
-
- public MapboxMapOptions[] newArray(int size) {
- return new MapboxMapOptions[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- throw new UnsupportedOperationException();
- }
-}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
index 6c388d9d8a..b7f583e943 100755
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
@@ -395,6 +395,10 @@ final class NativeMapView {
return nativeAddPolygons(mNativeMapViewPtr, polygon);
}
+ public void updateMarker(Marker marker) {
+ nativeUpdateMarker(mNativeMapViewPtr, marker);
+ }
+
public void removeAnnotation(long id) {
nativeRemoveAnnotation(mNativeMapViewPtr, id);
}
@@ -619,6 +623,8 @@ final class NativeMapView {
private native long nativeAddMarker(long nativeMapViewPtr, Marker marker);
+ private native void nativeUpdateMarker(long nativeMapViewPtr, Marker marker);
+
private native long[] nativeAddMarkers(long nativeMapViewPtr, List<Marker> markers);
private native long nativeAddPolyline(long nativeMapViewPtr, Polyline polyline);
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java
index e53d430b69..0d5745d4c9 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java
@@ -1,6 +1,7 @@
package com.mapbox.mapboxsdk.maps;
import android.graphics.PointF;
+import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
import com.mapbox.mapboxsdk.geometry.LatLng;
@@ -21,6 +22,20 @@ public class Projection {
}
/**
+ * <p>
+ * Returns the distance spanned by one pixel at the specified latitude and current zoom level.
+ * </p>
+ * The distance between pixels decreases as the latitude approaches the poles.
+ * This relationship parallels the relationship between longitudinal coordinates at different latitudes.
+ *
+ * @param latitude The latitude for which to return the value.
+ * @return The distance measured in meters.
+ */
+ public double getMetersPerPixelAtLatitude(@FloatRange(from = -180, to = 180) double latitude) {
+ return mMapView.getMetersPerPixelAtLatitude(latitude);
+ }
+
+ /**
* Returns the geographic location that corresponds to a screen location.
* The screen location is specified in screen pixels (not display pixels) relative to the
* top left of the map (not the top left of the whole screen).
@@ -55,7 +70,7 @@ public class Projection {
.include(bottomRight)
.include(bottomLeft);
- return new VisibleRegion(topLeft,topRight,bottomLeft,bottomRight,builder.build());
+ return new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight, builder.build());
}
/**
@@ -69,4 +84,14 @@ public class Projection {
public PointF toScreenLocation(LatLng location) {
return mMapView.toScreenLocation(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(mMapView.getScale() * minScale) / Math.log(2);
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java
index 147cd31b5a..8783712e10 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/SupportMapFragment.java
@@ -1,6 +1,7 @@
package com.mapbox.mapboxsdk.maps;
import android.os.Bundle;
+import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
@@ -29,18 +30,10 @@ public class SupportMapFragment extends Fragment {
private MapView mMap;
- public static SupportMapFragment newInstance(){
+ public static SupportMapFragment newInstance() {
return new SupportMapFragment();
}
- public static SupportMapFragment newInstance(MapboxMapOptions mapboxMapOptions) {
- final SupportMapFragment mapFragment = new SupportMapFragment();
- Bundle bundle = new Bundle();
- bundle.putParcelable(MapboxConstants.FRAG_ARG_MAPBOXMAPOPTIONS, mapboxMapOptions);
- mapFragment.setArguments(bundle);
- return mapFragment;
- }
-
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
@@ -94,7 +87,12 @@ public class SupportMapFragment extends Fragment {
}
@NonNull
- public void getMapAsync(@NonNull OnMapReadyCallback onMapReadyCallback){
- mMap.getMapAsync(onMapReadyCallback);
+ public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) {
+ new Handler().post(new Runnable() {
+ @Override
+ public void run() {
+ mMap.getMapAsync(onMapReadyCallback);
+ }
+ });
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java
new file mode 100644
index 0000000000..543ff19e56
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/TrackingSettings.java
@@ -0,0 +1,121 @@
+package com.mapbox.mapboxsdk.maps;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.UiThread;
+
+import com.mapbox.mapboxsdk.constants.MyBearingTracking;
+import com.mapbox.mapboxsdk.constants.MyLocationTracking;
+
+public class TrackingSettings {
+
+ private MapView mapView;
+ private UiSettings uiSettings;
+ private boolean dismissTrackingOnGesture = true;
+
+ @MyLocationTracking.Mode
+ private int mMyLocationTrackingMode;
+
+ @MyBearingTracking.Mode
+ private int mMyBearingTrackingMode;
+
+ TrackingSettings(@NonNull MapView mapView, UiSettings uiSettings) {
+ this.mapView = mapView;
+ this.uiSettings = uiSettings;
+ }
+
+ /**
+ * <p>
+ * Set the current my location tracking mode.
+ * </p>
+ * <p>
+ * Will enable my location if not active.
+ * </p>
+ * See {@link MyLocationTracking} for different values.
+ *
+ * @param myLocationTrackingMode The location tracking mode to be used.
+ * @throws SecurityException if no suitable permission is present
+ * @see MyLocationTracking
+ */
+ @UiThread
+ public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
+ mMyLocationTrackingMode = myLocationTrackingMode;
+ mapView.setMyLocationTrackingMode(myLocationTrackingMode);
+ validateGesturesForTrackingModes();
+ }
+
+ /**
+ * Returns the current user location tracking mode.
+ *
+ * @return The current user location tracking mode.
+ * One of the values from {@link MyLocationTracking.Mode}.
+ * @see MyLocationTracking.Mode
+ */
+ @UiThread
+ @MyLocationTracking.Mode
+ public int getMyLocationTrackingMode() {
+ return mMyLocationTrackingMode;
+ }
+
+ /**
+ * <p>
+ * Set the current my bearing tracking mode.
+ * </p>
+ * Shows the direction the user is heading.
+ * <p>
+ * When location tracking is disabled the direction of {@link UserLocationView} is rotated
+ * When location tracking is enabled the {@link MapView} is rotated based on bearing value.
+ * </p>
+ * See {@link MyBearingTracking} for different values.
+ *
+ * @param myBearingTrackingMode The bearing tracking mode to be used.
+ * @throws SecurityException if no suitable permission is present
+ * @see MyBearingTracking
+ */
+ @UiThread
+ public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
+ mMyBearingTrackingMode = myBearingTrackingMode;
+ mapView.setMyBearingTrackingMode(myBearingTrackingMode);
+ }
+
+ /**
+ * Returns the current user bearing tracking mode.
+ * See {@link MyBearingTracking} for possible return values.
+ *
+ * @return the current user bearing tracking mode.
+ * @see MyBearingTracking
+ */
+ @UiThread
+ @MyLocationTracking.Mode
+ public int getMyBearingTrackingMode() {
+ return mMyBearingTrackingMode;
+ }
+
+ public boolean isDismissTrackingOnGesture() {
+ return dismissTrackingOnGesture;
+ }
+
+ public void setDismissTrackingOnGesture(boolean dismissTrackingOnGesture) {
+ this.dismissTrackingOnGesture = dismissTrackingOnGesture;
+ validateGesturesForTrackingModes();
+ }
+
+ private void validateGesturesForTrackingModes() {
+ if (!dismissTrackingOnGesture) {
+ int myLocationTrackingMode = getMyLocationTrackingMode();
+ int myBearingTrackingMode = getMyBearingTrackingMode();
+
+ // Enable/disable gestures based on tracking mode
+ if (myLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
+ uiSettings.setScrollGesturesEnabled(true);
+ uiSettings.setRotateGesturesEnabled(true);
+ } else {
+ uiSettings.setScrollGesturesEnabled(false);
+ uiSettings.setRotateGesturesEnabled((myBearingTrackingMode == MyBearingTracking.NONE));
+ }
+ }
+ }
+
+ public boolean isLocationTrackingDisabled(){
+ return mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE;
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
index d6cb106054..1538f49d60 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UiSettings.java
@@ -1,9 +1,14 @@
package com.mapbox.mapboxsdk.maps;
+import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
import android.support.annotation.UiThread;
+import android.util.Log;
import android.view.Gravity;
import android.view.View;
+import android.widget.VideoView;
+
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
/**
* Settings for the user interface of a MapboxMap. To obtain this interface, call getUiSettings().
@@ -12,17 +17,9 @@ public class UiSettings {
private MapView mapView;
- private boolean compassEnabled;
- private int compassGravity;
- private int[] compassMargins;
-
- private boolean logoEnabled;
- private int logoGravity;
- private int[] logoMargins;
-
- private boolean attributionEnabled;
- private int attributionGravity;
- private int[] attributionMargins;
+ private ViewSettings compassSettings;
+ private ViewSettings logoSettings;
+ private ViewSettings attributionSettings;
private boolean rotateGesturesEnabled;
private boolean tiltGesturesEnabled;
@@ -30,11 +27,78 @@ public class UiSettings {
private boolean zoomControlsEnabled;
private boolean scrollGesturesEnabled;
+ private double maxZoomLevel = -1;
+ private double minZoomLevel = -1;
+
UiSettings(@NonNull MapView mapView) {
this.mapView = mapView;
- this.compassMargins = new int[4];
- this.attributionMargins = new int[4];
- this.logoMargins = new int[4];
+ this.compassSettings = new ViewSettings();
+ this.logoSettings = new ViewSettings();
+ this.attributionSettings = new ViewSettings();
+ }
+
+ /**
+ * <p>
+ * Sets the minimum zoom level the map can be displayed at.
+ * </p>
+ *
+ * @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)) {
+ Log.e(MapboxConstants.TAG, "Not setting minZoom, value is in unsupported range: " + minZoom);
+ return;
+ }
+ minZoomLevel = minZoom;
+ mapView.setMinZoom(minZoom);
+ }
+
+ /**
+ * <p>
+ * Gets the maximum zoom level the map can be displayed at.
+ * </p>
+ *
+ * @return The minimum zoom level.
+ */
+ @UiThread
+ public double getMinZoom() {
+ if (minZoomLevel == -1) {
+ return minZoomLevel = mapView.getMinZoom();
+ }
+ return minZoomLevel;
+ }
+
+ /**
+ * <p>
+ * Sets the maximum zoom level the map can be displayed at.
+ * </p>
+ *
+ * @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)) {
+ Log.e(MapboxConstants.TAG, "Not setting maxZoom, value is in unsupported range: " + maxZoom);
+ return;
+ }
+ maxZoomLevel = maxZoom;
+ mapView.setMaxZoom(maxZoom);
+ }
+
+ /**
+ * <p>
+ * Gets the maximum zoom level the map can be displayed at.
+ * </p>
+ *
+ * @return The maximum zoom level.
+ */
+ @UiThread
+ public double getMaxZoom() {
+ if (maxZoomLevel == -1) {
+ return maxZoomLevel = mapView.getMaxZoom();
+ }
+ return maxZoomLevel;
}
/**
@@ -49,8 +113,8 @@ public class UiSettings {
* @param compassEnabled True to enable the compass; false to disable the compass.
*/
public void setCompassEnabled(boolean compassEnabled) {
- this.compassEnabled = compassEnabled;
- this.mapView.setCompassEnabled(compassEnabled);
+ compassSettings.setEnabled(compassEnabled);
+ mapView.setCompassEnabled(compassEnabled);
}
/**
@@ -59,7 +123,7 @@ public class UiSettings {
* @return True if the compass is enabled; false if the compass is disabled.
*/
public boolean isCompassEnabled() {
- return compassEnabled;
+ return compassSettings.isEnabled();
}
/**
@@ -74,8 +138,8 @@ public class UiSettings {
*/
@UiThread
public void setCompassGravity(int gravity) {
- this.compassGravity = gravity;
- this.mapView.setCompassGravity(gravity);
+ compassSettings.setGravity(gravity);
+ mapView.setCompassGravity(gravity);
}
/**
@@ -84,7 +148,7 @@ public class UiSettings {
* @return The gravity
*/
public int getCompassGravity() {
- return compassGravity;
+ return compassSettings.getGravity();
}
/**
@@ -98,8 +162,8 @@ public class UiSettings {
*/
@UiThread
public void setCompassMargins(int left, int top, int right, int bottom) {
- this.compassMargins = new int[]{left, top, right, bottom};
- this.mapView.setCompassMargins(left, top, right, bottom);
+ compassSettings.setMargins(new int[]{left, top, right, bottom});
+ mapView.setCompassMargins(left, top, right, bottom);
}
/**
@@ -108,7 +172,7 @@ public class UiSettings {
* @return The left margin in pixels
*/
public int getCompassMarginLeft() {
- return compassMargins[0];
+ return compassSettings.getMargins()[0];
}
/**
@@ -117,7 +181,7 @@ public class UiSettings {
* @return The top margin in pixels
*/
public int getCompassMarginTop() {
- return compassMargins[1];
+ return compassSettings.getMargins()[1];
}
/**
@@ -126,7 +190,7 @@ public class UiSettings {
* @return The right margin in pixels
*/
public int getCompassMarginRight() {
- return compassMargins[2];
+ return compassSettings.getMargins()[2];
}
/**
@@ -135,7 +199,7 @@ public class UiSettings {
* @return The bottom margin in pixels
*/
public int getCompassMarginBottom() {
- return compassMargins[3];
+ return compassSettings.getMargins()[3];
}
/**
@@ -147,8 +211,8 @@ public class UiSettings {
* @param enabled True to enable the logo; false to disable the logo.
*/
public void setLogoEnabled(boolean enabled) {
- this.logoEnabled = enabled;
- this.mapView.setLogoVisibility(enabled );
+ logoSettings.setEnabled(enabled);
+ mapView.setLogoVisibility(enabled);
}
/**
@@ -157,7 +221,7 @@ public class UiSettings {
* @return True if the logo is enabled; false if the logo is disabled.
*/
public boolean isLogoEnabled() {
- return logoEnabled;
+ return logoSettings.isEnabled();
}
/**
@@ -171,8 +235,8 @@ public class UiSettings {
* @see Gravity
*/
public void setLogoGravity(int gravity) {
- this.logoGravity = gravity;
- this.mapView.setLogoGravity(gravity);
+ logoSettings.setGravity(gravity);
+ mapView.setLogoGravity(gravity);
}
/**
@@ -181,7 +245,7 @@ public class UiSettings {
* @return The gravity
*/
public int getLogoGravity() {
- return logoGravity;
+ return logoSettings.getGravity();
}
/**
@@ -194,8 +258,8 @@ public class UiSettings {
* @param bottom The bottom margin in pixels.
*/
public void setLogoMargins(int left, int top, int right, int bottom) {
- this.logoMargins = new int[]{left, top, right, bottom};
- this.mapView.setLogoMargins(left, top, right, bottom);
+ logoSettings.setMargins(new int[]{left, top, right, bottom});
+ mapView.setLogoMargins(left, top, right, bottom);
}
/**
@@ -203,8 +267,8 @@ public class UiSettings {
*
* @return The left margin in pixels
*/
- public int getLogoMarginLeft(){
- return logoMargins[0];
+ public int getLogoMarginLeft() {
+ return logoSettings.getMargins()[0];
}
/**
@@ -212,8 +276,8 @@ public class UiSettings {
*
* @return The top margin in pixels
*/
- public int getLogoMarginTop(){
- return logoMargins[1];
+ public int getLogoMarginTop() {
+ return logoSettings.getMargins()[1];
}
/**
@@ -221,8 +285,8 @@ public class UiSettings {
*
* @return The right margin in pixels
*/
- public int getLogoMarginRight(){
- return logoMargins[2];
+ public int getLogoMarginRight() {
+ return logoSettings.getMargins()[2];
}
/**
@@ -230,8 +294,8 @@ public class UiSettings {
*
* @return The bottom margin in pixels
*/
- public int getLogoMarginBottom(){
- return logoMargins[3];
+ public int getLogoMarginBottom() {
+ return logoSettings.getMargins()[3];
}
/**
@@ -243,8 +307,8 @@ public class UiSettings {
* @param enabled True to enable the logo; false to disable the logo.
*/
public void setAttributionEnabled(boolean enabled) {
- this.attributionEnabled = enabled;
- this.mapView.setAttributionVisibility(enabled ? View.VISIBLE : View.GONE);
+ attributionSettings.setEnabled(enabled);
+ mapView.setAttributionVisibility(enabled ? View.VISIBLE : View.GONE);
}
/**
@@ -253,7 +317,7 @@ public class UiSettings {
* @return True if the logo is enabled; false if the logo is disabled.
*/
public boolean isAttributionEnabled() {
- return attributionEnabled;
+ return attributionSettings.isEnabled();
}
/**
@@ -267,8 +331,8 @@ public class UiSettings {
* @see Gravity
*/
public void setAttributionGravity(int gravity) {
- this.attributionGravity = gravity;
- this.mapView.setAttributionGravity(gravity);
+ attributionSettings.setGravity(gravity);
+ mapView.setAttributionGravity(gravity);
}
/**
@@ -277,7 +341,7 @@ public class UiSettings {
* @return The gravity
*/
public int getAttributionGravity() {
- return attributionGravity;
+ return attributionSettings.getGravity();
}
/**
@@ -290,8 +354,8 @@ public class UiSettings {
* @param bottom The bottom margin in pixels.
*/
public void setAttributionMargins(int left, int top, int right, int bottom) {
- this.attributionMargins = new int[]{left, top, right, bottom};
- this.mapView.setAttributionMargins(left, top, right, bottom);
+ attributionSettings.setMargins(new int[]{left, top, right, bottom});
+ mapView.setAttributionMargins(left, top, right, bottom);
}
/**
@@ -299,8 +363,8 @@ public class UiSettings {
*
* @return The left margin in pixels
*/
- public int getAttributionMarginLeft(){
- return attributionMargins[0];
+ public int getAttributionMarginLeft() {
+ return attributionSettings.getMargins()[0];
}
/**
@@ -308,8 +372,8 @@ public class UiSettings {
*
* @return The top margin in pixels
*/
- public int getAttributionMarginTop(){
- return attributionMargins[1];
+ public int getAttributionMarginTop() {
+ return attributionSettings.getMargins()[1];
}
/**
@@ -317,8 +381,8 @@ public class UiSettings {
*
* @return The right margin in pixels
*/
- public int getAttributionMarginRight(){
- return attributionMargins[2];
+ public int getAttributionMarginRight() {
+ return attributionSettings.getMargins()[2];
}
/**
@@ -326,8 +390,8 @@ public class UiSettings {
*
* @return The bottom margin in pixels
*/
- public int getAttributionMarginBottom(){
- return attributionMargins[3];
+ public int getAttributionMarginBottom() {
+ return attributionSettings.getMargins()[3];
}
/**
@@ -477,4 +541,31 @@ public class UiSettings {
setTiltGesturesEnabled(enabled);
setZoomGesturesEnabled(enabled);
}
+
+ /**
+ * Returns the measured height of the MapView
+ *
+ * @return height in pixels
+ */
+ public float getHeight() {
+ return mapView.getMeasuredHeight();
+ }
+
+ /**
+ * Returns the measured width of the MapView
+ *
+ * @return widht in pixels
+ */
+ public float getWidth() {
+ return mapView.getMeasuredWidth();
+ }
+
+ /**
+ * 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());
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ViewSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ViewSettings.java
new file mode 100644
index 0000000000..a192a1b576
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ViewSettings.java
@@ -0,0 +1,36 @@
+package com.mapbox.mapboxsdk.maps;
+
+public class ViewSettings {
+
+ private boolean enabled;
+ private int gravity;
+ private int[]margins;
+
+ 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;
+ }
+}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CompassView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java
index 0d84289332..28afb70de3 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/CompassView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java
@@ -1,4 +1,4 @@
-package com.mapbox.mapboxsdk.maps;
+package com.mapbox.mapboxsdk.maps.widgets;
import android.content.Context;
import android.support.v4.content.ContextCompat;
@@ -11,6 +11,8 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import com.mapbox.mapboxsdk.R;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
import java.lang.ref.WeakReference;
import java.util.Timer;
@@ -21,7 +23,7 @@ import java.util.TimerTask;
* when it isn't true north (0.0). Tapping the compass resets the bearing to true
* north and hides the compass.
*/
-public class CompassView extends ImageView {
+public final class CompassView extends ImageView {
private Timer mNorthTimer;
private double mDirection = 0.0f;
@@ -46,7 +48,7 @@ public class CompassView extends ImageView {
// View configuration
setImageDrawable(ContextCompat.getDrawable(getContext(), R.drawable.compass));
- setContentDescription(getResources().getString(R.string.compassContentDescription));
+ setContentDescription(getResources().getString(R.string.mapbox_compassContentDescription));
setEnabled(false);
// Layout params
@@ -139,17 +141,17 @@ public class CompassView extends ImageView {
public static class CompassClickListener implements View.OnClickListener {
- private WeakReference<MapView> mMapView;
+ private WeakReference<MapboxMap> mMapboxMap;
- public CompassClickListener(final MapView mapView) {
- mMapView = new WeakReference<>(mapView);
+ public CompassClickListener(final MapboxMap mapboxMap) {
+ mMapboxMap = new WeakReference<>(mapboxMap);
}
@Override
public void onClick(View v) {
- final MapView mapView = mMapView.get();
- if (mapView != null) {
- mapView.resetNorth();
+ final MapboxMap mapboxMap = mMapboxMap.get();
+ if (mapboxMap != null) {
+ mapboxMap.resetNorth();
}
}
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UserLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/UserLocationView.java
index 9f8261a0a7..98d66b9307 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/UserLocationView.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/UserLocationView.java
@@ -1,4 +1,4 @@
-package com.mapbox.mapboxsdk.maps;
+package com.mapbox.mapboxsdk.maps.widgets;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
@@ -27,11 +27,14 @@ import android.view.ViewGroup;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.camera.CameraPosition;
+import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.location.LocationListener;
-import com.mapbox.mapboxsdk.location.LocationServices;
+import com.mapbox.mapboxsdk.location.LocationService;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
+import com.mapbox.mapboxsdk.maps.Projection;
import java.lang.ref.WeakReference;
@@ -42,9 +45,8 @@ import java.lang.ref.WeakReference;
public final class UserLocationView extends View {
- private MapView mMapView;
-
- private float mDensity;
+ private MapboxMap mMapboxMap;
+ private Projection mProjection;
private boolean mShowMarker;
private boolean mShowDirection;
@@ -84,7 +86,6 @@ public final class UserLocationView extends View {
private LatLng mCurrentMapViewCoordinate;
private double mCurrentBearing;
-
private boolean mPaused = false;
private Location mUserLocation;
private UserLocationListener mUserLocationListener;
@@ -99,7 +100,6 @@ public final class UserLocationView extends View {
// Compass data
private MyBearingListener mBearingChangeListener;
- private static final long BEARING_DURATION = 100;
public UserLocationView(Context context) {
super(context);
@@ -132,9 +132,9 @@ public final class UserLocationView extends View {
// Setup the custom paint
Resources resources = context.getResources();
- int accuracyColor = resources.getColor(R.color.my_location_ring);
+ int accuracyColor = ContextCompat.getColor(context,R.color.my_location_ring);
- mDensity = resources.getDisplayMetrics().density;
+ float density = resources.getDisplayMetrics().density;
mMarkerCoordinate = new LatLng(0.0, 0.0);
mMarkerScreenPoint = new PointF();
mMarkerScreenMatrix = new Matrix();
@@ -148,7 +148,7 @@ public final class UserLocationView extends View {
mAccuracyPaintStroke = new Paint();
mAccuracyPaintStroke.setAntiAlias(true);
mAccuracyPaintStroke.setStyle(Paint.Style.STROKE);
- mAccuracyPaintStroke.setStrokeWidth(0.5f * mDensity);
+ mAccuracyPaintStroke.setStrokeWidth(0.5f * density);
mAccuracyPaintStroke.setColor(accuracyColor);
mAccuracyPaintStroke.setAlpha((int) (255 * 0.5f));
@@ -195,8 +195,9 @@ public final class UserLocationView extends View {
mUserLocationStaleDrawable.setBounds(mUserLocationStaleDrawableBounds);
}
- public void setMapView(MapView mapView) {
- mMapView = mapView;
+ public void setMapboxMap(MapboxMap mapboxMap) {
+ mMapboxMap = mapboxMap;
+ mProjection = mapboxMap.getProjection();
}
public void onStart() {
@@ -247,21 +248,15 @@ public final class UserLocationView extends View {
if (myLocationTrackingMode != MyLocationTracking.TRACKING_NONE && mUserLocation != null) {
// center map directly if we have a location fix
mMarkerCoordinate = new LatLng(mUserLocation.getLatitude(), mUserLocation.getLongitude());
- mMapView.getMapboxMap().moveCamera(CameraUpdateFactory.newLatLng(new LatLng(mUserLocation)));
+ mMapboxMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(mUserLocation)));
// center view directly
mMarkerScreenMatrix.reset();
- mMarkerScreenMatrix.setTranslate(
- getMeasuredWidth() / 2,
- getMeasuredHeight() / 2);
+ mMarkerScreenPoint = getMarkerScreenPoint();
+ mMarkerScreenMatrix.setTranslate(mMarkerScreenPoint.x, mMarkerScreenPoint.y);
}
}
- @MyLocationTracking.Mode
- public int getMyLocationTrackingMode() {
- return mMyLocationTrackingMode;
- }
-
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
@@ -278,7 +273,7 @@ public final class UserLocationView extends View {
// compute new marker position
// TODO add JNI method that takes existing pointf
if (mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
- mMarkerScreenPoint = mMapView.toScreenLocation(mMarkerCoordinate);
+ mMarkerScreenPoint = getMarkerScreenPoint();
mMarkerScreenMatrix.reset();
mMarkerScreenMatrix.setTranslate(
mMarkerScreenPoint.x,
@@ -289,11 +284,11 @@ public final class UserLocationView extends View {
if (mShowDirection) {
bearing = mMyBearingTrackingMode == MyBearingTracking.COMPASS ? mBearingChangeListener.getCompassBearing() : mUserLocation.getBearing();
} else {
- bearing = (float) mMapView.getBearing();
+ bearing = mMapboxMap.getCameraPosition().bearing;
}
if (mCurrentMapViewCoordinate == null) {
- mCurrentMapViewCoordinate = mMapView.getMapboxMap().getCameraPosition().target;
+ mCurrentMapViewCoordinate = mMapboxMap.getCameraPosition().target;
}
// only update if there is an actual change
@@ -302,11 +297,10 @@ public final class UserLocationView extends View {
.target(mMarkerCoordinate)
.bearing(bearing)
.build();
- mMapView.getMapboxMap().animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 300, null);
+ mMapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), 300, null);
mMarkerScreenMatrix.reset();
- mMarkerScreenMatrix.setTranslate(
- getMeasuredWidth() / 2,
- getMeasuredHeight() / 2);
+ mMarkerScreenPoint = getMarkerScreenPoint();
+ mMarkerScreenMatrix.setTranslate(mMarkerScreenPoint.x, mMarkerScreenPoint.y);
// set values for next check for actual change
mCurrentMapViewCoordinate = mMarkerCoordinate;
@@ -317,10 +311,10 @@ public final class UserLocationView extends View {
// rotate so arrow in points to bearing
if (mShowDirection) {
if (mMyBearingTrackingMode == MyBearingTracking.COMPASS && mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
- mMarkerScreenMatrix.preRotate(mCompassMarkerDirection + (float) mMapView.getDirection());
+ mMarkerScreenMatrix.preRotate(mCompassMarkerDirection + mMapboxMap.getCameraPosition().bearing);
} else if (mMyBearingTrackingMode == MyBearingTracking.GPS) {
if (mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
- mMarkerScreenMatrix.preRotate(mGpsMarkerDirection + (float) mMapView.getDirection());
+ mMarkerScreenMatrix.preRotate(mGpsMarkerDirection + mMapboxMap.getCameraPosition().bearing);
} else {
mMarkerScreenMatrix.preRotate(mGpsMarkerDirection);
}
@@ -331,7 +325,7 @@ public final class UserLocationView extends View {
if (mShowAccuracy && !mStaleMarker) {
mAccuracyPath.reset();
mAccuracyPath.addCircle(0.0f, 0.0f,
- (float) (mMarkerAccuracy / mMapView.getMetersPerPixelAtLatitude(
+ (float) (mMarkerAccuracy / mMapboxMap.getProjection().getMetersPerPixelAtLatitude(
mMarkerCoordinate.getLatitude())),
Path.Direction.CW);
@@ -371,11 +365,11 @@ public final class UserLocationView extends View {
*/
private void toggleGps(boolean enableGps) {
- LocationServices locationServices = LocationServices.getLocationServices(getContext());
+ LocationService locationService = LocationService.getInstance(getContext());
if (enableGps) {
// Set an initial location if one available
- Location lastLocation = locationServices.getLastLocation();
+ Location lastLocation = locationService.getLastLocation();
if (lastLocation != null) {
setLocation(lastLocation);
}
@@ -385,16 +379,16 @@ public final class UserLocationView extends View {
}
// Register for Location Updates
- locationServices.addLocationListener(mUserLocationListener);
+ locationService.addLocationListener(mUserLocationListener);
} else {
// Disable location and user dot
setLocation(null);
// Deregister for Location Updates
- locationServices.removeLocationListener(mUserLocationListener);
+ locationService.removeLocationListener(mUserLocationListener);
}
- locationServices.toggleGPS(enableGps);
+ locationService.toggleGPS(enableGps);
}
public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
@@ -415,11 +409,6 @@ public final class UserLocationView extends View {
update();
}
- @MyBearingTracking.Mode
- public int getMyBearingTrackingMode() {
- return mMyBearingTrackingMode;
- }
-
private class MyBearingListener implements SensorEventListener {
private SensorManager mSensorManager;
@@ -483,9 +472,8 @@ public final class UserLocationView extends View {
SensorManager.getRotationMatrix(mR, null, mLastAccelerometer, mLastMagnetometer);
SensorManager.getOrientation(mR, mOrientation);
float azimuthInRadians = mOrientation[0];
- float azimuthInDegress = (float) (Math.toDegrees(azimuthInRadians) + 360) % 360;
- mCompassBearing = azimuthInDegress;
+ mCompassBearing = (float) (Math.toDegrees(azimuthInRadians) + 360) % 360;
if (mCompassBearing < 0) {
// only allow positive degrees
mCompassBearing += 360;
@@ -515,7 +503,7 @@ public final class UserLocationView extends View {
/**
- * Callback method for receiving location updates from LocationServices.
+ * Callback method for receiving location updates from LocationService.
*
* @param location The new Location data
*/
@@ -670,7 +658,7 @@ public final class UserLocationView extends View {
}
void updateOnNextFrame() {
- mMapView.update();
+ mMapboxMap.invalidate();
}
/**
@@ -770,4 +758,14 @@ public final class UserLocationView extends View {
return mPaused;
}
+ public PointF getMarkerScreenPoint() {
+ if (mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
+ mMarkerScreenPoint = mProjection.toScreenLocation(mMarkerCoordinate);
+ } else {
+ int[] contentPadding = mMapboxMap.getPadding();
+ mMarkerScreenPoint = new PointF(((getMeasuredWidth() + contentPadding[0] - contentPadding[2]) / 2)
+ , ((getMeasuredHeight() - contentPadding[3] + contentPadding[1]) / 2));
+ }
+ return mMarkerScreenPoint;
+ }
}