summaryrefslogtreecommitdiff
path: root/android
diff options
context:
space:
mode:
Diffstat (limited to 'android')
-rw-r--r--android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapFragment.java2
-rw-r--r--android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java41
-rw-r--r--android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java40
-rw-r--r--android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java41
-rw-r--r--android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java29
-rw-r--r--android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java23
-rw-r--r--android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java194
-rw-r--r--android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java293
-rw-r--r--android/MapboxGLAndroidSDK/src/main/res/layout/fragment_mapview.xml (renamed from android/MapboxGLAndroidSDK/src/main/res/layout/mapview.xml)0
-rw-r--r--android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml36
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java29
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MyLocationTrackingModeActivity.java73
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/icon.pngbin2546 -> 1587 bytes
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/icon_burned.pngbin2546 -> 1587 bytes
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/icon.pngbin2015 -> 913 bytes
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/icon_burned.pngbin2015 -> 913 bytes
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/icon.pngbin3358 -> 1587 bytes
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/icon_burned.pngbin3358 -> 1587 bytes
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/icon.pngbin10233 -> 2382 bytes
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/icon_burned.pngbin10233 -> 2382 bytes
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/icon.pngbin2162 -> 3018 bytes
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/icon_burned.pngbin2162 -> 3018 bytes
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml27
-rw-r--r--android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml10
24 files changed, 656 insertions, 182 deletions
diff --git a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapFragment.java b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapFragment.java
index 92405dc5cc..9a1861ec19 100644
--- a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapFragment.java
+++ b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/MapFragment.java
@@ -37,7 +37,7 @@ public class MapFragment extends Fragment {
Log.v(TAG, "onCreateView");
// Create the map
- mMap = (MapView) inflater.inflate(R.layout.mapview, container, false);
+ mMap = (MapView) inflater.inflate(R.layout.fragment_mapview, container, false);
// Set accessToken
mMap.setAccessToken(ApiAccess.getToken(container.getContext()));
diff --git a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java
index f0c15906e0..921905d4fd 100644
--- a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java
+++ b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerOptions.java
@@ -1,10 +1,49 @@
package com.mapbox.mapboxsdk.annotations;
+import android.graphics.Bitmap;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.support.annotation.Nullable;
import com.mapbox.mapboxsdk.geometry.LatLng;
-public final class MarkerOptions {
+public final class MarkerOptions implements Parcelable {
+
+ public static final Parcelable.Creator<MarkerOptions> CREATOR
+ = new Parcelable.Creator<MarkerOptions>() {
+ public MarkerOptions createFromParcel(Parcel in) {
+ return new MarkerOptions(in);
+ }
+
+ public MarkerOptions[] newArray(int size) {
+ return new MarkerOptions[size];
+ }
+ };
+
+ private MarkerOptions(Parcel in) {
+ marker = new Marker();
+ position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
+ snippet(in.readString());
+ String spriteId = in.readString();
+ Bitmap spriteBitmap = in.readParcelable(Bitmap.class.getClassLoader());
+ Sprite icon = new Sprite(spriteId, spriteBitmap);
+ icon(icon);
+ title(in.readString());
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(getPosition(), flags);
+ out.writeString(getSnippet());
+ out.writeString(getIcon().getId());
+ out.writeParcelable(getIcon().getBitmap(), flags);
+ out.writeString(getTitle());
+ }
private Marker marker;
diff --git a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java
index 42e80edc2c..c716d10edf 100644
--- a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java
+++ b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolygonOptions.java
@@ -1,11 +1,49 @@
package com.mapbox.mapboxsdk.annotations;
+import android.os.Parcel;
+import android.os.Parcelable;
+
import com.mapbox.mapboxsdk.geometry.LatLng;
+import java.util.ArrayList;
import java.util.List;
-public final class PolygonOptions {
+public final class PolygonOptions implements Parcelable {
+
+ public static final Parcelable.Creator<PolygonOptions> CREATOR
+ = new Parcelable.Creator<PolygonOptions>() {
+ public PolygonOptions createFromParcel(Parcel in) {
+ return new PolygonOptions(in);
+ }
+
+ public PolygonOptions[] newArray(int size) {
+ return new PolygonOptions[size];
+ }
+ };
+
+ private PolygonOptions(Parcel in) {
+ polygon = new Polygon();
+ ArrayList<LatLng> pointsList = new ArrayList<>();
+ in.readList(pointsList, LatLng.class.getClassLoader());
+ addAll(pointsList);
+ alpha(in.readFloat());
+ fillColor(in.readInt());
+ strokeColor(in.readInt());
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeList(getPoints());
+ out.writeFloat(getAlpha());
+ out.writeInt(getFillColor());
+ out.writeInt(getStrokeColor());
+ }
private Polygon polygon;
diff --git a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java
index 089646696d..d48858c7d9 100644
--- a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java
+++ b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/PolylineOptions.java
@@ -1,10 +1,49 @@
package com.mapbox.mapboxsdk.annotations;
+import android.os.Parcel;
+import android.os.Parcelable;
+
import com.mapbox.mapboxsdk.geometry.LatLng;
+import java.util.ArrayList;
import java.util.List;
-public final class PolylineOptions {
+public final class PolylineOptions implements Parcelable {
+
+
+ public static final Parcelable.Creator<PolylineOptions> CREATOR
+ = new Parcelable.Creator<PolylineOptions>() {
+ public PolylineOptions createFromParcel(Parcel in) {
+ return new PolylineOptions(in);
+ }
+
+ public PolylineOptions[] newArray(int size) {
+ return new PolylineOptions[size];
+ }
+ };
+
+ private PolylineOptions(Parcel in) {
+ polyline = new Polyline();
+ ArrayList<LatLng> pointsList = new ArrayList<>();
+ in.readList(pointsList, LatLng.class.getClassLoader());
+ addAll(pointsList);
+ alpha(in.readFloat());
+ color(in.readInt());
+ width(in.readFloat());
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeList(getPoints());
+ out.writeFloat(getAlpha());
+ out.writeInt(getColor());
+ out.writeFloat(getWidth());
+ }
private Polyline polyline;
diff --git a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java
new file mode 100644
index 0000000000..ce01e7b4c5
--- /dev/null
+++ b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java
@@ -0,0 +1,29 @@
+package com.mapbox.mapboxsdk.constants;
+
+import android.support.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * MyBearingTracking exposes different types bearing tracking modes.
+ *
+ * @see
+ * @see
+ */
+public class MyBearingTracking {
+
+ /**
+ * Indicates the parameter accepts one of the values from {@link MyBearingTracking}.
+ */
+ @IntDef({NONE, COMPASS, GPS, /**COMBINED**/})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Mode {
+ }
+
+ public static final int NONE = 0x00000000;
+ public static final int COMPASS = 0x00000004;
+ public static final int GPS = 0x00000008;
+// public static final int COMBINED = 0x00000012;
+
+}
diff --git a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java
index 6cfc48c0e1..f477c4ab45 100644
--- a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java
+++ b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java
@@ -8,7 +8,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
- * MyLocationTracking exposes different types of location tracking modes.
+ * MyLocationTracking exposes different types of locational tracking modes.
*
* @see MapView#setMyLocationTrackingMode(int)
* @see com.mapbox.mapboxsdk.views.UserLocationView#setMyLocationTrackingMode(int)
@@ -18,7 +18,7 @@ public class MyLocationTracking {
/**
* Indicates the parameter accepts one of the values from {@link MyLocationTracking}.
*/
- @IntDef({TRACKING_NONE, TRACKING_FOLLOW, /**TRACKING_FOLLOW_BEARING_GPS, TRACKING_FOLLOW_BEARING_COMPASS, TRACKING_FOLLOW_BEARING**/})
+ @IntDef({TRACKING_NONE, TRACKING_FOLLOW})
@Retention(RetentionPolicy.SOURCE)
public @interface Mode {
}
@@ -29,25 +29,8 @@ public class MyLocationTracking {
public static final int TRACKING_NONE = 0x00000000;
/**
- * Tracking the only the location of the user.
+ * Tracking user, {@link MapView} will reposition to center of {@link com.mapbox.mapboxsdk.views.UserLocationView}
*/
public static final int TRACKING_FOLLOW = 0x00000004;
-// /**
-// * Tracking the location of the user with bearing from GPS.
-// */
-// public static final int TRACKING_FOLLOW_BEARING_GPS = 0x00000008;
-//
-// /**
-// * Tracking the location of the user with bearing from compass.
-// */
-// public static final int TRACKING_FOLLOW_BEARING_COMPASS = 0x00000012;
-//
-// /**
-// * Tracking the location fot the user with bearing from GPS or compass.
-// * <p>
-// * The best source of bearing is selected automatically.
-// */
-// public static final int TRACKING_FOLLOW_BEARING = 0x00000016;
-
} \ No newline at end of file
diff --git a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
index f1c021c0c7..2b6a3071ec 100644
--- a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
+++ b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/MapView.java
@@ -29,7 +29,6 @@ import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.UiThread;
-import android.support.v4.content.ContextCompat;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.view.ScaleGestureDetectorCompat;
import android.support.v7.app.AlertDialog;
@@ -41,13 +40,13 @@ import android.view.GestureDetector;
import android.view.Gravity;
import android.view.InputDevice;
import android.view.KeyEvent;
+import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.view.ViewConfiguration;
-import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -65,6 +64,7 @@ import com.mapbox.mapboxsdk.annotations.Polyline;
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
import com.mapbox.mapboxsdk.annotations.Sprite;
import com.mapbox.mapboxsdk.annotations.SpriteFactory;
+import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException;
@@ -188,9 +188,6 @@ public final class MapView extends FrameLayout {
// Receives changes to network connectivity
private ConnectivityReceiver mConnectivityReceiver;
- // Holds the context
- private Context mContext;
-
// Used for user location
private UserLocationView mUserLocationView;
@@ -502,7 +499,7 @@ public final class MapView extends FrameLayout {
*
* @param location The current location of the My Location dot The type of map change event.
*/
- void onMyLocationChange(@Nullable Location location);
+ void onMyLocationChange(@Nullable Location location);
}
//
@@ -520,7 +517,8 @@ public final class MapView extends FrameLayout {
public MapView(@NonNull Context context, @NonNull String accessToken) {
super(context);
if (accessToken == null) {
- throw new NullPointerException("accessToken is null");
+ Log.w(TAG, "accessToken was null, so just returning");
+ return;
}
initialize(context, null);
setAccessToken(accessToken);
@@ -540,10 +538,12 @@ public final class MapView extends FrameLayout {
public MapView(@NonNull Context context, @NonNull String accessToken, @NonNull String styleUrl) {
super(context);
if (accessToken == null) {
- throw new NullPointerException("accessToken is null");
+ Log.w(TAG, "accessToken was null, so just returning");
+ return;
}
if (styleUrl == null) {
- throw new NullPointerException("styleUrl is null");
+ Log.w(TAG, "styleUrl was null, so just returning");
+ return;
}
initialize(context, null);
setAccessToken(accessToken);
@@ -579,17 +579,19 @@ public final class MapView extends FrameLayout {
// Common initialization code goes here
private void initialize(Context context, AttributeSet attrs) {
if (context == null) {
- throw new NullPointerException("context is null");
+ Log.w(TAG, "context was null, so just returning");
+ return;
}
- // Save the context
- mContext = context;
+ // Inflate content
+ View view = LayoutInflater.from(context).inflate(R.layout.mapview_internal, this);
- setWillNotDraw(false);
+ if (!isInEditMode()) {
+ setWillNotDraw(false);
+ }
- // Create the TextureView
- mTextureView = new TextureView(mContext);
- addView(mTextureView);
+ // Reference the TextureView
+ mTextureView = (TextureView) view.findViewById(R.id.textureView);
mTextureView.setSurfaceTextureListener(new SurfaceTextureListener());
// Check if we are in Android Studio UI editor to avoid error in layout preview
@@ -651,36 +653,18 @@ public final class MapView extends FrameLayout {
}
// Setup user location UI
- mUserLocationView = new UserLocationView(this, getContext());
- addView(mUserLocationView);
+ mUserLocationView = (UserLocationView) view.findViewById(R.id.userLocationView);
+ mUserLocationView.setMapView(this);
// Setup compass
- mCompassView = new CompassView(mContext);
+ mCompassView = (CompassView) view.findViewById(R.id.compassView);
mCompassView.setOnClickListener(new CompassView.CompassClickListener(this));
- addView(mCompassView);
// Setup Mapbox logo
- mLogoView = new ImageView(mContext);
- mLogoView.setImageDrawable(ContextCompat.getDrawable(mContext, R.drawable.attribution_logo));
- mLogoView.setContentDescription(getResources().getString(R.string.mapboxIconContentDescription));
- ViewGroup.LayoutParams logoParams = new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- mLogoView.setLayoutParams(logoParams);
- addView(mLogoView);
+ mLogoView = (ImageView) view.findViewById(R.id.logoView);
// Setup Attributions control
- mAttributionsView = new ImageView(mContext);
- mAttributionsView.setClickable(true);
- mAttributionsView.setImageResource(R.drawable.ic_info_selector);
- int attrPadding = (int) (DIMENSION_SEVEN_DP * mScreenDensity);
- mAttributionsView.setPadding(attrPadding, attrPadding, attrPadding, attrPadding);
- mAttributionsView.setAdjustViewBounds(true);
- mAttributionsView.setContentDescription(getResources()
- .getString(R.string.attributionsIconContentDescription));
- LayoutParams attrParams = new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- mAttributionsView.setLayoutParams(attrParams);
- addView(mAttributionsView);
+ mAttributionsView = (ImageView) view.findViewById(R.id.attributionView);
mAttributionsView.setOnClickListener(new AttributionOnClickListener(this));
// Load the attributes
@@ -842,7 +826,8 @@ public final class MapView extends FrameLayout {
@UiThread
public void onSaveInstanceState(@NonNull Bundle outState) {
if (outState == null) {
- throw new NullPointerException("outState is null");
+ Log.w(TAG, "outState was null, so just returning");
+ return;
}
outState.putParcelable(STATE_CENTER_COORDINATE, getCenterCoordinate());
@@ -905,6 +890,7 @@ public final class MapView extends FrameLayout {
*/
@UiThread
public void onStart() {
+ mUserLocationView.onStart();
}
/**
@@ -912,7 +898,7 @@ public final class MapView extends FrameLayout {
*/
@UiThread
public void onStop() {
- mUserLocationView.cancelAnimations();
+ mUserLocationView.onStop();
}
/**
@@ -935,7 +921,7 @@ public final class MapView extends FrameLayout {
public void onResume() {
// Register for connectivity changes
mConnectivityReceiver = new ConnectivityReceiver();
- mContext.registerReceiver(mConnectivityReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
+ getContext().registerReceiver(mConnectivityReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
mUserLocationView.resume();
mNativeMapView.resume();
@@ -1037,7 +1023,8 @@ public final class MapView extends FrameLayout {
public void setCenterCoordinate(@NonNull LatLngZoom centerCoordinate,
boolean animated) {
if (centerCoordinate == null) {
- throw new NullPointerException("centerCoordinate is null");
+ Log.w(TAG, "centerCoordinate was null, so just returning");
+ return;
}
long duration = animated ? ANIMATION_DURATION : 0;
mNativeMapView.cancelTransitions();
@@ -1426,7 +1413,8 @@ public final class MapView extends FrameLayout {
@UiThread
public void setStyleClasses(@NonNull List<String> styleClasses, @IntRange(from = 0) long transitionDuration) {
if (styleClasses == null) {
- throw new NullPointerException("styleClasses is null");
+ Log.w(TAG, "styleClasses was null, so just returning");
+ return;
}
if (transitionDuration < 0) {
throw new IllegalArgumentException("transitionDuration is < 0");
@@ -1447,7 +1435,8 @@ public final class MapView extends FrameLayout {
@UiThread
public void addStyleClass(@NonNull String styleClass) {
if (styleClass == null) {
- throw new NullPointerException("styleClass is null");
+ Log.w(TAG, "styleClass was null, so just returning");
+ return;
}
mNativeMapView.addClass(styleClass);
}
@@ -1463,7 +1452,8 @@ public final class MapView extends FrameLayout {
@UiThread
public void removeStyleClass(@NonNull String styleClass) {
if (styleClass == null) {
- throw new NullPointerException("styleClass is null");
+ Log.w(TAG, "styleClass was null, so just returning");
+ return;
}
mNativeMapView.removeClass(styleClass);
}
@@ -1477,7 +1467,8 @@ public final class MapView extends FrameLayout {
@UiThread
public boolean hasStyleClass(@NonNull String styleClass) {
if (styleClass == null) {
- throw new NullPointerException("styleClass is null");
+ Log.w(TAG, "centerCoordinate was null, so just returning false");
+ return false;
}
return mNativeMapView.hasClass(styleClass);
}
@@ -1565,7 +1556,8 @@ public final class MapView extends FrameLayout {
@NonNull
public LatLng fromScreenLocation(@NonNull PointF point) {
if (point == null) {
- throw new NullPointerException("point is null");
+ Log.w(TAG, "point was null, so just returning (0, 0)");
+ return new LatLng();
}
float x = point.x;
@@ -1587,7 +1579,8 @@ public final class MapView extends FrameLayout {
@NonNull
public PointF toScreenLocation(@NonNull LatLng location) {
if (location == null) {
- throw new NullPointerException("location is null");
+ Log.w(TAG, "location was null, so just returning (0, 0)");
+ return new PointF();
}
PointF point = mNativeMapView.pixelForLatLng(location);
@@ -1675,7 +1668,8 @@ public final class MapView extends FrameLayout {
@NonNull
public Marker addMarker(@NonNull MarkerOptions markerOptions) {
if (markerOptions == null) {
- throw new NullPointerException("markerOptions is null");
+ Log.w(TAG, "markerOptions was null, so just returning null");
+ return null;
}
Marker marker = prepareMarker(markerOptions);
@@ -1699,7 +1693,8 @@ public final class MapView extends FrameLayout {
@NonNull
public List<Marker> addMarkers(@NonNull List<MarkerOptions> markerOptionsList) {
if (markerOptionsList == null) {
- throw new NullPointerException("markerOptionsList is null");
+ Log.w(TAG, "markerOptionsList was null, so just returning null");
+ return null;
}
int count = markerOptionsList.size();
@@ -1733,7 +1728,8 @@ public final class MapView extends FrameLayout {
@NonNull
public Polyline addPolyline(@NonNull PolylineOptions polylineOptions) {
if (polylineOptions == null) {
- throw new NullPointerException("polylineOptions is null");
+ Log.w(TAG, "polylineOptions was null, so just returning null");
+ return null;
}
Polyline polyline = polylineOptions.getPolyline();
@@ -1754,7 +1750,8 @@ public final class MapView extends FrameLayout {
@NonNull
public List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList) {
if (polylineOptionsList == null) {
- throw new NullPointerException("polylineOptionsList is null");
+ Log.w(TAG, "polylineOptionsList was null, so just returning null");
+ return null;
}
int count = polylineOptionsList.size();
@@ -1786,7 +1783,8 @@ public final class MapView extends FrameLayout {
@NonNull
public Polygon addPolygon(@NonNull PolygonOptions polygonOptions) {
if (polygonOptions == null) {
- throw new NullPointerException("polygonOptions is null");
+ Log.w(TAG, "polygonOptions was null, so just returning null");
+ return null;
}
Polygon polygon = polygonOptions.getPolygon();
@@ -1808,7 +1806,8 @@ public final class MapView extends FrameLayout {
@NonNull
public List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList) {
if (polygonOptionsList == null) {
- throw new NullPointerException("polygonOptionsList is null");
+ Log.w(TAG, "polygonOptionsList was null, so just returning null");
+ return null;
}
int count = polygonOptionsList.size();
@@ -1838,7 +1837,8 @@ public final class MapView extends FrameLayout {
@UiThread
public void removeAnnotation(@NonNull Annotation annotation) {
if (annotation == null) {
- throw new NullPointerException("annotation is null");
+ Log.w(TAG, "annotation was null, so just returning");
+ return;
}
if (annotation instanceof Marker) {
@@ -1857,7 +1857,8 @@ public final class MapView extends FrameLayout {
@UiThread
public void removeAnnotations(@NonNull List<? extends Annotation> annotationList) {
if (annotationList == null) {
- throw new NullPointerException("annotationList is null");
+ Log.w(TAG, "annotationList was null, so just returning");
+ return;
}
int count = annotationList.size();
@@ -1902,7 +1903,8 @@ public final class MapView extends FrameLayout {
private List<Marker> getMarkersInBounds(@NonNull BoundingBox bbox) {
if (bbox == null) {
- throw new NullPointerException("bbox is null");
+ Log.w(TAG, "bbox was null, so just returning null");
+ return null;
}
// TODO: filter in JNI using C++ parameter to getAnnotationsInBounds
@@ -1961,7 +1963,8 @@ public final class MapView extends FrameLayout {
@UiThread
public void selectMarker(@NonNull Marker marker) {
if (marker == null) {
- throw new NullPointerException("marker is null");
+ Log.w(TAG, "marker was null, so just returning");
+ return;
}
if (marker == mSelectedMarker) {
@@ -2017,7 +2020,7 @@ public final class MapView extends FrameLayout {
/**
* Changes the map's viewing area to fit the given coordinate bounds, optionally animating the change.
*
- * @param bounds The bounds that the viewport will show in its entirety.
+ * @param bounds The bounds that the viewport will show in its entirety.
* @param animated If true, animates the change. If false, immediately changes the map.
*/
@UiThread
@@ -2029,8 +2032,8 @@ public final class MapView extends FrameLayout {
* Changes the map’s viewport to fit the given coordinate bounds with additional padding at the
* edge of the map, optionally animating the change.
*
- * @param bounds The bounds that the viewport will show in its entirety.
- * @param padding The minimum padding (in pixels) that will be visible around the given coordinate bounds.
+ * @param bounds The bounds that the viewport will show in its entirety.
+ * @param padding The minimum padding (in pixels) that will be visible around the given coordinate bounds.
* @param animated If true, animates the change. If false, immediately changes the map.
*/
@UiThread
@@ -2050,8 +2053,8 @@ public final class MapView extends FrameLayout {
* and animating the change.
*
* @param coordinates The coordinates that the viewport will show.
- * @param padding The minimum padding (in pixels) that will be visible around the given coordinate bounds.
- * @param animated If true, animates the change. If false, immediately changes the map.
+ * @param padding The minimum padding (in pixels) that will be visible around the given coordinate bounds.
+ * @param animated If true, animates the change. If false, immediately changes the map.
*/
@UiThread
public void setVisibleCoordinateBounds(@NonNull LatLng[] coordinates, @NonNull RectF padding, boolean animated) {
@@ -2064,12 +2067,13 @@ public final class MapView extends FrameLayout {
private void setVisibleCoordinateBounds(LatLng[] coordinates, RectF padding, double direction, long duration) {
mNativeMapView.setVisibleCoordinateBounds(coordinates, new RectF(padding.left / mScreenDensity,
- padding.top / mScreenDensity, padding.right / mScreenDensity, padding.bottom / mScreenDensity),
+ padding.top / mScreenDensity, padding.right / mScreenDensity, padding.bottom / mScreenDensity),
direction, duration);
}
/**
* Gets the currently selected marker.
+ *
* @return The currently selected marker.
*/
@UiThread
@@ -2124,10 +2128,14 @@ public final class MapView extends FrameLayout {
@Override
public void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+ if (isInEditMode()) {
+ return;
+ }
+
if (!mNativeMapView.isPaused()) {
mNativeMapView.renderSync();
}
- super.onDraw(canvas);
}
@Override
@@ -2176,7 +2184,14 @@ public final class MapView extends FrameLayout {
// Used by UserLocationView
void update() {
- mNativeMapView.update();
+ if (mNativeMapView != null) {
+ mNativeMapView.update();
+ }
+ }
+
+ // Used by UserLocationView
+ void setBearing(float bearing) {
+ mNativeMapView.setBearing(bearing, 100);
}
//
@@ -2989,7 +3004,6 @@ public final class MapView extends FrameLayout {
}
-
/**
* Sets a callback that's invoked on every frame rendered to the map view.
*
@@ -3146,14 +3160,13 @@ public final class MapView extends FrameLayout {
}
/**
- * Sets the current my location tracking mode.
- * <p>
- * My location racking disables gestures, automatically moves the viewport to the users
- * location and shows the direction the user is heading.
+ * Set the current my location tracking mode.
+ * Tracking my location disables gestures and pans the viewport
+ * <p/>
+ * See {@link MyLocationTracking} for different values.
*
- * @param myLocationTrackingMode The my location tracking mode to use.
- * Accepts one of the values from {@link MyLocationTracking.Mode}.
- * @see MyLocationTracking.Mode
+ * @param myLocationTrackingMode The location tracking mode to be used.
+ * @see MyLocationTracking
*/
@UiThread
public void setMyLocationTrackingMode(@MyLocationTracking.Mode int myLocationTrackingMode) {
@@ -3182,6 +3195,33 @@ public final class MapView extends FrameLayout {
return mUserLocationView.getMyLocationTrackingMode();
}
+ /**
+ * Set the current my bearing tracking mode.
+ * Tracking my bearing disables gestures and shows the direction the user is heading.
+ * See {@link MyBearingTracking} for different values.
+ *
+ * @param myBearingTrackingMode The bearing tracking mode to be used.
+ * @see MyBearingTracking
+ */
+ @UiThread
+ public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
+ mUserLocationView.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() {
+ //noinspection ResourceType
+ return mUserLocationView.getMyBearingTrackingMode();
+ }
+
//
// Compass
//
@@ -3220,8 +3260,8 @@ public final class MapView extends FrameLayout {
* @param gravity One of the values from {@link Gravity}.
* @see Gravity
*/
- @UiThread
- public void setCompassGravity(int gravity) {
+ @UiThread
+ public void setCompassGravity(int gravity) {
setWidgetGravity(mCompassView, gravity);
}
diff --git a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java
index 06ef550a7d..349765bdd3 100644
--- a/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java
+++ b/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/views/UserLocationView.java
@@ -12,14 +12,24 @@ import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
+import android.hardware.GeomagneticField;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
import android.location.Location;
+import android.os.Build;
+import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
+import android.view.Surface;
import android.view.View;
import android.view.ViewGroup;
+import android.view.WindowManager;
import com.mapbox.mapboxsdk.R;
+import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapzen.android.lost.api.LocationListener;
@@ -27,6 +37,8 @@ import com.mapzen.android.lost.api.LocationRequest;
import com.mapzen.android.lost.api.LocationServices;
import com.mapzen.android.lost.api.LostApiClient;
+import java.util.ArrayDeque;
+
final class UserLocationView extends View {
private MapView mMapView;
@@ -38,6 +50,7 @@ final class UserLocationView extends View {
private boolean mShowMarker;
private boolean mShowDirection;
private boolean mShowAccuracy;
+ private boolean mStaleMarker;
private PointF mMarkerScreenPoint;
private Matrix mMarkerScreenMatrix;
@@ -80,24 +93,28 @@ final class UserLocationView extends View {
@MyLocationTracking.Mode
private int mMyLocationTrackingMode;
- public UserLocationView(MapView mapView, Context context) {
+ @MyBearingTracking.Mode
+ private int mMyBearingTrackingMode;
+
+ // Compass data
+ private MyBearingListener mBearingChangeListener;
+
+ public UserLocationView(Context context) {
super(context);
- initialize(mapView, context);
+ initialize(context);
}
- public UserLocationView(MapView mapView, Context context, AttributeSet attrs) {
+ public UserLocationView(Context context, AttributeSet attrs) {
super(context, attrs);
- initialize(mapView, context);
+ initialize(context);
}
- public UserLocationView(MapView mapView, Context context, AttributeSet attrs, int defStyleAttr) {
+ public UserLocationView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
- initialize(mapView, context);
+ initialize(context);
}
- private void initialize(MapView mapView, Context context) {
- mMapView = mapView;
-
+ private void initialize(Context context) {
// View configuration
setEnabled(false);
setWillNotDraw(false);
@@ -115,6 +132,9 @@ final class UserLocationView extends View {
.setSmallestDisplacement(3.0f)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
+ // Setup sensors
+ mBearingChangeListener = new MyBearingListener(context);
+
// Setup the custom paint
Resources resources = context.getResources();
mDensity = resources.getDisplayMetrics().density;
@@ -178,6 +198,21 @@ final class UserLocationView extends View {
mUserLocationStaleDrawable.setBounds(mUserLocationStaleDrawableBounds);
}
+ public void setMapView(MapView mapView) {
+ mMapView = mapView;
+ }
+
+ public void onStart() {
+ if (mMyBearingTrackingMode == MyBearingTracking.COMPASS) {
+ mBearingChangeListener.onStart(getContext());
+ }
+ }
+
+ public void onStop() {
+ mBearingChangeListener.onStop();
+ cancelAnimations();
+ }
+
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
@@ -189,19 +224,17 @@ final class UserLocationView extends View {
canvas.concat(mMarkerScreenMatrix);
Drawable dotDrawable = mShowDirection ? mUserLocationBearingDrawable : mUserLocationDrawable;
- // IMPORTANT also update in uodate()
+ dotDrawable = mStaleMarker ? mUserLocationStaleDrawable : dotDrawable;
+ // IMPORTANT also update in update()
RectF dotBounds = mShowDirection ? mUserLocationBearingDrawableBoundsF : mUserLocationDrawableBoundsF;
+ dotBounds = mStaleMarker ? mUserLocationStaleDrawableBoundsF : dotBounds;
- boolean willDraw;
- willDraw = mShowAccuracy && !canvas.quickReject(mAccuracyPath, Canvas.EdgeType.AA);
+ boolean willDraw =
+ mShowAccuracy && !mStaleMarker && !canvas.quickReject(mAccuracyPath, Canvas.EdgeType.AA);
willDraw |= !canvas.quickReject(dotBounds, Canvas.EdgeType.AA);
- dotBounds.offset(
- (int) -mMarkerScreenPoint.x,
- (int) -mMarkerScreenPoint.y);
-
if (willDraw) {
- if (mShowAccuracy) {
+ if (mShowAccuracy && !mStaleMarker) {
canvas.drawPath(mAccuracyPath, mAccuracyPaintFill);
canvas.drawPath(mAccuracyPath, mAccuracyPaintStroke);
}
@@ -234,6 +267,8 @@ final class UserLocationView extends View {
if (isEnabled() && mShowMarker) {
setVisibility(View.VISIBLE);
+ mStaleMarker = isStale(mUserLocation);
+
// compute new marker position
// TODO add JNI method that takes existing pointf
mMarkerScreenPoint = mMapView.toScreenLocation(mMarkerCoordinate);
@@ -249,7 +284,7 @@ final class UserLocationView extends View {
}
// adjust accuracy circle
- if (mShowAccuracy) {
+ if (mShowAccuracy && !mStaleMarker) {
mAccuracyPath.reset();
mAccuracyPath.addCircle(0.0f, 0.0f,
(float) (mMarkerAccuracy / mMapView.getMetersPerPixelAtLatitude(
@@ -270,7 +305,9 @@ final class UserLocationView extends View {
}
RectF dotBounds = mShowDirection ? mUserLocationBearingDrawableBoundsF : mUserLocationDrawableBoundsF;
- RectF largerBounds = mAccuracyBounds.contains(dotBounds) ? mAccuracyBounds : dotBounds;
+ dotBounds = mStaleMarker ? mUserLocationStaleDrawableBoundsF : dotBounds;
+ RectF largerBounds = mShowAccuracy && !mStaleMarker && mAccuracyBounds.contains(dotBounds)
+ ? mAccuracyBounds : dotBounds;
mMarkerScreenMatrix.mapRect(mDirtyRectF, largerBounds);
mDirtyRectF.roundOut(mDirtyRect);
invalidate(mDirtyRect); // the new marker location
@@ -297,7 +334,10 @@ final class UserLocationView extends View {
if (!mLocationClient.isConnected()) {
mUserLocation = null;
mLocationClient.connect();
- setLocation(LocationServices.FusedLocationApi.getLastLocation());
+ Location lastLocation = LocationServices.FusedLocationApi.getLastLocation();
+ if (lastLocation != null) {
+ setLocation(lastLocation);
+ }
mLocationListener = new MyLocationListener();
LocationServices.FusedLocationApi.requestLocationUpdates(mLocationRequest, mLocationListener);
}
@@ -311,6 +351,136 @@ final class UserLocationView extends View {
}
}
+ public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) {
+ mMyBearingTrackingMode = myBearingTrackingMode;
+
+ if (myBearingTrackingMode == MyBearingTracking.COMPASS) {
+ mBearingChangeListener.onStart(getContext());
+ } else {
+ mBearingChangeListener.onStop();
+ }
+ }
+
+ @MyBearingTracking.Mode
+ public int getMyBearingTrackingMode() {
+ return mMyBearingTrackingMode;
+ }
+
+ private class MyBearingListener implements SensorEventListener {
+
+ // Sensor model
+ private SensorManager mSensorManager;
+ private Sensor mSensorRotationVector;
+ private int mRotationDevice;
+
+ // Sensor data sensor rotation vector
+ private float[] mRotationMatrix = new float[16];
+ private float[] mRemappedMatrix = new float[16];
+ private float[] mOrientation = new float[3];
+
+ // Location data
+ private GeomagneticField mGeomagneticField;
+
+ // Controls the sensor update rate in milliseconds
+ private static final int UPDATE_RATE_MS = 500;
+ private AngleLowPassFilter mLowPassFilter;
+
+ // Compass data
+ private float mCompassBearing;
+ private long mCompassUpdateNextTimestamp = 0;
+
+ public MyBearingListener(Context context) {
+ mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
+ mSensorRotationVector = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
+ mLowPassFilter = new AngleLowPassFilter();
+ }
+
+ public void onStart(Context context) {
+ mRotationDevice = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
+ mSensorManager.registerListener(this, mSensorRotationVector, UPDATE_RATE_MS * 1000);
+ }
+
+ public void onStop() {
+ mSensorManager.unregisterListener(this, mSensorRotationVector);
+ }
+
+ public float getCompassBearing() {
+ return mCompassBearing;
+ }
+
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ if (mPaused) {
+ return;
+ }
+
+ switch (event.sensor.getType()) {
+ case Sensor.TYPE_ROTATION_VECTOR:
+ SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values);
+ break;
+ }
+
+ switch (mRotationDevice) {
+ case Surface.ROTATION_0:
+ // Portrait
+ SensorManager.getOrientation(mRotationMatrix, mOrientation);
+ break;
+ default:
+ // Landscape
+ SensorManager.remapCoordinateSystem(mRotationMatrix, SensorManager.AXIS_MINUS_Y, SensorManager.AXIS_MINUS_X, mRemappedMatrix);
+ SensorManager.getOrientation(mRemappedMatrix, mOrientation);
+ break;
+ }
+
+ mLowPassFilter.add(mOrientation[0]);
+ long currentTime = System.currentTimeMillis();
+ if (currentTime < mCompassUpdateNextTimestamp) {
+ return;
+ }
+
+ mCompassUpdateNextTimestamp = currentTime + UPDATE_RATE_MS;
+ mGeomagneticField = new GeomagneticField(
+ (float) mUserLocation.getLatitude(),
+ (float) mUserLocation.getLongitude(),
+ (float) mUserLocation.getAltitude(),
+ currentTime);
+ mCompassBearing = (float) Math.toDegrees(mLowPassFilter.average()) + mGeomagneticField.getDeclination();
+ setCompass(mCompassBearing);
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int accuracy) {
+ // TODO add accuracy to the equiation
+ }
+
+ private class AngleLowPassFilter {
+
+ private final int LENGTH = 5;
+
+ private float sumSin, sumCos;
+
+ private ArrayDeque<Float> queue = new ArrayDeque<>();
+
+ public void add(float radians) {
+ sumSin += (float) Math.sin(radians);
+ sumCos += (float) Math.cos(radians);
+ queue.add(radians);
+
+ if (queue.size() > LENGTH) {
+ float old = queue.poll();
+ sumSin -= Math.sin(old);
+ sumCos -= Math.cos(old);
+ }
+ }
+
+ public float average() {
+ int size = queue.size();
+ return (float) Math.atan2(sumSin / size, sumCos / size);
+ }
+ }
+ }
+
+
private class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location) {
@@ -321,6 +491,22 @@ final class UserLocationView extends View {
}
}
+ private boolean isStale(Location location) {
+ if (location != null) {
+ long ageInNanos;
+ if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ ageInNanos = SystemClock.elapsedRealtimeNanos() -
+ location.getElapsedRealtimeNanos();
+ } else {
+ ageInNanos = (System.currentTimeMillis() - location.getTime()) * 1000 * 1000;
+ }
+ final long oneMinuteInNanos = 60L * 1000 * 1000 * 1000;
+ return ageInNanos > oneMinuteInNanos;
+ } else {
+ return false;
+ }
+ }
+
// Handles location updates from GPS
private void setLocation(Location location) {
// if null we should hide the marker
@@ -359,7 +545,7 @@ final class UserLocationView extends View {
previousCoordinate = new LatLng(mUserLocation);
}
- if(mMyLocationTrackingMode== MyLocationTracking.TRACKING_NONE) {
+ if (mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
// moving marker above map
mMarkerCoordinateAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
mMarkerCoordinateAnimator.setDuration(1000);
@@ -367,28 +553,36 @@ final class UserLocationView extends View {
previousCoordinate, new LatLng(location)
));
mMarkerCoordinateAnimator.start();
- }else{
+ } else {
// moving map under the tracker
mMarkerCoordinate = new LatLng(location);
mMapView.setCenterCoordinate(mMarkerCoordinate, true);
}
- mShowDirection = location.hasBearing();
- if (mShowDirection) {
- if (mUserLocation != null && mUserLocation.hasBearing()) {
- mMarkerDirection = mUserLocation.getBearing();
+ if (mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE && mMyBearingTrackingMode == MyBearingTracking.GPS) {
+ // show GPS direction
+ mShowDirection = location.hasBearing();
+ if (mShowDirection) {
+ if (mUserLocation != null && mUserLocation.hasBearing()) {
+ mMarkerDirection = mUserLocation.getBearing();
+ }
+ float oldDir = mMarkerDirection;
+ float newDir = location.getBearing();
+ float diff = oldDir - newDir;
+ if (diff > 180.0f) {
+ newDir += 360.0f;
+ } else if (diff < -180.0f) {
+ newDir -= 360.f;
+ }
+ mMarkerDirectionAnimator = ObjectAnimator.ofFloat(this, "direction", oldDir, newDir);
+ mMarkerDirectionAnimator.setDuration(1000);
+ mMarkerDirectionAnimator.start();
}
- float oldDir = mMarkerDirection;
- float newDir = location.getBearing();
- float diff = oldDir - newDir;
- if (diff > 180.0f) {
- newDir += 360.0f;
- } else if (diff < -180.0f) {
- newDir -= 360.f;
+ } else if (mMyLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW && mMyBearingTrackingMode == MyBearingTracking.GPS) {
+ // set bearing on map
+ if (location.hasBearing()) {
+ mMapView.setBearing(mUserLocation.getBearing());
}
- mMarkerDirectionAnimator = ObjectAnimator.ofFloat(this, "direction", oldDir, newDir);
- mMarkerDirectionAnimator.setDuration(1000);
- mMarkerDirectionAnimator.start();
}
mShowAccuracy = location.hasAccuracy();
@@ -409,6 +603,32 @@ final class UserLocationView extends View {
}
}
+ // handles compass sensor updates
+ private void setCompass(float bearing) {
+ if (mMyLocationTrackingMode == MyLocationTracking.TRACKING_NONE) {
+ // animate marker
+ mShowDirection = true;
+ float oldDir = mMarkerDirection;
+ float newDir = bearing;
+ float diff = oldDir - newDir;
+ if (diff > 180.0f) {
+ newDir += 360.0f;
+ } else if (diff < -180.0f) {
+ newDir -= 360.f;
+ }
+ mMarkerDirectionAnimator = ObjectAnimator.ofFloat(this, "direction", oldDir, newDir);
+ mMarkerDirectionAnimator.setDuration(1000);
+ mMarkerDirectionAnimator.start();
+ mMarkerDirection = bearing;
+ } else if (mMyLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) {
+ // change map direction
+ if (mMyBearingTrackingMode == MyBearingTracking.COMPASS) {
+ mMarkerDirection = bearing;
+ mMapView.setBearing(mMarkerDirection);
+ }
+ }
+ }
+
void updateOnNextFrame() {
mMapView.update();
}
@@ -492,4 +712,5 @@ final class UserLocationView extends View {
mMarkerAccuracyAnimator = null;
}
}
+
}
diff --git a/android/MapboxGLAndroidSDK/src/main/res/layout/mapview.xml b/android/MapboxGLAndroidSDK/src/main/res/layout/fragment_mapview.xml
index 22afd6e513..22afd6e513 100644
--- a/android/MapboxGLAndroidSDK/src/main/res/layout/mapview.xml
+++ b/android/MapboxGLAndroidSDK/src/main/res/layout/fragment_mapview.xml
diff --git a/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml b/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml
new file mode 100644
index 0000000000..c4eaecc079
--- /dev/null
+++ b/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <TextureView
+ android:id="@+id/textureView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <com.mapbox.mapboxsdk.views.CompassView
+ android:id="@+id/compassView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+ <ImageView
+ android:id="@+id/logoView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:contentDescription="@string/mapboxIconContentDescription"
+ android:src="@drawable/attribution_logo" />
+
+ <ImageView
+ android:id="@+id/attributionView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:adjustViewBounds="true"
+ android:clickable="true"
+ android:contentDescription="@string/attributionsIconContentDescription"
+ android:padding="7dp"
+ android:src="@drawable/ic_info_selector" />
+
+ <com.mapbox.mapboxsdk.views.UserLocationView
+ android:id="@+id/userLocationView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+
+</merge> \ No newline at end of file
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java b/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
index 4d9d1ecc49..29d6de7f4f 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MainActivity.java
@@ -23,22 +23,27 @@ import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
+
import com.crashlytics.android.Crashlytics;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.PolygonOptions;
import com.mapbox.mapboxsdk.annotations.PolylineOptions;
import com.mapbox.mapboxsdk.annotations.Sprite;
+import com.mapbox.mapboxsdk.constants.MyBearingTracking;
+import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.testapp.utils.GeoParseUtil;
import com.mapbox.mapboxsdk.utils.ApiAccess;
import com.mapbox.mapboxsdk.views.MapView;
-import io.fabric.sdk.android.Fabric;
+
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
+import io.fabric.sdk.android.Fabric;
+
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@@ -72,7 +77,6 @@ public class MainActivity extends AppCompatActivity {
// Used for Annotations
private boolean mIsAnnotationsOn = false;
-
private static final DecimalFormat latLngFormatter = new DecimalFormat("#.#####");
//
@@ -179,13 +183,6 @@ public class MainActivity extends AppCompatActivity {
public void onClick(View v) {
// Toggle GPS position updates
toggleGps(!mMapView.isMyLocationEnabled());
- if (mMapView.isMyLocationEnabled()) {
- Location location = mMapView.getMyLocation();
- if (location != null) {
- mMapView.setZoomLevel(18);
- mMapView.setCenterCoordinate(new LatLng(location));
- }
- }
}
});
@@ -425,7 +422,19 @@ public class MainActivity extends AppCompatActivity {
}
private void enableGps() {
+ mMapView.setOnMyLocationChangeListener(new MapView.OnMyLocationChangeListener() {
+ @Override
+ public void onMyLocationChange(@Nullable Location location) {
+ if (location != null) {
+ mMapView.setZoomLevel(16);
+ mMapView.setCenterCoordinate(new LatLng(location));
+ mMapView.setOnMyLocationChangeListener(null);
+ }
+ }
+ });
mMapView.setMyLocationEnabled(true);
+ mMapView.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
+ mMapView.setMyBearingTrackingMode(MyBearingTracking.GPS);
mLocationFAB.setColorFilter(ContextCompat.getColor(this, R.color.primary));
}
@@ -465,7 +474,7 @@ public class MainActivity extends AppCompatActivity {
List<Marker> markers = mMapView.addMarkers(markerOptionsList);
}
- private MarkerOptions generateMarker(String title, String snippet, Sprite icon, double lat, double lng){
+ private MarkerOptions generateMarker(String title, String snippet, Sprite icon, double lat, double lng) {
return new MarkerOptions()
.position(new LatLng(lat, lng))
.title(title)
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MyLocationTrackingModeActivity.java b/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MyLocationTrackingModeActivity.java
index 366db4b8f4..c5d8b16d86 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MyLocationTrackingModeActivity.java
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/MyLocationTrackingModeActivity.java
@@ -13,6 +13,7 @@ import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
+import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.utils.ApiAccess;
@@ -21,7 +22,7 @@ import com.mapbox.mapboxsdk.views.MapView;
public class MyLocationTrackingModeActivity extends AppCompatActivity implements MapView.OnMyLocationChangeListener, AdapterView.OnItemSelectedListener {
private MapView mMapView;
- private Spinner mSpinner;
+ private Spinner mLocationSpinner, mBearingSpinner;
private Location mLocation;
@Override
@@ -39,12 +40,19 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements
actionBar.setDisplayShowHomeEnabled(true);
}
- ArrayAdapter<CharSequence> spinnerAdapter = ArrayAdapter.createFromResource(actionBar.getThemedContext(), R.array.user_tracking_mode, android.R.layout.simple_spinner_item);
- spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
- mSpinner = (Spinner) findViewById(R.id.spinner);
- mSpinner.setAdapter(spinnerAdapter);
- mSpinner.setOnItemSelectedListener(this);
- mSpinner.setEnabled(false);
+ ArrayAdapter<CharSequence> locationTrackingAdapter = ArrayAdapter.createFromResource(actionBar.getThemedContext(), R.array.user_tracking_mode, android.R.layout.simple_spinner_item);
+ locationTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mLocationSpinner = (Spinner) findViewById(R.id.spinner_location);
+ mLocationSpinner.setAdapter(locationTrackingAdapter);
+ mLocationSpinner.setOnItemSelectedListener(this);
+// mLocationSpinner.setEnabled(false);
+
+ ArrayAdapter<CharSequence> bearingTrackingAdapter = ArrayAdapter.createFromResource(actionBar.getThemedContext(), R.array.user_bearing_mode, android.R.layout.simple_spinner_item);
+ bearingTrackingAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+ mBearingSpinner = (Spinner) findViewById(R.id.spinner_bearing);
+ mBearingSpinner.setAdapter(bearingTrackingAdapter);
+ mBearingSpinner.setOnItemSelectedListener(this);
+// mBearingSpinner.setEnabled(false);
mMapView = (MapView) findViewById(R.id.mapView);
mMapView.setAccessToken(ApiAccess.getToken(this));
@@ -59,7 +67,8 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements
if (mLocation == null) {
// initial location to reposition map
mMapView.setCenterCoordinate(new LatLng(location.getLatitude(), location.getLongitude()));
- mSpinner.setEnabled(true);
+ mLocationSpinner.setEnabled(true);
+ mBearingSpinner.setEnabled(true);
}
mLocation = location;
showSnackBar();
@@ -85,26 +94,34 @@ public class MyLocationTrackingModeActivity extends AppCompatActivity implements
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- switch (position) {
- case 0:
- mMapView.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
- break;
-
- case 1:
- mMapView.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
- break;
-
-// case 2:
-// mMapView.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW_BEARING_GPS);
-// break;
-//
-// case 3:
-// mMapView.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW_BEARING_COMPASS);
-// break;
-//
-// case 4:
-// mMapView.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW_BEARING);
-// break;
+ if (parent.getId() == R.id.spinner_location) {
+ switch (position) {
+ case 0:
+ mMapView.setMyLocationTrackingMode(MyLocationTracking.TRACKING_NONE);
+ break;
+
+ case 1:
+ mMapView.setMyLocationTrackingMode(MyLocationTracking.TRACKING_FOLLOW);
+ break;
+ }
+ } else if (parent.getId() == R.id.spinner_bearing) {
+ switch (position) {
+ case 0:
+ mMapView.setMyBearingTrackingMode(MyBearingTracking.NONE);
+ break;
+
+ case 1:
+ mMapView.setMyBearingTrackingMode(MyBearingTracking.GPS);
+ break;
+
+ case 2:
+ mMapView.setMyBearingTrackingMode(MyBearingTracking.COMPASS);
+ break;
+
+// case 3:
+// mMapView.setMyBearingTrackingMode(MyBearingTracking.COMBINED);
+// break;
+ }
}
}
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/icon.png b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/icon.png
index f9875161da..c9d3f3d2d0 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/icon.png
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/icon_burned.png b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/icon_burned.png
index f9875161da..c9d3f3d2d0 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/icon_burned.png
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-hdpi/icon_burned.png
Binary files differ
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/icon.png b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/icon.png
index 3c0cc701a0..235a854d71 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/icon.png
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/icon_burned.png b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/icon_burned.png
index 3c0cc701a0..235a854d71 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/icon_burned.png
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-mdpi/icon_burned.png
Binary files differ
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/icon.png b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/icon.png
index 0cbf599362..c9d3f3d2d0 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/icon.png
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/icon.png
Binary files differ
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/icon_burned.png b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/icon_burned.png
index 0cbf599362..c9d3f3d2d0 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/icon_burned.png
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xhdpi/icon_burned.png
Binary files differ
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/icon.png b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/icon.png
index 6ac3191ebf..8667ce6c44 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/icon.png
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/icon.png
Binary files differ
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/icon_burned.png b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/icon_burned.png
index 6ac3191ebf..8667ce6c44 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/icon_burned.png
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxhdpi/icon_burned.png
Binary files differ
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/icon.png b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/icon.png
index 987e6b0247..df0ca2e83d 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/icon.png
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/icon.png
Binary files differ
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/icon_burned.png b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/icon_burned.png
index 987e6b0247..df0ca2e83d 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/icon_burned.png
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/res/drawable-xxxhdpi/icon_burned.png
Binary files differ
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml b/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml
index 0a750b074c..e526faeaa6 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/activity_my_location_tracking.xml
@@ -12,10 +12,29 @@
android:background="@color/primary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
- <Spinner
- android:id="@+id/spinner"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:weightSum="2">
+
+ <Spinner
+ android:id="@+id/spinner_location"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="8dp"
+ android:layout_marginRight="8dp"
+ android:layout_weight="1" />
+
+ <Spinner
+ android:id="@+id/spinner_bearing"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="8dp"
+ android:layout_marginStart="8dp"
+ android:layout_weight="1" />
+
+ </LinearLayout>
+
</android.support.v7.widget.Toolbar>
diff --git a/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
index 6f1263dcab..6a281d01f1 100644
--- a/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
+++ b/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
@@ -54,9 +54,13 @@
<string-array name="user_tracking_mode">
<item>Disable tracking</item>
<item>Follow tracking mode</item>
- <!--<item>Bearing tracking GPS mode</item>-->
- <!--<item>Bearing tracking Compass mode</item>-->
- <!--<item>Bearing tracking mode</item>-->
+ </string-array>
+
+ <string-array name="user_bearing_mode">
+ <item>Disable bearing</item>
+ <item>GPS mode</item>
+ <item>Compass mode</item>
+ <!--<item>Combined mode</item>-->
</string-array>
</resources>