diff options
Diffstat (limited to 'platform/android/MapboxGLAndroidSDK/src/main/java')
93 files changed, 4349 insertions, 3978 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java index 9d20e968c8..f954073974 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/Mapbox.java @@ -8,8 +8,11 @@ import android.text.TextUtils; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.exceptions.InvalidAccessTokenException; +import com.mapbox.mapboxsdk.location.LocationSource; import com.mapbox.mapboxsdk.net.ConnectivityReceiver; -import com.mapbox.mapboxsdk.telemetry.MapboxEventManager; +import com.mapbox.services.android.telemetry.MapboxTelemetry; +import com.mapbox.services.android.telemetry.location.LocationEngine; +import com.mapbox.services.android.telemetry.location.LocationEnginePriority; public final class Mapbox { @@ -32,7 +35,9 @@ public final class Mapbox { if (INSTANCE == null) { Context appContext = context.getApplicationContext(); INSTANCE = new Mapbox(appContext, accessToken); - MapboxEventManager.getMapboxEventManager().initialize(appContext, accessToken); + LocationEngine locationEngine = new LocationSource(appContext); + locationEngine.setPriority(LocationEnginePriority.NO_POWER); + MapboxTelemetry.getInstance().initialize(appContext, accessToken, locationEngine); ConnectivityReceiver.instance(appContext); } return INSTANCE; @@ -101,4 +106,4 @@ public final class Mapbox { NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); return (activeNetwork != null && activeNetwork.isConnected()); } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/ArrowDirection.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/ArrowDirection.java new file mode 100644 index 0000000000..2fe5f8f420 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/ArrowDirection.java @@ -0,0 +1,30 @@ +package com.mapbox.mapboxsdk.annotations; + +import android.support.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +class ArrowDirection { + @IntDef( {LEFT, RIGHT, TOP, BOTTOM}) + @Retention(RetentionPolicy.SOURCE) + @interface Value { + } + + static final int LEFT = 0; + static final int RIGHT = 1; + static final int TOP = 2; + static final int BOTTOM = 3; + + @Value + private final int value; + + ArrowDirection(@Value int value) { + this.value = value; + } + + @Value + public int getValue() { + return value; + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Bubble.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Bubble.java new file mode 100644 index 0000000000..6fad249780 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Bubble.java @@ -0,0 +1,311 @@ +package com.mapbox.mapboxsdk.annotations; + +import android.graphics.Canvas; +import android.graphics.ColorFilter; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.RectF; +import android.graphics.drawable.Drawable; + +class Bubble extends Drawable { + + private RectF rect; + private float arrowWidth; + private float arrowHeight; + private float arrowPosition; + private float cornersRadius; + private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); + private float strokeWidth; + private Paint strokePaint; + private Path strokePath; + private Path path = new Path(); + + Bubble(RectF rect, ArrowDirection arrowDirection, float arrowWidth, float arrowHeight, float arrowPosition, + float cornersRadius, int bubbleColor, float strokeWidth, int strokeColor) { + this.rect = rect; + this.arrowWidth = arrowWidth; + this.arrowHeight = arrowHeight; + this.arrowPosition = arrowPosition; + this.cornersRadius = cornersRadius; + paint.setColor(bubbleColor); + this.strokeWidth = strokeWidth; + + if (strokeWidth > 0) { + strokePaint = new Paint(Paint.ANTI_ALIAS_FLAG); + strokePaint.setColor(strokeColor); + strokePath = new Path(); + initPath(arrowDirection, path, strokeWidth); + initPath(arrowDirection, strokePath, 0); + } else { + initPath(arrowDirection, path, 0); + } + } + + @Override + protected void onBoundsChange(Rect bounds) { + super.onBoundsChange(bounds); + } + + @Override + public void draw(Canvas canvas) { + if (strokeWidth > 0) { + canvas.drawPath(strokePath, strokePaint); + } + canvas.drawPath(path, paint); + } + + @Override + public int getOpacity() { + return PixelFormat.TRANSLUCENT; + } + + @Override + public void setAlpha(int alpha) { + paint.setAlpha(alpha); + } + + @Override + public void setColorFilter(ColorFilter cf) { + paint.setColorFilter(cf); + } + + @Override + public int getIntrinsicWidth() { + return (int) rect.width(); + } + + @Override + public int getIntrinsicHeight() { + return (int) rect.height(); + } + + private void initPath(ArrowDirection arrowDirection, Path path, float strokeWidth) { + switch (arrowDirection.getValue()) { + case ArrowDirection.LEFT: + if (cornersRadius <= 0) { + initLeftSquarePath(rect, path, strokeWidth); + break; + } + + if (strokeWidth > 0 && strokeWidth > cornersRadius) { + initLeftSquarePath(rect, path, strokeWidth); + break; + } + + initLeftRoundedPath(rect, path, strokeWidth); + break; + case ArrowDirection.TOP: + if (cornersRadius <= 0) { + initTopSquarePath(rect, path, strokeWidth); + break; + } + + if (strokeWidth > 0 && strokeWidth > cornersRadius) { + initTopSquarePath(rect, path, strokeWidth); + break; + } + + initTopRoundedPath(rect, path, strokeWidth); + break; + case ArrowDirection.RIGHT: + if (cornersRadius <= 0) { + initRightSquarePath(rect, path, strokeWidth); + break; + } + + if (strokeWidth > 0 && strokeWidth > cornersRadius) { + initRightSquarePath(rect, path, strokeWidth); + break; + } + + initRightRoundedPath(rect, path, strokeWidth); + break; + case ArrowDirection.BOTTOM: + if (cornersRadius <= 0) { + initBottomSquarePath(rect, path, strokeWidth); + break; + } + + if (strokeWidth > 0 && strokeWidth > cornersRadius) { + initBottomSquarePath(rect, path, strokeWidth); + break; + } + + initBottomRoundedPath(rect, path, strokeWidth); + break; + } + } + + private void initLeftSquarePath(RectF rect, Path path, float strokeWidth) { + path.moveTo(arrowWidth + rect.left + strokeWidth, rect.top + strokeWidth); + path.lineTo(rect.width() - strokeWidth, rect.top + strokeWidth); + + path.lineTo(rect.right - strokeWidth, rect.bottom - strokeWidth); + + path.lineTo(rect.left + arrowWidth + strokeWidth, rect.bottom - strokeWidth); + + path.lineTo(rect.left + arrowWidth + strokeWidth, arrowHeight + arrowPosition - (strokeWidth / 2)); + path.lineTo(rect.left + strokeWidth + strokeWidth, arrowPosition + arrowHeight / 2); + path.lineTo(rect.left + arrowWidth + strokeWidth, arrowPosition + (strokeWidth / 2)); + + path.lineTo(rect.left + arrowWidth + strokeWidth, rect.top + strokeWidth); + + path.close(); + } + + private void initLeftRoundedPath(RectF rect, Path path, float strokeWidth) { + path.moveTo(arrowWidth + rect.left + cornersRadius + strokeWidth, rect.top + strokeWidth); + path.lineTo(rect.width() - cornersRadius - strokeWidth, rect.top + strokeWidth); + path.arcTo(new RectF(rect.right - cornersRadius, rect.top + strokeWidth, rect.right - strokeWidth, + cornersRadius + rect.top), 270, 90); + + path.lineTo(rect.right - strokeWidth, rect.bottom - cornersRadius - strokeWidth); + path.arcTo(new RectF(rect.right - cornersRadius, rect.bottom - cornersRadius, + rect.right - strokeWidth, rect.bottom - strokeWidth), 0, 90); + + path.lineTo(rect.left + arrowWidth + cornersRadius + strokeWidth, rect.bottom - strokeWidth); + + path.arcTo(new RectF(rect.left + arrowWidth + strokeWidth, rect.bottom - cornersRadius, + cornersRadius + rect.left + arrowWidth, rect.bottom - strokeWidth), 90, 90); + + path.lineTo(rect.left + arrowWidth + strokeWidth, arrowHeight + arrowPosition - (strokeWidth / 2)); + + path.lineTo(rect.left + strokeWidth + strokeWidth, arrowPosition + arrowHeight / 2); + + path.lineTo(rect.left + arrowWidth + strokeWidth, arrowPosition + (strokeWidth / 2)); + + path.lineTo(rect.left + arrowWidth + strokeWidth, rect.top + cornersRadius + strokeWidth); + + path.arcTo(new RectF(rect.left + arrowWidth + strokeWidth, rect.top + strokeWidth, cornersRadius + + rect.left + arrowWidth, cornersRadius + rect.top), 180, 90); + + path.close(); + } + + private void initTopSquarePath(RectF rect, Path path, float strokeWidth) { + path.moveTo(rect.left + arrowPosition + strokeWidth, rect.top + arrowHeight + strokeWidth); + + path.lineTo(rect.left + arrowPosition + (strokeWidth / 2), rect.top + arrowHeight + strokeWidth); + path.lineTo(rect.left + arrowWidth / 2 + arrowPosition, rect.top + strokeWidth + strokeWidth); + path.lineTo(rect.left + arrowWidth + arrowPosition - (strokeWidth / 2), rect.top + arrowHeight + strokeWidth); + path.lineTo(rect.right - strokeWidth, rect.top + arrowHeight + strokeWidth); + + path.lineTo(rect.right - strokeWidth, rect.bottom - strokeWidth); + + path.lineTo(rect.left + strokeWidth, rect.bottom - strokeWidth); + + path.lineTo(rect.left + strokeWidth, rect.top + arrowHeight + strokeWidth); + + path.lineTo(rect.left + arrowPosition + strokeWidth, rect.top + arrowHeight + strokeWidth); + + path.close(); + } + + private void initTopRoundedPath(RectF rect, Path path, float strokeWidth) { + path.moveTo(rect.left + Math.min(arrowPosition, cornersRadius) + strokeWidth, rect.top + arrowHeight + + strokeWidth); + path.lineTo(rect.left + arrowPosition + (strokeWidth / 2), rect.top + arrowHeight + strokeWidth); + path.lineTo(rect.left + arrowWidth / 2 + arrowPosition, rect.top + strokeWidth + strokeWidth); + path.lineTo(rect.left + arrowWidth + arrowPosition - (strokeWidth / 2), rect.top + arrowHeight + strokeWidth); + path.lineTo(rect.right - cornersRadius - strokeWidth, rect.top + arrowHeight + strokeWidth); + + path.arcTo(new RectF(rect.right - cornersRadius, + rect.top + arrowHeight + strokeWidth, rect.right - strokeWidth, cornersRadius + rect.top + arrowHeight), + 270, 90); + path.lineTo(rect.right - strokeWidth, rect.bottom - cornersRadius - strokeWidth); + + path.arcTo(new RectF(rect.right - cornersRadius, rect.bottom - cornersRadius, + rect.right - strokeWidth, rect.bottom - strokeWidth), 0, 90); + path.lineTo(rect.left + cornersRadius + strokeWidth, rect.bottom - strokeWidth); + + path.arcTo(new RectF(rect.left + strokeWidth, rect.bottom - cornersRadius, + cornersRadius + rect.left, rect.bottom - strokeWidth), 90, 90); + + path.lineTo(rect.left + strokeWidth, rect.top + arrowHeight + cornersRadius + strokeWidth); + + path.arcTo(new RectF(rect.left + strokeWidth, rect.top + arrowHeight + strokeWidth, cornersRadius + + rect.left, cornersRadius + rect.top + arrowHeight), 180, 90); + + path.close(); + } + + private void initRightSquarePath(RectF rect, Path path, float strokeWidth) { + path.moveTo(rect.left + strokeWidth, rect.top + strokeWidth); + path.lineTo(rect.width() - arrowWidth - strokeWidth, rect.top + strokeWidth); + + path.lineTo(rect.right - arrowWidth - strokeWidth, arrowPosition + (strokeWidth / 2)); + path.lineTo(rect.right - strokeWidth - strokeWidth, arrowPosition + arrowHeight / 2); + path.lineTo(rect.right - arrowWidth - strokeWidth, arrowPosition + arrowHeight - (strokeWidth / 2)); + + path.lineTo(rect.right - arrowWidth - strokeWidth, rect.bottom - strokeWidth); + + path.lineTo(rect.left + strokeWidth, rect.bottom - strokeWidth); + path.lineTo(rect.left + strokeWidth, rect.top + strokeWidth); + + path.close(); + } + + private void initRightRoundedPath(RectF rect, Path path, float strokeWidth) { + path.moveTo(rect.left + cornersRadius + strokeWidth, rect.top + strokeWidth); + path.lineTo(rect.width() - cornersRadius - arrowWidth - strokeWidth, rect.top + strokeWidth); + path.arcTo(new RectF(rect.right - cornersRadius - arrowWidth, + rect.top + strokeWidth, rect.right - arrowWidth - strokeWidth, cornersRadius + rect.top), 270, 90); + + path.lineTo(rect.right - arrowWidth - strokeWidth, arrowPosition + (strokeWidth / 2)); + path.lineTo(rect.right - strokeWidth - strokeWidth, arrowPosition + arrowHeight / 2); + path.lineTo(rect.right - arrowWidth - strokeWidth, arrowPosition + arrowHeight - (strokeWidth / 2)); + path.lineTo(rect.right - arrowWidth - strokeWidth, rect.bottom - cornersRadius - strokeWidth); + + path.arcTo(new RectF(rect.right - cornersRadius - arrowWidth, rect.bottom - cornersRadius, + rect.right - arrowWidth - strokeWidth, rect.bottom - strokeWidth), 0, 90); + path.lineTo(rect.left + arrowWidth + strokeWidth, rect.bottom - strokeWidth); + + path.arcTo(new RectF(rect.left + strokeWidth, rect.bottom - cornersRadius, + cornersRadius + rect.left, rect.bottom - strokeWidth), 90, 90); + + path.arcTo(new RectF(rect.left + strokeWidth, rect.top + strokeWidth, cornersRadius + + rect.left, cornersRadius + rect.top), 180, 90); + path.close(); + } + + private void initBottomSquarePath(RectF rect, Path path, float strokeWidth) { + path.moveTo(rect.left + strokeWidth, rect.top + strokeWidth); + path.lineTo(rect.right - strokeWidth, rect.top + strokeWidth); + path.lineTo(rect.right - strokeWidth, rect.bottom - arrowHeight - strokeWidth); + + path.lineTo(rect.left + arrowWidth + arrowPosition - (strokeWidth / 2), rect.bottom - arrowHeight - strokeWidth); + path.lineTo(rect.left + arrowPosition + arrowWidth / 2, rect.bottom - strokeWidth - strokeWidth); + path.lineTo(rect.left + arrowPosition + (strokeWidth / 2), rect.bottom - arrowHeight - strokeWidth); + path.lineTo(rect.left + arrowPosition + strokeWidth, rect.bottom - arrowHeight - strokeWidth); + + path.lineTo(rect.left + strokeWidth, rect.bottom - arrowHeight - strokeWidth); + path.lineTo(rect.left + strokeWidth, rect.top + strokeWidth); + path.close(); + } + + private void initBottomRoundedPath(RectF rect, Path path, float strokeWidth) { + path.moveTo(rect.left + cornersRadius + strokeWidth, rect.top + strokeWidth); + path.lineTo(rect.width() - cornersRadius - strokeWidth, rect.top + strokeWidth); + path.arcTo(new RectF(rect.right - cornersRadius, + rect.top + strokeWidth, rect.right - strokeWidth, cornersRadius + rect.top), 270, 90); + + path.lineTo(rect.right - strokeWidth, rect.bottom - arrowHeight - cornersRadius - strokeWidth); + path.arcTo(new RectF(rect.right - cornersRadius, rect.bottom - cornersRadius - arrowHeight, + rect.right - strokeWidth, rect.bottom - arrowHeight - strokeWidth), 0, 90); + + path.lineTo(rect.left + arrowWidth + arrowPosition - (strokeWidth / 2), rect.bottom - arrowHeight - strokeWidth); + path.lineTo(rect.left + arrowPosition + arrowWidth / 2, rect.bottom - strokeWidth - strokeWidth); + path.lineTo(rect.left + arrowPosition + (strokeWidth / 2), rect.bottom - arrowHeight - strokeWidth); + path.lineTo(rect.left + Math.min(cornersRadius, arrowPosition) + strokeWidth, rect.bottom - arrowHeight + - strokeWidth); + + path.arcTo(new RectF(rect.left + strokeWidth, rect.bottom - cornersRadius - arrowHeight, + cornersRadius + rect.left, rect.bottom - arrowHeight - strokeWidth), 90, 90); + path.lineTo(rect.left + strokeWidth, rect.top + cornersRadius + strokeWidth); + path.arcTo(new RectF(rect.left + strokeWidth, rect.top + strokeWidth, cornersRadius + + rect.left, cornersRadius + rect.top), 180, 90); + path.close(); + } +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BubbleLayout.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BubbleLayout.java new file mode 100644 index 0000000000..2e6445170f --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BubbleLayout.java @@ -0,0 +1,231 @@ +package com.mapbox.mapboxsdk.annotations; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.RectF; +import android.util.AttributeSet; +import android.util.DisplayMetrics; +import android.widget.LinearLayout; + +import com.mapbox.mapboxsdk.R; + +/** + * Bubble View for Android with custom stroke width and color, arrow size, position and direction. + */ +class BubbleLayout extends LinearLayout { + + public static final float DEFAULT_STROKE_WIDTH = -1; + private ArrowDirection arrowDirection; + private float arrowWidth; + private float arrowHeight; + private float arrowPosition; + private float cornersRadius; + private Bubble bubble; + private int bubbleColor; + private float strokeWidth; + private int strokeColor; + + public BubbleLayout(Context context) { + this(context, null, 0); + } + + public BubbleLayout(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public BubbleLayout(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.mapbox_BubbleLayout); + @ArrowDirection.Value + int location = a.getInt(R.styleable.mapbox_BubbleLayout_mapbox_bl_arrowDirection, + ArrowDirection.LEFT); + arrowDirection = new ArrowDirection(location); + arrowWidth = a.getDimension(R.styleable.mapbox_BubbleLayout_mapbox_bl_arrowWidth, + convertDpToPixel(8, context)); + arrowHeight = a.getDimension(R.styleable.mapbox_BubbleLayout_mapbox_bl_arrowHeight, + convertDpToPixel(8, context)); + arrowPosition = a.getDimension(R.styleable.mapbox_BubbleLayout_mapbox_bl_arrowPosition, + convertDpToPixel(12, context)); + cornersRadius = a.getDimension(R.styleable.mapbox_BubbleLayout_mapbox_bl_cornersRadius, 0); + bubbleColor = a.getColor(R.styleable.mapbox_BubbleLayout_mapbox_bl_bubbleColor, Color.WHITE); + strokeWidth = + a.getDimension(R.styleable.mapbox_BubbleLayout_mapbox_bl_strokeWidth, DEFAULT_STROKE_WIDTH); + strokeColor = a.getColor(R.styleable.mapbox_BubbleLayout_mapbox_bl_strokeColor, Color.GRAY); + + a.recycle(); + initPadding(); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + initDrawable(0, getWidth(), 0, getHeight()); + } + + @Override + protected void dispatchDraw(Canvas canvas) { + if (bubble != null) { + bubble.draw(canvas); + } + super.dispatchDraw(canvas); + } + + static float convertDpToPixel(float dp, Context context) { + DisplayMetrics metrics = context.getResources().getDisplayMetrics(); + return dp * (metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT); + } + + public ArrowDirection getArrowDirection() { + return arrowDirection; + } + + public BubbleLayout setArrowDirection(ArrowDirection arrowDirection) { + resetPadding(); + this.arrowDirection = arrowDirection; + initPadding(); + return this; + } + + public float getArrowWidth() { + return arrowWidth; + } + + public BubbleLayout setArrowWidth(float arrowWidth) { + resetPadding(); + this.arrowWidth = arrowWidth; + initPadding(); + return this; + } + + public float getArrowHeight() { + return arrowHeight; + } + + public BubbleLayout setArrowHeight(float arrowHeight) { + resetPadding(); + this.arrowHeight = arrowHeight; + initPadding(); + return this; + } + + public float getArrowPosition() { + return arrowPosition; + } + + public BubbleLayout setArrowPosition(float arrowPosition) { + resetPadding(); + this.arrowPosition = arrowPosition; + initPadding(); + return this; + } + + public float getCornersRadius() { + return cornersRadius; + } + + public BubbleLayout setCornersRadius(float cornersRadius) { + this.cornersRadius = cornersRadius; + requestLayout(); + return this; + } + + public int getBubbleColor() { + return bubbleColor; + } + + public BubbleLayout setBubbleColor(int bubbleColor) { + this.bubbleColor = bubbleColor; + requestLayout(); + return this; + } + + public float getStrokeWidth() { + return strokeWidth; + } + + public BubbleLayout setStrokeWidth(float strokeWidth) { + resetPadding(); + this.strokeWidth = strokeWidth; + initPadding(); + return this; + } + + public int getStrokeColor() { + return strokeColor; + } + + public BubbleLayout setStrokeColor(int strokeColor) { + this.strokeColor = strokeColor; + requestLayout(); + return this; + } + + private void initPadding() { + int paddingLeft = getPaddingLeft(); + int paddingRight = getPaddingRight(); + int paddingTop = getPaddingTop(); + int paddingBottom = getPaddingBottom(); + switch (arrowDirection.getValue()) { + case ArrowDirection.LEFT: + paddingLeft += arrowWidth; + break; + case ArrowDirection.RIGHT: + paddingRight += arrowWidth; + break; + case ArrowDirection.TOP: + paddingTop += arrowHeight; + break; + case ArrowDirection.BOTTOM: + paddingBottom += arrowHeight; + break; + } + if (strokeWidth > 0) { + paddingLeft += strokeWidth; + paddingRight += strokeWidth; + paddingTop += strokeWidth; + paddingBottom += strokeWidth; + } + setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); + } + + private void initDrawable(int left, int right, int top, int bottom) { + if (right < left || bottom < top) { + return; + } + + RectF rectF = new RectF(left, top, right, bottom); + bubble = new Bubble(rectF, arrowDirection, arrowWidth, arrowHeight, arrowPosition, cornersRadius, + bubbleColor, strokeWidth, strokeColor); + } + + private void resetPadding() { + int paddingLeft = getPaddingLeft(); + int paddingRight = getPaddingRight(); + int paddingTop = getPaddingTop(); + int paddingBottom = getPaddingBottom(); + switch (arrowDirection.getValue()) { + case ArrowDirection.LEFT: + paddingLeft -= arrowWidth; + break; + case ArrowDirection.RIGHT: + paddingRight -= arrowWidth; + break; + case ArrowDirection.TOP: + paddingTop -= arrowHeight; + break; + case ArrowDirection.BOTTOM: + paddingBottom -= arrowHeight; + break; + } + if (strokeWidth > 0) { + paddingLeft -= strokeWidth; + paddingRight -= strokeWidth; + paddingTop -= strokeWidth; + paddingBottom -= strokeWidth; + } + setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom); + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BubblePopupHelper.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BubblePopupHelper.java new file mode 100644 index 0000000000..215445abaa --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BubblePopupHelper.java @@ -0,0 +1,33 @@ +package com.mapbox.mapboxsdk.annotations; + +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.support.annotation.NonNull; +import android.view.ViewGroup; +import android.widget.PopupWindow; + +import com.mapbox.mapboxsdk.R; + +class BubblePopupHelper { + + static PopupWindow create(@NonNull Context context, @NonNull BubbleLayout bubbleLayout) { + PopupWindow popupWindow = new PopupWindow(context); + + popupWindow.setContentView(bubbleLayout); + popupWindow.setOutsideTouchable(true); + popupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT); + popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT); + popupWindow.setAnimationStyle(android.R.style.Animation_Dialog); + // change background color to transparent + Drawable drawable; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + drawable = context.getDrawable(R.drawable.mapbox_popup_window_transparent); + } else { + drawable = context.getResources().getDrawable(R.drawable.mapbox_popup_window_transparent); + } + popupWindow.setBackgroundDrawable(drawable); + + return popupWindow; + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java index 052d5592e4..57aa512401 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/IconFactory.java @@ -3,8 +3,6 @@ package com.mapbox.mapboxsdk.annotations; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; -import android.graphics.Canvas; -import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.Build; @@ -23,7 +21,10 @@ import java.io.IOException; import java.io.InputStream; /** - * Factory for creating {@link Icon} objects. + * Factory for creating Icons from bitmap images. + * <p> + * {@link Icon} is used to display bitmaps on top of the map using {@link Marker} and {@link MarkerView}. + * </p> * * @see Icon */ @@ -33,23 +34,23 @@ public final class IconFactory { public static final Bitmap ICON_MARKERVIEW_BITMAP = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8); public static final String ICON_MARKERVIEW_ID = ICON_ID_PREFIX + "marker_view"; - private Context mContext; - private static IconFactory sInstance; - private Icon mDefaultMarker; - private Icon mDefaultMarkerView; - private BitmapFactory.Options mOptions; + private Context context; + private static IconFactory instance; + private Icon defaultMarker; + private Icon defaultMarkerView; + private BitmapFactory.Options options; - private int mNextId = 0; + private int nextId = 0; public static synchronized IconFactory getInstance(@NonNull Context context) { - if (sInstance == null) { - sInstance = new IconFactory(context.getApplicationContext()); + if (instance == null) { + instance = new IconFactory(context.getApplicationContext()); } - return sInstance; + return instance; } private IconFactory(@NonNull Context context) { - mContext = context; + this.context = context; DisplayMetrics realMetrics = null; DisplayMetrics metrics = new DisplayMetrics(); WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); @@ -60,12 +61,12 @@ public final class IconFactory { } wm.getDefaultDisplay().getMetrics(metrics); - mOptions = new BitmapFactory.Options(); - mOptions.inScaled = true; - mOptions.inDensity = DisplayMetrics.DENSITY_DEFAULT; - mOptions.inTargetDensity = metrics.densityDpi; + options = new BitmapFactory.Options(); + options.inScaled = true; + options.inDensity = DisplayMetrics.DENSITY_DEFAULT; + options.inTargetDensity = metrics.densityDpi; if (realMetrics != null) { - mOptions.inScreenDensity = realMetrics.densityDpi; + options.inScreenDensity = realMetrics.densityDpi; } } @@ -76,73 +77,27 @@ public final class IconFactory { * @return The {@link Icon} using the given Bitmap image. */ public Icon fromBitmap(@NonNull Bitmap bitmap) { - if (mNextId < 0) { + if (nextId < 0) { throw new TooManyIconsException(); } - String id = ICON_ID_PREFIX + ++mNextId; + String id = ICON_ID_PREFIX + ++nextId; return new Icon(id, bitmap); } /** - * Create an {@link Icon} from a given {@link Drawable}. - * - * @param drawable A {@link Drawable} object used for creating the {@link Icon}. - * @return {@link Icon} with the provided {@link Drawable}. - */ - public Icon fromDrawable(@NonNull Drawable drawable) { - int width = drawable.getIntrinsicWidth(); - int height = drawable.getIntrinsicHeight(); - return fromDrawable(drawable, width, height); - } - - /** - * Create an {@link Icon} from a given {@link Drawable}. - * - * @param drawable A {@link Drawable} object used for creating the {@link Icon}. - * @param width An integer greater then zero defining the {@link Icon} width. - * @param height An integer greater then zero defining the {@link Icon} height. - * @return {@link Icon} with the provided {@link Drawable}. - */ - public Icon fromDrawable(@NonNull Drawable drawable, int width, int height) { - if ((width < 0) || (height < 0)) { - return null; - } - - Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); - Rect temp = drawable.getBounds(); - Rect bounds = new Rect(0, 0, width, height); - drawable.setBounds(bounds); - drawable.draw(canvas); - drawable.setBounds(temp); - return fromBitmap(bitmap); - } - - /** * Create an {@link Icon} using the resource ID of a Bitmap image. * * @param resourceId The resource ID of a Bitmap image. * @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load. */ public Icon fromResource(@DrawableRes int resourceId) { - Drawable drawable = ContextCompat.getDrawable(mContext, resourceId); - Bitmap bitmap; + Drawable drawable = ContextCompat.getDrawable(context, resourceId); if (drawable instanceof BitmapDrawable) { BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; - bitmap = bitmapDrawable.getBitmap(); + return fromBitmap(bitmapDrawable.getBitmap()); } else { - if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) { - bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); - } else { - bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), - Bitmap.Config.ARGB_8888); - } - - Canvas canvas = new Canvas(bitmap); - drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); - drawable.draw(canvas); + throw new IllegalArgumentException("Failed to decode image. The resource provided must be a Bitmap."); } - return fromBitmap(bitmap); } /** @@ -151,10 +106,10 @@ public final class IconFactory { * @return An {@link Icon} with the default {@link Marker} icon. */ public Icon defaultMarker() { - if (mDefaultMarker == null) { - mDefaultMarker = fromResource(R.drawable.mapbox_marker_icon_default); + if (defaultMarker == null) { + defaultMarker = fromResource(R.drawable.mapbox_marker_icon_default); } - return mDefaultMarker; + return defaultMarker; } /** @@ -163,14 +118,14 @@ public final class IconFactory { * @return An {@link Icon} with the default {@link MarkerView} icon. */ public Icon defaultMarkerView() { - if (mDefaultMarkerView == null) { - mDefaultMarkerView = fromResource(R.drawable.mapbox_markerview_icon_default); + if (defaultMarkerView == null) { + defaultMarkerView = fromResource(R.drawable.mapbox_markerview_icon_default); } - return mDefaultMarkerView; + return defaultMarkerView; } private Icon fromInputStream(@NonNull InputStream is) { - Bitmap bitmap = BitmapFactory.decodeStream(is, null, mOptions); + Bitmap bitmap = BitmapFactory.decodeStream(is, null, options); return fromBitmap(bitmap); } @@ -183,7 +138,7 @@ public final class IconFactory { public Icon fromAsset(@NonNull String assetName) { InputStream is; try { - is = mContext.getAssets().open(assetName); + is = context.getAssets().open(assetName); } catch (IOException ioException) { return null; } @@ -198,7 +153,7 @@ public final class IconFactory { * load. */ public Icon fromPath(@NonNull String absolutePath) { - Bitmap bitmap = BitmapFactory.decodeFile(absolutePath, mOptions); + Bitmap bitmap = BitmapFactory.decodeFile(absolutePath, options); return fromBitmap(bitmap); } @@ -209,12 +164,12 @@ public final class IconFactory { * @param fileName The name of the Bitmap image file. * @return The {@link Icon} that was loaded from the asset or {@code null} if failed to load. * @see <a href="https://developer.android.com/guide/topics/data/data-storage.html#filesInternal"> - * Using the Internal Storage</a> + * Using the Internal Storage</a> */ public Icon fromFile(@NonNull String fileName) { FileInputStream is; try { - is = mContext.openFileInput(fileName); + is = context.openFileInput(fileName); } catch (FileNotFoundException fileNotFoundException) { return null; } @@ -232,4 +187,5 @@ public final class IconFactory { public static Icon recreate(@NonNull String iconId, @NonNull Bitmap bitmap) { return new Icon(iconId, bitmap); } + } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java index 4e080d98f6..cf42bfe738 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java @@ -133,7 +133,7 @@ public class InfoWindow { float x = coordinates.x - (view.getMeasuredWidth() / 2) + offsetX; float y = coordinates.y - view.getMeasuredHeight() + offsetY; - if (view instanceof InfoWindowView) { + if (view instanceof BubbleLayout) { // only apply repositioning/margin for InfoWindowView Resources resources = mapView.getContext().getResources(); @@ -187,8 +187,7 @@ public class InfoWindow { } // Adjust tipView - InfoWindowView infoWindowView = (InfoWindowView) view; - infoWindowView.setTipViewMarginLeft((int) tipViewMarginLeft); + ((BubbleLayout) view).setArrowPosition(tipViewMarginLeft); } // set anchor popupwindowview @@ -198,7 +197,7 @@ public class InfoWindow { // Calculate x-offset for update method viewWidthOffset = x - coordinates.x - offsetX; - close(); //if it was already opened + close(); // if it was already opened mapView.addView(view, lp); isVisible = true; } @@ -284,7 +283,7 @@ public class InfoWindow { if (mapboxMap != null && marker != null && view != null) { coordinates = mapboxMap.getProjection().toScreenLocation(marker.getPosition()); - if (view instanceof InfoWindowView) { + if (view instanceof BubbleLayout) { view.setX(coordinates.x + viewWidthOffset - markerWidthOffset); } else { view.setX(coordinates.x - (view.getMeasuredWidth() / 2) - markerWidthOffset); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowTipView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowTipView.java deleted file mode 100644 index abcebfec83..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowTipView.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.mapbox.mapboxsdk.annotations; - -import android.content.Context; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Path; -import android.util.AttributeSet; -import android.view.View; - -import com.mapbox.mapboxsdk.R; - -final class InfoWindowTipView extends View { - - private Paint mPaint; - private Path mPath; - private int mLineWidth; - - public InfoWindowTipView(Context context, AttributeSet attrs) { - super(context, attrs); - - mPath = new Path(); - mLineWidth = (int) context.getResources().getDimension(R.dimen.mapbox_infowindow_line_width); - mPaint = new Paint(); - mPaint.setColor(Color.WHITE); - mPaint.setAntiAlias(true); - mPaint.setStrokeWidth(0.0f); - mPaint.setStyle(Paint.Style.FILL); - } - - @Override - protected void onDraw(Canvas canvas) { - super.onDraw(canvas); - int height = getMeasuredHeight(); - int width = getMeasuredWidth(); - - mPath.rewind(); - - this.mPaint.setColor(Color.WHITE); - this.mPaint.setAntiAlias(true); - this.mPaint.setStrokeWidth(0.0f); - this.mPaint.setStyle(Paint.Style.FILL); - - mPath.moveTo(0, 0); - mPath.lineTo(width, 0); - mPath.lineTo((width / 2), height); - mPath.lineTo(0, 0); - canvas.drawPath(mPath, this.mPaint); - - mPath.rewind(); - - this.mPaint.setColor(Color.parseColor("#C2C2C2")); - this.mPaint.setAntiAlias(true); - this.mPaint.setStrokeWidth(mLineWidth); - this.mPaint.setStyle(Paint.Style.STROKE); - - mPath.moveTo(0, 0); - mPath.lineTo(width / 2, height); - mPath.lineTo(width, 0); - canvas.drawPath(mPath, this.mPaint); - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowView.java deleted file mode 100644 index d1a59aae4e..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindowView.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.mapbox.mapboxsdk.annotations; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.widget.RelativeLayout; - -import com.mapbox.mapboxsdk.R; - -class InfoWindowView extends RelativeLayout { - - private InfoWindowTipView mTipView; - - public InfoWindowView(Context context) { - this(context, null); - } - - public InfoWindowView(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public InfoWindowView(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - initialize(context); - } - - private void initialize(Context context) { - LayoutInflater.from(context).inflate(R.layout.mapbox_infowindow_content, this); - mTipView = (InfoWindowTipView) findViewById(R.id.infowindow_tipview); - } - - void setTipViewMarginLeft(int marginLeft) { - RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) mTipView.getLayoutParams(); - layoutParams.leftMargin = marginLeft; - // This is a bit of a hack but prevents an occasional gap between the InfoWindow - layoutParams.topMargin = (int) getResources().getDimension(R.dimen.mapbox_infowindow_offset); - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java index edf118205b..18f74cd990 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java @@ -30,6 +30,8 @@ public class Marker extends Annotation { private LatLng position; private String snippet; private Icon icon; + //Redundantly stored for JNI access + private String iconId; private String title; private InfoWindow infoWindow; @@ -51,24 +53,19 @@ public class Marker extends Annotation { * @param baseMarkerOptions The builder used to construct the Marker. */ public Marker(BaseMarkerOptions baseMarkerOptions) { - position = baseMarkerOptions.position; - snippet = baseMarkerOptions.snippet; - icon = baseMarkerOptions.icon; - title = baseMarkerOptions.title; + this(baseMarkerOptions.position, baseMarkerOptions.icon, baseMarkerOptions.title, baseMarkerOptions.snippet); } Marker(BaseMarkerViewOptions baseMarkerViewOptions) { - position = baseMarkerViewOptions.position; - snippet = baseMarkerViewOptions.snippet; - icon = baseMarkerViewOptions.icon; - title = baseMarkerViewOptions.title; + this(baseMarkerViewOptions.position, baseMarkerViewOptions.icon, + baseMarkerViewOptions.title, baseMarkerViewOptions.snippet); } Marker(LatLng position, Icon icon, String title, String snippet) { this.position = position; - this.icon = icon; this.title = title; this.snippet = snippet; + setIcon(icon); } /** @@ -148,6 +145,7 @@ public class Marker extends Annotation { */ public void setIcon(@Nullable Icon icon) { this.icon = icon; + this.iconId = icon != null ? icon.getId() : null; MapboxMap map = getMapboxMap(); if (map != null) { map.updateMarker(this); @@ -240,7 +238,7 @@ public class Marker extends Annotation { private InfoWindow getInfoWindow(@NonNull MapView mapView) { if (infoWindow == null && mapView.getContext() != null) { - infoWindow = new InfoWindow(mapView, R.layout.mapbox_infowindow_view, getMapboxMap()); + infoWindow = new InfoWindow(mapView, R.layout.mapbox_infowindow_content, getMapboxMap()); } return infoWindow; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java index c1b643eb4c..220d3322cb 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java @@ -266,18 +266,9 @@ public class MarkerView extends Marker { * @param rotation the rotation value to animate to. */ public void setRotation(float rotation) { - // limit to 0 - 360 degrees - float newRotation = rotation; - while (newRotation > 360) { - newRotation -= 360; - } - while (newRotation < 0) { - newRotation += 360; - } - - this.rotation = newRotation; + this.rotation = rotation; if (markerViewManager != null) { - markerViewManager.animateRotationBy(this, newRotation); + markerViewManager.setRotation(this, rotation); } } @@ -342,6 +333,7 @@ public class MarkerView extends Marker { public void setPosition(LatLng position) { super.setPosition(position); if (markerViewManager != null) { + markerViewManager.setWaitingForRenderInvoke(true); markerViewManager.update(); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java index ad221691b4..17a1866379 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java @@ -125,6 +125,14 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { } } + public void setRotation(@NonNull MarkerView marker, float rotation) { + View convertView = markerViewMap.get(marker); + if (convertView != null) { + convertView.animate().cancel(); + convertView.setRotation(rotation); + } + } + /** * Animate a MarkerView to a given alpha value. * <p> @@ -466,7 +474,6 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { if (adapter.getMarkerClass().equals(marker.getClass())) { adapter.prepareViewForReuse(marker, convertView); adapter.releaseView(convertView); - marker.setMapboxMap(null); iterator.remove(); } } @@ -573,7 +580,7 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { if (view != null) { if (marker.getWidth() == 0) { if (view.getMeasuredWidth() == 0) { - //Ensure the marker's view is measured first + // Ensure the marker's view is measured first view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); } marker.setWidth(view.getMeasuredWidth()); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java index 79045b68bb..74170bb72b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java @@ -7,9 +7,7 @@ import android.os.Parcelable; import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.utils.MathUtils; - -import static com.mapbox.mapboxsdk.utils.MathUtils.convertNativeBearing; +import com.mapbox.services.android.telemetry.utils.MathUtils; /** * Resembles the position, angle, zoom and tilt of the user's viewpoint. @@ -244,8 +242,8 @@ public final class CameraPosition implements Parcelable { public Builder(double[] nativeCameraValues) { super(); if (nativeCameraValues != null && nativeCameraValues.length == 5) { - target(new LatLng(nativeCameraValues[0], nativeCameraValues[1])); - bearing(convertNativeBearing(nativeCameraValues[2])); + target(new LatLng(nativeCameraValues[0], nativeCameraValues[1]).wrap()); + bearing(MathUtils.convertNativeBearing(nativeCameraValues[2])); tilt(nativeCameraValues[3]); zoom(nativeCameraValues[4]); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java index aecc51530b..ef8a4d58e8 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java @@ -11,7 +11,7 @@ import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.Projection; import com.mapbox.mapboxsdk.maps.UiSettings; -import com.mapbox.mapboxsdk.utils.MathUtils; +import com.mapbox.services.android.telemetry.utils.MathUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -259,7 +259,7 @@ public final class CameraUpdateFactory { float scaleX = (uiSettings.getWidth() - padding.left - padding.right) / width; float scaleY = (uiSettings.getHeight() - padding.top - padding.bottom) / height; minScale = scaleX < scaleY ? scaleX : scaleY; - zoom = calculateZoom(mapboxMap, minScale); + zoom = projection.calculateZoom(minScale); zoom = MathUtils.clamp(zoom, mapboxMap.getMinZoomLevel(), mapboxMap.getMaxZoomLevel()); } @@ -277,16 +277,6 @@ public final class CameraUpdateFactory { .bearing(0) .build(); } - - /** - * 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(MapboxMap mapboxMap, float minScale) { - return Math.log(mapboxMap.getCameraPosition().zoom * minScale) / Math.log(2); - } } static final class CameraMoveUpdate implements CameraUpdate { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeoConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeoConstants.java deleted file mode 100644 index 009ae936d5..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/GeoConstants.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.mapbox.mapboxsdk.constants; - -/** - * GeoConstants exposes constants for doing locational calculations on Earth - */ -public class GeoConstants { - - /** - * The <a href='http://en.wikipedia.org/wiki/Earth_radius#Equatorial_radius'>equatorial radius</a> - * value in meters - */ - public static final int RADIUS_EARTH_METERS = 6378137; - - /** - * The minimum latitude on Earth. This is the minimum latitude representable - * by Mapbox GL's Mercator projection, because the projection distorts latitude - * near the poles towards infinity. - */ - public static final double MIN_LATITUDE = -85.05112878; - - /** - * The maximum latitude on Earth. This is the maximum latitude representable - * by Mapbox GL's Mercator projection, because the projection distorts latitude - * near the poles towards infinity. - */ - public static final double MAX_LATITUDE = 85.05112878; - - /** - * The minimum longitude on Earth - */ - public static final double MIN_LONGITUDE = -180; - - /** - * The maximum longitude on Earth - */ - public static final double MAX_LONGITUDE = 180; - -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java index fbf307541b..0bd9523f4f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java @@ -13,16 +13,6 @@ public class MapboxConstants { public static final Locale MAPBOX_LOCALE = Locale.US; /** - * Key used to store staging data server url in AndroidManifest.xml - */ - public static final String KEY_META_DATA_STAGING_SERVER = "com.mapbox.TestEventsServer"; - - /** - * Key used to store staging data server access token in AndroidManifest.xml - */ - public static final String KEY_META_DATA_STAGING_ACCESS_TOKEN = "com.mapbox.TestEventsAccessToken"; - - /** * Key used to switch storage to external in AndroidManifest.xml */ public static final String KEY_META_DATA_SET_STORAGE_EXTERNAL = "com.mapbox.SetStorageExternal"; @@ -103,48 +93,45 @@ public class MapboxConstants { public static final String FRAG_ARG_MAPBOXMAPOPTIONS = "MapboxMapOptions"; // Save instance state keys - public static final String STATE_HAS_SAVED_STATE = "savedState"; - public static final String STATE_CAMERA_POSITION = "cameraPosition"; - public static final String STATE_ZOOM_ENABLED = "zoomEnabled"; - public static final String STATE_ZOOM_ENABLED_CHANGE = "zoomEnabledChange"; - public static final String STATE_SCROLL_ENABLED = "scrollEnabled"; - public static final String STATE_SCROLL_ENABLED_CHANGE = "scrollEnabledChange"; - public static final String STATE_ROTATE_ENABLED = "rotateEnabled"; - public static final String STATE_ROTATE_ENABLED_CHANGE = "rotateEnabledChange"; - public static final String STATE_TILT_ENABLED = "tiltEnabled"; - public static final String STATE_TILT_ENABLED_CHANGE = "tiltEnabledChange"; - public static final String STATE_ZOOM_CONTROLS_ENABLED = "zoomControlsEnabled"; - public static final String STATE_DEBUG_ACTIVE = "debugActive"; - public static final String STATE_STYLE_URL = "styleUrl"; - public static final String STATE_MY_LOCATION_ENABLED = "myLocationEnabled"; - public static final String STATE_MY_LOCATION_TRACKING_MODE = "myLocationTracking"; - public static final String STATE_MY_BEARING_TRACKING_MODE = "myBearingTracking"; - public static final String STATE_MY_LOCATION_TRACKING_DISMISS = "myLocationTrackingDismiss"; - public static final String STATE_MY_BEARING_TRACKING_DISMISS = "myBearingTrackingDismiss"; - public static final String STATE_COMPASS_ENABLED = "compassEnabled"; - public static final String STATE_COMPASS_GRAVITY = "compassGravity"; - public static final String STATE_COMPASS_MARGIN_LEFT = "compassMarginLeft"; - public static final String STATE_COMPASS_MARGIN_TOP = "compassMarginTop"; - public static final String STATE_COMPASS_MARGIN_RIGHT = "compassMarginRight"; - public static final String STATE_COMPASS_MARGIN_BOTTOM = "compassMarginBottom"; - public static final String STATE_COMPASS_FADE_WHEN_FACING_NORTH = "compassFade"; - public static final String STATE_LOGO_GRAVITY = "logoGravity"; - public static final String STATE_LOGO_MARGIN_LEFT = "logoMarginLeft"; - public static final String STATE_LOGO_MARGIN_TOP = "logoMarginTop"; - public static final String STATE_LOGO_MARGIN_RIGHT = "logoMarginRight"; - public static final String STATE_LOGO_MARGIN_BOTTOM = "logoMarginBottom"; - public static final String STATE_LOGO_ENABLED = "logoEnabled"; - public static final String STATE_ATTRIBUTION_GRAVITY = "attrGravity"; - public static final String STATE_ATTRIBUTION_MARGIN_LEFT = "attrMarginLeft"; - public static final String STATE_ATTRIBUTION_MARGIN_TOP = "attrMarginTop"; - public static final String STATE_ATTRIBUTION_MARGIN_RIGHT = "attrMarginRight"; - public static final String STATE_ATTRIBUTION_MARGIN_BOTTOM = "atrrMarginBottom"; - public static final String STATE_ATTRIBUTION_ENABLED = "atrrEnabled"; - - public static final String MAPBOX_SHARED_PREFERENCES_FILE = "MapboxSharedPreferences"; - public static final String MAPBOX_SHARED_PREFERENCE_KEY_VENDORID = "mapboxVendorId"; - public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED = "mapboxTelemetryEnabled"; - public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_URL = "mapboxTelemetryStagingUrl"; - public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_ACCESS_TOKEN = - "mapboxTelemetryStagingAccessToken"; + public static final String STATE_HAS_SAVED_STATE = "mapbox_savedState"; + public static final String STATE_CAMERA_POSITION = "mapbox_cameraPosition"; + public static final String STATE_ZOOM_ENABLED = "mapbox_zoomEnabled"; + public static final String STATE_ZOOM_ENABLED_CHANGE = "mapbox_zoomEnabledChange"; + public static final String STATE_SCROLL_ENABLED = "mapbox_scrollEnabled"; + public static final String STATE_SCROLL_ENABLED_CHANGE = "mapbox_scrollEnabledChange"; + public static final String STATE_ROTATE_ENABLED = "mapbox_rotateEnabled"; + public static final String STATE_ROTATE_ENABLED_CHANGE = "mapbox_rotateEnabledChange"; + public static final String STATE_TILT_ENABLED = "mapbox_tiltEnabled"; + public static final String STATE_TILT_ENABLED_CHANGE = "mapbox_tiltEnabledChange"; + public static final String STATE_ZOOM_CONTROLS_ENABLED = "mapbox_zoomControlsEnabled"; + public static final String STATE_DOUBLE_TAP_ENABLED = "mapbox_doubleTapEnabled"; + public static final String STATE_DOUBLE_TAP_ENABLED_CHANGE = "mapbox_doubleTapEnabledChange"; + public static final String STATE_DEBUG_ACTIVE = "mapbox_debugActive"; + public static final String STATE_STYLE_URL = "mapbox_styleUrl"; + public static final String STATE_MY_LOCATION_ENABLED = "mapbox_myLocationEnabled"; + public static final String STATE_MY_LOCATION_TRACKING_MODE = "mapbox_myLocationTracking"; + public static final String STATE_MY_BEARING_TRACKING_MODE = "mapbox_myBearingTracking"; + public static final String STATE_MY_LOCATION_TRACKING_DISMISS = "mapbox_myLocationTrackingDismiss"; + public static final String STATE_MY_BEARING_TRACKING_DISMISS = "mapbox_myBearingTrackingDismiss"; + public static final String STATE_MY_TRACKING_MODE_DISMISS_FOR_CAMERA = "mapbox_myBearingTrackingDismiss"; + public static final String STATE_COMPASS_ENABLED = "mapbox_compassEnabled"; + public static final String STATE_COMPASS_GRAVITY = "mapbox_compassGravity"; + public static final String STATE_COMPASS_MARGIN_LEFT = "mapbox_compassMarginLeft"; + public static final String STATE_COMPASS_MARGIN_TOP = "mapbox_compassMarginTop"; + public static final String STATE_COMPASS_MARGIN_RIGHT = "mapbox_compassMarginRight"; + public static final String STATE_COMPASS_MARGIN_BOTTOM = "mapbox_compassMarginBottom"; + public static final String STATE_COMPASS_FADE_WHEN_FACING_NORTH = "mapbox_compassFade"; + public static final String STATE_LOGO_GRAVITY = "mapbox_logoGravity"; + public static final String STATE_LOGO_MARGIN_LEFT = "mapbox_logoMarginLeft"; + public static final String STATE_LOGO_MARGIN_TOP = "mapbox_logoMarginTop"; + public static final String STATE_LOGO_MARGIN_RIGHT = "mapbox_logoMarginRight"; + public static final String STATE_LOGO_MARGIN_BOTTOM = "mapbox_logoMarginBottom"; + public static final String STATE_LOGO_ENABLED = "mapbox_logoEnabled"; + public static final String STATE_ATTRIBUTION_GRAVITY = "mapbox_attrGravity"; + public static final String STATE_ATTRIBUTION_MARGIN_LEFT = "mapbox_attrMarginLeft"; + public static final String STATE_ATTRIBUTION_MARGIN_TOP = "mapbox_attrMarginTop"; + public static final String STATE_ATTRIBUTION_MARGIN_RIGHT = "mapbox_attrMarginRight"; + public static final String STATE_ATTRIBUTION_MARGIN_BOTTOM = "mapbox_atrrMarginBottom"; + public static final String STATE_ATTRIBUTION_ENABLED = "mapbox_atrrEnabled"; + } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java index cba2fb282c..f53c65d055 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyBearingTracking.java @@ -38,6 +38,6 @@ public class MyBearingTracking { */ public static final int GPS = 0x00000008; - //public static final int COMBINED = 0x00000012; + // public static final int COMBINED = 0x00000012; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java index d1eaac04de..39f653596f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MyLocationTracking.java @@ -34,4 +34,4 @@ public class MyLocationTracking { */ public static final int TRACKING_FOLLOW = 0x00000004; -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidMarkerPositionException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidMarkerPositionException.java index e5a647841f..bd24379af3 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidMarkerPositionException.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/InvalidMarkerPositionException.java @@ -7,4 +7,4 @@ public class InvalidMarkerPositionException extends RuntimeException { + "Missing the required position field. " + "Provide a non null LatLng as position to the Marker."); } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java deleted file mode 100644 index e2e114fa77..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/exceptions/TelemetryServiceNotConfiguredException.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.mapbox.mapboxsdk.exceptions; - -import android.os.Bundle; - -import com.mapbox.mapboxsdk.maps.MapView; - -/** - * A {@code TelemetryServiceNotConfiguredException} is thrown by {@link MapView} when it checks and finds that - * TelemetryService has not been configured in the app's AndroidManifest.xml {@link MapView#onCreate(Bundle)} - * - * @see MapView#onCreate(Bundle) - */ -public class TelemetryServiceNotConfiguredException extends RuntimeException { - - public TelemetryServiceNotConfiguredException() { - super("\nTelemetryService is not configured in your applications AndroidManifest.xml. " - + "\nPlease add \"com.mapbox.mapboxsdk.telemetry.TelemetryService\" service in your applications " - + "AndroidManifest.xml" - + "\nFor an example visit http://goo.gl/cET0Jn. For more information visit https://www.mapbox.com/android-sdk/."); - } - -}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java index b18b7e87b0..5e3064f75f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLng.java @@ -4,8 +4,8 @@ import android.location.Location; import android.os.Parcel; import android.os.Parcelable; -import com.mapbox.mapboxsdk.constants.GeoConstants; -import com.mapbox.mapboxsdk.utils.MathUtils; +import com.mapbox.services.android.telemetry.constants.GeoConstants; +import com.mapbox.services.android.telemetry.utils.MathUtils; /** * A geographical location which contains a single latitude, longitude pair, with @@ -127,13 +127,8 @@ public class LatLng implements ILatLng, Parcelable { * @return New LatLng object with wrapped Longitude */ public LatLng wrap() { - LatLng wrappedVersion = new LatLng(this); - double lon = wrappedVersion.getLongitude(); - if (lon < GeoConstants.MIN_LONGITUDE || lon > GeoConstants.MAX_LONGITUDE) { - wrappedVersion.setLongitude(MathUtils.wrap(wrappedVersion.getLongitude(), GeoConstants.MIN_LONGITUDE, - GeoConstants.MAX_LONGITUDE)); - } - return wrappedVersion; + longitude = MathUtils.wrap(longitude, GeoConstants.MIN_LONGITUDE, GeoConstants.MAX_LONGITUDE); + return this; } @Override diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java index dd7fef4d23..d00ccdb9b8 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/LatLngSpan.java @@ -100,4 +100,4 @@ public class LatLngSpan implements Parcelable { out.writeDouble(mLatitudeSpan); out.writeDouble(mLongitudeSpan); } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java index 45300f248c..c5b8ad3077 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/geometry/VisibleRegion.java @@ -127,4 +127,4 @@ public class VisibleRegion implements Parcelable { } }; -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java index 2c6251638a..cedc5fe46c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/http/HTTPRequest.java @@ -123,7 +123,7 @@ class HTTPRequest implements Callback { body = response.body().bytes(); } catch (IOException ioException) { onFailure(ioException); - //throw ioException; + // throw ioException; return; } finally { response.body().close(); @@ -183,7 +183,7 @@ class HTTPRequest implements Callback { return USER_AGENT_STRING = Util.toHumanReadableAscii( String.format("%s %s (%s) Android/%s (%s)", getApplicationIdentifier(), - BuildConfig.MAPBOX_VERSION_STRING, + com.mapbox.services.android.telemetry.BuildConfig.MAPBOX_VERSION_STRING, BuildConfig.GIT_REVISION_SHORT, Build.VERSION.SDK_INT, Build.CPU_ABI) @@ -202,4 +202,4 @@ class HTTPRequest implements Callback { return ""; } } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java deleted file mode 100644 index 7d86d8b096..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationListener.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.mapbox.mapboxsdk.location; - -import android.location.Location; - -/** - * Callback interface for when a location change occurs. - */ -public interface LocationListener { - - /** - * Callback method for receiving location updates from LocationServices. - * - * @param location The new Location data - */ - void onLocationChanged(Location location); - -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java deleted file mode 100644 index aaf08c8b55..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java +++ /dev/null @@ -1,213 +0,0 @@ -package com.mapbox.mapboxsdk.location; - -import android.Manifest; -import android.content.Context; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.location.Location; -import android.location.LocationManager; -import android.support.annotation.NonNull; -import android.support.v4.content.ContextCompat; -import android.support.v4.content.LocalBroadcastManager; - -import timber.log.Timber; - -import com.mapbox.mapboxsdk.telemetry.TelemetryLocationReceiver; -import com.mapzen.android.lost.api.LocationRequest; -import com.mapzen.android.lost.api.LostApiClient; - -import java.util.concurrent.CopyOnWriteArrayList; - -import static com.mapzen.android.lost.api.LocationServices.FusedLocationApi; - -/** - * Manages locational updates. Contains methods to register and unregister location listeners. - * <ul> - * <li>You can register a {@link LocationListener} with {@link #addLocationListener(LocationListener)} to receive - * location updates.</li> - * <li> You can unregister a {@link LocationListener} with {@link #removeLocationListener(LocationListener)}.</li> - * </ul> - * <p> - * Note: If registering a listener in your Activity.onStart() implementation, you should unregister it in - * Activity.onStop(). (You won't receive location updates when paused, and this will cut down on unnecessary system - * overhead). Do not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back - * in the history stack. - * </p> - */ -public class LocationServices implements LostApiClient.ConnectionCallbacks, - com.mapzen.android.lost.api.LocationListener { - - private static LocationServices instance; - - private Context context; - private LostApiClient locationClient; - private Location lastLocation; - - private CopyOnWriteArrayList<LocationListener> locationListeners; - - private boolean isGpsEnabled; - - /** - * Private constructor for singleton LocationServices - */ - private LocationServices(Context context) { - super(); - this.context = context; - // Setup location services - locationClient = new LostApiClient.Builder(context).addConnectionCallbacks(this).build(); - locationListeners = new CopyOnWriteArrayList<>(); - } - - /** - * Primary (singleton) access method for LocationServices - * - * @param context Context - * @return LocationServices - */ - public static LocationServices getLocationServices(@NonNull final Context context) { - if (instance == null) { - instance = new LocationServices(context.getApplicationContext()); - } - return instance; - } - - /** - * Enabled / Disable GPS focused location tracking - * - * @param enableGPS true if GPS is to be enabled, false if GPS is to be disabled - */ - public void toggleGPS(boolean enableGPS) { - if (!areLocationPermissionsGranted()) { - Timber.w("Location Permissions Not Granted Yet. Try again after requesting."); - return; - } - - // Disconnect - if (locationClient.isConnected()) { - // Disconnect first to ensure that the new requests are GPS - FusedLocationApi.removeLocationUpdates(locationClient, this); - locationClient.disconnect(); - } - isGpsEnabled = enableGPS; - - // Setup Fresh - locationClient.connect(); - } - - @Override - public void onConnected() { - //noinspection MissingPermission - Location lastLocation = FusedLocationApi.getLastLocation(locationClient); - if (lastLocation != null) { - this.lastLocation = lastLocation; - } - - LocationRequest locationRequest; - - if (isGpsEnabled) { - // LocationRequest Tuned for GPS - locationRequest = LocationRequest.create() - .setFastestInterval(1000) - .setSmallestDisplacement(3.0f) - .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); - //noinspection MissingPermission - FusedLocationApi.requestLocationUpdates(locationClient, locationRequest, this); - } else { - // LocationRequest Tuned for PASSIVE - locationRequest = LocationRequest.create() - .setFastestInterval(1000) - .setSmallestDisplacement(3.0f) - .setPriority(LocationRequest.PRIORITY_NO_POWER); - //noinspection MissingPermission - FusedLocationApi.requestLocationUpdates(locationClient, locationRequest, this); - } - } - - @Override - public void onConnectionSuspended() { - } - - /** - * Returns if the GPS sensor is currently enabled - * - * @return active state of the GPS - */ - public boolean isGpsEnabled() { - return isGpsEnabled; - } - - /** - * Called when the location has changed. - * - * @param location The updated location - */ - @Override - public void onLocationChanged(Location location) { - // Timber.d("onLocationChanged()..." + location); - this.lastLocation = location; - - // Update Listeners - for (LocationListener listener : this.locationListeners) { - listener.onLocationChanged(location); - } - - // Update the Telemetry Receiver - Intent locIntent = new Intent(TelemetryLocationReceiver.INTENT_STRING); - locIntent.putExtra(LocationManager.KEY_LOCATION_CHANGED, location); - LocalBroadcastManager.getInstance(context.getApplicationContext()).sendBroadcast(locIntent); - } - - /** - * Last known location - * - * @return Last known location data - */ - public Location getLastLocation() { - return lastLocation; - } - - /** - * Registers a LocationListener to receive location updates - * - * @param locationListener LocationListener - */ - public void addLocationListener(@NonNull LocationListener locationListener) { - if (!this.locationListeners.contains(locationListener)) { - this.locationListeners.add(locationListener); - } - } - - /** - * Unregister a LocationListener to stop receiving location updates - * - * @param locationListener LocationListener to remove - * @return True if LocationListener was found and removed, False if it was not - */ - public boolean removeLocationListener(@NonNull LocationListener locationListener) { - return this.locationListeners.remove(locationListener); - } - - /** - * Check status of Location Permissions - * - * @return True if granted to the app, False if not - */ - public boolean areLocationPermissionsGranted() { - if ((ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) - != PackageManager.PERMISSION_GRANTED) - && (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) - != PackageManager.PERMISSION_GRANTED)) { - Timber.w("Location Permissions Not Granted Yet. Try again after requesting."); - return false; - } - return true; - } - - @Override - public void onProviderDisabled(String provider) { - } - - @Override - public void onProviderEnabled(String provider) { - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java new file mode 100644 index 0000000000..5a87f6384f --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationSource.java @@ -0,0 +1,148 @@ +package com.mapbox.mapboxsdk.location; + +import android.content.Context; +import android.location.Location; +import android.util.Log; + +import com.mapbox.services.android.telemetry.location.LocationEngine; +import com.mapbox.services.android.telemetry.location.LocationEngineListener; +import com.mapbox.services.android.telemetry.location.LocationEnginePriority; +import com.mapbox.services.android.telemetry.permissions.PermissionsManager; +import com.mapzen.android.lost.api.LocationListener; +import com.mapzen.android.lost.api.LocationRequest; +import com.mapzen.android.lost.api.LocationServices; +import com.mapzen.android.lost.api.LostApiClient; + +import java.lang.ref.WeakReference; + +/** + * Manages locational updates. Contains methods to register and unregister location listeners. + * <ul> + * <li>You can register a {@link LocationEngineListener} with + * {@link #addLocationEngineListener(LocationEngineListener)} to receive + * location updates.</li> + * <li> You can unregister a {@link LocationEngineListener} with + * {@link #removeLocationEngineListener(LocationEngineListener)} to stop receiving location updates.</li> + * </ul> + * <p> + * Note: If registering a listener in your Activity.onStart() implementation, you should unregister it in + * Activity.onStop(). (You won't receive location updates when paused, and this will cut down on unnecessary system + * overhead). Do not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back + * in the history stack. + * </p> + */ +public class LocationSource extends LocationEngine implements + LostApiClient.ConnectionCallbacks, LocationListener { + + private static final String LOG_TAG = LocationSource.class.getSimpleName(); + + private static LocationEngine instance; + + private WeakReference<Context> context; + private LostApiClient lostApiClient; + + public LocationSource(Context context) { + super(); + this.context = new WeakReference<>(context); + lostApiClient = new LostApiClient.Builder(this.context.get()) + .addConnectionCallbacks(this) + .build(); + } + + public static synchronized LocationEngine getLocationEngine(Context context) { + if (instance == null) { + instance = new LocationSource(context.getApplicationContext()); + } + + return instance; + } + + @Override + public void activate() { + if (lostApiClient != null && !lostApiClient.isConnected()) { + lostApiClient.connect(); + } + } + + @Override + public void deactivate() { + if (lostApiClient != null && lostApiClient.isConnected()) { + lostApiClient.disconnect(); + } + } + + @Override + public boolean isConnected() { + return lostApiClient.isConnected(); + } + + @Override + public void onConnected() { + for (LocationEngineListener listener : locationListeners) { + listener.onConnected(); + } + } + + @Override + public void onConnectionSuspended() { + Log.d(LOG_TAG, "Connection suspended."); + } + + @Override + public Location getLastLocation() { + if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context.get())) { + //noinspection MissingPermission + return LocationServices.FusedLocationApi.getLastLocation(lostApiClient); + } + + return null; + } + + @Override + public void requestLocationUpdates() { + // Common params + LocationRequest request = LocationRequest.create() + .setFastestInterval(1000) + .setSmallestDisplacement(3.0f); + + // Priority matching is straightforward + if (priority == LocationEnginePriority.NO_POWER) { + request.setPriority(LocationRequest.PRIORITY_NO_POWER); + } else if (priority == LocationEnginePriority.LOW_POWER) { + request.setPriority(LocationRequest.PRIORITY_LOW_POWER); + } else if (priority == LocationEnginePriority.BALANCED_POWER_ACCURACY) { + request.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); + } else if (priority == LocationEnginePriority.HIGH_ACCURACY) { + request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); + } + + if (lostApiClient.isConnected() && PermissionsManager.areLocationPermissionsGranted(context.get())) { + //noinspection MissingPermission + LocationServices.FusedLocationApi.requestLocationUpdates(lostApiClient, request, this); + } + } + + @Override + public void removeLocationUpdates() { + if (lostApiClient.isConnected()) { + LocationServices.FusedLocationApi.removeLocationUpdates(lostApiClient, this); + } + } + + @Override + public void onLocationChanged(Location location) { + for (LocationEngineListener listener : locationListeners) { + listener.onLocationChanged(location); + } + } + + @Override + public void onProviderDisabled(String provider) { + Log.d(LOG_TAG, "Provider disabled: " + provider); + } + + @Override + public void onProviderEnabled(String provider) { + Log.d(LOG_TAG, "Provider enabled: " + provider); + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java index 05b37bc80d..0c77723354 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java @@ -194,7 +194,7 @@ class AnnotationManager { if (ids != null) { id = ids[i]; } else { - //unit test + // unit test id++; } m.setId(id); @@ -359,6 +359,7 @@ class AnnotationManager { return selectedMarkers; } + @NonNull List<Marker> getMarkersInRect(@NonNull RectF rectangle) { // convert Rectangle to be density depedent float pixelRatio = nativeMapView.getPixelRatio(); @@ -622,6 +623,7 @@ class AnnotationManager { boolean onTap(PointF tapPoint, float screenDensity) { float toleranceSides = 4 * screenDensity; float toleranceTopBottom = 10 * screenDensity; + boolean handledDefaultClick = false; RectF tapRect = new RectF(tapPoint.x - iconManager.getAverageIconWidth() / 2 - toleranceSides, tapPoint.y - iconManager.getAverageIconHeight() / 2 - toleranceTopBottom, @@ -631,7 +633,8 @@ class AnnotationManager { List<Marker> nearbyMarkers = getMarkersInRect(tapRect); long newSelectedMarkerId = -1; - if (nearbyMarkers != null && nearbyMarkers.size() > 0) { + // find a Marker that isn't selected yet + if (nearbyMarkers.size() > 0) { Collections.sort(nearbyMarkers); for (Marker nearbyMarker : nearbyMarkers) { boolean found = false; @@ -647,6 +650,7 @@ class AnnotationManager { } } + // if unselected marker found if (newSelectedMarkerId >= 0) { List<Annotation> annotations = getAnnotations(); int count = annotations.size(); @@ -655,7 +659,6 @@ class AnnotationManager { if (annotation instanceof Marker) { if (annotation.getId() == newSelectedMarkerId) { Marker marker = (Marker) annotation; - boolean handledDefaultClick = false; if (marker instanceof MarkerView) { handledDefaultClick = markerViewManager.onClickMarkerView((MarkerView) marker); @@ -679,6 +682,22 @@ class AnnotationManager { } } } + } else if (nearbyMarkers.size() > 0) { + // we didn't find an unselected marker, check if we can close an already open markers + for (Marker nearbyMarker : nearbyMarkers) { + for (Marker selectedMarker : selectedMarkers) { + if (nearbyMarker.equals(selectedMarker)) { + if (onMarkerClickListener != null) { + // end developer has provided a custom click listener + handledDefaultClick = onMarkerClickListener.onMarkerClick(nearbyMarker); + if (!handledDefaultClick) { + deselectMarker(nearbyMarker); + } + } + return true; + } + } + } } return false; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java index 11dee078ac..0f4d3197cc 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java @@ -2,6 +2,7 @@ package com.mapbox.mapboxsdk.maps; import android.content.Context; import android.graphics.PointF; +import android.location.Location; import android.support.annotation.NonNull; import android.support.v4.view.GestureDetectorCompat; import android.support.v4.view.ScaleGestureDetectorCompat; @@ -15,8 +16,11 @@ 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.constants.MapboxConstants; -import com.mapbox.mapboxsdk.telemetry.MapboxEvent; -import com.mapbox.mapboxsdk.utils.MathUtils; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.services.android.telemetry.MapboxEvent; +import com.mapbox.services.android.telemetry.MapboxTelemetry; +import com.mapbox.services.android.telemetry.utils.MathUtils; +import com.mapbox.services.android.telemetry.utils.TelemetryUtils; /** * Manages gestures events on a MapView. @@ -88,6 +92,18 @@ final class MapGestureDetector { this.focalPoint = focalPoint; } + /** + * Given coordinates from a gesture, use the current projection to translate it into + * a Location object. + * + * @param x coordinate + * @param y coordinate + * @return location + */ + private Location getLocationFromGesture(float x, float y) { + LatLng latLng = projection.fromScreenLocation(new PointF(x, y)); + return TelemetryUtils.buildLocation(latLng.getLongitude(), latLng.getLatitude()); + } /** * Called when user touches the screen, all positions are absolute. @@ -123,8 +139,9 @@ final class MapGestureDetector { && uiSettings.isZoomGesturesEnabled(); if (twoTap) { // Confirmed 2nd Finger Down - MapboxEvent.trackGestureEvent(projection, - MapboxEvent.GESTURE_TWO_FINGER_SINGLETAP, event.getX(), event.getY(), transform.getZoom()); + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + getLocationFromGesture(event.getX(), event.getY()), + MapboxEvent.GESTURE_TWO_FINGER_SINGLETAP, transform.getZoom())); } break; @@ -153,7 +170,8 @@ final class MapGestureDetector { // Scroll / Pan Has Stopped if (scrollInProgress) { - MapboxEvent.trackGestureDragEndEvent(projection, event.getX(), event.getY(), transform.getZoom()); + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapDragEndEvent( + getLocationFromGesture(event.getX(), event.getY()), transform.getZoom())); scrollInProgress = false; } @@ -181,7 +199,7 @@ final class MapGestureDetector { */ boolean onGenericMotionEvent(MotionEvent event) { // Mouse events - //if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { // this is not available before API 18 + // if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) { // this is not available before API 18 if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == InputDevice.SOURCE_CLASS_POINTER) { // Choose the action switch (event.getActionMasked()) { @@ -225,7 +243,7 @@ final class MapGestureDetector { @Override public boolean onDoubleTapEvent(MotionEvent e) { - if (!uiSettings.isZoomGesturesEnabled()) { + if (!uiSettings.isZoomGesturesEnabled() || !uiSettings.isDoubleTapGesturesEnabled()) { return false; } @@ -252,7 +270,9 @@ final class MapGestureDetector { break; } - MapboxEvent.trackGestureEvent(projection, MapboxEvent.GESTURE_DOUBLETAP, e.getX(), e.getY(), transform.getZoom()); + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + getLocationFromGesture(e.getX(), e.getY()), + MapboxEvent.GESTURE_DOUBLETAP, transform.getZoom())); return true; } @@ -281,8 +301,10 @@ final class MapGestureDetector { } } - MapboxEvent.trackGestureEvent(projection, - MapboxEvent.GESTURE_SINGLETAP, motionEvent.getX(), motionEvent.getY(), transform.getZoom()); + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + getLocationFromGesture(motionEvent.getX(), motionEvent.getY()), + MapboxEvent.GESTURE_SINGLETAP, transform.getZoom())); + return true; } @@ -333,9 +355,6 @@ final class MapGestureDetector { if (onFlingListener != null) { onFlingListener.onFling(); } - - MapboxEvent.trackGestureEvent(projection, - MapboxEvent.GESTURE_PAN_START, e1.getX(), e1.getY(), transform.getZoom()); return true; } @@ -344,6 +363,9 @@ final class MapGestureDetector { public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (!scrollInProgress) { scrollInProgress = true; + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + getLocationFromGesture(e1.getX(), e1.getY()), + MapboxEvent.GESTURE_PAN_START, transform.getZoom())); } if (!trackingSettings.isScrollGestureCurrentlyEnabled()) { return false; @@ -385,8 +407,9 @@ final class MapGestureDetector { scaleGestureOccurred = true; beginTime = detector.getEventTime(); - MapboxEvent.trackGestureEvent(projection, - MapboxEvent.GESTURE_PINCH_START, detector.getFocusX(), detector.getFocusY(), transform.getZoom()); + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), + MapboxEvent.GESTURE_PINCH_START, transform.getZoom())); return true; } @@ -476,8 +499,9 @@ final class MapGestureDetector { } beginTime = detector.getEventTime(); - MapboxEvent.trackGestureEvent(projection, - MapboxEvent.GESTURE_ROTATION_START, detector.getFocusX(), detector.getFocusY(), transform.getZoom()); + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), + MapboxEvent.GESTURE_ROTATION_START, transform.getZoom())); return true; } @@ -556,8 +580,9 @@ final class MapGestureDetector { } beginTime = detector.getEventTime(); - MapboxEvent.trackGestureEvent(projection, - MapboxEvent.GESTURE_PITCH_START, detector.getFocusX(), detector.getFocusY(), transform.getZoom()); + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), + MapboxEvent.GESTURE_PITCH_START, transform.getZoom())); return true; } @@ -654,4 +679,4 @@ final class MapGestureDetector { void setOnScrollListener(MapboxMap.OnScrollListener onScrollListener) { this.onScrollListener = onScrollListener; } -}
\ No newline at end of file +} 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 3cb074d209..16b7bf1800 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 @@ -3,25 +3,21 @@ package com.mapbox.mapboxsdk.maps; import android.app.Activity; import android.app.Dialog; import android.app.Fragment; -import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; -import android.content.IntentFilter; import android.graphics.Canvas; import android.graphics.PointF; import android.graphics.SurfaceTexture; -import android.net.ConnectivityManager; -import android.net.NetworkInfo; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; import android.support.annotation.CallSuper; import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; import android.support.v7.app.AlertDialog; -import android.text.TextUtils; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -45,8 +41,9 @@ import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.maps.widgets.CompassView; import com.mapbox.mapboxsdk.maps.widgets.MyLocationView; import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings; -import com.mapbox.mapboxsdk.telemetry.MapboxEvent; -import com.mapbox.mapboxsdk.telemetry.MapboxEventManager; +import com.mapbox.mapboxsdk.net.ConnectivityReceiver; +import com.mapbox.services.android.telemetry.MapboxEvent; +import com.mapbox.services.android.telemetry.MapboxTelemetry; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -72,7 +69,7 @@ public class MapView extends FrameLayout { private NativeMapView nativeMapView; private boolean destroyed; - private boolean hasSurface = false; + private boolean hasSurface; private MapboxMap mapboxMap; private MapCallback mapCallback; @@ -83,8 +80,6 @@ public class MapView extends FrameLayout { private MapKeyListener mapKeyListener; private MapZoomButtonController mapZoomButtonController; - private ConnectivityReceiver connectivityReceiver; - @UiThread public MapView(@NonNull Context context) { super(context); @@ -106,7 +101,7 @@ public class MapView extends FrameLayout { @UiThread public MapView(@NonNull Context context, @Nullable MapboxMapOptions options) { super(context); - initialise(context, options); + initialise(context, options == null ? MapboxMapOptions.createFromAttributes(context, null) : options); } private void initialise(@NonNull final Context context, @NonNull final MapboxMapOptions options) { @@ -127,15 +122,18 @@ public class MapView extends FrameLayout { nativeMapView = new NativeMapView(this); // callback for focal point invalidation - FocalPointInvalidator focalPoint = new FocalPointInvalidator(); + FocalPointInvalidator focalPoint = new FocalPointInvalidator(compassView); // callback for registering touch listeners RegisterTouchListener registerTouchListener = new RegisterTouchListener(); + // callback for zooming in the camera + CameraZoomInvalidator zoomInvalidator = new CameraZoomInvalidator(); + // setup components for MapboxMap creation Projection proj = new Projection(nativeMapView); UiSettings uiSettings = new UiSettings(proj, focalPoint, compassView, attrView, view.findViewById(R.id.logoView)); - TrackingSettings trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPoint); + TrackingSettings trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPoint, zoomInvalidator); MyLocationViewSettings myLocationViewSettings = new MyLocationViewSettings(myLocationView, proj, focalPoint); MarkerViewManager markerViewManager = new MarkerViewManager((ViewGroup) findViewById(R.id.markerViewContainer)); AnnotationManager annotations = new AnnotationManager(nativeMapView, this, markerViewManager); @@ -164,7 +162,7 @@ public class MapView extends FrameLayout { setWillNotDraw(false); // notify Map object about current connectivity state - nativeMapView.setReachability(isConnected()); + nativeMapView.setReachability(ConnectivityReceiver.instance(context).isConnected(context)); // initialise MapboxMap mapboxMap.initialise(context, options); @@ -199,10 +197,8 @@ public class MapView extends FrameLayout { */ @UiThread public void onCreate(@Nullable Bundle savedInstanceState) { - nativeMapView.setAccessToken(Mapbox.getAccessToken()); - if (savedInstanceState == null) { - MapboxEvent.trackMapLoadEvent(); + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapLoadEvent()); } else if (savedInstanceState.getBoolean(MapboxConstants.STATE_HAS_SAVED_STATE)) { mapboxMap.onRestoreInstanceState(savedInstanceState); } @@ -234,7 +230,7 @@ public class MapView extends FrameLayout { public void onStart() { onStartCalled = true; mapboxMap.onStart(); - registerConnectivityReceiver(); + ConnectivityReceiver.instance(getContext()).activate(); } /** @@ -264,7 +260,7 @@ public class MapView extends FrameLayout { public void onStop() { onStopCalled = true; mapboxMap.onStop(); - unregisterConnectivityReceiver(); + ConnectivityReceiver.instance(getContext()).deactivate(); } /** @@ -286,18 +282,6 @@ public class MapView extends FrameLayout { nativeMapView = null; } - private void registerConnectivityReceiver() { - getContext().registerReceiver(connectivityReceiver = new ConnectivityReceiver(), - new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); - } - - private void unregisterConnectivityReceiver() { - if (connectivityReceiver != null) { - getContext().unregisterReceiver(connectivityReceiver); - connectivityReceiver = null; - } - } - @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { @@ -405,11 +389,6 @@ public class MapView extends FrameLayout { return; } - // stopgap for https://github.com/mapbox/mapbox-gl-native/issues/6242 - if (TextUtils.isEmpty(nativeMapView.getAccessToken())) { - nativeMapView.setAccessToken(Mapbox.getAccessToken()); - } - nativeMapView.setStyleUrl(url); } @@ -552,30 +531,6 @@ public class MapView extends FrameLayout { } // - // Connectivity events - // - - // This class handles connectivity changes - private class ConnectivityReceiver extends BroadcastReceiver { - - // Called when an action we are listening to in the manifest has been sent - @Override - public void onReceive(Context context, Intent intent) { - if (!destroyed && intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) { - nativeMapView.setReachability(!intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)); - } - } - } - - // Called when MapView is being created - private boolean isConnected() { - ConnectivityManager connectivityManager = (ConnectivityManager) - getContext().getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo(); - return (activeNetwork != null) && activeNetwork.isConnectedOrConnecting(); - } - - // // Map events // @@ -663,7 +618,7 @@ public class MapView extends FrameLayout { builder.setPositiveButton(R.string.mapbox_attributionTelemetryPositive, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - MapboxEventManager.getMapboxEventManager().setTelemetryEnabled(true); + MapboxTelemetry.getInstance().setTelemetryEnabled(true); dialog.cancel(); } }); @@ -680,7 +635,7 @@ public class MapView extends FrameLayout { builder.setNegativeButton(R.string.mapbox_attributionTelemetryNegative, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - MapboxEventManager.getMapboxEventManager().setTelemetryEnabled(false); + MapboxTelemetry.getInstance().setTelemetryEnabled(false); dialog.cancel(); } }); @@ -941,9 +896,18 @@ public class MapView extends FrameLayout { private class FocalPointInvalidator implements FocalPointChangeListener { + private final FocalPointChangeListener[] focalPointChangeListeners; + + FocalPointInvalidator(FocalPointChangeListener... listeners) { + focalPointChangeListeners = listeners; + } + @Override public void onFocalPointChanged(PointF pointF) { mapGestureDetector.setFocalPoint(pointF); + for (FocalPointChangeListener focalPointChangeListener : focalPointChangeListeners) { + focalPointChangeListener.onFocalPointChanged(pointF); + } } } @@ -970,6 +934,16 @@ public class MapView extends FrameLayout { } } + private class CameraZoomInvalidator implements TrackingSettings.CameraZoomInvalidator { + @Override + public void zoomTo(double zoomLevel) { + double currentZoomLevel = mapboxMap.getCameraPosition().zoom; + if (currentZoomLevel < zoomLevel) { + mapboxMap.getTransform().setZoom(zoomLevel); + } + } + } + private static class MapCallback implements OnMapChangedListener { private final MapboxMap mapboxMap; @@ -984,9 +958,14 @@ public class MapView extends FrameLayout { public void onMapChanged(@MapChange int change) { if (change == DID_FINISH_LOADING_STYLE && initialLoad) { initialLoad = false; - mapboxMap.onPreMapReady(); - onMapReady(); - mapboxMap.onPostMapReady(); + new Handler().post(new Runnable() { + @Override + public void run() { + mapboxMap.onPreMapReady(); + onMapReady(); + mapboxMap.onPostMapReady(); + } + }); } else if (change == REGION_IS_CHANGING || change == REGION_DID_CHANGE || change == DID_FINISH_LOADING_MAP) { mapboxMap.onUpdate(); } 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 9e8073edb8..e3e33ec067 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 @@ -8,6 +8,7 @@ import android.location.Location; import android.os.Bundle; import android.os.Handler; import android.support.annotation.FloatRange; +import android.support.annotation.IntRange; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; @@ -16,7 +17,6 @@ import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; -import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.annotations.Annotation; import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions; import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions; @@ -38,8 +38,6 @@ import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings; import com.mapbox.mapboxsdk.style.layers.Layer; -import com.mapbox.mapboxsdk.style.layers.NoSuchLayerException; -import com.mapbox.mapboxsdk.style.sources.NoSuchSourceException; import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.services.commons.geojson.Feature; @@ -212,6 +210,22 @@ public final class MapboxMap { nativeMapView.setTransitionDelay(delay); } + /** + * Retrieve all the layers in the style + * + * @return all the layers in the current style + */ + @UiThread + public List<Layer> getLayers() { + return nativeMapView.getLayers(); + } + + /** + * Get the layer by id + * + * @param layerId the layer's id + * @return the layer, if present in the style + */ @Nullable @UiThread public Layer getLayer(@NonNull String layerId) { @@ -229,7 +243,7 @@ public final class MapboxMap { @UiThread public <T extends Layer> T getLayerAs(@NonNull String layerId) { try { - //noinspection unchecked + // noinspection unchecked return (T) nativeMapView.getLayer(layerId); } catch (ClassCastException exception) { Timber.e(String.format("Layer: %s is a different type: %s", layerId, exception)); @@ -244,42 +258,95 @@ public final class MapboxMap { */ @UiThread public void addLayer(@NonNull Layer layer) { - addLayer(layer, null); + nativeMapView.addLayer(layer); + } + + /** + * Adds the layer to the map. The layer must be newly created and not added to the map before + * + * @param layer the layer to add + * @param below the layer id to add this layer before + */ + @UiThread + public void addLayerBelow(@NonNull Layer layer, @NonNull String below) { + nativeMapView.addLayerBelow(layer, below); } /** * Adds the layer to the map. The layer must be newly created and not added to the map before * - * @param layer the layer to add - * @param before the layer id to add this layer before + * @param layer the layer to add + * @param above the layer id to add this layer above */ @UiThread - public void addLayer(@NonNull Layer layer, String before) { - nativeMapView.addLayer(layer, before); + public void addLayerAbove(@NonNull Layer layer, @NonNull String above) { + nativeMapView.addLayerAbove(layer, above); + } + + /** + * Adds the layer to the map at the specified index. The layer must be newly + * created and not added to the map before + * + * @param layer the layer to add + * @param index the index to insert the layer at + */ + @UiThread + public void addLayerAt(@NonNull Layer layer, @IntRange(from = 0) int index) { + nativeMapView.addLayerAt(layer, index); } /** * Removes the layer. Any references to the layer become invalid and should not be used anymore * * @param layerId the layer to remove - * @throws NoSuchLayerException the exception thrown when layer with layerId doesn't exist + * @return the removed layer or null if not found */ @UiThread - public void removeLayer(@NonNull String layerId) throws NoSuchLayerException { - nativeMapView.removeLayer(layerId); + @Nullable + public Layer removeLayer(@NonNull String layerId) { + return nativeMapView.removeLayer(layerId); } /** * Removes the layer. The reference is re-usable after this and can be re-added * * @param layer the layer to remove - * @throws NoSuchLayerException the exeption thrown when the layer doesn't exist + * @return the layer */ @UiThread - public void removeLayer(@NonNull Layer layer) throws NoSuchLayerException { - nativeMapView.removeLayer(layer); + @Nullable + public Layer removeLayer(@NonNull Layer layer) { + return nativeMapView.removeLayer(layer); } + /** + * Removes the layer. Any other references to the layer become invalid and should not be used anymore + * + * @param index the layer index + * @return the removed layer or null if not found + */ + @UiThread + @Nullable + public Layer removeLayerAt(@IntRange(from = 0) int index) { + return nativeMapView.removeLayerAt(index); + } + + /** + * Retrieve all the sources in the style + * + * @return all the sources in the current style + */ + @UiThread + public List<Source> getSources() { + return nativeMapView.getSources(); + } + + /** + * Retrieve a source by id + * + * @param sourceId the source's id + * @return the source if present in the current style + */ @Nullable @UiThread public Source getSource(@NonNull String sourceId) { @@ -297,7 +364,7 @@ public final class MapboxMap { @UiThread public <T extends Source> T getSourceAs(@NonNull String sourceId) { try { - //noinspection unchecked + // noinspection unchecked return (T) nativeMapView.getSource(sourceId); } catch (ClassCastException exception) { Timber.e(String.format("Source: %s is a different type: %s", sourceId, exception)); @@ -319,22 +386,24 @@ public final class MapboxMap { * Removes the source. Any references to the source become invalid and should not be used anymore * * @param sourceId the source to remove - * @throws NoSuchSourceException the exception thrown when the source with sourceId doesn't exist + * @return the source handle or null if the source was not present */ @UiThread - public void removeSource(@NonNull String sourceId) throws NoSuchSourceException { - nativeMapView.removeSource(sourceId); + @Nullable + public Source removeSource(@NonNull String sourceId) { + return nativeMapView.removeSource(sourceId); } /** * Removes the source, preserving the reverence for re-use * * @param source the source to remove - * @throws NoSuchSourceException the exception thrown when the source with sourceId doesn't exist + * @return the source */ @UiThread - public void removeSource(@NonNull Source source) throws NoSuchSourceException { - nativeMapView.removeSource(source); + @Nullable + public Source removeSource(@NonNull Source source) { + return nativeMapView.removeSource(source); } /** @@ -515,9 +584,6 @@ public final class MapboxMap { @UiThread public final void moveCamera(CameraUpdate update) { moveCamera(update, null); - // MapChange.REGION_DID_CHANGE_ANIMATED is not called for `jumpTo` - // invalidate camera position to provide OnCameraChange event. - invalidateCameraPosition(); } /** @@ -534,6 +600,9 @@ public final class MapboxMap { @Override public void run() { transform.moveCamera(MapboxMap.this, update, callback); + // MapChange.REGION_DID_CHANGE_ANIMATED is not called for `jumpTo` + // invalidate camera position to provide OnCameraChange event. + invalidateCameraPosition(); } }); } @@ -615,7 +684,9 @@ public final class MapboxMap { * easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it * will return the current location of the camera in flight. * <p> - * Note that this will cancel location tracking mode if enabled. + * Note that this will cancel location tracking mode if enabled. You can change this behaviour by calling + * {@link TrackingSettings#setDismissTrackingModeForCameraPositionChange(boolean)} with false before invoking this + * method and calling it with true in the {@link CancelableCallback#onFinish()}. * </p> * * @param update The change that should be applied to the camera. @@ -629,39 +700,12 @@ public final class MapboxMap { * Do not update or ease the camera from within onCancel(). */ @UiThread - public final void easeCamera( - CameraUpdate update, int durationMs, boolean easingInterpolator, final MapboxMap.CancelableCallback callback) { - // dismiss tracking, moving camera is equal to a gesture - easeCamera(update, durationMs, easingInterpolator, true, callback); - } - - /** - * Gradually move the camera by a specified duration in milliseconds, zoom will not be affected - * unless specified within {@link CameraUpdate}. A callback can be used to be notified when - * easing the camera stops. If {@link #getCameraPosition()} is called during the animation, it - * will return the current location of the camera in flight. - * <p> - * Note that this will cancel location tracking mode if enabled. - * </p> - * - * @param update The change that should be applied to the camera. - * @param durationMs The duration of the animation in milliseconds. This must be strictly - * positive, otherwise an IllegalArgumentException will be thrown. - * @param resetTrackingMode True to reset tracking modes if required, false to ignore - * @param easingInterpolator True for easing interpolator, false for linear. - * @param callback An optional callback to be notified from the main thread when the animation - * stops. If the animation stops due to its natural completion, the callback - * will be notified with onFinish(). If the animation stops due to interruption - * by a later camera movement or a user gesture, onCancel() will be called. - * Do not update or ease the camera from within onCancel(). - */ - @UiThread public final void easeCamera(final CameraUpdate update, final int durationMs, final boolean easingInterpolator, - final boolean resetTrackingMode, final MapboxMap.CancelableCallback callback) { + final MapboxMap.CancelableCallback callback) { new Handler().post(new Runnable() { @Override public void run() { - transform.easeCamera(MapboxMap.this, update, durationMs, easingInterpolator, resetTrackingMode, callback); + transform.easeCamera(MapboxMap.this, update, durationMs, easingInterpolator, callback); } }); } @@ -763,6 +807,21 @@ public final class MapboxMap { transform.resetNorth(); } + /** + * Set focal bearing. + */ + public void setFocalBearing(double bearing, float focalX, float focalY, long duration) { + transform.setBearing(bearing, focalX, focalY, duration); + } + + public float getHeight() { + return nativeMapView.getHeight(); + } + + public float getWidth() { + return nativeMapView.getWidth(); + } + // // Debug // @@ -882,10 +941,6 @@ public final class MapboxMap { private void setStyleUrl(@NonNull MapboxMapOptions options) { String style = options.getStyle(); if (!TextUtils.isEmpty(style)) { - // stopgap for https://github.com/mapbox/mapbox-gl-native/issues/6242 - if (TextUtils.isEmpty(nativeMapView.getAccessToken())) { - nativeMapView.setAccessToken(Mapbox.getAccessToken()); - } setStyleUrl(style); } } @@ -1604,18 +1659,8 @@ public final class MapboxMap { * @param bitmap A pre-allocated bitmap. */ @UiThread - public void snapshot(@NonNull SnapshotReadyCallback callback, @Nullable final Bitmap bitmap) { - nativeMapView.addSnapshotCallback(callback, bitmap); - } - - /** - * Takes a snapshot of the map. - * - * @param callback Callback method invoked when the snapshot is taken. - */ - @UiThread public void snapshot(@NonNull SnapshotReadyCallback callback) { - snapshot(callback, null); + nativeMapView.addSnapshotCallback(callback); } /** @@ -2032,4 +2077,4 @@ public final class MapboxMap { Transform getTransform() { return transform; } -}
\ No newline at end of file +} 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 index 518ef47329..6467033ead 100644 --- 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 @@ -66,6 +66,7 @@ public class MapboxMapOptions implements Parcelable { private boolean tiltGesturesEnabled = true; private boolean zoomGesturesEnabled = true; private boolean zoomControlsEnabled = false; + private boolean doubleTapGesturesEnabled = true; private boolean myLocationEnabled; private Drawable myLocationForegroundDrawable; @@ -116,6 +117,7 @@ public class MapboxMapOptions implements Parcelable { tiltGesturesEnabled = in.readByte() != 0; zoomControlsEnabled = in.readByte() != 0; zoomGesturesEnabled = in.readByte() != 0; + doubleTapGesturesEnabled = in.readByte() != 0; myLocationEnabled = in.readByte() != 0; @@ -184,6 +186,8 @@ public class MapboxMapOptions implements Parcelable { typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_uiTiltGestures, true)); mapboxMapOptions.zoomControlsEnabled( typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_uiZoomControls, false)); + mapboxMapOptions.doubleTapGesturesEnabled( + typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_uiDoubleTapGestures, true)); mapboxMapOptions.maxZoomPreference(typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_cameraZoomMax, MapboxConstants.MAXIMUM_ZOOM)); @@ -529,6 +533,17 @@ public class MapboxMapOptions implements Parcelable { } /** + * Specifies if the double tap gesture is enabled for a map view. + * + * @param enabled True and gesture will be enabled + * @return This + */ + public MapboxMapOptions doubleTapGesturesEnabled(boolean enabled) { + doubleTapGesturesEnabled = enabled; + return this; + } + + /** * Specifies if the user location view is enabled for a map view. * * @param locationEnabled True and gesture will be enabled @@ -809,6 +824,15 @@ public class MapboxMapOptions implements Parcelable { } /** + * Get the current configured double tap gesture state for a map view. + * + * @return True indicates gesture is enabled + */ + public boolean getDoubleTapGesturesEnabled() { + return doubleTapGesturesEnabled; + } + + /** * Get the current configured visibility state for attribution for a map view. * * @return Visibility state of the attribution @@ -987,6 +1011,7 @@ public class MapboxMapOptions implements Parcelable { dest.writeByte((byte) (tiltGesturesEnabled ? 1 : 0)); dest.writeByte((byte) (zoomControlsEnabled ? 1 : 0)); dest.writeByte((byte) (zoomGesturesEnabled ? 1 : 0)); + dest.writeByte((byte) (doubleTapGesturesEnabled ? 1 : 0)); dest.writeByte((byte) (myLocationEnabled ? 1 : 0)); @@ -1066,6 +1091,9 @@ public class MapboxMapOptions implements Parcelable { if (zoomControlsEnabled != options.zoomControlsEnabled) { return false; } + if (doubleTapGesturesEnabled != options.doubleTapGesturesEnabled) { + return false; + } if (myLocationEnabled != options.myLocationEnabled) { return false; } @@ -1146,6 +1174,7 @@ public class MapboxMapOptions implements Parcelable { result = 31 * result + (tiltGesturesEnabled ? 1 : 0); result = 31 * result + (zoomGesturesEnabled ? 1 : 0); result = 31 * result + (zoomControlsEnabled ? 1 : 0); + result = 31 * result + (doubleTapGesturesEnabled ? 1 : 0); result = 31 * result + (myLocationEnabled ? 1 : 0); result = 31 * result + (myLocationForegroundDrawable != null ? myLocationForegroundDrawable.hashCode() : 0); result = 31 * result + (myLocationForegroundBearingDrawable != null @@ -1161,4 +1190,4 @@ public class MapboxMapOptions implements Parcelable { result = 31 * result + (style != null ? style.hashCode() : 0); return result; } -}
\ No newline at end of file +} 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 0c15480dee..e02a0f3d36 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 @@ -3,10 +3,10 @@ package com.mapbox.mapboxsdk.maps; import android.app.ActivityManager; import android.content.Context; import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.graphics.PointF; import android.graphics.RectF; import android.os.Build; +import android.support.annotation.IntRange; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.text.TextUtils; @@ -20,10 +20,10 @@ import com.mapbox.mapboxsdk.annotations.Polyline; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.ProjectedMeters; -import com.mapbox.mapboxsdk.offline.OfflineManager; +import com.mapbox.mapboxsdk.storage.FileSource; +import com.mapbox.mapboxsdk.style.layers.CannotAddLayerException; import com.mapbox.mapboxsdk.style.layers.Layer; -import com.mapbox.mapboxsdk.style.layers.NoSuchLayerException; -import com.mapbox.mapboxsdk.style.sources.NoSuchSourceException; +import com.mapbox.mapboxsdk.style.sources.CannotAddSourceException; import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.services.commons.geojson.Feature; @@ -35,6 +35,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import timber.log.Timber; + // Class that wraps the native methods for convenience final class NativeMapView { @@ -42,11 +43,14 @@ final class NativeMapView { private boolean destroyed = false; // Holds the pointer to JNI NativeMapView - private long nativeMapViewPtr = 0; + private long nativePtr = 0; // Used for callbacks private MapView mapView; + //Hold a reference to prevent it from being GC'd as long as it's used on the native side + private final FileSource fileSource; + // Device density private final float pixelRatio; @@ -54,7 +58,7 @@ final class NativeMapView { private CopyOnWriteArrayList<MapView.OnMapChangedListener> onMapChangedListeners; // Listener invoked to return a bitmap of the map - private SnapshotRequest snapshotRequest; + private MapboxMap.SnapshotReadyCallback snapshotReadyCallback; // // Static methods @@ -70,15 +74,9 @@ final class NativeMapView { public NativeMapView(MapView mapView) { Context context = mapView.getContext(); - String dataPath = OfflineManager.getDatabasePath(context); - - // With the availability of offline, we're unifying the ambient (cache) and the offline - // databases to be in the same folder, outside cache, to avoid automatic deletion from - // the system - String cachePath = dataPath; + fileSource = FileSource.getInstance(context); pixelRatio = context.getResources().getDisplayMetrics().density; - String apkPath = context.getPackageCodePath(); int availableProcessors = Runtime.getRuntime().availableProcessors(); ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); @@ -97,7 +95,8 @@ final class NativeMapView { } onMapChangedListeners = new CopyOnWriteArrayList<>(); this.mapView = mapView; - nativeMapViewPtr = nativeCreate(cachePath, dataPath, apkPath, pixelRatio, availableProcessors, totalMemory); + + nativeInitialize(this, fileSource, pixelRatio, availableProcessors, totalMemory); } // @@ -114,8 +113,7 @@ final class NativeMapView { } public void destroy() { - nativeDestroy(nativeMapViewPtr); - nativeMapViewPtr = 0; + nativeDestroy(); mapView = null; destroyed = true; } @@ -124,56 +122,56 @@ final class NativeMapView { if (isDestroyedOn("initializeDisplay")) { return; } - nativeInitializeDisplay(nativeMapViewPtr); + nativeInitializeDisplay(); } public void terminateDisplay() { if (isDestroyedOn("terminateDisplay")) { return; } - nativeTerminateDisplay(nativeMapViewPtr); + nativeTerminateDisplay(); } public void initializeContext() { if (isDestroyedOn("initializeContext")) { return; } - nativeInitializeContext(nativeMapViewPtr); + nativeInitializeContext(); } public void terminateContext() { if (isDestroyedOn("terminateContext")) { return; } - nativeTerminateContext(nativeMapViewPtr); + nativeTerminateContext(); } public void createSurface(Surface surface) { if (isDestroyedOn("createSurface")) { return; } - nativeCreateSurface(nativeMapViewPtr, surface); + nativeCreateSurface(surface); } public void destroySurface() { if (isDestroyedOn("destroySurface")) { return; } - nativeDestroySurface(nativeMapViewPtr); + nativeDestroySurface(); } public void update() { if (isDestroyedOn("update")) { return; } - nativeUpdate(nativeMapViewPtr); + nativeUpdate(); } public void render() { if (isDestroyedOn("render")) { return; } - nativeRender(nativeMapViewPtr); + nativeRender(); } public void resizeView(int width, int height) { @@ -204,7 +202,7 @@ final class NativeMapView { + "capping value at 65535 instead of " + height); height = 65535; } - nativeViewResize(nativeMapViewPtr, width, height); + nativeResizeView(width, height); } public void resizeFramebuffer(int fbWidth, int fbHeight) { @@ -228,98 +226,49 @@ final class NativeMapView { throw new IllegalArgumentException( "fbHeight cannot be greater than 65535."); } - nativeFramebufferResize(nativeMapViewPtr, fbWidth, fbHeight); - } - - public void addClass(String clazz) { - if (isDestroyedOn("addClass")) { - return; - } - nativeAddClass(nativeMapViewPtr, clazz); - } - - public void removeClass(String clazz) { - if (isDestroyedOn("removeClass")) { - return; - } - nativeRemoveClass(nativeMapViewPtr, clazz); - } - - public boolean hasClass(String clazz) { - if (isDestroyedOn("hasClass")) { - return false; - } - return nativeHasClass(nativeMapViewPtr, clazz); - } - - public void setClasses(List<String> classes) { - if (isDestroyedOn("setClasses")) { - return; - } - nativeSetClasses(nativeMapViewPtr, classes); - } - - public List<String> getClasses() { - if (isDestroyedOn("getClasses")) { - return new ArrayList<>(); - } - return nativeGetClasses(nativeMapViewPtr); + nativeResizeFramebuffer(fbWidth, fbHeight); } public void setStyleUrl(String url) { if (isDestroyedOn("setStyleUrl")) { return; } - nativeSetStyleUrl(nativeMapViewPtr, url); + nativeSetStyleUrl(url); } public String getStyleUrl() { if (isDestroyedOn("getStyleUrl")) { return null; } - return nativeGetStyleUrl(nativeMapViewPtr); + return nativeGetStyleUrl(); } public void setStyleJson(String newStyleJson) { if (isDestroyedOn("setStyleJson")) { return; } - nativeSetStyleJson(nativeMapViewPtr, newStyleJson); + nativeSetStyleJson(newStyleJson); } public String getStyleJson() { if (isDestroyedOn("getStyleJson")) { return null; } - return nativeGetStyleJson(nativeMapViewPtr); - } - - public void setAccessToken(String accessToken) { - if (isDestroyedOn("setAccessToken")) { - return; - } - nativeSetAccessToken(nativeMapViewPtr, accessToken); - } - - public String getAccessToken() { - if (isDestroyedOn("getAccessToken")) { - return null; - } - return nativeGetAccessToken(nativeMapViewPtr); + return nativeGetStyleJson(); } public void cancelTransitions() { if (isDestroyedOn("cancelTransitions")) { return; } - nativeCancelTransitions(nativeMapViewPtr); + nativeCancelTransitions(); } public void setGestureInProgress(boolean inProgress) { if (isDestroyedOn("setGestureInProgress")) { return; } - nativeSetGestureInProgress(nativeMapViewPtr, inProgress); + nativeSetGestureInProgress(inProgress); } public void moveBy(double dx, double dy) { @@ -333,7 +282,7 @@ final class NativeMapView { if (isDestroyedOn("moveBy")) { return; } - nativeMoveBy(nativeMapViewPtr, dx / pixelRatio, dy / pixelRatio, duration); + nativeMoveBy(dx / pixelRatio, dy / pixelRatio, duration); } public void setLatLng(LatLng latLng) { @@ -347,35 +296,36 @@ final class NativeMapView { if (isDestroyedOn("setLatLng")) { return; } - nativeSetLatLng(nativeMapViewPtr, latLng.getLatitude(), latLng.getLongitude(), duration); + nativeSetLatLng(latLng.getLatitude(), latLng.getLongitude(), duration); } public LatLng getLatLng() { if (isDestroyedOn("")) { return new LatLng(); } - return nativeGetLatLng(nativeMapViewPtr); + // wrap longitude values coming from core + return nativeGetLatLng().wrap(); } public void resetPosition() { if (isDestroyedOn("resetPosition")) { return; } - nativeResetPosition(nativeMapViewPtr); + nativeResetPosition(); } public double getPitch() { if (isDestroyedOn("getPitch")) { return 0; } - return nativeGetPitch(nativeMapViewPtr); + return nativeGetPitch(); } public void setPitch(double pitch, long duration) { if (isDestroyedOn("setPitch")) { return; } - nativeSetPitch(nativeMapViewPtr, pitch, duration); + nativeSetPitch(pitch, duration); } public void scaleBy(double ds) { @@ -396,7 +346,7 @@ final class NativeMapView { if (isDestroyedOn("scaleBy")) { return; } - nativeScaleBy(nativeMapViewPtr, ds, cx / pixelRatio, cy / pixelRatio, duration); + nativeScaleBy(ds, cx / pixelRatio, cy / pixelRatio, duration); } public void setScale(double scale) { @@ -417,14 +367,14 @@ final class NativeMapView { if (isDestroyedOn("setScale")) { return; } - nativeSetScale(nativeMapViewPtr, scale, cx / pixelRatio, cy / pixelRatio, duration); + nativeSetScale(scale, cx / pixelRatio, cy / pixelRatio, duration); } public double getScale() { if (isDestroyedOn("getScale")) { return 0; } - return nativeGetScale(nativeMapViewPtr); + return nativeGetScale(); } public void setZoom(double zoom) { @@ -438,49 +388,49 @@ final class NativeMapView { if (isDestroyedOn("setZoom")) { return; } - nativeSetZoom(nativeMapViewPtr, zoom, duration); + nativeSetZoom(zoom, duration); } public double getZoom() { if (isDestroyedOn("getZoom")) { return 0; } - return nativeGetZoom(nativeMapViewPtr); + return nativeGetZoom(); } public void resetZoom() { if (isDestroyedOn("resetZoom")) { return; } - nativeResetZoom(nativeMapViewPtr); + nativeResetZoom(); } public void setMinZoom(double zoom) { if (isDestroyedOn("setMinZoom")) { return; } - nativeSetMinZoom(nativeMapViewPtr, zoom); + nativeSetMinZoom(zoom); } public double getMinZoom() { if (isDestroyedOn("getMinZoom")) { return 0; } - return nativeGetMinZoom(nativeMapViewPtr); + return nativeGetMinZoom(); } public void setMaxZoom(double zoom) { if (isDestroyedOn("setMaxZoom")) { return; } - nativeSetMaxZoom(nativeMapViewPtr, zoom); + nativeSetMaxZoom(zoom); } public double getMaxZoom() { if (isDestroyedOn("getMaxZoom")) { return 0; } - return nativeGetMaxZoom(nativeMapViewPtr); + return nativeGetMaxZoom(); } public void rotateBy(double sx, double sy, double ex, double ey) { @@ -495,14 +445,14 @@ final class NativeMapView { if (isDestroyedOn("rotateBy")) { return; } - nativeRotateBy(nativeMapViewPtr, sx / pixelRatio, sy / pixelRatio, ex, ey, duration); + nativeRotateBy(sx / pixelRatio, sy / pixelRatio, ex, ey, duration); } public void setContentPadding(int[] padding) { if (isDestroyedOn("setContentPadding")) { return; } - nativeSetContentPadding(nativeMapViewPtr, + nativeSetContentPadding( padding[1] / pixelRatio, padding[0] / pixelRatio, padding[3] / pixelRatio, @@ -520,28 +470,35 @@ final class NativeMapView { if (isDestroyedOn("setBearing")) { return; } - nativeSetBearing(nativeMapViewPtr, degrees, duration); + nativeSetBearing(degrees, duration); } public void setBearing(double degrees, double cx, double cy) { if (isDestroyedOn("setBearing")) { return; } - nativeSetBearingXY(nativeMapViewPtr, degrees, cx / pixelRatio, cy / pixelRatio); + setBearing(degrees, cx, cy, 0); + } + + public void setBearing(double degrees, double fx, double fy, long duration) { + if (isDestroyedOn("setBearing")) { + return; + } + nativeSetBearingXY(degrees, fx / pixelRatio, fy / pixelRatio, duration); } public double getBearing() { if (isDestroyedOn("getBearing")) { return 0; } - return nativeGetBearing(nativeMapViewPtr); + return nativeGetBearing(); } public void resetNorth() { if (isDestroyedOn("resetNorth")) { return; } - nativeResetNorth(nativeMapViewPtr); + nativeResetNorth(); } public long addMarker(Marker marker) { @@ -549,14 +506,14 @@ final class NativeMapView { return 0; } Marker[] markers = {marker}; - return nativeAddMarkers(nativeMapViewPtr, markers)[0]; + return nativeAddMarkers(markers)[0]; } public long[] addMarkers(List<Marker> markers) { if (isDestroyedOn("addMarkers")) { return new long[] {}; } - return nativeAddMarkers(nativeMapViewPtr, markers.toArray(new Marker[markers.size()])); + return nativeAddMarkers(markers.toArray(new Marker[markers.size()])); } public long addPolyline(Polyline polyline) { @@ -564,14 +521,14 @@ final class NativeMapView { return 0; } Polyline[] polylines = {polyline}; - return nativeAddPolylines(nativeMapViewPtr, polylines)[0]; + return nativeAddPolylines(polylines)[0]; } public long[] addPolylines(List<Polyline> polylines) { if (isDestroyedOn("addPolylines")) { return new long[] {}; } - return nativeAddPolylines(nativeMapViewPtr, polylines.toArray(new Polyline[polylines.size()])); + return nativeAddPolylines(polylines.toArray(new Polyline[polylines.size()])); } public long addPolygon(Polygon polygon) { @@ -579,14 +536,14 @@ final class NativeMapView { return 0; } Polygon[] polygons = {polygon}; - return nativeAddPolygons(nativeMapViewPtr, polygons)[0]; + return nativeAddPolygons(polygons)[0]; } public long[] addPolygons(List<Polygon> polygons) { if (isDestroyedOn("addPolygons")) { return new long[] {}; } - return nativeAddPolygons(nativeMapViewPtr, polygons.toArray(new Polygon[polygons.size()])); + return nativeAddPolygons(polygons.toArray(new Polygon[polygons.size()])); } public void updateMarker(Marker marker) { @@ -595,21 +552,21 @@ final class NativeMapView { } LatLng position = marker.getPosition(); Icon icon = marker.getIcon(); - nativeUpdateMarker(nativeMapViewPtr, marker.getId(), position.getLatitude(), position.getLongitude(), icon.getId()); + nativeUpdateMarker(marker.getId(), position.getLatitude(), position.getLongitude(), icon.getId()); } public void updatePolygon(Polygon polygon) { if (isDestroyedOn("updatePolygon")) { return; } - nativeUpdatePolygon(nativeMapViewPtr, polygon.getId(), polygon); + nativeUpdatePolygon(polygon.getId(), polygon); } public void updatePolyline(Polyline polyline) { if (isDestroyedOn("updatePolyline")) { return; } - nativeUpdatePolyline(nativeMapViewPtr, polyline.getId(), polyline); + nativeUpdatePolyline(polyline.getId(), polyline); } public void removeAnnotation(long id) { @@ -624,99 +581,106 @@ final class NativeMapView { if (isDestroyedOn("removeAnnotations")) { return; } - nativeRemoveAnnotations(nativeMapViewPtr, ids); + nativeRemoveAnnotations(ids); } public long[] queryPointAnnotations(RectF rect) { if (isDestroyedOn("queryPointAnnotations")) { return new long[] {}; } - return nativeQueryPointAnnotations(nativeMapViewPtr, rect); + return nativeQueryPointAnnotations(rect); } public void addAnnotationIcon(String symbol, int width, int height, float scale, byte[] pixels) { if (isDestroyedOn("addAnnotationIcon")) { return; } - nativeAddAnnotationIcon(nativeMapViewPtr, symbol, width, height, scale, pixels); + nativeAddAnnotationIcon(symbol, width, height, scale, pixels); } public void setVisibleCoordinateBounds(LatLng[] coordinates, RectF padding, double direction, long duration) { if (isDestroyedOn("setVisibleCoordinateBounds")) { return; } - nativeSetVisibleCoordinateBounds(nativeMapViewPtr, coordinates, padding, direction, duration); + nativeSetVisibleCoordinateBounds(coordinates, padding, direction, duration); } public void onLowMemory() { if (isDestroyedOn("onLowMemory")) { return; } - nativeOnLowMemory(nativeMapViewPtr); + nativeOnLowMemory(); } public void setDebug(boolean debug) { if (isDestroyedOn("setDebug")) { return; } - nativeSetDebug(nativeMapViewPtr, debug); + nativeSetDebug(debug); } public void cycleDebugOptions() { if (isDestroyedOn("cycleDebugOptions")) { return; } - nativeToggleDebug(nativeMapViewPtr); + nativeCycleDebugOptions(); } public boolean getDebug() { if (isDestroyedOn("getDebug")) { return false; } - return nativeGetDebug(nativeMapViewPtr); + return nativeGetDebug(); + } + + public void setEnableFps(boolean enable) { + if (isDestroyedOn("setEnableFps")) { + return; + } + nativeSetEnableFps(enable); } public boolean isFullyLoaded() { if (isDestroyedOn("isFullyLoaded")) { return false; } - return nativeIsFullyLoaded(nativeMapViewPtr); + return nativeIsFullyLoaded(); } public void setReachability(boolean status) { if (isDestroyedOn("setReachability")) { return; } - nativeSetReachability(nativeMapViewPtr, status); + nativeSetReachability(status); } public double getMetersPerPixelAtLatitude(double lat) { if (isDestroyedOn("getMetersPerPixelAtLatitude")) { return 0; } - return nativeGetMetersPerPixelAtLatitude(nativeMapViewPtr, lat, getZoom()); + return nativeGetMetersPerPixelAtLatitude(lat, getZoom()); } public ProjectedMeters projectedMetersForLatLng(LatLng latLng) { if (isDestroyedOn("projectedMetersForLatLng")) { return null; } - return nativeProjectedMetersForLatLng(nativeMapViewPtr, latLng.getLatitude(), latLng.getLongitude()); + return nativeProjectedMetersForLatLng(latLng.getLatitude(), latLng.getLongitude()); } public LatLng latLngForProjectedMeters(ProjectedMeters projectedMeters) { if (isDestroyedOn("latLngForProjectedMeters")) { return new LatLng(); } - return nativeLatLngForProjectedMeters(nativeMapViewPtr, projectedMeters.getNorthing(), - projectedMeters.getEasting()); + return nativeLatLngForProjectedMeters(projectedMeters.getNorthing(), + projectedMeters.getEasting()).wrap(); } public PointF pixelForLatLng(LatLng latLng) { if (isDestroyedOn("pixelForLatLng")) { return new PointF(); } - PointF pointF = nativePixelForLatLng(nativeMapViewPtr, latLng.getLatitude(), latLng.getLongitude()); + PointF pointF = nativePixelForLatLng(latLng.getLatitude(), latLng.getLongitude()); pointF.set(pointF.x * pixelRatio, pointF.y * pixelRatio); return pointF; } @@ -725,21 +689,21 @@ final class NativeMapView { if (isDestroyedOn("latLngForPixel")) { return new LatLng(); } - return nativeLatLngForPixel(nativeMapViewPtr, pixel.x / pixelRatio, pixel.y / pixelRatio); + return nativeLatLngForPixel(pixel.x / pixelRatio, pixel.y / pixelRatio).wrap(); } public double getTopOffsetPixelsForAnnotationSymbol(String symbolName) { if (isDestroyedOn("getTopOffsetPixelsForAnnotationSymbol")) { return 0; } - return nativeGetTopOffsetPixelsForAnnotationSymbol(nativeMapViewPtr, symbolName); + return nativeGetTopOffsetPixelsForAnnotationSymbol(symbolName); } public void jumpTo(double angle, LatLng center, double pitch, double zoom) { if (isDestroyedOn("jumpTo")) { return; } - nativeJumpTo(nativeMapViewPtr, angle, center.getLatitude(), center.getLongitude(), pitch, zoom); + nativeJumpTo(angle, center.getLatitude(), center.getLongitude(), pitch, zoom); } public void easeTo(double angle, LatLng center, long duration, double pitch, double zoom, @@ -747,7 +711,7 @@ final class NativeMapView { if (isDestroyedOn("easeTo")) { return; } - nativeEaseTo(nativeMapViewPtr, angle, center.getLatitude(), center.getLongitude(), duration, pitch, zoom, + nativeEaseTo(angle, center.getLatitude(), center.getLongitude(), duration, pitch, zoom, easingInterpolator); } @@ -755,115 +719,163 @@ final class NativeMapView { if (isDestroyedOn("flyTo")) { return; } - nativeFlyTo(nativeMapViewPtr, angle, center.getLatitude(), center.getLongitude(), duration, pitch, zoom); + nativeFlyTo(angle, center.getLatitude(), center.getLongitude(), duration, pitch, zoom); } public double[] getCameraValues() { if (isDestroyedOn("getCameraValues")) { return new double[] {}; } - return nativeGetCameraValues(nativeMapViewPtr); + return nativeGetCameraValues(); } // Runtime style Api public long getTransitionDuration() { - return nativeGetTransitionDuration(nativeMapViewPtr); + return nativeGetTransitionDuration(); } public void setTransitionDuration(long duration) { - nativeSetTransitionDuration(nativeMapViewPtr, duration); + nativeSetTransitionDuration(duration); } public long getTransitionDelay() { - return nativeGetTransitionDelay(nativeMapViewPtr); + return nativeGetTransitionDelay(); } public void setTransitionDelay(long delay) { - nativeSetTransitionDelay(nativeMapViewPtr, delay); + nativeSetTransitionDelay(delay); + } + + public List<Layer> getLayers() { + if (isDestroyedOn("getLayers")) { + return null; + } + return Arrays.asList(nativeGetLayers()); } public Layer getLayer(String layerId) { if (isDestroyedOn("getLayer")) { return null; } - return nativeGetLayer(nativeMapViewPtr, layerId); + return nativeGetLayer(layerId); } - public void addLayer(@NonNull Layer layer, @Nullable String before) { - if (isDestroyedOn("")) { + public void addLayer(@NonNull Layer layer) { + if (isDestroyedOn("addLayer")) { return; } - nativeAddLayer(nativeMapViewPtr, layer.getNativePtr(), before); + nativeAddLayer(layer.getNativePtr(), null); } - public void removeLayer(@NonNull String layerId) throws NoSuchLayerException { - if (isDestroyedOn("removeLayer")) { + public void addLayerBelow(@NonNull Layer layer, @NonNull String below) { + if (isDestroyedOn("addLayerBelow")) { return; } - nativeRemoveLayerById(nativeMapViewPtr, layerId); + nativeAddLayer(layer.getNativePtr(), below); } - public void removeLayer(@NonNull Layer layer) throws NoSuchLayerException { - if (isDestroyedOn("removeLayer")) { + public void addLayerAbove(@NonNull Layer layer, @NonNull String above) { + if (isDestroyedOn("addLayerAbove")) { + return; + } + nativeAddLayerAbove(layer.getNativePtr(), above); + } + + public void addLayerAt(@NonNull Layer layer, @IntRange(from = 0) int index) { + if (isDestroyedOn("addLayerAt")) { return; } - nativeRemoveLayer(nativeMapViewPtr, layer.getNativePtr()); + nativeAddLayerAt(layer.getNativePtr(), index); + } + + @Nullable + public Layer removeLayer(@NonNull String layerId) { + if (isDestroyedOn("removeLayer")) { + return null; + } + return nativeRemoveLayerById(layerId); + } + + @Nullable + public Layer removeLayer(@NonNull Layer layer) { + if (isDestroyedOn("removeLayer")) { + return null; + } + nativeRemoveLayer(layer.getNativePtr()); + return layer; + } + + @Nullable + public Layer removeLayerAt(@IntRange(from = 0) int index) { + if (isDestroyedOn("removeLayerAt")) { + return null; + } + return nativeRemoveLayerAt(index); + } + + public List<Source> getSources() { + if (isDestroyedOn("getSources")) { + return null; + } + return Arrays.asList(nativeGetSources()); } public Source getSource(@NonNull String sourceId) { if (isDestroyedOn("getSource")) { return null; } - return nativeGetSource(nativeMapViewPtr, sourceId); + return nativeGetSource(sourceId); } public void addSource(@NonNull Source source) { if (isDestroyedOn("addSource")) { return; } - nativeAddSource(nativeMapViewPtr, source.getNativePtr()); + nativeAddSource(source.getNativePtr()); } - public void removeSource(@NonNull String sourceId) throws NoSuchSourceException { + @Nullable + public Source removeSource(@NonNull String sourceId) { if (isDestroyedOn("removeSource")) { - return; + return null; } - nativeRemoveSourceById(nativeMapViewPtr, sourceId); + return nativeRemoveSourceById(sourceId); } - public void removeSource(@NonNull Source source) throws NoSuchSourceException { + public Source removeSource(@NonNull Source source) { if (isDestroyedOn("removeSource")) { - return; + return null; } - nativeRemoveSource(nativeMapViewPtr, source.getNativePtr()); + nativeRemoveSource(source.getNativePtr()); + return source; } public void addImage(@NonNull String name, @NonNull Bitmap image) { if (isDestroyedOn("addImage")) { return; } - //Check/correct config + // Check/correct config if (image.getConfig() != Bitmap.Config.ARGB_8888) { image = image.copy(Bitmap.Config.ARGB_8888, false); } - //Get pixels + // Get pixels ByteBuffer buffer = ByteBuffer.allocate(image.getByteCount()); image.copyPixelsToBuffer(buffer); - //Determine pixel ratio + // Determine pixel ratio float density = image.getDensity() == Bitmap.DENSITY_NONE ? Bitmap.DENSITY_NONE : image.getDensity(); float pixelRatio = density / DisplayMetrics.DENSITY_DEFAULT; - nativeAddImage(nativeMapViewPtr, name, image.getWidth(), image.getHeight(), pixelRatio, buffer.array()); + nativeAddImage(name, image.getWidth(), image.getHeight(), pixelRatio, buffer.array()); } public void removeImage(String name) { if (isDestroyedOn("removeImage")) { return; } - nativeRemoveImage(nativeMapViewPtr, name); + nativeRemoveImage(name); } // Feature querying @@ -873,7 +885,7 @@ final class NativeMapView { if (isDestroyedOn("queryRenderedFeatures")) { return new ArrayList<>(); } - Feature[] features = nativeQueryRenderedFeaturesForPoint(nativeMapViewPtr, coordinates.x / pixelRatio, + Feature[] features = nativeQueryRenderedFeaturesForPoint(coordinates.x / pixelRatio, coordinates.y / pixelRatio, layerIds); return features != null ? Arrays.asList(features) : new ArrayList<Feature>(); } @@ -884,7 +896,7 @@ final class NativeMapView { return new ArrayList<>(); } Feature[] features = nativeQueryRenderedFeaturesForBox( - nativeMapViewPtr, + coordinates.left / pixelRatio, coordinates.top / pixelRatio, coordinates.right / pixelRatio, @@ -897,14 +909,14 @@ final class NativeMapView { if (isDestroyedOn("scheduleTakeSnapshot")) { return; } - nativeScheduleTakeSnapshot(nativeMapViewPtr); + nativeTakeSnapshot(); } public void setApiBaseUrl(String baseUrl) { if (isDestroyedOn("setApiBaseUrl")) { return; } - nativeSetAPIBaseURL(nativeMapViewPtr, baseUrl); + fileSource.setApiBaseUrl(baseUrl); } public float getPixelRatio() { @@ -920,7 +932,9 @@ final class NativeMapView { // protected void onInvalidate() { - mapView.onInvalidate(); + if (mapView != null) { + mapView.onInvalidate(); + } } protected void onMapChanged(int rawChange) { @@ -935,18 +949,9 @@ final class NativeMapView { mapView.onFpsChanged(fps); } - protected void onSnapshotReady(byte[] bytes) { - if (snapshotRequest != null && bytes != null) { - BitmapFactory.Options options = new BitmapFactory.Options(); - options.inBitmap = snapshotRequest.getBitmap(); // the old Bitmap to be reused - options.inMutable = true; - options.inSampleSize = 1; - Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options); - - MapboxMap.SnapshotReadyCallback callback = snapshotRequest.getCallback(); - if (callback != null) { - callback.onSnapshotReady(bitmap); - } + protected void onSnapshotReady(Bitmap bitmap) { + if (snapshotReadyCallback != null && bitmap != null) { + snapshotReadyCallback.onSnapshotReady(bitmap); } } @@ -954,208 +959,192 @@ final class NativeMapView { // JNI methods // - private native long nativeCreate(String cachePath, String dataPath, String apkPath, float pixelRatio, - int availableProcessors, long totalMemory); - - private native void nativeDestroy(long nativeMapViewPtr); + private native void nativeInitialize(NativeMapView nativeMapView, FileSource fileSource, + float pixelRatio, int availableProcessors, long totalMemory); - private native void nativeInitializeDisplay(long nativeMapViewPtr); + private native void nativeDestroy(); - private native void nativeTerminateDisplay(long nativeMapViewPtr); + private native void nativeInitializeDisplay(); - private native void nativeInitializeContext(long nativeMapViewPtr); + private native void nativeTerminateDisplay(); - private native void nativeTerminateContext(long nativeMapViewPtr); + private native void nativeInitializeContext(); - private native void nativeCreateSurface(long nativeMapViewPtr, - Surface surface); + private native void nativeTerminateContext(); - private native void nativeDestroySurface(long nativeMapViewPtr); + private native void nativeCreateSurface(Object surface); - private native void nativeUpdate(long nativeMapViewPtr); + private native void nativeDestroySurface(); - private native void nativeRender(long nativeMapViewPtr); + private native void nativeUpdate(); - private native void nativeViewResize(long nativeMapViewPtr, int width, int height); + private native void nativeRender(); - private native void nativeFramebufferResize(long nativeMapViewPtr, int fbWidth, int fbHeight); + private native void nativeResizeView(int width, int height); - private native void nativeAddClass(long nativeMapViewPtr, String clazz); + private native void nativeResizeFramebuffer(int fbWidth, int fbHeight); - private native void nativeRemoveClass(long nativeMapViewPtr, String clazz); + private native void nativeSetStyleUrl(String url); - private native boolean nativeHasClass(long nativeMapViewPtr, String clazz); + private native String nativeGetStyleUrl(); - private native void nativeSetClasses(long nativeMapViewPtr, - List<String> classes); + private native void nativeSetStyleJson(String newStyleJson); - private native List<String> nativeGetClasses(long nativeMapViewPtr); + private native String nativeGetStyleJson(); - private native void nativeSetStyleUrl(long nativeMapViewPtr, String url); + private native void nativeCancelTransitions(); - private native String nativeGetStyleUrl(long nativeMapViewPtr); + private native void nativeSetGestureInProgress(boolean inProgress); - private native void nativeSetStyleJson(long nativeMapViewPtr, String newStyleJson); + private native void nativeMoveBy(double dx, double dy, long duration); - private native String nativeGetStyleJson(long nativeMapViewPtr); + private native void nativeSetLatLng(double latitude, double longitude, long duration); - private native void nativeSetAccessToken(long nativeMapViewPtr, String accessToken); + private native LatLng nativeGetLatLng(); - private native String nativeGetAccessToken(long nativeMapViewPtr); + private native void nativeResetPosition(); - private native void nativeCancelTransitions(long nativeMapViewPtr); + private native double nativeGetPitch(); - private native void nativeSetGestureInProgress(long nativeMapViewPtr, boolean inProgress); + private native void nativeSetPitch(double pitch, long duration); - private native void nativeMoveBy(long nativeMapViewPtr, double dx, - double dy, long duration); + private native void nativeScaleBy(double ds, double cx, double cy, long duration); - private native void nativeSetLatLng(long nativeMapViewPtr, double latitude, double longitude, - long duration); + private native void nativeSetScale(double scale, double cx, double cy, long duration); - private native LatLng nativeGetLatLng(long nativeMapViewPtr); + private native double nativeGetScale(); - private native void nativeResetPosition(long nativeMapViewPtr); + private native void nativeSetZoom(double zoom, long duration); - private native double nativeGetPitch(long nativeMapViewPtr); + private native double nativeGetZoom(); - private native void nativeSetPitch(long nativeMapViewPtr, double pitch, long duration); + private native void nativeResetZoom(); - private native void nativeScaleBy(long nativeMapViewPtr, double ds, - double cx, double cy, long duration); + private native void nativeSetMinZoom(double zoom); - private native void nativeSetScale(long nativeMapViewPtr, double scale, - double cx, double cy, long duration); + private native double nativeGetMinZoom(); - private native double nativeGetScale(long nativeMapViewPtr); + private native void nativeSetMaxZoom(double zoom); - private native void nativeSetZoom(long nativeMapViewPtr, double zoom, - long duration); + private native double nativeGetMaxZoom(); - private native double nativeGetZoom(long nativeMapViewPtr); + private native void nativeRotateBy(double sx, double sy, double ex, double ey, long duration); - private native void nativeResetZoom(long nativeMapViewPtr); + private native void nativeSetContentPadding(double top, double left, double bottom, double right); - private native void nativeSetMinZoom(long nativeMapViewPtr, double zoom); + private native void nativeSetBearing(double degrees, long duration); - private native double nativeGetMinZoom(long nativeMapViewPtr); + private native void nativeSetBearingXY(double degrees, double fx, double fy, long duration); - private native void nativeSetMaxZoom(long nativeMapViewPtr, double zoom); + private native double nativeGetBearing(); - private native double nativeGetMaxZoom(long nativeMapViewPtr); + private native void nativeResetNorth(); - private native void nativeRotateBy(long nativeMapViewPtr, double sx, - double sy, double ex, double ey, long duration); + private native void nativeUpdateMarker(long markerId, double lat, double lon, String iconId); - private native void nativeSetContentPadding(long nativeMapViewPtr, double top, double left, double bottom, - double right); + private native long[] nativeAddMarkers(Marker[] markers); - private native void nativeSetBearing(long nativeMapViewPtr, double degrees, - long duration); + private native long[] nativeAddPolylines(Polyline[] polylines); - private native void nativeSetBearingXY(long nativeMapViewPtr, double degrees, - double cx, double cy); + private native long[] nativeAddPolygons(Polygon[] polygons); - private native double nativeGetBearing(long nativeMapViewPtr); + private native void nativeRemoveAnnotations(long[] id); - private native void nativeResetNorth(long nativeMapViewPtr); + private native long[] nativeQueryPointAnnotations(RectF rect); - private native void nativeUpdateMarker(long nativeMapViewPtr, long markerId, double lat, double lon, String iconId); + private native void nativeAddAnnotationIcon(String symbol, int width, int height, float scale, byte[] pixels); - private native long[] nativeAddMarkers(long nativeMapViewPtr, Marker[] markers); + private native void nativeSetVisibleCoordinateBounds(LatLng[] coordinates, RectF padding, + double direction, long duration); - private native long[] nativeAddPolylines(long nativeMapViewPtr, Polyline[] polylines); + private native void nativeOnLowMemory(); - private native long[] nativeAddPolygons(long nativeMapViewPtr, Polygon[] polygons); + private native void nativeSetDebug(boolean debug); - private native void nativeRemoveAnnotations(long nativeMapViewPtr, long[] id); + private native void nativeCycleDebugOptions(); - private native long[] nativeQueryPointAnnotations(long nativeMapViewPtr, RectF rect); + private native boolean nativeGetDebug(); - private native void nativeAddAnnotationIcon(long nativeMapViewPtr, String symbol, - int width, int height, float scale, byte[] pixels); + private native void nativeSetEnableFps(boolean enable); - private native void nativeSetVisibleCoordinateBounds(long nativeMapViewPtr, LatLng[] coordinates, - RectF padding, double direction, long duration); + private native boolean nativeIsFullyLoaded(); - private native void nativeOnLowMemory(long nativeMapViewPtr); + private native void nativeSetReachability(boolean status); - private native void nativeSetDebug(long nativeMapViewPtr, boolean debug); + private native double nativeGetMetersPerPixelAtLatitude(double lat, double zoom); - private native void nativeToggleDebug(long nativeMapViewPtr); + private native ProjectedMeters nativeProjectedMetersForLatLng(double latitude, double longitude); - private native boolean nativeGetDebug(long nativeMapViewPtr); + private native LatLng nativeLatLngForProjectedMeters(double northing, double easting); - private native boolean nativeIsFullyLoaded(long nativeMapViewPtr); + private native PointF nativePixelForLatLng(double lat, double lon); - private native void nativeSetReachability(long nativeMapViewPtr, boolean status); + private native LatLng nativeLatLngForPixel(float x, float y); - private native double nativeGetMetersPerPixelAtLatitude(long nativeMapViewPtr, double lat, double zoom); + private native double nativeGetTopOffsetPixelsForAnnotationSymbol(String symbolName); - private native ProjectedMeters nativeProjectedMetersForLatLng(long nativeMapViewPtr, double latitude, - double longitude); + private native void nativeJumpTo(double angle, double latitude, double longitude, double pitch, double zoom); - private native LatLng nativeLatLngForProjectedMeters(long nativeMapViewPtr, double northing, double easting); + private native void nativeEaseTo(double angle, double latitude, double longitude, + long duration, double pitch, double zoom, + boolean easingInterpolator); - private native PointF nativePixelForLatLng(long nativeMapViewPtr, double lat, double lon); + private native void nativeFlyTo(double angle, double latitude, double longitude, + long duration, double pitch, double zoom); - private native LatLng nativeLatLngForPixel(long nativeMapViewPtr, float x, float y); + private native double[] nativeGetCameraValues(); - private native double nativeGetTopOffsetPixelsForAnnotationSymbol(long nativeMapViewPtr, String symbolName); + private native long nativeGetTransitionDuration(); - private native void nativeJumpTo(long nativeMapViewPtr, double angle, double latitude, double longitude, - double pitch, double zoom); + private native void nativeSetTransitionDuration(long duration); - private native void nativeEaseTo(long nativeMapViewPtr, double angle, double latitude, double longitude, - long duration, double pitch, double zoom, boolean easingInterpolator); + private native long nativeGetTransitionDelay(); - private native void nativeFlyTo(long nativeMapViewPtr, double angle, double latitude, double longitude, - long duration, double pitch, double zoom); + private native void nativeSetTransitionDelay(long delay); - private native double[] nativeGetCameraValues(long nativeMapViewPtr); + private native Layer[] nativeGetLayers(); - private native long nativeGetTransitionDuration(long nativeMapViewPtr); + private native Layer nativeGetLayer(String layerId); - private native void nativeSetTransitionDuration(long nativeMapViewPtr, long duration); + private native void nativeAddLayer(long layerPtr, String before) throws CannotAddLayerException; - private native long nativeGetTransitionDelay(long nativeMapViewPtr); + private native void nativeAddLayerAbove(long layerPtr, String above) throws CannotAddLayerException; - private native void nativeSetTransitionDelay(long nativeMapViewPtr, long delay); + private native void nativeAddLayerAt(long layerPtr, int index) throws CannotAddLayerException; - private native Layer nativeGetLayer(long nativeMapViewPtr, String layerId); + private native Layer nativeRemoveLayerById(String layerId); - private native void nativeAddLayer(long nativeMapViewPtr, long layerPtr, String before); + private native void nativeRemoveLayer(long layerId); - private native void nativeRemoveLayerById(long nativeMapViewPtr, String layerId) throws NoSuchLayerException; + private native Layer nativeRemoveLayerAt(int index); - private native void nativeRemoveLayer(long nativeMapViewPtr, long layerId) throws NoSuchLayerException; + private native Source[] nativeGetSources(); - private native Source nativeGetSource(long nativeMapViewPtr, String sourceId); + private native Source nativeGetSource(String sourceId); - private native void nativeAddSource(long nativeMapViewPtr, long nativeSourcePtr); + private native void nativeAddSource(long nativeSourcePtr) throws CannotAddSourceException; - private native void nativeRemoveSourceById(long nativeMapViewPtr, String sourceId) throws NoSuchSourceException; + private native Source nativeRemoveSourceById(String sourceId); - private native void nativeRemoveSource(long nativeMapViewPtr, long sourcePtr) throws NoSuchSourceException; + private native void nativeRemoveSource(long sourcePtr); - private native void nativeAddImage(long nativeMapViewPtr, String name, int width, int height, float pixelRatio, + private native void nativeAddImage(String name, int width, int height, float pixelRatio, byte[] array); - private native void nativeRemoveImage(long nativeMapViewPtr, String name); + private native void nativeRemoveImage(String name); - private native void nativeUpdatePolygon(long nativeMapViewPtr, long polygonId, Polygon polygon); + private native void nativeUpdatePolygon(long polygonId, Polygon polygon); - private native void nativeUpdatePolyline(long nativeMapviewPtr, long polylineId, Polyline polyline); + private native void nativeUpdatePolyline(long polylineId, Polyline polyline); - private native void nativeScheduleTakeSnapshot(long nativeMapViewPtr); + private native void nativeTakeSnapshot(); - private native Feature[] nativeQueryRenderedFeaturesForPoint(long nativeMapViewPtr, float x, float y, String[] + private native Feature[] nativeQueryRenderedFeaturesForPoint(float x, float y, String[] layerIds); - private native Feature[] nativeQueryRenderedFeaturesForBox(long nativeMapViewPtr, float left, float top, float right, - float bottom, String[] layerIds); - - private native void nativeSetAPIBaseURL(long nativeMapViewPtr, String baseUrl); + private native Feature[] nativeQueryRenderedFeaturesForBox(float left, float top, + float right, float bottom, + String[] layerIds); int getWidth() { if (isDestroyedOn("")) { @@ -1187,27 +1176,9 @@ final class NativeMapView { // Snapshot // - void addSnapshotCallback(@NonNull MapboxMap.SnapshotReadyCallback callback, @Nullable Bitmap bitmap) { - snapshotRequest = new SnapshotRequest(bitmap, callback); + void addSnapshotCallback(@NonNull MapboxMap.SnapshotReadyCallback callback) { + snapshotReadyCallback = callback; scheduleTakeSnapshot(); render(); } - - private static class SnapshotRequest { - private Bitmap bitmap; - private MapboxMap.SnapshotReadyCallback callback; - - SnapshotRequest(Bitmap bitmap, MapboxMap.SnapshotReadyCallback callback) { - this.bitmap = bitmap; - this.callback = callback; - } - - public Bitmap getBitmap() { - return bitmap; - } - - public MapboxMap.SnapshotReadyCallback getCallback() { - return callback; - } - } } 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 b7f93cc913..82d5dec6a0 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 @@ -117,4 +117,14 @@ public class Projection { float getWidth() { return nativeMapView.getWidth(); } + + /** + * 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(nativeMapView.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 90d933736b..77fea1a14a 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 @@ -152,4 +152,4 @@ public class SupportMapFragment extends Fragment { public void getMapAsync(@NonNull final OnMapReadyCallback onMapReadyCallback) { this.onMapReadyCallback = onMapReadyCallback; } -}
\ No newline at end of file +} 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 index ff8d92d116..38f307f149 100644 --- 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 @@ -1,22 +1,19 @@ package com.mapbox.mapboxsdk.maps; -import android.Manifest; -import android.content.pm.PackageManager; -import android.graphics.PointF; import android.location.Location; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; -import android.support.v4.content.ContextCompat; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.constants.MyBearingTracking; import com.mapbox.mapboxsdk.constants.MyLocationTracking; -import com.mapbox.mapboxsdk.location.LocationListener; -import com.mapbox.mapboxsdk.location.LocationServices; +import com.mapbox.mapboxsdk.location.LocationSource; import com.mapbox.mapboxsdk.maps.widgets.MyLocationView; +import com.mapbox.services.android.telemetry.location.LocationEngineListener; +import com.mapbox.services.android.telemetry.permissions.PermissionsManager; import timber.log.Timber; @@ -28,20 +25,23 @@ public final class TrackingSettings { private final MyLocationView myLocationView; private final UiSettings uiSettings; private final FocalPointChangeListener focalPointChangedListener; - private LocationListener myLocationListener; + private final CameraZoomInvalidator zoomInvalidator; + private LocationEngineListener myLocationListener; private boolean myLocationEnabled; private boolean dismissLocationTrackingOnGesture = true; private boolean dismissBearingTrackingOnGesture = true; + private boolean isResetTrackingWithCameraPositionChange = true; private MapboxMap.OnMyLocationTrackingModeChangeListener onMyLocationTrackingModeChangeListener; private MapboxMap.OnMyBearingTrackingModeChangeListener onMyBearingTrackingModeChangeListener; TrackingSettings(@NonNull MyLocationView myLocationView, UiSettings uiSettings, - FocalPointChangeListener focalPointChangedListener) { + FocalPointChangeListener focalPointChangedListener, CameraZoomInvalidator zoomInvalidator) { this.myLocationView = myLocationView; this.focalPointChangedListener = focalPointChangedListener; this.uiSettings = uiSettings; + this.zoomInvalidator = zoomInvalidator; } void initialise(MapboxMapOptions options) { @@ -54,6 +54,8 @@ public final class TrackingSettings { outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, isDismissLocationTrackingOnGesture()); outState.putBoolean(MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, isDismissBearingTrackingOnGesture()); outState.putBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED, isMyLocationEnabled()); + outState.putBoolean(MapboxConstants.STATE_MY_TRACKING_MODE_DISMISS_FOR_CAMERA, + isDismissTrackingModesForCameraPositionChange()); } void onRestoreInstanceState(Bundle savedInstanceState) { @@ -62,16 +64,18 @@ public final class TrackingSettings { } catch (SecurityException ignore) { // User did not accept location permissions } - //noinspection ResourceType + // noinspection ResourceType setMyLocationTrackingMode(savedInstanceState.getInt( MapboxConstants.STATE_MY_LOCATION_TRACKING_MODE, MyLocationTracking.TRACKING_NONE)); - //noinspection ResourceType + // noinspection ResourceType setMyBearingTrackingMode(savedInstanceState.getInt( MapboxConstants.STATE_MY_BEARING_TRACKING_MODE, MyBearingTracking.NONE)); setDismissLocationTrackingOnGesture(savedInstanceState.getBoolean( MapboxConstants.STATE_MY_LOCATION_TRACKING_DISMISS, true)); setDismissBearingTrackingOnGesture(savedInstanceState.getBoolean( MapboxConstants.STATE_MY_BEARING_TRACKING_DISMISS, true)); + setDismissTrackingModeForCameraPositionChange(savedInstanceState.getBoolean( + MapboxConstants.STATE_MY_TRACKING_MODE_DISMISS_FOR_CAMERA, true)); } /** @@ -92,8 +96,8 @@ public final class TrackingSettings { myLocationView.setMyLocationTrackingMode(myLocationTrackingMode); if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) { - focalPointChangedListener.onFocalPointChanged(new PointF(myLocationView.getCenterX(), - myLocationView.getCenterY())); + zoomInvalidator.zoomTo(2.0); + focalPointChangedListener.onFocalPointChanged(myLocationView.getCenter()); } else { focalPointChangedListener.onFocalPointChanged(null); } @@ -270,8 +274,39 @@ public final class TrackingSettings { } } + /** + * Reset the tracking modes as necessary. Animated camera position changes can reset the underlying tracking modes. + * + * @param cameraPosition the changed camera position + */ void resetTrackingModesIfRequired(CameraPosition cameraPosition) { - resetTrackingModesIfRequired(cameraPosition.target != null, cameraPosition.bearing != -1); + if (isDismissTrackingModesForCameraPositionChange()) { + resetTrackingModesIfRequired(cameraPosition.target != null, cameraPosition.bearing != -1); + } + } + + /** + * Returns if a animation allows to dismiss a tracking mode. + * <p> + * By default this is set to true. + * </p> + * + * @return True if camera animations will allow to dismiss a tracking mode + */ + public boolean isDismissTrackingModesForCameraPositionChange() { + return isResetTrackingWithCameraPositionChange; + } + + /** + * Sets a flag to allow animated camera position changes to dismiss a tracking mode. + * <p> + * <p> + * </p> + * + * @param willAllowToDismiss True will allow animated camera changes dismiss a trackig mode + */ + public void setDismissTrackingModeForCameraPositionChange(boolean willAllowToDismiss) { + isResetTrackingWithCameraPositionChange = willAllowToDismiss; } Location getMyLocation() { @@ -280,7 +315,12 @@ public final class TrackingSettings { void setOnMyLocationChangeListener(@Nullable final MapboxMap.OnMyLocationChangeListener listener) { if (listener != null) { - myLocationListener = new LocationListener() { + myLocationListener = new LocationEngineListener() { + @Override + public void onConnected() { + // Nothing + } + @Override public void onLocationChanged(Location location) { if (listener != null) { @@ -288,20 +328,13 @@ public final class TrackingSettings { } } }; - LocationServices.getLocationServices(myLocationView.getContext()).addLocationListener(myLocationListener); + LocationSource.getLocationEngine(myLocationView.getContext()).addLocationEngineListener(myLocationListener); } else { - LocationServices.getLocationServices(myLocationView.getContext()).removeLocationListener(myLocationListener); + LocationSource.getLocationEngine(myLocationView.getContext()).removeLocationEngineListener(myLocationListener); myLocationListener = null; } } - boolean isPermissionsAccepted() { - return (ContextCompat.checkSelfPermission(myLocationView.getContext(), - Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) - || ContextCompat.checkSelfPermission(myLocationView.getContext(), - Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; - } - void setOnMyLocationTrackingModeChangeListener(MapboxMap.OnMyLocationTrackingModeChangeListener listener) { this.onMyLocationTrackingModeChangeListener = listener; } @@ -320,7 +353,7 @@ public final class TrackingSettings { } void setMyLocationEnabled(boolean locationEnabled) { - if (!isPermissionsAccepted()) { + if (!PermissionsManager.areLocationPermissionsGranted(myLocationView.getContext())) { Timber.e("Could not activate user location tracking: " + "user did not accept the permission or permissions were not requested."); return; @@ -343,4 +376,8 @@ public final class TrackingSettings { void onStop() { myLocationView.onStop(); } + + interface CameraZoomInvalidator { + void zoomTo(double zoomLevel); + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java index 88acc13356..0f6b146907 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java @@ -73,7 +73,7 @@ final class Transform implements MapView.OnMapChangedListener { @Override public void onMapChanged(@MapView.MapChange int change) { if (change == REGION_DID_CHANGE_ANIMATED && cameraCancelableCallback != null) { - invalidateCameraPosition(); + updateCameraPosition(invalidateCameraPosition()); if (cameraCancelableCallback != null) { cameraCancelableCallback.onFinish(); cameraCancelableCallback = null; @@ -84,47 +84,50 @@ final class Transform implements MapView.OnMapChangedListener { @UiThread final void moveCamera(MapboxMap mapboxMap, CameraUpdate update, MapboxMap.CancelableCallback callback) { - cameraPosition = update.getCameraPosition(mapboxMap); - trackingSettings.resetTrackingModesIfRequired(cameraPosition); - cancelTransitions(); - mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom); - if (callback != null) { - callback.onFinish(); + CameraPosition cameraPosition = update.getCameraPosition(mapboxMap); + if (!cameraPosition.equals(this.cameraPosition)) { + trackingSettings.resetTrackingModesIfRequired(cameraPosition); + cancelTransitions(); + mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom); + if (callback != null) { + callback.onFinish(); + } } } @UiThread final void easeCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, boolean easingInterpolator, - boolean resetTrackingMode, final MapboxMap.CancelableCallback callback) { - cameraPosition = update.getCameraPosition(mapboxMap); - if (resetTrackingMode) { + final MapboxMap.CancelableCallback callback) { + CameraPosition cameraPosition = update.getCameraPosition(mapboxMap); + if (!cameraPosition.equals(this.cameraPosition)) { trackingSettings.resetTrackingModesIfRequired(cameraPosition); - } + cancelTransitions(); + if (callback != null) { + cameraCancelableCallback = callback; + mapView.addOnMapChangedListener(this); + } - cancelTransitions(); - if (callback != null) { - cameraCancelableCallback = callback; - mapView.addOnMapChangedListener(this); + mapView.easeTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt, + cameraPosition.zoom, easingInterpolator); } - - mapView.easeTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt, - cameraPosition.zoom, easingInterpolator); } @UiThread final void animateCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) { - cameraPosition = update.getCameraPosition(mapboxMap); - trackingSettings.resetTrackingModesIfRequired(cameraPosition); + CameraPosition cameraPosition = update.getCameraPosition(mapboxMap); + if (!cameraPosition.equals(this.cameraPosition)) { + trackingSettings.resetTrackingModesIfRequired(cameraPosition); - cancelTransitions(); - if (callback != null) { - cameraCancelableCallback = callback; - mapView.addOnMapChangedListener(this); - } + cancelTransitions(); + if (callback != null) { + cameraCancelableCallback = callback; + mapView.addOnMapChangedListener(this); + } - mapView.flyTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt, - cameraPosition.zoom); + mapView.flyTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt, + cameraPosition.zoom); + } } @UiThread @@ -186,6 +189,10 @@ final class Transform implements MapView.OnMapChangedListener { } } + void setZoom(double zoom) { + mapView.setZoom(zoom); + } + // Direction double getBearing() { double direction = -mapView.getBearing(); @@ -218,6 +225,13 @@ final class Transform implements MapView.OnMapChangedListener { mapView.setBearing(bearing, focalX, focalY); } + void setBearing(double bearing, float focalX, float focalY, long duration) { + if (myLocationView != null) { + myLocationView.setBearing(bearing); + } + mapView.setBearing(bearing, focalX, focalY, duration); + } + // // LatLng / CenterCoordinate 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 bb5271313b..8a3ae1e4f3 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 @@ -48,6 +48,9 @@ public final class UiSettings { private boolean zoomControlsEnabled; + private boolean doubleTapGesturesEnabled = true; + private boolean doubleTapGestureChangeAllowed = true; + private boolean deselectMarkersOnTap = true; private PointF userProvidedFocalPoint; @@ -99,6 +102,8 @@ public final class UiSettings { setTiltGesturesEnabled(options.getTiltGesturesEnabled()); setTiltGestureChangeAllowed(options.getTiltGesturesEnabled()); setZoomControlsEnabled(options.getZoomControlsEnabled()); + setDoubleTapGesturesEnabled(options.getDoubleTapGesturesEnabled()); + setDoubleTapGestureChangeAllowed(options.getDoubleTapGesturesEnabled()); } private void saveGestures(Bundle outState) { @@ -110,6 +115,8 @@ public final class UiSettings { outState.putBoolean(MapboxConstants.STATE_ROTATE_ENABLED_CHANGE, isRotateGestureChangeAllowed()); outState.putBoolean(MapboxConstants.STATE_TILT_ENABLED, isTiltGesturesEnabled()); outState.putBoolean(MapboxConstants.STATE_TILT_ENABLED_CHANGE, isTiltGestureChangeAllowed()); + outState.putBoolean(MapboxConstants.STATE_DOUBLE_TAP_ENABLED, isDoubleTapGesturesEnabled()); + outState.putBoolean(MapboxConstants.STATE_DOUBLE_TAP_ENABLED_CHANGE, isDoubleTapGestureChangeAllowed()); } private void restoreGestures(Bundle savedInstanceState) { @@ -121,6 +128,8 @@ public final class UiSettings { setRotateGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_ROTATE_ENABLED_CHANGE)); setTiltGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_TILT_ENABLED)); setTiltGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_TILT_ENABLED_CHANGE)); + setDoubleTapGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_DOUBLE_TAP_ENABLED)); + setDoubleTapGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_DOUBLE_TAP_ENABLED_CHANGE)); } private void initialiseCompass(MapboxMapOptions options, Resources resources) { @@ -696,6 +705,41 @@ public final class UiSettings { } /** + * <p> + * Changes whether the user may zoom the map with a double tap. + * </p> + * <p> + * This setting controls only user interactions with the map. If you set the value to false, + * you may still change the map location programmatically. + * </p> + * The default value is true. + * + * @param doubleTapGesturesEnabled If true, zooming with a double tap is enabled. + */ + public void setDoubleTapGesturesEnabled(boolean doubleTapGesturesEnabled) { + if (doubleTapGestureChangeAllowed) { + this.doubleTapGesturesEnabled = doubleTapGesturesEnabled; + } + } + + /** + * Returns whether the user may zoom the map with a double tap. + * + * @return If true, zooming with a double tap is enabled. + */ + public boolean isDoubleTapGesturesEnabled() { + return doubleTapGesturesEnabled; + } + + void setDoubleTapGestureChangeAllowed(boolean doubleTapGestureChangeAllowed) { + this.doubleTapGestureChangeAllowed = doubleTapGestureChangeAllowed; + } + + boolean isDoubleTapGestureChangeAllowed() { + return doubleTapGestureChangeAllowed; + } + + /** * Gets whether the markers are automatically deselected (and therefore, their infowindows * closed) when a map tap is detected. * @@ -771,6 +815,7 @@ public final class UiSettings { setRotateGesturesEnabled(enabled); setTiltGesturesEnabled(enabled); setZoomGesturesEnabled(enabled); + setDoubleTapGesturesEnabled(enabled); } /** diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java index dc4a21f2fe..6d8adc1e2a 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java @@ -1,17 +1,20 @@ package com.mapbox.mapboxsdk.maps.widgets; import android.content.Context; +import android.graphics.PointF; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.content.ContextCompat; import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewPropertyAnimatorCompat; import android.support.v4.view.ViewPropertyAnimatorListenerAdapter; +import android.support.v7.widget.AppCompatImageView; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; import com.mapbox.mapboxsdk.R; +import com.mapbox.mapboxsdk.maps.FocalPointChangeListener; import com.mapbox.mapboxsdk.maps.MapboxMap; import java.lang.ref.WeakReference; @@ -25,15 +28,16 @@ import java.lang.ref.WeakReference; * use {@link com.mapbox.mapboxsdk.maps.UiSettings}. * </p> */ -public final class CompassView extends ImageView implements Runnable { +public final class CompassView extends AppCompatImageView implements Runnable, FocalPointChangeListener { private static final long TIME_WAIT_IDLE = 500; private static final long TIME_FADE_ANIMATION = TIME_WAIT_IDLE; private static final long TIME_MAP_NORTH_ANIMATION = 150; - private double direction = 0.0; + private float rotation = 0.0f; private boolean fadeCompassViewFacingNorth = true; private ViewPropertyAnimatorCompat fadeAnimator; + private PointF focalPoint; public CompassView(Context context) { super(context); @@ -78,8 +82,8 @@ public final class CompassView extends ImageView implements Runnable { } public boolean isFacingNorth() { - // increase range more than just 0.0 - return direction >= 359.0 || direction <= 1.0; + // increase range of facing north to more than only 0.0 + return Math.abs(rotation) >= 359.0 || Math.abs(rotation) <= 1.0; } @Override @@ -96,8 +100,19 @@ public final class CompassView extends ImageView implements Runnable { } } - public void update(final double direction) { - this.direction = direction; + @Nullable + PointF getFocalPoint() { + return focalPoint; + } + + /** + * Updates the direction of the compass. + * + * @param bearing the direction value of the map + */ + public void update(final double bearing) { + // compass needs reverse bearing #8123 + rotation = (float) -bearing; if (!isEnabled()) { return; @@ -115,7 +130,7 @@ public final class CompassView extends ImageView implements Runnable { setVisibility(View.VISIBLE); } - setRotation((float) direction); + setRotation(rotation); } public void fadeCompassViewFacingNorth(boolean compassFadeFacingNorth) { @@ -143,6 +158,11 @@ public final class CompassView extends ImageView implements Runnable { } } + @Override + public void onFocalPointChanged(PointF pointF) { + focalPoint = pointF; + } + static class CompassClickListener implements View.OnClickListener { private WeakReference<MapboxMap> mapboxMap; @@ -158,7 +178,12 @@ public final class CompassView extends ImageView implements Runnable { final MapboxMap mapboxMap = this.mapboxMap.get(); final CompassView compassView = this.compassView.get(); if (mapboxMap != null && compassView != null) { - mapboxMap.resetNorth(); + PointF focalPoint = compassView.getFocalPoint(); + if (focalPoint != null) { + mapboxMap.setFocalBearing(0, focalPoint.x, focalPoint.y, TIME_MAP_NORTH_ANIMATION); + } else { + mapboxMap.setFocalBearing(0, mapboxMap.getWidth() / 2, mapboxMap.getHeight() / 2, TIME_MAP_NORTH_ANIMATION); + } compassView.postDelayed(compassView, TIME_WAIT_IDLE + TIME_MAP_NORTH_ANIMATION); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index c7dd867f2d..2c3685b862 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -31,10 +31,12 @@ 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.LocationSource; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.Projection; +import com.mapbox.services.android.telemetry.location.LocationEngine; +import com.mapbox.services.android.telemetry.location.LocationEngineListener; +import com.mapbox.services.android.telemetry.location.LocationEnginePriority; import java.lang.ref.WeakReference; @@ -296,7 +298,7 @@ public class MyLocationView extends View { } // draw foreground - if (myBearingTrackingMode == MyBearingTracking.NONE) { + if (myBearingTrackingMode == MyBearingTracking.NONE || !compassListener.isSensorAvailable()) { if (foregroundDrawable != null) { foregroundDrawable.draw(canvas); } @@ -308,8 +310,9 @@ public class MyLocationView extends View { public void setTilt(@FloatRange(from = 0, to = 60.0f) double tilt) { this.tilt = tilt; if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) { - mapboxMap.getUiSettings().setFocalPoint(new PointF(getCenterX(), getCenterY())); + mapboxMap.getUiSettings().setFocalPoint(getCenter()); } + invalidate(); } public void setBearing(double bearing) { @@ -319,7 +322,8 @@ public class MyLocationView extends View { if (location != null) { setCompass(location.getBearing() - bearing); } - } else if (myBearingTrackingMode == MyBearingTracking.COMPASS) { + } else if (myBearingTrackingMode == MyBearingTracking.COMPASS + && compassListener.isSensorAvailable()) { setCompass(magneticHeading - bearing); } } @@ -327,13 +331,14 @@ public class MyLocationView extends View { public void setCameraPosition(CameraPosition position) { if (position != null) { - setTilt(position.tilt); setBearing(position.bearing); + setTilt(position.tilt); } } public void onStart() { - if (myBearingTrackingMode == MyBearingTracking.COMPASS) { + if (myBearingTrackingMode == MyBearingTracking.COMPASS + && compassListener.isSensorAvailable()) { compassListener.onResume(); } if (isEnabled()) { @@ -366,8 +371,7 @@ public class MyLocationView extends View { } if (userLocationListener != null) { - LocationServices services = LocationServices.getLocationServices(getContext()); - services.removeLocationListener(userLocationListener); + LocationSource.getLocationEngine(getContext()).removeLocationEngineListener(userLocationListener); userLocationListener = null; } } @@ -417,10 +421,10 @@ public class MyLocationView extends View { * @param enableGps true if GPS is to be enabled, false if GPS is to be disabled */ private void toggleGps(boolean enableGps) { - LocationServices locationServices = LocationServices.getLocationServices(getContext()); + LocationEngine locationEngine = LocationSource.getLocationEngine(getContext()); if (enableGps) { // Set an initial location if one available - Location lastLocation = locationServices.getLastLocation(); + Location lastLocation = locationEngine.getLastLocation(); if (lastLocation != null) { setLocation(lastLocation); @@ -430,14 +434,14 @@ public class MyLocationView extends View { userLocationListener = new GpsLocationListener(this); } - locationServices.addLocationListener(userLocationListener); + locationEngine.addLocationEngineListener(userLocationListener); } else { // Disable location and user dot location = null; - locationServices.removeLocationListener(userLocationListener); + locationEngine.removeLocationEngineListener(userLocationListener); } - locationServices.toggleGPS(enableGps); + locationEngine.setPriority(LocationEnginePriority.HIGH_ACCURACY); } public Location getLocation() { @@ -456,7 +460,8 @@ public class MyLocationView extends View { public void setMyBearingTrackingMode(@MyBearingTracking.Mode int myBearingTrackingMode) { this.myBearingTrackingMode = myBearingTrackingMode; - if (myBearingTrackingMode == MyBearingTracking.COMPASS) { + if (myBearingTrackingMode == MyBearingTracking.COMPASS + && compassListener.isSensorAvailable()) { compassListener.onResume(); } else { compassListener.onPause(); @@ -477,8 +482,19 @@ public class MyLocationView extends View { if (location != null) { if (myLocationTrackingMode == MyLocationTracking.TRACKING_FOLLOW) { // center map directly + mapboxMap.getTrackingSettings().setDismissTrackingModeForCameraPositionChange(false); mapboxMap.easeCamera(CameraUpdateFactory.newLatLng(new LatLng(location)), 0, false /*linear interpolator*/, - false /*do not disable tracking*/, null); + new MapboxMap.CancelableCallback() { + @Override + public void onCancel() { + + } + + @Override + public void onFinish() { + mapboxMap.getTrackingSettings().setDismissTrackingModeForCameraPositionChange(true); + } + }); } else { // do not use interpolated location from tracking mode latLng = null; @@ -528,11 +544,15 @@ public class MyLocationView extends View { directionAnimator.start(); } - public float getCenterX() { + public PointF getCenter() { + return new PointF(getCenterX(), getCenterY()); + } + + private float getCenterX() { return (getX() + getMeasuredWidth()) / 2 + contentPaddingX - projectedX; } - public float getCenterY() { + private float getCenterY() { return (getY() + getMeasuredHeight()) / 2 + contentPaddingY - projectedY; } @@ -541,7 +561,7 @@ public class MyLocationView extends View { contentPaddingY = (padding[1] - padding[3]) / 2; } - private static class GpsLocationListener implements LocationListener { + private static class GpsLocationListener implements LocationEngineListener { private WeakReference<MyLocationView> userLocationView; @@ -549,6 +569,15 @@ public class MyLocationView extends View { userLocationView = new WeakReference<>(myLocationView); } + @Override + public void onConnected() { + MyLocationView locationView = userLocationView.get(); + if (locationView != null) { + Location location = LocationSource.getLocationEngine(locationView.getContext()).getLastLocation(); + locationView.setLocation(location); + } + } + /** * Callback method for receiving location updates from LocationServices. * @@ -587,6 +616,10 @@ public class MyLocationView extends View { sensorManager.unregisterListener(this, rotationVectorSensor); } + public boolean isSensorAvailable() { + return rotationVectorSensor != null; + } + @Override public void onSensorChanged(SensorEvent event) { @@ -619,8 +652,19 @@ public class MyLocationView extends View { private void rotateCamera(float rotation) { CameraPosition.Builder builder = new CameraPosition.Builder(); builder.bearing(rotation); + mapboxMap.getTrackingSettings().setDismissTrackingModeForCameraPositionChange(false); mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), COMPASS_UPDATE_RATE_MS, - false /*linear interpolator*/, false /*do not disable tracking*/, null); + false /*linear interpolator*/, new MapboxMap.CancelableCallback() { + @Override + public void onCancel() { + + } + + @Override + public void onFinish() { + mapboxMap.getTrackingSettings().setDismissTrackingModeForCameraPositionChange(true); + } + }); } @Override @@ -734,9 +778,20 @@ public class MyLocationView extends View { // accuracy updateAccuracy(location); + mapboxMap.getTrackingSettings().setDismissTrackingModeForCameraPositionChange(false); // ease to new camera position with a linear interpolator mapboxMap.easeCamera(CameraUpdateFactory.newCameraPosition(builder.build()), (int) animationDuration, - false /*linear interpolator*/, false /*do not disable tracking*/, null); + false /*linear interpolator*/, new MapboxMap.CancelableCallback() { + @Override + public void onCancel() { + + } + + @Override + public void onFinish() { + mapboxMap.getTrackingSettings().setDismissTrackingModeForCameraPositionChange(true); + } + }); } @Override diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java index 6cfbfed733..e9d823ebda 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java @@ -1,6 +1,5 @@ package com.mapbox.mapboxsdk.maps.widgets; -import android.graphics.PointF; import android.graphics.drawable.Drawable; import android.support.annotation.ColorInt; import android.support.annotation.IntRange; @@ -289,8 +288,7 @@ public class MyLocationViewSettings { private void invalidateFocalPointForTracking(MyLocationView myLocationView) { if (!(myLocationView.getMyLocationTrackingMode() == MyLocationTracking.TRACKING_NONE)) { - focalPointChangeListener.onFocalPointChanged(new PointF(myLocationView.getCenterX(), - myLocationView.getCenterY())); + focalPointChangeListener.onFocalPointChanged(myLocationView.getCenter()); } else { focalPointChangeListener.onFocalPointChanged(null); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java index 7c37569ae2..7be56fa694 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/net/ConnectivityReceiver.java @@ -7,6 +7,7 @@ import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.support.annotation.NonNull; +import android.support.annotation.UiThread; import com.mapbox.mapboxsdk.Mapbox; @@ -27,11 +28,9 @@ public class ConnectivityReceiver extends BroadcastReceiver { */ public static synchronized ConnectivityReceiver instance(Context context) { if (INSTANCE == null) { - //Register new instance - INSTANCE = new ConnectivityReceiver(); - context.registerReceiver(INSTANCE, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE")); - - //Add default listeners + // Register new instance + INSTANCE = new ConnectivityReceiver(context.getApplicationContext()); + // Add default listeners INSTANCE.addListener(new NativeConnectivityListener()); } @@ -39,8 +38,39 @@ public class ConnectivityReceiver extends BroadcastReceiver { } private List<ConnectivityListener> listeners = new CopyOnWriteArrayList<>(); + private Context context; + private int activationCounter; + + private ConnectivityReceiver(@NonNull Context context) { + this.context = context; + } + + /** + * Activates the connectivity receiver. + * <p> + * if the underlying connectivity receiver isn't active, register the connectivity receiver. + * </p> + */ + @UiThread + public void activate() { + if (activationCounter == 0) { + context.registerReceiver(INSTANCE, new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE")); + } + activationCounter++; + } - private ConnectivityReceiver() { + /** + * Deactivates the connectivity receiver. + * <p> + * if no other components are listening, unregister the underlying connectivity receiver. + * </p> + */ + @UiThread + public void deactivate() { + activationCounter--; + if (activationCounter == 0) { + context.unregisterReceiver(INSTANCE); + } } /** @@ -51,7 +81,7 @@ public class ConnectivityReceiver extends BroadcastReceiver { boolean connected = isConnected(context); Timber.v("Connected: " + connected); - //Loop over listeners + // Loop over listeners for (ConnectivityListener listener : listeners) { listener.onNetworkStateChanged(connected); } @@ -92,5 +122,4 @@ public class ConnectivityReceiver extends BroadcastReceiver { NetworkInfo activeNetwork = cm.getActiveNetworkInfo(); return (activeNetwork != null && activeNetwork.isConnected()); } - } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java index beaea73024..8bf19c4065 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineManager.java @@ -1,15 +1,12 @@ package com.mapbox.mapboxsdk.offline; import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.os.Environment; import android.os.Handler; import android.os.Looper; import android.support.annotation.NonNull; -import com.mapbox.mapboxsdk.Mapbox; -import com.mapbox.mapboxsdk.constants.MapboxConstants; +import com.mapbox.mapboxsdk.net.ConnectivityReceiver; +import com.mapbox.mapboxsdk.storage.FileSource; import java.io.File; @@ -29,18 +26,13 @@ public class OfflineManager { System.loadLibrary("mapbox-gl"); } - // Default database name - private static final String DATABASE_NAME = "mbgl-offline.db"; - /* - * The maximumCacheSize parameter is a limit applied to non-offline resources only, - * i.e. resources added to the database for the "ambient use" caching functionality. - * There is no size limit for offline resources. - */ - private static final long DEFAULT_MAX_CACHE_SIZE = 50 * 1024 * 1024; + // Native peer pointer + private long nativePtr; - // Holds the pointer to JNI DefaultFileSource - private long mDefaultFileSourcePtr = 0; + // Reference to the file source to keep it alive for the + // lifetime of this object + private final FileSource fileSource; // Makes sure callbacks come back to the main thread private Handler handler; @@ -48,6 +40,9 @@ public class OfflineManager { // This object is implemented as a singleton private static OfflineManager instance; + // The application context + private Context context; + /** * This callback receives an asynchronous response containing a list of all * {@link OfflineRegion} in the database, or an error message otherwise. @@ -89,77 +84,17 @@ public class OfflineManager { } /* - * Constructors + * Constructor */ private OfflineManager(Context context) { - // Get a pointer to the DefaultFileSource instance - String assetRoot = getDatabasePath(context); - String cachePath = assetRoot + File.separator + DATABASE_NAME; - mDefaultFileSourcePtr = createDefaultFileSource(cachePath, assetRoot, DEFAULT_MAX_CACHE_SIZE); - setAccessToken(mDefaultFileSourcePtr, Mapbox.getAccessToken()); + this.context = context.getApplicationContext(); + this.fileSource = FileSource.getInstance(context); + initialize(fileSource); // Delete any existing previous ambient cache database deleteAmbientDatabase(context); } - public static String getDatabasePath(Context context) { - // Default value - boolean setStorageExternal = MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL; - - try { - // Try getting a custom value from the app Manifest - ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo( - context.getPackageName(), PackageManager.GET_META_DATA); - setStorageExternal = appInfo.metaData.getBoolean( - MapboxConstants.KEY_META_DATA_SET_STORAGE_EXTERNAL, - MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL); - } catch (PackageManager.NameNotFoundException exception) { - Timber.e("Failed to read the package metadata: ", exception); - } catch (Exception exception) { - Timber.e("Failed to read the storage key: ", exception); - } - - String databasePath = null; - if (setStorageExternal && isExternalStorageReadable()) { - try { - // Try getting the external storage path - databasePath = context.getExternalFilesDir(null).getAbsolutePath(); - } catch (NullPointerException exception) { - Timber.e("Failed to obtain the external storage path: ", exception); - } - } - - if (databasePath == null) { - // Default to internal storage - databasePath = context.getFilesDir().getAbsolutePath(); - } - - return databasePath; - } - - /** - * Checks if external storage is available to at least read. In order for this to work, make - * sure you include <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> - * (or WRITE_EXTERNAL_STORAGE) for API level < 18 in your app Manifest. - * <p> - * Code from https://developer.android.com/guide/topics/data/data-storage.html#filesExternal - * </p> - * - * @return true if external storage is readable - */ - public static boolean isExternalStorageReadable() { - String state = Environment.getExternalStorageState(); - if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { - return true; - } - - Timber.w("External storage was requested but it isn't readable. For API level < 18" - + " make sure you've requested READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE" - + " permissions in your app Manifest (defaulting to internal storage)."); - - return false; - } - private void deleteAmbientDatabase(final Context context) { // Delete the file in a separate thread to avoid affecting the UI new Thread(new Runnable() { @@ -205,7 +140,8 @@ public class OfflineManager { * @param callback the callback to be invoked */ public void listOfflineRegions(@NonNull final ListOfflineRegionsCallback callback) { - listOfflineRegions(mDefaultFileSourcePtr, new ListOfflineRegionsCallback() { + listOfflineRegions(fileSource, new ListOfflineRegionsCallback() { + @Override public void onList(final OfflineRegion[] offlineRegions) { getHandler().post(new Runnable() { @@ -249,12 +185,15 @@ public class OfflineManager { @NonNull byte[] metadata, @NonNull final CreateOfflineRegionCallback callback) { - createOfflineRegion(mDefaultFileSourcePtr, definition, metadata, new CreateOfflineRegionCallback() { + ConnectivityReceiver.instance(context).activate(); + createOfflineRegion(fileSource, definition, metadata, new CreateOfflineRegionCallback() { + @Override public void onCreate(final OfflineRegion offlineRegion) { getHandler().post(new Runnable() { @Override public void run() { + ConnectivityReceiver.instance(context).deactivate(); callback.onCreate(offlineRegion); } }); @@ -265,6 +204,7 @@ public class OfflineManager { getHandler().post(new Runnable() { @Override public void run() { + ConnectivityReceiver.instance(context).deactivate(); callback.onError(error); } }); @@ -276,29 +216,16 @@ public class OfflineManager { * Changing or bypassing this limit without permission from Mapbox is prohibited * by the Mapbox Terms of Service. */ - public void setOfflineMapboxTileCountLimit(long limit) { - setOfflineMapboxTileCountLimit(mDefaultFileSourcePtr, limit); - } - - - /* - * Native methods - */ - private native long createDefaultFileSource( - String cachePath, String assetRoot, long maximumCacheSize); - - private native void setAccessToken(long defaultFileSourcePtr, String accessToken); + public native void setOfflineMapboxTileCountLimit(long limit); - private native String getAccessToken(long defaultFileSourcePtr); + private native void initialize(FileSource fileSource); - private native void listOfflineRegions( - long defaultFileSourcePtr, ListOfflineRegionsCallback callback); + @Override + protected native void finalize() throws Throwable; - private native void createOfflineRegion( - long defaultFileSourcePtr, OfflineRegionDefinition definition, - byte[] metadata, CreateOfflineRegionCallback callback); + private native void listOfflineRegions(FileSource fileSource, ListOfflineRegionsCallback callback); - private native void setOfflineMapboxTileCountLimit( - long defaultFileSourcePtr, long limit); + private native void createOfflineRegion(FileSource fileSource, OfflineRegionDefinition definition, + byte[] metadata, CreateOfflineRegionCallback callback); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java index a4d8a646d3..a55e8dd848 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegion.java @@ -5,7 +5,7 @@ import android.os.Looper; import android.support.annotation.IntDef; import android.support.annotation.NonNull; -import timber.log.Timber; +import com.mapbox.mapboxsdk.storage.FileSource; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -25,22 +25,25 @@ public class OfflineRegion { System.loadLibrary("mapbox-gl"); } - // Parent OfflineManager - private OfflineManager offlineManager; - // Members - private long mId = 0; - private OfflineRegionDefinition mDefinition = null; + + // Holds the pointer to JNI OfflineRegion + private long nativePtr; + + // Holds a reference to the FileSource to keep it alive + private FileSource fileSource; + + //Region id + private long id; + + private OfflineRegionDefinition definition; /** * Arbitrary binary region metadata. The contents are opaque to the SDK implementation; * it just stores and retrieves a byte[]. Check the `OfflineActivity` in the TestApp * for a sample implementation that uses JSON to store an offline region name. */ - private byte[] mMetadata = null; - - // Holds the pointer to JNI OfflineRegion - private long mOfflineRegionPtr = 0; + private byte[] metadata; // Makes sure callbacks come back to the main thread private Handler handler; @@ -197,19 +200,22 @@ public class OfflineRegion { if (state == STATE_ACTIVE) { return true; } - if (isDeliveringInactiveMessages()) { - return true; - } - return false; + return isDeliveringInactiveMessages(); } - /* + /** * Constructor + * + * For JNI use only, to create a new offline region, use + * {@link OfflineManager#createOfflineRegion} instead. */ - - private OfflineRegion() { - // For JNI use only, to create a new offline region, use - // OfflineManager.createOfflineRegion() instead. + private OfflineRegion(long offlineRegionPtr, FileSource fileSource, long id, + OfflineRegionDefinition definition, byte[] metadata) { + this.fileSource = fileSource; + this.id = id; + this.definition = definition; + this.metadata = metadata; + initialize(offlineRegionPtr, fileSource); } /* @@ -217,15 +223,15 @@ public class OfflineRegion { */ public long getID() { - return mId; + return id; } public OfflineRegionDefinition getDefinition() { - return mDefinition; + return definition; } public byte[] getMetadata() { - return mMetadata; + return metadata; } private Handler getHandler() { @@ -383,7 +389,7 @@ public class OfflineRegion { getHandler().post(new Runnable() { @Override public void run() { - mMetadata = metadata; + OfflineRegion.this.metadata = metadata; callback.onUpdate(metadata); } }); @@ -401,33 +407,18 @@ public class OfflineRegion { }); } - @Override - protected void finalize() { - try { - super.finalize(); - destroyOfflineRegion(); - } catch (Throwable throwable) { - Timber.e("Failed to finalize OfflineRegion: " + throwable.getMessage()); - } - } - - /* - * Native methods - */ + private native void initialize(long offlineRegionPtr, FileSource fileSource); - private native void destroyOfflineRegion(); + @Override + protected native void finalize(); - private native void setOfflineRegionObserver( - OfflineRegionObserver observerCallback); + private native void setOfflineRegionObserver(OfflineRegionObserver callback); - private native void setOfflineRegionDownloadState( - @DownloadState int offlineRegionDownloadState); + private native void setOfflineRegionDownloadState(@DownloadState int offlineRegionDownloadState); - private native void getOfflineRegionStatus( - OfflineRegionStatusCallback statusCallback); + private native void getOfflineRegionStatus(OfflineRegionStatusCallback callback); - private native void deleteOfflineRegion( - OfflineRegionDeleteCallback deleteCallback); + private native void deleteOfflineRegion(OfflineRegionDeleteCallback callback); private native void updateOfflineRegionMetadata(byte[] metadata, OfflineRegionUpdateMetadataCallback callback); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java index 60c4a8661c..83f3c06d68 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionError.java @@ -25,25 +25,23 @@ public class OfflineRegionError { public static final String REASON_OTHER = "REASON_OTHER"; @ErrorReason - private String reason; + private final String reason; /** * /* An error message from the request handler, e.g. a server message or a system message * /* informing the user about the reason for the failure. */ - private String message; + private final String message; - /* - * Constructors - */ + // Constructors - private OfflineRegionError() { + private OfflineRegionError(String reason, String message) { // For JNI use only + this.reason = reason; + this.message = message; } - /* - * Getters - */ + // Getters @ErrorReason public String getReason() { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java index 11f2da132d..9c3655fbec 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineRegionStatus.java @@ -56,24 +56,29 @@ public class OfflineRegionStatus { /* * Use setObserver(OfflineRegionObserver observer) to obtain a OfflineRegionStatus object. + * + * For JNI use only */ - - private OfflineRegionStatus() { - // For JNI use only + private OfflineRegionStatus(int downloadState, long completedResourceCount, + long completedResourceSize, long completedTileCount, + long completedTileSize, long requiredResourceCount, + boolean requiredResourceCountIsPrecise) { + this.downloadState = downloadState; + this.completedResourceCount = completedResourceCount; + this.completedResourceSize = completedResourceSize; + this.completedTileCount = completedTileCount; + this.completedTileSize = completedTileSize; + this.requiredResourceCount = requiredResourceCount; + this.requiredResourceCountIsPrecise = requiredResourceCountIsPrecise; } - /* + /** * Is the region complete? */ - public boolean isComplete() { return (completedResourceCount == requiredResourceCount); } - /* - * Getters - */ - @OfflineRegion.DownloadState public int getDownloadState() { return downloadState; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java index 5fc844afe5..f8ec0f3d39 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/offline/OfflineTilePyramidRegionDefinition.java @@ -21,16 +21,18 @@ public class OfflineTilePyramidRegionDefinition implements OfflineRegionDefiniti private double maxZoom; private float pixelRatio; - /* - * Constructors + /** + * Constructor + * + * @param styleURL the style + * @param bounds the bounds + * @param minZoom min zoom + * @param maxZoom max zoom + * @param pixelRatio pixel ratio of the device */ - - private OfflineTilePyramidRegionDefinition() { - // For JNI use only - } - public OfflineTilePyramidRegionDefinition( String styleURL, LatLngBounds bounds, double minZoom, double maxZoom, float pixelRatio) { + // Note: Also used in JNI this.styleURL = styleURL; this.bounds = bounds; this.minZoom = minZoom; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java new file mode 100644 index 0000000000..8681777023 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/FileSource.java @@ -0,0 +1,135 @@ +package com.mapbox.mapboxsdk.storage; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.os.Environment; +import android.support.annotation.NonNull; + +import com.mapbox.mapboxsdk.Mapbox; +import com.mapbox.mapboxsdk.constants.MapboxConstants; + +import timber.log.Timber; + +/** + * Holds a central reference to the core's DefaultFileSource for as long as + * there are active mapviews / offline managers + */ +public class FileSource { + + /** + * This callback allows implementors to transform URLs before they are requested + * from the internet. This can be used add or remove custom parameters, or reroute + * certain requests to other servers or endpoints. + */ + public interface ResourceTransformCallback { + + /** + * Called whenever a URL needs to be transformed. + * + * @param kind The kind of URL to be transformed. + * @return A URL that will now be downloaded. + */ + String onURL(@Resource.Kind int kind, String url); + + } + + // File source instance is kept alive after initialization + private static FileSource INSTANCE; + + public static synchronized FileSource getInstance(Context context) { + if (INSTANCE == null) { + String cachePath = getCachePath(context); + String apkPath = context.getPackageCodePath(); + INSTANCE = new FileSource(cachePath, apkPath); + } + + return INSTANCE; + } + + public static String getCachePath(Context context) { + // Default value + boolean setStorageExternal = MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL; + + try { + // Try getting a custom value from the app Manifest + ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), + PackageManager.GET_META_DATA); + setStorageExternal = appInfo.metaData.getBoolean( + MapboxConstants.KEY_META_DATA_SET_STORAGE_EXTERNAL, + MapboxConstants.DEFAULT_SET_STORAGE_EXTERNAL); + } catch (PackageManager.NameNotFoundException exception) { + Timber.e("Failed to read the package metadata: ", exception); + } catch (Exception exception) { + Timber.e("Failed to read the storage key: ", exception); + } + + String cachePath = null; + if (setStorageExternal && isExternalStorageReadable()) { + try { + // Try getting the external storage path + cachePath = context.getExternalFilesDir(null).getAbsolutePath(); + } catch (NullPointerException exception) { + Timber.e("Failed to obtain the external storage path: ", exception); + } + } + + if (cachePath == null) { + // Default to internal storage + cachePath = context.getFilesDir().getAbsolutePath(); + } + + return cachePath; + } + + /** + * Checks if external storage is available to at least read. In order for this to work, make + * sure you include <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + * (or WRITE_EXTERNAL_STORAGE) for API level < 18 in your app Manifest. + * <p> + * Code from https://developer.android.com/guide/topics/data/data-storage.html#filesExternal + * </p> + * + * @return true if external storage is readable + */ + public static boolean isExternalStorageReadable() { + String state = Environment.getExternalStorageState(); + if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { + return true; + } + + Timber.w("External storage was requested but it isn't readable. For API level < 18" + + " make sure you've requested READ_EXTERNAL_STORAGE or WRITE_EXTERNAL_STORAGE" + + " permissions in your app Manifest (defaulting to internal storage)."); + + return false; + } + + private long nativePtr; + + private FileSource(String cachePath, String apkPath) { + initialize(Mapbox.getAccessToken(), cachePath, apkPath); + } + + public native void setAccessToken(@NonNull String accessToken); + + public native String getAccessToken(); + + public native void setApiBaseUrl(String baseUrl); + + /** + * Sets a callback for transforming URLs requested from the internet + * <p> + * The callback will be executed on the main thread once for every requested URL. + * </p> + * + * @param callback the callback to be invoked + */ + public native void setResourceTransform(@NonNull final ResourceTransformCallback callback); + + private native void initialize(String accessToken, String cachePath, String apkPath); + + @Override + protected native void finalize() throws Throwable; + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/Resource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/Resource.java new file mode 100644 index 0000000000..af98a46a9b --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/storage/Resource.java @@ -0,0 +1,54 @@ +package com.mapbox.mapboxsdk.storage; + +import android.support.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +public final class Resource { + // Note: Keep this in sync with include/mbgl/storage/resource.hpp + + @IntDef( {UNKNOWN, STYLE, SOURCE, TILE, GLYPHS, SPRITE_IMAGE, SPRITE_JSON}) + @Retention(RetentionPolicy.SOURCE) + public @interface Kind { + } + + /** + * Unknown type + */ + public static final int UNKNOWN = 0; + + /** + * Style sheet JSON file + */ + public static final int STYLE = 1; + + /** + * TileJSON file as specified in https://www.mapbox.com/mapbox-gl-js/style-spec/#root-sources + */ + public static final int SOURCE = 2; + + /** + * A vector or raster tile as described in the style sheet at + * https://www.mapbox.com/mapbox-gl-js/style-spec/#sources + */ + public static final int TILE = 3; + + /** + * Signed distance field glyphs for text rendering. These are the URLs specified in the style + * in https://www.mapbox.com/mapbox-gl-js/style-spec/#root-glyphs + */ + public static final int GLYPHS = 4; + + /** + * Image part of a sprite sheet. It is constructed of the prefix in + * https://www.mapbox.com/mapbox-gl-js/style-spec/#root-sprite and a PNG file extension. + */ + public static final int SPRITE_IMAGE = 5; + + /** + * JSON part of a sprite sheet. It is constructed of the prefix in + * https://www.mapbox.com/mapbox-gl-js/style-spec/#root-sprite and a JSON file extension. + */ + public static final int SPRITE_JSON = 6; +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CameraFunction.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CameraFunction.java new file mode 100644 index 0000000000..bb87fe8a39 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CameraFunction.java @@ -0,0 +1,50 @@ +package com.mapbox.mapboxsdk.style.functions; + +import android.support.annotation.Keep; +import android.support.annotation.NonNull; + +import com.mapbox.mapboxsdk.style.functions.stops.ExponentialStops; +import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops; +import com.mapbox.mapboxsdk.style.functions.stops.Stop; +import com.mapbox.mapboxsdk.style.functions.stops.Stops; + +/** + * Camera function. Functions that take camera properties as input (zoom for now) + * <p> + * Zoom functions allow the appearance of a map feature to change with map’s zoom level. + * Zoom functions can be used to create the illusion of depth and control data density. + * Each stop is an array with two elements: the first is a zoom level and the second is + * a function output value. + * + * @param <I> the input type + * @param <O> the output type + * @see Function#zoom + */ +public class CameraFunction<I extends Number, O> extends Function<I, O> { + + /** + * Create an exponential camera function + * + * @param stops @see {@link com.mapbox.mapboxsdk.style.functions.stops.Stops#exponential(float, Stop[])} + */ + CameraFunction(@NonNull ExponentialStops<I, O> stops) { + super(stops); + } + + /** + * Create an interval camera function + * + * @param stops @see {@link com.mapbox.mapboxsdk.style.functions.stops.Stops#interval(Stop[])} + */ + CameraFunction(@NonNull IntervalStops<I, O> stops) { + super(stops); + } + + /** + * JNI constructor + */ + @Keep + private CameraFunction(Stops<I, O> stops) { + super(stops); + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CompositeFunction.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CompositeFunction.java new file mode 100644 index 0000000000..1db14afc5f --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/CompositeFunction.java @@ -0,0 +1,99 @@ +package com.mapbox.mapboxsdk.style.functions; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.mapbox.mapboxsdk.style.functions.stops.CategoricalStops; +import com.mapbox.mapboxsdk.style.functions.stops.ExponentialStops; +import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops; +import com.mapbox.mapboxsdk.style.functions.stops.Stop; +import com.mapbox.mapboxsdk.style.functions.stops.Stops; + +import java.util.Map; + +/** + * Composite functions combine {@link android.graphics.Camera} and {@link SourceFunction}s. + * <p> + * Composite functions allow the appearance of a map feature to change with both its + * properties and zoom. Each stop is an array with two elements, the first is an object + * with a property input value and a zoom, and the second is a function output value. Note + * that support for property functions is not yet complete. + * + * @param <Z> the zoom type (usually Float) + * @param <I> the input type (the feature property type) + * @param <O> the output type (the property type) + * @see Function#composite + */ +public class CompositeFunction<Z extends Number, I, O> extends Function<Stop.CompositeValue<Z, I>, O> { + + private final String property; + private O defaultValue; + + CompositeFunction(@NonNull String property, + @NonNull CategoricalStops<Stop.CompositeValue<Z, I>, O> stops) { + this(null, property, stops); + } + + CompositeFunction(@NonNull String property, + @NonNull ExponentialStops<Stop.CompositeValue<Z, I>, O> stops) { + this(null, property, stops); + } + + CompositeFunction(@NonNull String property, + @NonNull IntervalStops<Stop.CompositeValue<Z, I>, O> stops) { + this(null, property, stops); + } + + + /** + * JNI Constructor + */ + private CompositeFunction(@Nullable O defaultValue, @NonNull String property, + @NonNull Stops<Stop.CompositeValue<Z, I>, O> stops) { + super(stops); + this.defaultValue = defaultValue; + this.property = property; + } + + /** + * Set the default value + * + * @param defaultValue the default value to use when no other applies + * @return this (for chaining) + */ + public CompositeFunction<Z, I, O> withDefaultValue(O defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + /** + * @return the defaultValue + */ + @Nullable + public O getDefaultValue() { + return defaultValue; + } + + /** + * INTERNAL USAGE ONLY + * + * @return the feature property name + */ + public String getProperty() { + return property; + } + + /** + * {@inheritDoc} + */ + @Override + public Map<String, Object> toValueObject() { + Map<String, Object> valueObject = super.toValueObject(); + valueObject.put(PROPERTY_KEY, property); + if (defaultValue != null) { + valueObject.put(DEFAULT_VALUE_KEY, defaultValue); + } + return valueObject; + } + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/Function.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/Function.java new file mode 100644 index 0000000000..e1e40821b1 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/Function.java @@ -0,0 +1,300 @@ +package com.mapbox.mapboxsdk.style.functions; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.mapbox.mapboxsdk.style.functions.stops.CategoricalStops; +import com.mapbox.mapboxsdk.style.functions.stops.ExponentialStops; +import com.mapbox.mapboxsdk.style.functions.stops.IdentityStops; +import com.mapbox.mapboxsdk.style.functions.stops.IntervalStops; +import com.mapbox.mapboxsdk.style.functions.stops.Stop; +import com.mapbox.mapboxsdk.style.functions.stops.Stops; + +import java.util.Map; + +import timber.log.Timber; + +/** + * Functions are used to change properties in relation to the state of the map. + * <p> + * The value for any layout or paint property may be specified as a function. Functions allow you to + * make the appearance of a map feature change with the current zoom level and/or the feature's properties. + * + * @param <I> the function's input type + * @param <O> the target property's value type. Make sure it matches. + * @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-function">The style specification</a> + */ +public class Function<I, O> { + + static final String PROPERTY_KEY = "property"; + static final String DEFAULT_VALUE_KEY = "default"; + + /** + * Create an exponential {@link CameraFunction} + * <p> + * Zoom functions allow the appearance of a map feature to change with map’s zoom. + * Zoom functions can be used to create the illusion of depth and control data density. + * Each stop is an array with two elements, the first is a zoom and the second is a function output value. + * + * @param <Z> the zoom level type (Float, Integer) + * @param <O> the property type + * @param stops the stops implementation that define the function. @see {@link Stops#exponential(Stop[])} + * @return the {@link CameraFunction} + * @see CameraFunction + * @see ExponentialStops + * @see Stops#exponential(Stop[]) + * @see Stops#exponential(Stop[]) + * @see Stop#stop + */ + public static <Z extends Number, O> CameraFunction<Z, O> zoom(@NonNull ExponentialStops<Z, O> stops) { + return new CameraFunction<>(stops); + } + + /** + * Create an interval {@link CameraFunction} + * <p> + * Zoom functions allow the appearance of a map feature to change with map’s zoom. + * Zoom functions can be used to create the illusion of depth and control data density. + * Each stop is an array with two elements, the first is a zoom and the second is a function output value. + * + * @param <Z> the zoom level type (Float, Integer) + * @param <O> the property type + * @param stops the stops implementation that define the function. @see {@link Stops#interval(Stop[])} + * @return the {@link CameraFunction} + * @see CameraFunction + * @see IntervalStops + * @see Stops#interval(Stop[]) + * @see Stop#stop + */ + public static <Z extends Number, O> CameraFunction<Z, O> zoom(@NonNull IntervalStops<Z, O> stops) { + return new CameraFunction<>(stops); + } + + /** + * Create an exponential {@link SourceFunction} + * <p> + * Source functions allow the appearance of a map feature to change with + * its properties. Source functions can be used to visually differentiate + * types of features within the same layer or create data visualizations. + * Each stop is an array with two elements, the first is a property input + * value and the second is a function output value. Note that support for + * property functions is not available across all properties and platforms + * at this time. + * + * @param property the feature property name + * @param stops the stops + * @param <I> the function input type + * @param <O> the function output type + * @return the {@link SourceFunction} + * @see SourceFunction + * @see ExponentialStops + * @see Stops#exponential(Stop[]) + * @see Stop#stop + */ + public static <I, O> SourceFunction<I, O> property(@NonNull String property, @NonNull ExponentialStops<I, O> stops) { + return new SourceFunction<>(property, stops); + } + + /** + * Create an identity {@link SourceFunction} + * <p> + * Source functions allow the appearance of a map feature to change with + * its properties. Source functions can be used to visually differentiate + * types of features within the same layer or create data visualizations. + * Each stop is an array with two elements, the first is a property input + * value and the second is a function output value. Note that support for + * property functions is not available across all properties and platforms + * at this time. + * + * @param property the feature property name + * @param stops the stops + * @param <T> the function input/output type + * @return the {@link SourceFunction} + * @see SourceFunction + * @see IdentityStops + * @see Stops#identity() + * @see Stop#stop + */ + public static <T> SourceFunction<T, T> property(@NonNull String property, @NonNull IdentityStops<T> stops) { + return new SourceFunction<>(property, stops); + } + + /** + * Create an interval {@link SourceFunction} + * <p> + * Source functions allow the appearance of a map feature to change with + * its properties. Source functions can be used to visually differentiate + * types of features within the same layer or create data visualizations. + * Each stop is an array with two elements, the first is a property input + * value and the second is a function output value. Note that support for + * property functions is not available across all properties and platforms + * at this time. + * + * @param property the feature property name + * @param stops the stops + * @param <I> the function input type + * @param <O> the function output type + * @return the {@link SourceFunction} + * @see SourceFunction + * @see IntervalStops + * @see Stops#interval(Stop[]) + * @see Stop#stop + */ + public static <I, O> SourceFunction<I, O> property(@NonNull String property, @NonNull IntervalStops<I, O> stops) { + return new SourceFunction<>(property, stops); + } + + /** + * Create an categorical {@link SourceFunction} + * <p> + * Source functions allow the appearance of a map feature to change with + * its properties. Source functions can be used to visually differentiate + * types of features within the same layer or create data visualizations. + * Each stop is an array with two elements, the first is a property input + * value and the second is a function output value. Note that support for + * property functions is not available across all properties and platforms + * at this time. + * + * @param property the feature property name + * @param stops the stops + * @param <I> the function input type + * @param <O> the function output type + * @return the {@link SourceFunction} + * @see SourceFunction + * @see CategoricalStops + * @see Stops#categorical(Stop[]) + * @see Stop#stop + */ + public static <I, O> SourceFunction<I, O> property(@NonNull String property, @NonNull CategoricalStops<I, O> stops) { + return new SourceFunction<>(property, stops); + } + + /** + * Create a composite, categorical function. + * <p> + * Composite functions allow the appearance of a map feature to change with both its + * properties and zoom. Each stop is an array with two elements, the first is an object + * with a property input value and a zoom, and the second is a function output value. Note + * that support for property functions is not yet complete. + * + * @param property the feature property name for the source part of the function + * @param stops the stops + * @param <Z> the zoom function input type (Float usually) + * @param <I> the function input type for the source part of the function + * @param <O> the function output type + * @return the {@link CompositeFunction} + * @see CompositeFunction + * @see CategoricalStops + * @see Stops#categorical(Stop[]) + * @see Stop#stop + */ + public static <Z extends Number, I, O> CompositeFunction<Z, I, O> composite( + @NonNull String property, + @NonNull CategoricalStops<Stop.CompositeValue<Z, I>, O> stops) { + + return new CompositeFunction<>(property, stops); + } + + /** + * Create a composite, exponential function. + * <p> + * Composite functions allow the appearance of a map feature to change with both its + * properties and zoom. Each stop is an array with two elements, the first is an object + * with a property input value and a zoom, and the second is a function output value. Note + * that support for property functions is not yet complete. + * + * @param property the feature property name for the source part of the function + * @param stops the stops + * @param <Z> the zoom function input type (Float usually) + * @param <I> the function input type for the source part of the function + * @param <O> the function output type + * @return the {@link CompositeFunction} + * @see CompositeFunction + * @see ExponentialStops + * @see Stops#exponential(Stop[]) + * @see Stop#stop + */ + public static <Z extends Number, I, O> CompositeFunction<Z, I, O> composite( + @NonNull String property, + @NonNull ExponentialStops<Stop.CompositeValue<Z, I>, O> stops) { + + return new CompositeFunction<>(property, stops); + } + + /** + * Create a composite, interval function. + * <p> + * Composite functions allow the appearance of a map feature to change with both its + * properties and zoom. Each stop is an array with two elements, the first is an object + * with a property input value and a zoom, and the second is a function output value. Note + * that support for property functions is not yet complete. + * + * @param property the feature property name for the source part of the function + * @param stops the stops + * @param <Z> the zoom function input type (Float usually) + * @param <I> the function input type for the source part of the function + * @param <O> the function output type + * @return the {@link CompositeFunction} + * @see CompositeFunction + * @see IntervalStops + * @see Stops#interval(Stop[]) + * @see Stop#stop + */ + public static <Z extends Number, I, O> CompositeFunction<Z, I, O> composite( + @NonNull String property, + @NonNull IntervalStops<Stop.CompositeValue<Z, I>, O> stops) { + + return new CompositeFunction<>(property, stops); + } + + // Class definition // + + private final Stops<I, O> stops; + + /** + * JNI Cosntructor for implementation classes + * + * @param stops the stops + */ + Function(@NonNull Stops<I, O> stops) { + this.stops = stops; + } + + /** + * @return the stops in this function + */ + public Stops getStops() { + return stops; + } + + /** + * Convenience method + * + * @param <S> the Stops implementation type + * @return the Stops implementation or null when the wrong type is specified + */ + @Nullable + public <S extends Stops> S getStopsAs() { + try { + // noinspection unchecked + return (S) stops; + } catch (ClassCastException exception) { + Timber.e(String.format("Stops: %s is a different type: %s", stops.getClass(), exception)); + return null; + } + } + + /** + * INTERNAL USAGE ONLY + * + * @return a value object representation for core conversion + */ + public Map<String, Object> toValueObject() { + return stops.toValueObject(); + } + + @Override + public String toString() { + return String.format("%s: %s", getClass().getSimpleName(), stops); + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/SourceFunction.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/SourceFunction.java new file mode 100644 index 0000000000..f0eed760a4 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/SourceFunction.java @@ -0,0 +1,84 @@ +package com.mapbox.mapboxsdk.style.functions; + +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.mapbox.mapboxsdk.style.functions.stops.Stops; + +import java.util.Map; + +/** + * Source functions take Feature property names as input. + * <p> + * Source functions allow the appearance of a map feature to change with + * its properties. Source functions can be used to visually differentiate + * types of features within the same layer or create data visualizations. + * Each stop is an array with two elements, the first is a property input + * value and the second is a function output value. Note that support for + * property functions is not available across all properties and platforms + * at this time. + * + * @param <I> the input type + * @param <O> the output type + * @see Function#property + */ +public class SourceFunction<I, O> extends Function<I, O> { + + private final String property; + private O defaultValue; + + SourceFunction(@NonNull String property, @NonNull Stops<I, O> stops) { + this(null, property, stops); + } + + /** + * JNI Constructor + */ + private SourceFunction(@Nullable O defaultValue, @NonNull String property, @NonNull Stops<I, O> stops) { + super(stops); + this.property = property; + this.defaultValue = defaultValue; + } + + + /** + * INTERNAL USAGE ONLY + * + * @return The feature property name + */ + public String getProperty() { + return property; + } + + /** + * Set the default value + * + * @param defaultValue the default value to use when no other applies + * @return this (for chaining) + */ + public SourceFunction<I, O> withDefaultValue(O defaultValue) { + this.defaultValue = defaultValue; + return this; + } + + /** + * @return the defaultValue + */ + @Nullable + public O getDefaultValue() { + return defaultValue; + } + + /** + * {@inheritDoc} + */ + @Override + public Map<String, Object> toValueObject() { + Map<String, Object> valueObject = super.toValueObject(); + valueObject.put(PROPERTY_KEY, property); + if (defaultValue != null) { + valueObject.put(DEFAULT_VALUE_KEY, defaultValue); + } + return valueObject; + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/package-info.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/package-info.java new file mode 100644 index 0000000000..6979676c9e --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/package-info.java @@ -0,0 +1,6 @@ +/** + * Contains the Mapbox Maps Android Style Function API classes. + * + * @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-function">The style specification</a> + */ +package com.mapbox.mapboxsdk.style.functions; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/CategoricalStops.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/CategoricalStops.java new file mode 100644 index 0000000000..f9b2929350 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/CategoricalStops.java @@ -0,0 +1,64 @@ +package com.mapbox.mapboxsdk.style.functions.stops; + +import android.support.annotation.NonNull; +import android.support.annotation.Size; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.Map; + +/** + * {@link Stops} implementation for categorical functions + * + * @param <I> the {@link Stop} input type + * @param <O> the {@link Stop} output type + */ +public class CategoricalStops<I, O> extends IterableStops<I, O, Stop<I, O>> { + + private final Stop<I, O>[] stops; + + /** + * Create a categorical {@link Stops} implementation. Use through {@link Stops#categorical(Stop[])} + * + * @param stops the stops + */ + @SafeVarargs + public CategoricalStops(@NonNull @Size(min = 1) Stop<I, O>... stops) { + this.stops = stops; + } + + /** + * {@inheritDoc} + */ + @Override + public Map<String, Object> toValueObject() { + Map<String, Object> map = super.toValueObject(); + map.put("stops", toValueObjects(stops)); + return map; + } + + /** + * {@inheritDoc} + */ + @Override + public String getTypeName() { + return "categorical"; + } + + /** + * {@inheritDoc} + */ + @Override + public Iterator<Stop<I, O>> iterator() { + return Arrays.asList(stops).iterator(); + } + + /** + * {@inheritDoc} + */ + @Override + public int size() { + return stops.length; + } + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/ExponentialStops.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/ExponentialStops.java new file mode 100644 index 0000000000..d47aa1fc91 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/ExponentialStops.java @@ -0,0 +1,97 @@ +package com.mapbox.mapboxsdk.style.functions.stops; + +import android.support.annotation.NonNull; +import android.support.annotation.Size; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.Map; + +/** + * The {@link Stops} implementation for exponential functions + * + * @param <I> the input type + * @param <O> the output type + */ +public class ExponentialStops<I, O> extends IterableStops<I, O, Stop<I, O>> { + + private float base; + private final Stop<I, O>[] stops; + + /** + * Create exponential stops with an explicit base. Use through {@link Stops#exponential(Stop[])} + * + * @param base The exponential base of the interpolation curve. It controls the rate at which the function output + * increases. Higher values make the output increase more towards the high end of the range. + * With values close to 1 the output increases linearly. + * @param stops the stops + */ + @SafeVarargs + public ExponentialStops(Float base, @NonNull @Size(min = 1) Stop<I, O>... stops) { + this.base = base != null ? base : 1.0f; + this.stops = stops; + } + + /** + * Create exponential stops without an explicit base. Use through {@link Stops#exponential(Stop[])} + * + * @param stops the stops + */ + @SafeVarargs + public ExponentialStops(@NonNull @Size(min = 1) Stop<I, O>... stops) { + this(null, stops); + } + + /** + * Set the exponential base + * + * @param base the base to use in the exponential function + * @return this (for chaining) + */ + public ExponentialStops<I, O> withBase(float base) { + this.base = base; + return this; + } + + /** + * @return The exponential base + */ + public float getBase() { + return base; + } + + /** + * {@inheritDoc} + */ + @Override + public Map<String, Object> toValueObject() { + Map<String, Object> map = super.toValueObject(); + map.put("base", base); + map.put("stops", toValueObjects(stops)); + return map; + } + + /** + * {@inheritDoc} + */ + @Override + public String getTypeName() { + return "exponential"; + } + + /** + * {@inheritDoc} + */ + @Override + public Iterator<Stop<I, O>> iterator() { + return Arrays.asList(stops).iterator(); + } + + /** + * {@inheritDoc} + */ + @Override + public int size() { + return stops.length; + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/IdentityStops.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/IdentityStops.java new file mode 100644 index 0000000000..2c0b198dc2 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/IdentityStops.java @@ -0,0 +1,18 @@ +package com.mapbox.mapboxsdk.style.functions.stops; + +/** + * The {@link Stops} implementation for identity functions + * + * @param <T> the input/output type + */ +public class IdentityStops<T> extends Stops<T, T> { + + /** + * {@inheritDoc} + */ + @Override + protected String getTypeName() { + return "identity"; + } + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/IntervalStops.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/IntervalStops.java new file mode 100644 index 0000000000..9d95b3f8c1 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/IntervalStops.java @@ -0,0 +1,58 @@ +package com.mapbox.mapboxsdk.style.functions.stops; + +import android.support.annotation.NonNull; +import android.support.annotation.Size; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.Map; + +/** + * The {@link Stops} implementation for interval functions + * + * @param <I> the input type + * @param <O> the output type + */ +public class IntervalStops<I, O> extends IterableStops<I, O, Stop<I, O>> { + + private final Stop<I, O>[] stops; + + @SafeVarargs + public IntervalStops(@NonNull @Size(min = 1) Stop<I, O>... stops) { + this.stops = stops; + } + + /** + * {@inheritDoc} + */ + @Override + public String getTypeName() { + return "interval"; + } + + /** + * {@inheritDoc} + */ + @Override + public Map<String, Object> toValueObject() { + Map<String, Object> map = super.toValueObject(); + map.put("stops", toValueObjects(stops)); + return map; + } + + /** + * @return an {@link Iterator} for the contained stops + */ + @Override + public Iterator<Stop<I, O>> iterator() { + return Arrays.asList(stops).iterator(); + } + + /** + * @return The number of contained stops + */ + @Override + public int size() { + return stops.length; + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/IterableStops.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/IterableStops.java new file mode 100644 index 0000000000..8c5a6e8913 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/IterableStops.java @@ -0,0 +1,52 @@ +package com.mapbox.mapboxsdk.style.functions.stops; + +import java.util.Iterator; + +/** + * Base class for {@link Stops} implementations with a collection of stops + * + * @param <I> the {@link Stops} input type + * @param <O> the {@link Stops} output type + * @param <S> the {@link Iterable} element type (usually {@link Stop}) + */ +public abstract class IterableStops<I, O, S> extends Stops<I, O> implements Iterable<S> { + + /** + * @return The size of the contained stops collection + */ + public abstract int size(); + + /** + * Convenience function to toValueObjects an array of stops to an array of value objects + * + * @param stops the stops to toValueObjects + * @return the stops as value objects + */ + Object[] toValueObjects(Stop<I, O>[] stops) { + if (stops != null) { + Object[] stopsValue = new Object[stops.length]; + + for (int i = 0; i < stopsValue.length; i++) { + Stop stop = stops[i]; + stopsValue[i] = stop.toValueObject(); + } + return stopsValue; + } + + return null; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + Iterator<S> iterator = iterator(); + while (iterator.hasNext()) { + S stop = iterator.next(); + buffer.append(stop); + if (iterator.hasNext()) { + buffer.append(","); + } + } + return String.format("%s: [%s]", super.toString(), buffer.toString()); + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/Stop.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/Stop.java new file mode 100644 index 0000000000..72164f4c4b --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/Stop.java @@ -0,0 +1,109 @@ +package com.mapbox.mapboxsdk.style.functions.stops; + +import com.mapbox.mapboxsdk.style.functions.Function; +import com.mapbox.mapboxsdk.style.layers.PropertyValue; + +import java.util.HashMap; +import java.util.Map; + +/** + * A stop represents a certain point in the range of this function + * + * @param <I> input the stop (function) input type + * @param <O> output the stop (function) output type + * @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-function">The style specification</a> + */ +public class Stop<I, O> { + /** + * Creates a {@link Stop} to use in a {@link Function} + * + * @param in the input for the stop + * @param output the output for the stop + * @param <I> the input property type + * @param <O> the output property type + * @return the {@link Stop} + */ + public static <I, O> Stop<I, O> stop(I in, PropertyValue<O> output) { + return new Stop<>(in, output.value); + } + + /** + * Create a composite {@link Stop} for use in a {@link com.mapbox.mapboxsdk.style.functions.CompositeFunction} + * + * @param zoom the zoom input + * @param value the feature property input + * @param output the output for the stop + * @param <Z> the zoom type + * @param <I> the feature property input type + * @param <O> the output property type + * @return the {@link Stop} + * @see Function#composite(String, ExponentialStops) + */ + public static <Z extends Number, I, O> Stop<Stop.CompositeValue<Z, I>, O> stop(Z zoom, + I value, + PropertyValue<O> output) { + return new Stop<>(new Stop.CompositeValue<>(zoom, value), output.value); + } + + /** + * Represents a composite input value for composite functions (eg zoom and feature property value) + * + * @param <Z> the zoom input type (typically Float) + * @param <V> the feature property input type + */ + public static class CompositeValue<Z extends Number, V> { + public final Z zoom; + public final V value; + + CompositeValue(Z zoom, V value) { + this.zoom = zoom; + this.value = value; + } + + /** + * INTERNAL USAGE ONLY + * + * @return the value object representation for core conversion + */ + Map<String, Object> toValueObject() { + HashMap<String, Object> map = new HashMap<>(); + map.put("zoom", zoom); + map.put("value", value); + return map; + } + + @Override + public String toString() { + return String.format("[zoom: %s, value: %s]", zoom, value); + } + } + + /** + * The input type + */ + public final I in; + + /** + * The output type + */ + public final O out; + + Stop(I in, O out) { + this.in = in; + this.out = out; + } + + /** + * INTERNAL USAGE ONLY + * + * @return an array representation of the Stop + */ + Object[] toValueObject() { + return new Object[] {in instanceof CompositeValue ? ((CompositeValue) in).toValueObject() : in, out}; + } + + @Override + public String toString() { + return String.format("[%s, %s]", in, out); + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/Stops.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/Stops.java new file mode 100644 index 0000000000..af4f53c072 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/Stops.java @@ -0,0 +1,99 @@ +package com.mapbox.mapboxsdk.style.functions.stops; + +import android.support.annotation.CallSuper; +import android.support.annotation.NonNull; +import android.support.annotation.Size; + +import java.util.HashMap; +import java.util.Map; + +/** + * The base class for different stops implementations + * + * @param <I> the input type + * @param <O> the output type + * @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-function">The style specification</a> + */ +public abstract class Stops<I, O> { + + /** + * Convenience method for use in function declarations + * + * @param stops the collections of discrete stops + * @param <I> the Stops input type + * @param <O> the Stops output type + * @return the {@link Stops} implementation + * @see Stop#stop + * @see CategoricalStops + */ + @SafeVarargs + public static <I, O> CategoricalStops<I, O> categorical(@NonNull @Size(min = 1) Stop<I, O>... stops) { + return new CategoricalStops<>(stops); + } + + /** + * Convenience method for use in function declarations + * + * @param stops the collections of discrete stops + * @param <I> the Stops input type + * @param <O> the Stops output type + * @return the {@link Stops} implementation + * @see Stop#stop + * @see ExponentialStops + */ + @SafeVarargs + public static <I, O> ExponentialStops<I, O> exponential(@NonNull @Size(min = 1) Stop<I, O>... stops) { + return new ExponentialStops<>(stops); + } + + /** + * Convenience method for use in function declarations + * + * @param <T> the Stops input/output type + * @return the {@link IdentityStops} implementation + * @see Stop#stop + * @see IdentityStops + */ + public static <T> IdentityStops<T> identity() { + return new IdentityStops<>(); + } + + /** + * Convenience method for use in function declarations + * + * @param stops the collections of discrete stops + * @param <I> the Stops input type + * @param <O> the Stops output type + * @return the {@link Stops} implementation + * @see Stop#stop + * @see IntervalStops + */ + @SafeVarargs + public static <I, O> IntervalStops<I, O> interval(@NonNull @Size(min = 1) Stop<I, O>... stops) { + return new IntervalStops<>(stops); + } + + /** + * INTERNAL USAGE ONLY + * + * @return the value object representation for conversion to core + */ + @CallSuper + public Map<String, Object> toValueObject() { + HashMap<String, Object> map = new HashMap<>(); + map.put("type", getTypeName()); + return map; + } + + /** + * INTERNAL USAGE ONLY + * + * @return the unique type name as a string according to the style specification + */ + protected abstract String getTypeName(); + + @Override + public String toString() { + return getTypeName(); + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/package-info.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/package-info.java new file mode 100644 index 0000000000..fa388a9589 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/functions/stops/package-info.java @@ -0,0 +1,6 @@ +/** + * Contains the Mapbox Maps Android Style Function Stop implementation API classes. + * + * @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-function">The style specification</a> + */ +package com.mapbox.mapboxsdk.style.functions.stops; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/BackgroundLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/BackgroundLayer.java index 45523b41ab..0f1265f1a1 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/BackgroundLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/BackgroundLayer.java @@ -1,6 +1,7 @@ -package com.mapbox.mapboxsdk.style.layers; // This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. +package com.mapbox.mapboxsdk.style.layers; + import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.UiThread; @@ -41,7 +42,7 @@ public class BackgroundLayer extends Layer { * @param properties the var-args properties * @return This */ - public BackgroundLayer withProperties(@NonNull Property<?>... properties) { + public BackgroundLayer withProperties(@NonNull PropertyValue<?>... properties) { setProperties(properties); return this; } @@ -55,7 +56,7 @@ public class BackgroundLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getBackgroundColor() { - return (PropertyValue<String>) new PropertyValue(nativeGetBackgroundColor()); + return (PropertyValue<String>) new PropertyValue("background-color", nativeGetBackgroundColor()); } /** @@ -82,7 +83,7 @@ public class BackgroundLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getBackgroundPattern() { - return (PropertyValue<String>) new PropertyValue(nativeGetBackgroundPattern()); + return (PropertyValue<String>) new PropertyValue("background-pattern", nativeGetBackgroundPattern()); } /** @@ -92,7 +93,7 @@ public class BackgroundLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getBackgroundOpacity() { - return (PropertyValue<Float>) new PropertyValue(nativeGetBackgroundOpacity()); + return (PropertyValue<Float>) new PropertyValue("background-opacity", nativeGetBackgroundOpacity()); } private native Object nativeGetBackgroundColor(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java index f16ab688d6..43ec255e81 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/CircleLayer.java @@ -1,6 +1,7 @@ -package com.mapbox.mapboxsdk.style.layers; // This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. +package com.mapbox.mapboxsdk.style.layers; + import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.UiThread; @@ -62,27 +63,7 @@ public class CircleLayer extends Layer { * @param filter the filter to set */ public void setFilter(Filter.Statement filter) { - this.setFilter(filter.toArray()); - } - - /** - * Set an array of filters. - * - * @param filter the filter array to set - */ - public void setFilter(Object[] filter) { - nativeSetFilter(filter); - } - - /** - * Set an array of filters. - * - * @param filter tthe filter array to set - * @return This - */ - public CircleLayer withFilter(Object[] filter) { - setFilter(filter); - return this; + nativeSetFilter(filter.toArray()); } /** @@ -96,14 +77,13 @@ public class CircleLayer extends Layer { return this; } - /** * Set a property or properties. * * @param properties the var-args properties * @return This */ - public CircleLayer withProperties(@NonNull Property<?>... properties) { + public CircleLayer withProperties(@NonNull PropertyValue<?>... properties) { setProperties(properties); return this; } @@ -117,7 +97,7 @@ public class CircleLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getCircleRadius() { - return (PropertyValue<Float>) new PropertyValue(nativeGetCircleRadius()); + return (PropertyValue<Float>) new PropertyValue("circle-radius", nativeGetCircleRadius()); } /** @@ -127,7 +107,7 @@ public class CircleLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getCircleColor() { - return (PropertyValue<String>) new PropertyValue(nativeGetCircleColor()); + return (PropertyValue<String>) new PropertyValue("circle-color", nativeGetCircleColor()); } /** @@ -154,7 +134,7 @@ public class CircleLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getCircleBlur() { - return (PropertyValue<Float>) new PropertyValue(nativeGetCircleBlur()); + return (PropertyValue<Float>) new PropertyValue("circle-blur", nativeGetCircleBlur()); } /** @@ -164,7 +144,7 @@ public class CircleLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getCircleOpacity() { - return (PropertyValue<Float>) new PropertyValue(nativeGetCircleOpacity()); + return (PropertyValue<Float>) new PropertyValue("circle-opacity", nativeGetCircleOpacity()); } /** @@ -174,7 +154,7 @@ public class CircleLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float[]> getCircleTranslate() { - return (PropertyValue<Float[]>) new PropertyValue(nativeGetCircleTranslate()); + return (PropertyValue<Float[]>) new PropertyValue("circle-translate", nativeGetCircleTranslate()); } /** @@ -184,7 +164,7 @@ public class CircleLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getCircleTranslateAnchor() { - return (PropertyValue<String>) new PropertyValue(nativeGetCircleTranslateAnchor()); + return (PropertyValue<String>) new PropertyValue("circle-translate-anchor", nativeGetCircleTranslateAnchor()); } /** @@ -194,7 +174,7 @@ public class CircleLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getCirclePitchScale() { - return (PropertyValue<String>) new PropertyValue(nativeGetCirclePitchScale()); + return (PropertyValue<String>) new PropertyValue("circle-pitch-scale", nativeGetCirclePitchScale()); } /** @@ -204,7 +184,7 @@ public class CircleLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getCircleStrokeWidth() { - return (PropertyValue<Float>) new PropertyValue(nativeGetCircleStrokeWidth()); + return (PropertyValue<Float>) new PropertyValue("circle-stroke-width", nativeGetCircleStrokeWidth()); } /** @@ -214,7 +194,7 @@ public class CircleLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getCircleStrokeColor() { - return (PropertyValue<String>) new PropertyValue(nativeGetCircleStrokeColor()); + return (PropertyValue<String>) new PropertyValue("circle-stroke-color", nativeGetCircleStrokeColor()); } /** @@ -241,7 +221,7 @@ public class CircleLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getCircleStrokeOpacity() { - return (PropertyValue<Float>) new PropertyValue(nativeGetCircleStrokeOpacity()); + return (PropertyValue<Float>) new PropertyValue("circle-stroke-opacity", nativeGetCircleStrokeOpacity()); } private native Object nativeGetCircleRadius(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java index 3f79c9306a..8989f3a2ec 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/FillLayer.java @@ -1,6 +1,7 @@ -package com.mapbox.mapboxsdk.style.layers; // This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. +package com.mapbox.mapboxsdk.style.layers; + import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.UiThread; @@ -62,27 +63,7 @@ public class FillLayer extends Layer { * @param filter the filter to set */ public void setFilter(Filter.Statement filter) { - this.setFilter(filter.toArray()); - } - - /** - * Set an array of filters. - * - * @param filter the filter array to set - */ - public void setFilter(Object[] filter) { - nativeSetFilter(filter); - } - - /** - * Set an array of filters. - * - * @param filter tthe filter array to set - * @return This - */ - public FillLayer withFilter(Object[] filter) { - setFilter(filter); - return this; + nativeSetFilter(filter.toArray()); } /** @@ -96,14 +77,13 @@ public class FillLayer extends Layer { return this; } - /** * Set a property or properties. * * @param properties the var-args properties * @return This */ - public FillLayer withProperties(@NonNull Property<?>... properties) { + public FillLayer withProperties(@NonNull PropertyValue<?>... properties) { setProperties(properties); return this; } @@ -117,7 +97,7 @@ public class FillLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Boolean> getFillAntialias() { - return (PropertyValue<Boolean>) new PropertyValue(nativeGetFillAntialias()); + return (PropertyValue<Boolean>) new PropertyValue("fill-antialias", nativeGetFillAntialias()); } /** @@ -127,7 +107,7 @@ public class FillLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getFillOpacity() { - return (PropertyValue<Float>) new PropertyValue(nativeGetFillOpacity()); + return (PropertyValue<Float>) new PropertyValue("fill-opacity", nativeGetFillOpacity()); } /** @@ -137,12 +117,11 @@ public class FillLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getFillColor() { - return (PropertyValue<String>) new PropertyValue(nativeGetFillColor()); + return (PropertyValue<String>) new PropertyValue("fill-color", nativeGetFillColor()); } /** - * The color of the filled part of this layer. This color can be specified as `rgba` with an alpha component and the - * color's opacity will not affect the opacity of the 1px stroke, if it is used. + * The color of the filled part of this layer. This color can be specified as `rgba` with an alpha component and the color's opacity will not affect the opacity of the 1px stroke, if it is used. * * @return int representation of a rgba string color * @throws RuntimeException thrown if property isn't a value @@ -165,7 +144,7 @@ public class FillLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getFillOutlineColor() { - return (PropertyValue<String>) new PropertyValue(nativeGetFillOutlineColor()); + return (PropertyValue<String>) new PropertyValue("fill-outline-color", nativeGetFillOutlineColor()); } /** @@ -192,7 +171,7 @@ public class FillLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float[]> getFillTranslate() { - return (PropertyValue<Float[]>) new PropertyValue(nativeGetFillTranslate()); + return (PropertyValue<Float[]>) new PropertyValue("fill-translate", nativeGetFillTranslate()); } /** @@ -202,7 +181,7 @@ public class FillLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getFillTranslateAnchor() { - return (PropertyValue<String>) new PropertyValue(nativeGetFillTranslateAnchor()); + return (PropertyValue<String>) new PropertyValue("fill-translate-anchor", nativeGetFillTranslateAnchor()); } /** @@ -212,7 +191,7 @@ public class FillLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getFillPattern() { - return (PropertyValue<String>) new PropertyValue(nativeGetFillPattern()); + return (PropertyValue<String>) new PropertyValue("fill-pattern", nativeGetFillPattern()); } private native Object nativeGetFillAntialias(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Function.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Function.java deleted file mode 100644 index 900fe10476..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Function.java +++ /dev/null @@ -1,137 +0,0 @@ -package com.mapbox.mapboxsdk.style.layers; - -import android.support.annotation.FloatRange; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.annotation.Size; - -import java.util.HashMap; -import java.util.Map; - -/** - * Functions are used to change properties in relation to the state of the map. - * <p> - * Currently, only zoom functions are supported. - * </p> - * - * @param <T> the target property's value type. Make sure it matches. - * @see <a href="https://www.mapbox.com/mapbox-gl-style-spec/#types-function">The online documentation</a> - */ -public class Function<T> { - - /** - * A stop represents a certain point in the range of this function - * - * @param <I> input - * @param <O> output - */ - public static class Stop<I, O> { - public final I in; - public final O out; - - Stop(I in, O out) { - this.in = in; - this.out = out; - } - - /** - * @return an array representation of the Stop - */ - Object[] toValueObject() { - return new Object[] {in, out}; - } - - @Override - public String toString() { - return String.format("[%s, %s]", in, out); - } - } - - /** - * Zoom functions allow the appearance of a map feature to change with map’s zoom. - * Zoom functions can be used to create the illusion of depth and control data density. - * Each stop is an array with two elements, the first is a zoom and the second is a function output value. - * - * @param stops the stops that define the function - * @param <T> the property type - * @return the {@link Function} - */ - @SafeVarargs - public static <T> Function<T> zoom(@NonNull @Size(min = 1) Stop<Float, T>... stops) { - return new Function<T>(stops); - } - - - /** - * Zoom functions allow the appearance of a map feature to change with map’s zoom. - * Zoom functions can be used to create the illusion of depth and control data density. - * Each stop is an array with two elements, the first is a zoom and the second is a function output value. - * - * @param stops the stops that define the function - * @param base the exponential base of the interpolation curve - Default 1 - * @param <T> the property type - * @return the {@link Function} - */ - @SafeVarargs - public static <T> Function<T> zoom( - @FloatRange(from = 0, to = 1, fromInclusive = false, toInclusive = false) float base, - @NonNull @Size(min = 1) Stop<Float, T>... stops) { - return new Function<T>(stops) - .withBase(base); - } - - /** - * Creates a stop to use in a {@link Function} - * - * @param in the input for the stop - * @param output the output for the stop - * @param <T> the output property type - * @return the {@link Stop} - */ - public static <T> Stop<Float, T> stop(float in, Property<T> output) { - return new Stop<>(in, output.value); - } - - private final Stop<Float, T>[] stops; - private Float base; - - Function(@NonNull @Size(min = 1) Stop<Float, T>[] stops) { - this.stops = stops; - } - - Function<T> withBase(float base) { - this.base = base; - return this; - } - - /** - * @return the base - */ - @Nullable - public Float getBase() { - return base; - } - - /** - * @return the stops in this function - */ - public Stop<Float, T>[] getStops() { - return stops; - } - - Map<String, Object> toValueObject() { - Object[] stopsValue = new Object[stops.length]; - - for (int i = 0; i < stopsValue.length; i++) { - Stop stop = stops[i]; - stopsValue[i] = stop.toValueObject(); - } - - Map<String, Object> value = new HashMap<>(); - if (base != null) { - value.put("base", base); - } - value.put("stops", stopsValue); - return value; - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java index 2878d76430..b4120f4f9a 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Layer.java @@ -2,6 +2,8 @@ package com.mapbox.mapboxsdk.style.layers; import android.support.annotation.NonNull; +import com.mapbox.mapboxsdk.style.functions.Function; + /** * Base class for the different Layer types */ @@ -17,14 +19,14 @@ public abstract class Layer { public Layer() { } - public void setProperties(@NonNull Property<?>... properties) { + public void setProperties(@NonNull PropertyValue<?>... properties) { if (properties.length == 0) { return; } - for (Property<?> property : properties) { + for (PropertyValue<?> property : properties) { Object converted = convertValue(property.value); - if (property instanceof PaintProperty) { + if (property instanceof PaintPropertyValue) { nativeSetPaintProperty(property.name, converted); } else { nativeSetLayoutProperty(property.name, converted); @@ -37,7 +39,7 @@ public abstract class Layer { } public PropertyValue<String> getVisibility() { - return new PropertyValue<>(nativeGetVisibility()); + return new PaintPropertyValue<>("visibility", (String) nativeGetVisibility()); } public float getMinZoom() { diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LayoutProperty.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LayoutProperty.java deleted file mode 100644 index 4c0b52be55..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LayoutProperty.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.mapbox.mapboxsdk.style.layers; - -class LayoutProperty<T> extends Property<T> { - - LayoutProperty(String name, T value) { - super(name, value); - } - -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LayoutPropertyValue.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LayoutPropertyValue.java new file mode 100644 index 0000000000..ed88a85912 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LayoutPropertyValue.java @@ -0,0 +1,11 @@ +package com.mapbox.mapboxsdk.style.layers; + +import android.support.annotation.NonNull; + +class LayoutPropertyValue<T> extends PropertyValue<T> { + + LayoutPropertyValue(@NonNull String name, T value) { + super(name, value); + } + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java index 4c52a40b05..6992c22ace 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/LineLayer.java @@ -1,6 +1,7 @@ -package com.mapbox.mapboxsdk.style.layers; // This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. +package com.mapbox.mapboxsdk.style.layers; + import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.UiThread; @@ -62,27 +63,7 @@ public class LineLayer extends Layer { * @param filter the filter to set */ public void setFilter(Filter.Statement filter) { - this.setFilter(filter.toArray()); - } - - /** - * Set an array of filters. - * - * @param filter the filter array to set - */ - public void setFilter(Object[] filter) { - nativeSetFilter(filter); - } - - /** - * Set an array of filters. - * - * @param filter tthe filter array to set - * @return This - */ - public LineLayer withFilter(Object[] filter) { - setFilter(filter); - return this; + nativeSetFilter(filter.toArray()); } /** @@ -96,14 +77,13 @@ public class LineLayer extends Layer { return this; } - /** * Set a property or properties. * * @param properties the var-args properties * @return This */ - public LineLayer withProperties(@NonNull Property<?>... properties) { + public LineLayer withProperties(@NonNull PropertyValue<?>... properties) { setProperties(properties); return this; } @@ -117,7 +97,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getLineCap() { - return (PropertyValue<String>) new PropertyValue(nativeGetLineCap()); + return (PropertyValue<String>) new PropertyValue("line-cap", nativeGetLineCap()); } /** @@ -127,7 +107,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getLineJoin() { - return (PropertyValue<String>) new PropertyValue(nativeGetLineJoin()); + return (PropertyValue<String>) new PropertyValue("line-join", nativeGetLineJoin()); } /** @@ -137,7 +117,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getLineMiterLimit() { - return (PropertyValue<Float>) new PropertyValue(nativeGetLineMiterLimit()); + return (PropertyValue<Float>) new PropertyValue("line-miter-limit", nativeGetLineMiterLimit()); } /** @@ -147,7 +127,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getLineRoundLimit() { - return (PropertyValue<Float>) new PropertyValue(nativeGetLineRoundLimit()); + return (PropertyValue<Float>) new PropertyValue("line-round-limit", nativeGetLineRoundLimit()); } /** @@ -157,7 +137,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getLineOpacity() { - return (PropertyValue<Float>) new PropertyValue(nativeGetLineOpacity()); + return (PropertyValue<Float>) new PropertyValue("line-opacity", nativeGetLineOpacity()); } /** @@ -167,7 +147,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getLineColor() { - return (PropertyValue<String>) new PropertyValue(nativeGetLineColor()); + return (PropertyValue<String>) new PropertyValue("line-color", nativeGetLineColor()); } /** @@ -194,7 +174,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float[]> getLineTranslate() { - return (PropertyValue<Float[]>) new PropertyValue(nativeGetLineTranslate()); + return (PropertyValue<Float[]>) new PropertyValue("line-translate", nativeGetLineTranslate()); } /** @@ -204,7 +184,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getLineTranslateAnchor() { - return (PropertyValue<String>) new PropertyValue(nativeGetLineTranslateAnchor()); + return (PropertyValue<String>) new PropertyValue("line-translate-anchor", nativeGetLineTranslateAnchor()); } /** @@ -214,7 +194,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getLineWidth() { - return (PropertyValue<Float>) new PropertyValue(nativeGetLineWidth()); + return (PropertyValue<Float>) new PropertyValue("line-width", nativeGetLineWidth()); } /** @@ -224,7 +204,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getLineGapWidth() { - return (PropertyValue<Float>) new PropertyValue(nativeGetLineGapWidth()); + return (PropertyValue<Float>) new PropertyValue("line-gap-width", nativeGetLineGapWidth()); } /** @@ -234,7 +214,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getLineOffset() { - return (PropertyValue<Float>) new PropertyValue(nativeGetLineOffset()); + return (PropertyValue<Float>) new PropertyValue("line-offset", nativeGetLineOffset()); } /** @@ -244,7 +224,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getLineBlur() { - return (PropertyValue<Float>) new PropertyValue(nativeGetLineBlur()); + return (PropertyValue<Float>) new PropertyValue("line-blur", nativeGetLineBlur()); } /** @@ -254,7 +234,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float[]> getLineDasharray() { - return (PropertyValue<Float[]>) new PropertyValue(nativeGetLineDasharray()); + return (PropertyValue<Float[]>) new PropertyValue("line-dasharray", nativeGetLineDasharray()); } /** @@ -264,7 +244,7 @@ public class LineLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getLinePattern() { - return (PropertyValue<String>) new PropertyValue(nativeGetLinePattern()); + return (PropertyValue<String>) new PropertyValue("line-pattern", nativeGetLinePattern()); } private native Object nativeGetLineCap(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/NoSuchLayerException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/NoSuchLayerException.java deleted file mode 100644 index 3b8777080d..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/NoSuchLayerException.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.mapbox.mapboxsdk.style.layers; - -/** - * No such layer. - */ -public class NoSuchLayerException extends Exception { - - public NoSuchLayerException(String message) { - super(message); - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PaintProperty.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PaintProperty.java deleted file mode 100644 index 69405177d9..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PaintProperty.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.mapbox.mapboxsdk.style.layers; - -class PaintProperty<T> extends Property<T> { - - PaintProperty(String name, T value) { - super(name, value); - } - -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PaintPropertyValue.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PaintPropertyValue.java new file mode 100644 index 0000000000..e6ac2d9763 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PaintPropertyValue.java @@ -0,0 +1,11 @@ +package com.mapbox.mapboxsdk.style.layers; + +import android.support.annotation.NonNull; + +class PaintPropertyValue<T> extends PropertyValue<T> { + + PaintPropertyValue(@NonNull String name, T value) { + super(name, value); + } + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java index bb060ddf15..641ee551a2 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/Property.java @@ -1,6 +1,7 @@ -package com.mapbox.mapboxsdk.style.layers; // This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. +package com.mapbox.mapboxsdk.style.layers; + import android.support.annotation.StringDef; import java.lang.annotation.Retention; @@ -9,9 +10,9 @@ import java.lang.annotation.RetentionPolicy; /** * Paint/Layout properties for Layer */ -public abstract class Property<T> { +public final class Property { - //VISIBILITY: Whether this layer is displayed. + // VISIBILITY: Whether this layer is displayed. /** * The layer is shown. @@ -22,74 +23,66 @@ public abstract class Property<T> { */ public static final String NONE = "none"; - @StringDef( { - VISIBLE, - NONE + @StringDef({ + VISIBLE, + NONE }) @Retention(RetentionPolicy.SOURCE) - public @interface VISIBILITY { - } + public @interface VISIBILITY {} - //LINE_CAP: The display of line endings. + // LINE_CAP: The display of line endings. /** * A cap with a squared-off end which is drawn to the exact endpoint of the line. */ public static final String LINE_CAP_BUTT = "butt"; /** - * A cap with a rounded end which is drawn beyond the endpoint of the line at a radius of one-half of the line's - * width and centered on the endpoint of the line. + * A cap with a rounded end which is drawn beyond the endpoint of the line at a radius of one-half of the line's width and centered on the endpoint of the line. */ public static final String LINE_CAP_ROUND = "round"; /** - * A cap with a squared-off end which is drawn beyond the endpoint of the line at a distance of one-half of the - * line's width. + * A cap with a squared-off end which is drawn beyond the endpoint of the line at a distance of one-half of the line's width. */ public static final String LINE_CAP_SQUARE = "square"; /** * The display of line endings. */ - @StringDef( { - LINE_CAP_BUTT, - LINE_CAP_ROUND, - LINE_CAP_SQUARE, - }) + @StringDef({ + LINE_CAP_BUTT, + LINE_CAP_ROUND, + LINE_CAP_SQUARE, + }) @Retention(RetentionPolicy.SOURCE) - public @interface LINE_CAP { - } + public @interface LINE_CAP {} - //LINE_JOIN: The display of lines when joining. + // LINE_JOIN: The display of lines when joining. /** - * A join with a squared-off end which is drawn beyond the endpoint of the line at a distance of one-half of the - * line's width. + * A join with a squared-off end which is drawn beyond the endpoint of the line at a distance of one-half of the line's width. */ public static final String LINE_JOIN_BEVEL = "bevel"; /** - * A join with a rounded end which is drawn beyond the endpoint of the line at a radius of one-half of the line's - * width and centered on the endpoint of the line. + * A join with a rounded end which is drawn beyond the endpoint of the line at a radius of one-half of the line's width and centered on the endpoint of the line. */ public static final String LINE_JOIN_ROUND = "round"; /** - * A join with a sharp, angled corner which is drawn with the outer sides beyond the endpoint of the path until - * they meet. + * A join with a sharp, angled corner which is drawn with the outer sides beyond the endpoint of the path until they meet. */ public static final String LINE_JOIN_MITER = "miter"; /** * The display of lines when joining. */ - @StringDef( { - LINE_JOIN_BEVEL, - LINE_JOIN_ROUND, - LINE_JOIN_MITER, - }) + @StringDef({ + LINE_JOIN_BEVEL, + LINE_JOIN_ROUND, + LINE_JOIN_MITER, + }) @Retention(RetentionPolicy.SOURCE) - public @interface LINE_JOIN { - } + public @interface LINE_JOIN {} - //SYMBOL_PLACEMENT: Label placement relative to its geometry. + // SYMBOL_PLACEMENT: Label placement relative to its geometry. /** * The label is placed at the point where the geometry is located. @@ -103,46 +96,40 @@ public abstract class Property<T> { /** * Label placement relative to its geometry. */ - @StringDef( { - SYMBOL_PLACEMENT_POINT, - SYMBOL_PLACEMENT_LINE, - }) + @StringDef({ + SYMBOL_PLACEMENT_POINT, + SYMBOL_PLACEMENT_LINE, + }) @Retention(RetentionPolicy.SOURCE) - public @interface SYMBOL_PLACEMENT { - } + public @interface SYMBOL_PLACEMENT {} - //ICON_ROTATION_ALIGNMENT: In combination with `symbol-placement`, determines the rotation behavior of icons. + // ICON_ROTATION_ALIGNMENT: In combination with `symbol-placement`, determines the rotation behavior of icons. /** - * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, aligns icons east-west. When - * {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, aligns icon x-axes with the line. + * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, aligns icons east-west. When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, aligns icon x-axes with the line. */ public static final String ICON_ROTATION_ALIGNMENT_MAP = "map"; /** - * Produces icons whose x-axes are aligned with the x-axis of the viewport, regardless of the value of - * {@link SYMBOL_PLACEMENT}. + * Produces icons whose x-axes are aligned with the x-axis of the viewport, regardless of the value of {@link SYMBOL_PLACEMENT}. */ public static final String ICON_ROTATION_ALIGNMENT_VIEWPORT = "viewport"; /** - * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, this is equivalent to - * {@link Property#ICON_ROTATION_ALIGNMENT_VIEWPORT}. When {@link SYMBOL_PLACEMENT} is set to - * {@link Property#SYMBOL_PLACEMENT_LINE}, this is equivalent to {@link Property#ICON_ROTATION_ALIGNMENT_MAP}. + * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, this is equivalent to {@link Property#ICON_ROTATION_ALIGNMENT_VIEWPORT}. When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, this is equivalent to {@link Property#ICON_ROTATION_ALIGNMENT_MAP}. */ public static final String ICON_ROTATION_ALIGNMENT_AUTO = "auto"; /** * In combination with `symbol-placement`, determines the rotation behavior of icons. */ - @StringDef( { - ICON_ROTATION_ALIGNMENT_MAP, - ICON_ROTATION_ALIGNMENT_VIEWPORT, - ICON_ROTATION_ALIGNMENT_AUTO, - }) + @StringDef({ + ICON_ROTATION_ALIGNMENT_MAP, + ICON_ROTATION_ALIGNMENT_VIEWPORT, + ICON_ROTATION_ALIGNMENT_AUTO, + }) @Retention(RetentionPolicy.SOURCE) - public @interface ICON_ROTATION_ALIGNMENT { - } + public @interface ICON_ROTATION_ALIGNMENT {} - //ICON_TEXT_FIT: Scales the icon to fit around the associated text. + // ICON_TEXT_FIT: Scales the icon to fit around the associated text. /** * The icon is displayed at its intrinsic aspect ratio. @@ -164,17 +151,16 @@ public abstract class Property<T> { /** * Scales the icon to fit around the associated text. */ - @StringDef( { - ICON_TEXT_FIT_NONE, - ICON_TEXT_FIT_WIDTH, - ICON_TEXT_FIT_HEIGHT, - ICON_TEXT_FIT_BOTH, - }) + @StringDef({ + ICON_TEXT_FIT_NONE, + ICON_TEXT_FIT_WIDTH, + ICON_TEXT_FIT_HEIGHT, + ICON_TEXT_FIT_BOTH, + }) @Retention(RetentionPolicy.SOURCE) - public @interface ICON_TEXT_FIT { - } + public @interface ICON_TEXT_FIT {} - //TEXT_PITCH_ALIGNMENT: Orientation of text when map is pitched. + // TEXT_PITCH_ALIGNMENT: Orientation of text when map is pitched. /** * The text is aligned to the plane of the map. @@ -192,48 +178,41 @@ public abstract class Property<T> { /** * Orientation of text when map is pitched. */ - @StringDef( { - TEXT_PITCH_ALIGNMENT_MAP, - TEXT_PITCH_ALIGNMENT_VIEWPORT, - TEXT_PITCH_ALIGNMENT_AUTO, - }) + @StringDef({ + TEXT_PITCH_ALIGNMENT_MAP, + TEXT_PITCH_ALIGNMENT_VIEWPORT, + TEXT_PITCH_ALIGNMENT_AUTO, + }) @Retention(RetentionPolicy.SOURCE) - public @interface TEXT_PITCH_ALIGNMENT { - } + public @interface TEXT_PITCH_ALIGNMENT {} - //TEXT_ROTATION_ALIGNMENT: In combination with `symbol-placement`, determines the rotation behavior of the individual - // glyphs forming the text. + // TEXT_ROTATION_ALIGNMENT: In combination with `symbol-placement`, determines the rotation behavior of the individual glyphs forming the text. /** - * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, aligns text east-west. When - * {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, aligns text x-axes with the line. + * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, aligns text east-west. When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, aligns text x-axes with the line. */ public static final String TEXT_ROTATION_ALIGNMENT_MAP = "map"; /** - * Produces glyphs whose x-axes are aligned with the x-axis of the viewport, regardless of the value of - * {@link SYMBOL_PLACEMENT}. + * Produces glyphs whose x-axes are aligned with the x-axis of the viewport, regardless of the value of {@link SYMBOL_PLACEMENT}. */ public static final String TEXT_ROTATION_ALIGNMENT_VIEWPORT = "viewport"; /** - * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, this is equivalent to - * {@link Property#TEXT_ROTATION_ALIGNMENT_VIEWPORT}. When {@link SYMBOL_PLACEMENT} is set to - * {@link Property#SYMBOL_PLACEMENT_LINE}, this is equivalent to {@link Property#TEXT_ROTATION_ALIGNMENT_MAP}. + * When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_POINT}, this is equivalent to {@link Property#TEXT_ROTATION_ALIGNMENT_VIEWPORT}. When {@link SYMBOL_PLACEMENT} is set to {@link Property#SYMBOL_PLACEMENT_LINE}, this is equivalent to {@link Property#TEXT_ROTATION_ALIGNMENT_MAP}. */ public static final String TEXT_ROTATION_ALIGNMENT_AUTO = "auto"; /** * In combination with `symbol-placement`, determines the rotation behavior of the individual glyphs forming the text. */ - @StringDef( { - TEXT_ROTATION_ALIGNMENT_MAP, - TEXT_ROTATION_ALIGNMENT_VIEWPORT, - TEXT_ROTATION_ALIGNMENT_AUTO, - }) + @StringDef({ + TEXT_ROTATION_ALIGNMENT_MAP, + TEXT_ROTATION_ALIGNMENT_VIEWPORT, + TEXT_ROTATION_ALIGNMENT_AUTO, + }) @Retention(RetentionPolicy.SOURCE) - public @interface TEXT_ROTATION_ALIGNMENT { - } + public @interface TEXT_ROTATION_ALIGNMENT {} - //TEXT_JUSTIFY: Text justification options. + // TEXT_JUSTIFY: Text justification options. /** * The text is aligned to the left. @@ -251,16 +230,15 @@ public abstract class Property<T> { /** * Text justification options. */ - @StringDef( { - TEXT_JUSTIFY_LEFT, - TEXT_JUSTIFY_CENTER, - TEXT_JUSTIFY_RIGHT, - }) + @StringDef({ + TEXT_JUSTIFY_LEFT, + TEXT_JUSTIFY_CENTER, + TEXT_JUSTIFY_RIGHT, + }) @Retention(RetentionPolicy.SOURCE) - public @interface TEXT_JUSTIFY { - } + public @interface TEXT_JUSTIFY {} - //TEXT_ANCHOR: Part of the text placed closest to the anchor. + // TEXT_ANCHOR: Part of the text placed closest to the anchor. /** * The center of the text is placed closest to the anchor. @@ -302,22 +280,21 @@ public abstract class Property<T> { /** * Part of the text placed closest to the anchor. */ - @StringDef( { - TEXT_ANCHOR_CENTER, - TEXT_ANCHOR_LEFT, - TEXT_ANCHOR_RIGHT, - TEXT_ANCHOR_TOP, - TEXT_ANCHOR_BOTTOM, - TEXT_ANCHOR_TOP_LEFT, - TEXT_ANCHOR_TOP_RIGHT, - TEXT_ANCHOR_BOTTOM_LEFT, - TEXT_ANCHOR_BOTTOM_RIGHT, - }) + @StringDef({ + TEXT_ANCHOR_CENTER, + TEXT_ANCHOR_LEFT, + TEXT_ANCHOR_RIGHT, + TEXT_ANCHOR_TOP, + TEXT_ANCHOR_BOTTOM, + TEXT_ANCHOR_TOP_LEFT, + TEXT_ANCHOR_TOP_RIGHT, + TEXT_ANCHOR_BOTTOM_LEFT, + TEXT_ANCHOR_BOTTOM_RIGHT, + }) @Retention(RetentionPolicy.SOURCE) - public @interface TEXT_ANCHOR { - } + public @interface TEXT_ANCHOR {} - //TEXT_TRANSFORM: Specifies how to capitalize text, similar to the CSS `text-transform` property. + // TEXT_TRANSFORM: Specifies how to capitalize text, similar to the CSS `text-transform` property. /** * The text is not altered. @@ -335,16 +312,15 @@ public abstract class Property<T> { /** * Specifies how to capitalize text, similar to the CSS `text-transform` property. */ - @StringDef( { - TEXT_TRANSFORM_NONE, - TEXT_TRANSFORM_UPPERCASE, - TEXT_TRANSFORM_LOWERCASE, - }) + @StringDef({ + TEXT_TRANSFORM_NONE, + TEXT_TRANSFORM_UPPERCASE, + TEXT_TRANSFORM_LOWERCASE, + }) @Retention(RetentionPolicy.SOURCE) - public @interface TEXT_TRANSFORM { - } + public @interface TEXT_TRANSFORM {} - //FILL_TRANSLATE_ANCHOR: Controls the translation reference point. + // FILL_TRANSLATE_ANCHOR: Controls the translation reference point. /** * The fill is translated relative to the map. @@ -358,15 +334,14 @@ public abstract class Property<T> { /** * Controls the translation reference point. */ - @StringDef( { - FILL_TRANSLATE_ANCHOR_MAP, - FILL_TRANSLATE_ANCHOR_VIEWPORT, - }) + @StringDef({ + FILL_TRANSLATE_ANCHOR_MAP, + FILL_TRANSLATE_ANCHOR_VIEWPORT, + }) @Retention(RetentionPolicy.SOURCE) - public @interface FILL_TRANSLATE_ANCHOR { - } + public @interface FILL_TRANSLATE_ANCHOR {} - //LINE_TRANSLATE_ANCHOR: Controls the translation reference point. + // LINE_TRANSLATE_ANCHOR: Controls the translation reference point. /** * The line is translated relative to the map. @@ -380,15 +355,14 @@ public abstract class Property<T> { /** * Controls the translation reference point. */ - @StringDef( { - LINE_TRANSLATE_ANCHOR_MAP, - LINE_TRANSLATE_ANCHOR_VIEWPORT, - }) + @StringDef({ + LINE_TRANSLATE_ANCHOR_MAP, + LINE_TRANSLATE_ANCHOR_VIEWPORT, + }) @Retention(RetentionPolicy.SOURCE) - public @interface LINE_TRANSLATE_ANCHOR { - } + public @interface LINE_TRANSLATE_ANCHOR {} - //ICON_TRANSLATE_ANCHOR: Controls the translation reference point. + // ICON_TRANSLATE_ANCHOR: Controls the translation reference point. /** * Icons are translated relative to the map. @@ -402,15 +376,14 @@ public abstract class Property<T> { /** * Controls the translation reference point. */ - @StringDef( { - ICON_TRANSLATE_ANCHOR_MAP, - ICON_TRANSLATE_ANCHOR_VIEWPORT, - }) + @StringDef({ + ICON_TRANSLATE_ANCHOR_MAP, + ICON_TRANSLATE_ANCHOR_VIEWPORT, + }) @Retention(RetentionPolicy.SOURCE) - public @interface ICON_TRANSLATE_ANCHOR { - } + public @interface ICON_TRANSLATE_ANCHOR {} - //TEXT_TRANSLATE_ANCHOR: Controls the translation reference point. + // TEXT_TRANSLATE_ANCHOR: Controls the translation reference point. /** * The text is translated relative to the map. @@ -424,15 +397,14 @@ public abstract class Property<T> { /** * Controls the translation reference point. */ - @StringDef( { - TEXT_TRANSLATE_ANCHOR_MAP, - TEXT_TRANSLATE_ANCHOR_VIEWPORT, - }) + @StringDef({ + TEXT_TRANSLATE_ANCHOR_MAP, + TEXT_TRANSLATE_ANCHOR_VIEWPORT, + }) @Retention(RetentionPolicy.SOURCE) - public @interface TEXT_TRANSLATE_ANCHOR { - } + public @interface TEXT_TRANSLATE_ANCHOR {} - //CIRCLE_TRANSLATE_ANCHOR: Controls the translation reference point. + // CIRCLE_TRANSLATE_ANCHOR: Controls the translation reference point. /** * The circle is translated relative to the map. @@ -446,15 +418,14 @@ public abstract class Property<T> { /** * Controls the translation reference point. */ - @StringDef( { - CIRCLE_TRANSLATE_ANCHOR_MAP, - CIRCLE_TRANSLATE_ANCHOR_VIEWPORT, - }) + @StringDef({ + CIRCLE_TRANSLATE_ANCHOR_MAP, + CIRCLE_TRANSLATE_ANCHOR_VIEWPORT, + }) @Retention(RetentionPolicy.SOURCE) - public @interface CIRCLE_TRANSLATE_ANCHOR { - } + public @interface CIRCLE_TRANSLATE_ANCHOR {} - //CIRCLE_PITCH_SCALE: Controls the scaling behavior of the circle when the map is pitched. + // CIRCLE_PITCH_SCALE: Controls the scaling behavior of the circle when the map is pitched. /** * Circles are scaled according to their apparent distance to the camera. @@ -468,20 +439,14 @@ public abstract class Property<T> { /** * Controls the scaling behavior of the circle when the map is pitched. */ - @StringDef( { - CIRCLE_PITCH_SCALE_MAP, - CIRCLE_PITCH_SCALE_VIEWPORT, - }) + @StringDef({ + CIRCLE_PITCH_SCALE_MAP, + CIRCLE_PITCH_SCALE_VIEWPORT, + }) @Retention(RetentionPolicy.SOURCE) - public @interface CIRCLE_PITCH_SCALE { - } + public @interface CIRCLE_PITCH_SCALE {} - //Class definition - public final String name; - public final T value; - /* package */ Property(String name, T value) { - this.name = name; - this.value = value; + private Property() { } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java index 8e7d516a39..5cd0d99270 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyFactory.java @@ -1,9 +1,13 @@ -package com.mapbox.mapboxsdk.style.layers; // This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. +package com.mapbox.mapboxsdk.style.layers; + import android.annotation.SuppressLint; import android.support.annotation.ColorInt; +import com.mapbox.mapboxsdk.style.functions.Function; +import com.mapbox.mapboxsdk.style.functions.CameraFunction; + /** * Constructs paint/layout properties for Layers * @@ -17,18 +21,19 @@ public class PropertyFactory { * @param value the visibility value * @return property wrapper around visibility */ - public static Property<String> visibility(@Property.VISIBILITY String value) { - return new LayoutProperty<>("visibility", value); + public static PropertyValue<String> visibility(@Property.VISIBILITY String value) { + return new LayoutPropertyValue<>("visibility", value); } /** * Set the property visibility. * + * @param <T> the function input type * @param function the visibility function * @return property wrapper around a String function */ - public static Property<Function<String>> visibility(Function<String> function) { - return new LayoutProperty<>("visibility", function); + public static <T> PropertyValue<Function<T, String>> visibility(Function<T, String> function) { + return new LayoutPropertyValue<>("visibility", function); } /** @@ -37,73 +42,74 @@ public class PropertyFactory { * @param value a Boolean value * @return property wrapper around Boolean */ - public static Property<Boolean> fillAntialias(Boolean value) { - return new PaintProperty<>("fill-antialias", value); + public static PropertyValue<Boolean> fillAntialias(Boolean value) { + return new PaintPropertyValue<>("fill-antialias", value); } + /** * Whether or not the fill should be antialiased. * - * @param function a wrapper function for Boolean + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Boolean * @return property wrapper around a Boolean function */ - public static Property<Function<Boolean>> fillAntialias(Function<Boolean> function) { - return new PaintProperty<>("fill-antialias", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Boolean>> fillAntialias(CameraFunction<Z, Boolean> function) { + return new PaintPropertyValue<>("fill-antialias", function); } /** - * The opacity of the entire fill layer. In contrast to the {@link PropertyFactory#fillColor}, this value will also - * affect the 1px stroke around the fill, if the stroke is used. + * The opacity of the entire fill layer. In contrast to the {@link PropertyFactory#fillColor}, this value will also affect the 1px stroke around the fill, if the stroke is used. * * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> fillOpacity(Float value) { - return new PaintProperty<>("fill-opacity", value); + public static PropertyValue<Float> fillOpacity(Float value) { + return new PaintPropertyValue<>("fill-opacity", value); } + /** - * The opacity of the entire fill layer. In contrast to the {@link PropertyFactory#fillColor}, this value will also - * affect the 1px stroke around the fill, if the stroke is used. + * The opacity of the entire fill layer. In contrast to the {@link PropertyFactory#fillColor}, this value will also affect the 1px stroke around the fill, if the stroke is used. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> fillOpacity(Function<Float> function) { - return new PaintProperty<>("fill-opacity", function); + public static <T> PropertyValue<Function<T, Float>> fillOpacity(Function<T, Float> function) { + return new PaintPropertyValue<>("fill-opacity", function); } /** - * The color of the filled part of this layer. This color can be specified as `rgba` with an alpha component and the - * color's opacity will not affect the opacity of the 1px stroke, if it is used. + * The color of the filled part of this layer. This color can be specified as `rgba` with an alpha component and the color's opacity will not affect the opacity of the 1px stroke, if it is used. * * @param value a int color value * @return property wrapper around String color */ - public static Property<String> fillColor(@ColorInt int value) { - return new PaintProperty<>("fill-color", colorToRgbaString(value)); + public static PropertyValue<String> fillColor(@ColorInt int value) { + return new PaintPropertyValue<>("fill-color", colorToRgbaString(value)); } /** - * The color of the filled part of this layer. This color can be specified as `rgba` with an alpha component and the - * color's opacity will not affect the opacity of the 1px stroke, if it is used. + * The color of the filled part of this layer. This color can be specified as `rgba` with an alpha component and the color's opacity will not affect the opacity of the 1px stroke, if it is used. * * @param value a String value * @return property wrapper around String */ - public static Property<String> fillColor(String value) { - return new PaintProperty<>("fill-color", value); + public static PropertyValue<String> fillColor(String value) { + return new PaintPropertyValue<>("fill-color", value); } + /** - * The color of the filled part of this layer. This color can be specified as `rgba` with an alpha component and the - * color's opacity will not affect the opacity of the 1px stroke, if it is used. + * The color of the filled part of this layer. This color can be specified as `rgba` with an alpha component and the color's opacity will not affect the opacity of the 1px stroke, if it is used. * + * @param <T> the function input type * @param function a wrapper function for String * @return property wrapper around a String function */ - public static Property<Function<String>> fillColor(Function<String> function) { - return new PaintProperty<>("fill-color", function); + public static <T> PropertyValue<Function<T, String>> fillColor(Function<T, String> function) { + return new PaintPropertyValue<>("fill-color", function); } /** @@ -112,8 +118,8 @@ public class PropertyFactory { * @param value a int color value * @return property wrapper around String color */ - public static Property<String> fillOutlineColor(@ColorInt int value) { - return new PaintProperty<>("fill-outline-color", colorToRgbaString(value)); + public static PropertyValue<String> fillOutlineColor(@ColorInt int value) { + return new PaintPropertyValue<>("fill-outline-color", colorToRgbaString(value)); } /** @@ -122,18 +128,20 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> fillOutlineColor(String value) { - return new PaintProperty<>("fill-outline-color", value); + public static PropertyValue<String> fillOutlineColor(String value) { + return new PaintPropertyValue<>("fill-outline-color", value); } + /** * The outline color of the fill. Matches the value of {@link PropertyFactory#fillColor} if unspecified. * + * @param <T> the function input type * @param function a wrapper function for String * @return property wrapper around a String function */ - public static Property<Function<String>> fillOutlineColor(Function<String> function) { - return new PaintProperty<>("fill-outline-color", function); + public static <T> PropertyValue<Function<T, String>> fillOutlineColor(Function<T, String> function) { + return new PaintPropertyValue<>("fill-outline-color", function); } /** @@ -142,18 +150,20 @@ public class PropertyFactory { * @param value a Float[] value * @return property wrapper around Float[] */ - public static Property<Float[]> fillTranslate(Float[] value) { - return new PaintProperty<>("fill-translate", value); + public static PropertyValue<Float[]> fillTranslate(Float[] value) { + return new PaintPropertyValue<>("fill-translate", value); } + /** * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively. * - * @param function a wrapper function for Float[] + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float[] * @return property wrapper around a Float[] function */ - public static Property<Function<Float[]>> fillTranslate(Function<Float[]> function) { - return new PaintProperty<>("fill-translate", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float[]>> fillTranslate(CameraFunction<Z, Float[]> function) { + return new PaintPropertyValue<>("fill-translate", function); } /** @@ -162,40 +172,42 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> fillTranslateAnchor(@Property.FILL_TRANSLATE_ANCHOR String value) { - return new PaintProperty<>("fill-translate-anchor", value); + public static PropertyValue<String> fillTranslateAnchor(@Property.FILL_TRANSLATE_ANCHOR String value) { + return new PaintPropertyValue<>("fill-translate-anchor", value); } + /** * Controls the translation reference point. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> fillTranslateAnchor(Function<String> function) { - return new PaintProperty<>("fill-translate-anchor", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> fillTranslateAnchor(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("fill-translate-anchor", function); } /** - * Name of image in sprite to use for drawing image fills. For seamless patterns, image width and height must be a - * factor of two (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing image fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). * * @param value a String value * @return property wrapper around String */ - public static Property<String> fillPattern(String value) { - return new PaintProperty<>("fill-pattern", value); + public static PropertyValue<String> fillPattern(String value) { + return new PaintPropertyValue<>("fill-pattern", value); } + /** - * Name of image in sprite to use for drawing image fills. For seamless patterns, image width and height must be a - * factor of two (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing image fills. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> fillPattern(Function<String> function) { - return new PaintProperty<>("fill-pattern", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> fillPattern(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("fill-pattern", function); } /** @@ -204,18 +216,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> lineOpacity(Float value) { - return new PaintProperty<>("line-opacity", value); + public static PropertyValue<Float> lineOpacity(Float value) { + return new PaintPropertyValue<>("line-opacity", value); } + /** * The opacity at which the line will be drawn. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> lineOpacity(Function<Float> function) { - return new PaintProperty<>("line-opacity", function); + public static <T> PropertyValue<Function<T, Float>> lineOpacity(Function<T, Float> function) { + return new PaintPropertyValue<>("line-opacity", function); } /** @@ -224,8 +238,8 @@ public class PropertyFactory { * @param value a int color value * @return property wrapper around String color */ - public static Property<String> lineColor(@ColorInt int value) { - return new PaintProperty<>("line-color", colorToRgbaString(value)); + public static PropertyValue<String> lineColor(@ColorInt int value) { + return new PaintPropertyValue<>("line-color", colorToRgbaString(value)); } /** @@ -234,18 +248,20 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> lineColor(String value) { - return new PaintProperty<>("line-color", value); + public static PropertyValue<String> lineColor(String value) { + return new PaintPropertyValue<>("line-color", value); } + /** * The color with which the line will be drawn. * + * @param <T> the function input type * @param function a wrapper function for String * @return property wrapper around a String function */ - public static Property<Function<String>> lineColor(Function<String> function) { - return new PaintProperty<>("line-color", function); + public static <T> PropertyValue<Function<T, String>> lineColor(Function<T, String> function) { + return new PaintPropertyValue<>("line-color", function); } /** @@ -254,18 +270,20 @@ public class PropertyFactory { * @param value a Float[] value * @return property wrapper around Float[] */ - public static Property<Float[]> lineTranslate(Float[] value) { - return new PaintProperty<>("line-translate", value); + public static PropertyValue<Float[]> lineTranslate(Float[] value) { + return new PaintPropertyValue<>("line-translate", value); } + /** * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively. * - * @param function a wrapper function for Float[] + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float[] * @return property wrapper around a Float[] function */ - public static Property<Function<Float[]>> lineTranslate(Function<Float[]> function) { - return new PaintProperty<>("line-translate", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float[]>> lineTranslate(CameraFunction<Z, Float[]> function) { + return new PaintPropertyValue<>("line-translate", function); } /** @@ -274,18 +292,20 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> lineTranslateAnchor(@Property.LINE_TRANSLATE_ANCHOR String value) { - return new PaintProperty<>("line-translate-anchor", value); + public static PropertyValue<String> lineTranslateAnchor(@Property.LINE_TRANSLATE_ANCHOR String value) { + return new PaintPropertyValue<>("line-translate-anchor", value); } + /** * Controls the translation reference point. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> lineTranslateAnchor(Function<String> function) { - return new PaintProperty<>("line-translate-anchor", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> lineTranslateAnchor(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("line-translate-anchor", function); } /** @@ -294,18 +314,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> lineWidth(Float value) { - return new PaintProperty<>("line-width", value); + public static PropertyValue<Float> lineWidth(Float value) { + return new PaintPropertyValue<>("line-width", value); } + /** * Stroke thickness. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> lineWidth(Function<Float> function) { - return new PaintProperty<>("line-width", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> lineWidth(CameraFunction<Z, Float> function) { + return new PaintPropertyValue<>("line-width", function); } /** @@ -314,106 +336,108 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> lineGapWidth(Float value) { - return new PaintProperty<>("line-gap-width", value); + public static PropertyValue<Float> lineGapWidth(Float value) { + return new PaintPropertyValue<>("line-gap-width", value); } + /** * Draws a line casing outside of a line's actual path. Value indicates the width of the inner gap. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> lineGapWidth(Function<Float> function) { - return new PaintProperty<>("line-gap-width", function); + public static <T> PropertyValue<Function<T, Float>> lineGapWidth(Function<T, Float> function) { + return new PaintPropertyValue<>("line-gap-width", function); } /** - * The line's offset. For linear features, a positive value offsets the line to the right, relative to the direction - * of the line, and a negative value to the left. For polygon features, a positive value results in an inset, and a - * negative value results in an outset. + * The line's offset. For linear features, a positive value offsets the line to the right, relative to the direction of the line, and a negative value to the left. For polygon features, a positive value results in an inset, and a negative value results in an outset. * * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> lineOffset(Float value) { - return new PaintProperty<>("line-offset", value); + public static PropertyValue<Float> lineOffset(Float value) { + return new PaintPropertyValue<>("line-offset", value); } + /** - * The line's offset. For linear features, a positive value offsets the line to the right, relative to the direction - * of the line, and a negative value to the left. For polygon features, a positive value results in an inset, and a - * negative value results in an outset. + * The line's offset. For linear features, a positive value offsets the line to the right, relative to the direction of the line, and a negative value to the left. For polygon features, a positive value results in an inset, and a negative value results in an outset. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> lineOffset(Function<Float> function) { - return new PaintProperty<>("line-offset", function); + public static <T> PropertyValue<Function<T, Float>> lineOffset(Function<T, Float> function) { + return new PaintPropertyValue<>("line-offset", function); } /** - * Blur applied to the line, in pixels. + * Blur applied to the line, in density-independent pixels. * * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> lineBlur(Float value) { - return new PaintProperty<>("line-blur", value); + public static PropertyValue<Float> lineBlur(Float value) { + return new PaintPropertyValue<>("line-blur", value); } + /** - * Blur applied to the line, in pixels. + * Blur applied to the line, in density-independent pixels. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> lineBlur(Function<Float> function) { - return new PaintProperty<>("line-blur", function); + public static <T> PropertyValue<Function<T, Float>> lineBlur(Function<T, Float> function) { + return new PaintPropertyValue<>("line-blur", function); } /** - * Specifies the lengths of the alternating dashes and gaps that form the dash pattern. The lengths are later scaled - * by the line width. To convert a dash length to pixels, multiply the length by the current line width. + * Specifies the lengths of the alternating dashes and gaps that form the dash pattern. The lengths are later scaled by the line width. To convert a dash length to density-independent pixels, multiply the length by the current line width. * * @param value a Float[] value * @return property wrapper around Float[] */ - public static Property<Float[]> lineDasharray(Float[] value) { - return new PaintProperty<>("line-dasharray", value); + public static PropertyValue<Float[]> lineDasharray(Float[] value) { + return new PaintPropertyValue<>("line-dasharray", value); } + /** - * Specifies the lengths of the alternating dashes and gaps that form the dash pattern. The lengths are later scaled - * by the line width. To convert a dash length to pixels, multiply the length by the current line width. + * Specifies the lengths of the alternating dashes and gaps that form the dash pattern. The lengths are later scaled by the line width. To convert a dash length to density-independent pixels, multiply the length by the current line width. * - * @param function a wrapper function for Float[] + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float[] * @return property wrapper around a Float[] function */ - public static Property<Function<Float[]>> lineDasharray(Function<Float[]> function) { - return new PaintProperty<>("line-dasharray", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float[]>> lineDasharray(CameraFunction<Z, Float[]> function) { + return new PaintPropertyValue<>("line-dasharray", function); } /** - * Name of image in sprite to use for drawing image lines. For seamless patterns, image width must be a factor of two - * (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing image lines. For seamless patterns, image width must be a factor of two (2, 4, 8, ..., 512). * * @param value a String value * @return property wrapper around String */ - public static Property<String> linePattern(String value) { - return new PaintProperty<>("line-pattern", value); + public static PropertyValue<String> linePattern(String value) { + return new PaintPropertyValue<>("line-pattern", value); } + /** - * Name of image in sprite to use for drawing image lines. For seamless patterns, image width must be a factor of two - * (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing image lines. For seamless patterns, image width must be a factor of two (2, 4, 8, ..., 512). * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> linePattern(Function<String> function) { - return new PaintProperty<>("line-pattern", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> linePattern(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("line-pattern", function); } /** @@ -422,18 +446,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> iconOpacity(Float value) { - return new PaintProperty<>("icon-opacity", value); + public static PropertyValue<Float> iconOpacity(Float value) { + return new PaintPropertyValue<>("icon-opacity", value); } + /** * The opacity at which the icon will be drawn. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> iconOpacity(Function<Float> function) { - return new PaintProperty<>("icon-opacity", function); + public static <T> PropertyValue<Function<T, Float>> iconOpacity(Function<T, Float> function) { + return new PaintPropertyValue<>("icon-opacity", function); } /** @@ -442,8 +468,8 @@ public class PropertyFactory { * @param value a int color value * @return property wrapper around String color */ - public static Property<String> iconColor(@ColorInt int value) { - return new PaintProperty<>("icon-color", colorToRgbaString(value)); + public static PropertyValue<String> iconColor(@ColorInt int value) { + return new PaintPropertyValue<>("icon-color", colorToRgbaString(value)); } /** @@ -452,18 +478,20 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> iconColor(String value) { - return new PaintProperty<>("icon-color", value); + public static PropertyValue<String> iconColor(String value) { + return new PaintPropertyValue<>("icon-color", value); } + /** * The color of the icon. This can only be used with sdf icons. * + * @param <T> the function input type * @param function a wrapper function for String * @return property wrapper around a String function */ - public static Property<Function<String>> iconColor(Function<String> function) { - return new PaintProperty<>("icon-color", function); + public static <T> PropertyValue<Function<T, String>> iconColor(Function<T, String> function) { + return new PaintPropertyValue<>("icon-color", function); } /** @@ -472,8 +500,8 @@ public class PropertyFactory { * @param value a int color value * @return property wrapper around String color */ - public static Property<String> iconHaloColor(@ColorInt int value) { - return new PaintProperty<>("icon-halo-color", colorToRgbaString(value)); + public static PropertyValue<String> iconHaloColor(@ColorInt int value) { + return new PaintPropertyValue<>("icon-halo-color", colorToRgbaString(value)); } /** @@ -482,18 +510,20 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> iconHaloColor(String value) { - return new PaintProperty<>("icon-halo-color", value); + public static PropertyValue<String> iconHaloColor(String value) { + return new PaintPropertyValue<>("icon-halo-color", value); } + /** * The color of the icon's halo. Icon halos can only be used with SDF icons. * + * @param <T> the function input type * @param function a wrapper function for String * @return property wrapper around a String function */ - public static Property<Function<String>> iconHaloColor(Function<String> function) { - return new PaintProperty<>("icon-halo-color", function); + public static <T> PropertyValue<Function<T, String>> iconHaloColor(Function<T, String> function) { + return new PaintPropertyValue<>("icon-halo-color", function); } /** @@ -502,18 +532,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> iconHaloWidth(Float value) { - return new PaintProperty<>("icon-halo-width", value); + public static PropertyValue<Float> iconHaloWidth(Float value) { + return new PaintPropertyValue<>("icon-halo-width", value); } + /** * Distance of halo to the icon outline. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> iconHaloWidth(Function<Float> function) { - return new PaintProperty<>("icon-halo-width", function); + public static <T> PropertyValue<Function<T, Float>> iconHaloWidth(Function<T, Float> function) { + return new PaintPropertyValue<>("icon-halo-width", function); } /** @@ -522,40 +554,42 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> iconHaloBlur(Float value) { - return new PaintProperty<>("icon-halo-blur", value); + public static PropertyValue<Float> iconHaloBlur(Float value) { + return new PaintPropertyValue<>("icon-halo-blur", value); } + /** * Fade out the halo towards the outside. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> iconHaloBlur(Function<Float> function) { - return new PaintProperty<>("icon-halo-blur", function); + public static <T> PropertyValue<Function<T, Float>> iconHaloBlur(Function<T, Float> function) { + return new PaintPropertyValue<>("icon-halo-blur", function); } /** - * Distance that the icon's anchor is moved from its original placement. Positive values indicate right and down, - * while negative values indicate left and up. + * Distance that the icon's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up. * * @param value a Float[] value * @return property wrapper around Float[] */ - public static Property<Float[]> iconTranslate(Float[] value) { - return new PaintProperty<>("icon-translate", value); + public static PropertyValue<Float[]> iconTranslate(Float[] value) { + return new PaintPropertyValue<>("icon-translate", value); } + /** - * Distance that the icon's anchor is moved from its original placement. Positive values indicate right and down, - * while negative values indicate left and up. + * Distance that the icon's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up. * - * @param function a wrapper function for Float[] + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float[] * @return property wrapper around a Float[] function */ - public static Property<Function<Float[]>> iconTranslate(Function<Float[]> function) { - return new PaintProperty<>("icon-translate", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float[]>> iconTranslate(CameraFunction<Z, Float[]> function) { + return new PaintPropertyValue<>("icon-translate", function); } /** @@ -564,18 +598,20 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> iconTranslateAnchor(@Property.ICON_TRANSLATE_ANCHOR String value) { - return new PaintProperty<>("icon-translate-anchor", value); + public static PropertyValue<String> iconTranslateAnchor(@Property.ICON_TRANSLATE_ANCHOR String value) { + return new PaintPropertyValue<>("icon-translate-anchor", value); } + /** * Controls the translation reference point. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> iconTranslateAnchor(Function<String> function) { - return new PaintProperty<>("icon-translate-anchor", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> iconTranslateAnchor(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("icon-translate-anchor", function); } /** @@ -584,18 +620,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> textOpacity(Float value) { - return new PaintProperty<>("text-opacity", value); + public static PropertyValue<Float> textOpacity(Float value) { + return new PaintPropertyValue<>("text-opacity", value); } + /** * The opacity at which the text will be drawn. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> textOpacity(Function<Float> function) { - return new PaintProperty<>("text-opacity", function); + public static <T> PropertyValue<Function<T, Float>> textOpacity(Function<T, Float> function) { + return new PaintPropertyValue<>("text-opacity", function); } /** @@ -604,8 +642,8 @@ public class PropertyFactory { * @param value a int color value * @return property wrapper around String color */ - public static Property<String> textColor(@ColorInt int value) { - return new PaintProperty<>("text-color", colorToRgbaString(value)); + public static PropertyValue<String> textColor(@ColorInt int value) { + return new PaintPropertyValue<>("text-color", colorToRgbaString(value)); } /** @@ -614,18 +652,20 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> textColor(String value) { - return new PaintProperty<>("text-color", value); + public static PropertyValue<String> textColor(String value) { + return new PaintPropertyValue<>("text-color", value); } + /** * The color with which the text will be drawn. * + * @param <T> the function input type * @param function a wrapper function for String * @return property wrapper around a String function */ - public static Property<Function<String>> textColor(Function<String> function) { - return new PaintProperty<>("text-color", function); + public static <T> PropertyValue<Function<T, String>> textColor(Function<T, String> function) { + return new PaintPropertyValue<>("text-color", function); } /** @@ -634,8 +674,8 @@ public class PropertyFactory { * @param value a int color value * @return property wrapper around String color */ - public static Property<String> textHaloColor(@ColorInt int value) { - return new PaintProperty<>("text-halo-color", colorToRgbaString(value)); + public static PropertyValue<String> textHaloColor(@ColorInt int value) { + return new PaintPropertyValue<>("text-halo-color", colorToRgbaString(value)); } /** @@ -644,18 +684,20 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> textHaloColor(String value) { - return new PaintProperty<>("text-halo-color", value); + public static PropertyValue<String> textHaloColor(String value) { + return new PaintPropertyValue<>("text-halo-color", value); } + /** * The color of the text's halo, which helps it stand out from backgrounds. * + * @param <T> the function input type * @param function a wrapper function for String * @return property wrapper around a String function */ - public static Property<Function<String>> textHaloColor(Function<String> function) { - return new PaintProperty<>("text-halo-color", function); + public static <T> PropertyValue<Function<T, String>> textHaloColor(Function<T, String> function) { + return new PaintPropertyValue<>("text-halo-color", function); } /** @@ -664,18 +706,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> textHaloWidth(Float value) { - return new PaintProperty<>("text-halo-width", value); + public static PropertyValue<Float> textHaloWidth(Float value) { + return new PaintPropertyValue<>("text-halo-width", value); } + /** * Distance of halo to the font outline. Max text halo width is 1/4 of the font-size. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> textHaloWidth(Function<Float> function) { - return new PaintProperty<>("text-halo-width", function); + public static <T> PropertyValue<Function<T, Float>> textHaloWidth(Function<T, Float> function) { + return new PaintPropertyValue<>("text-halo-width", function); } /** @@ -684,40 +728,42 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> textHaloBlur(Float value) { - return new PaintProperty<>("text-halo-blur", value); + public static PropertyValue<Float> textHaloBlur(Float value) { + return new PaintPropertyValue<>("text-halo-blur", value); } + /** * The halo's fadeout distance towards the outside. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> textHaloBlur(Function<Float> function) { - return new PaintProperty<>("text-halo-blur", function); + public static <T> PropertyValue<Function<T, Float>> textHaloBlur(Function<T, Float> function) { + return new PaintPropertyValue<>("text-halo-blur", function); } /** - * Distance that the text's anchor is moved from its original placement. Positive values indicate right and down, - * while negative values indicate left and up. + * Distance that the text's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up. * * @param value a Float[] value * @return property wrapper around Float[] */ - public static Property<Float[]> textTranslate(Float[] value) { - return new PaintProperty<>("text-translate", value); + public static PropertyValue<Float[]> textTranslate(Float[] value) { + return new PaintPropertyValue<>("text-translate", value); } + /** - * Distance that the text's anchor is moved from its original placement. Positive values indicate right and down, - * while negative values indicate left and up. + * Distance that the text's anchor is moved from its original placement. Positive values indicate right and down, while negative values indicate left and up. * - * @param function a wrapper function for Float[] + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float[] * @return property wrapper around a Float[] function */ - public static Property<Function<Float[]>> textTranslate(Function<Float[]> function) { - return new PaintProperty<>("text-translate", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float[]>> textTranslate(CameraFunction<Z, Float[]> function) { + return new PaintPropertyValue<>("text-translate", function); } /** @@ -726,18 +772,20 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> textTranslateAnchor(@Property.TEXT_TRANSLATE_ANCHOR String value) { - return new PaintProperty<>("text-translate-anchor", value); + public static PropertyValue<String> textTranslateAnchor(@Property.TEXT_TRANSLATE_ANCHOR String value) { + return new PaintPropertyValue<>("text-translate-anchor", value); } + /** * Controls the translation reference point. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> textTranslateAnchor(Function<String> function) { - return new PaintProperty<>("text-translate-anchor", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> textTranslateAnchor(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("text-translate-anchor", function); } /** @@ -746,18 +794,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> circleRadius(Float value) { - return new PaintProperty<>("circle-radius", value); + public static PropertyValue<Float> circleRadius(Float value) { + return new PaintPropertyValue<>("circle-radius", value); } + /** * Circle radius. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> circleRadius(Function<Float> function) { - return new PaintProperty<>("circle-radius", function); + public static <T> PropertyValue<Function<T, Float>> circleRadius(Function<T, Float> function) { + return new PaintPropertyValue<>("circle-radius", function); } /** @@ -766,8 +816,8 @@ public class PropertyFactory { * @param value a int color value * @return property wrapper around String color */ - public static Property<String> circleColor(@ColorInt int value) { - return new PaintProperty<>("circle-color", colorToRgbaString(value)); + public static PropertyValue<String> circleColor(@ColorInt int value) { + return new PaintPropertyValue<>("circle-color", colorToRgbaString(value)); } /** @@ -776,18 +826,20 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> circleColor(String value) { - return new PaintProperty<>("circle-color", value); + public static PropertyValue<String> circleColor(String value) { + return new PaintPropertyValue<>("circle-color", value); } + /** * The fill color of the circle. * + * @param <T> the function input type * @param function a wrapper function for String * @return property wrapper around a String function */ - public static Property<Function<String>> circleColor(Function<String> function) { - return new PaintProperty<>("circle-color", function); + public static <T> PropertyValue<Function<T, String>> circleColor(Function<T, String> function) { + return new PaintPropertyValue<>("circle-color", function); } /** @@ -796,18 +848,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> circleBlur(Float value) { - return new PaintProperty<>("circle-blur", value); + public static PropertyValue<Float> circleBlur(Float value) { + return new PaintPropertyValue<>("circle-blur", value); } + /** * Amount to blur the circle. 1 blurs the circle such that only the centerpoint is full opacity. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> circleBlur(Function<Float> function) { - return new PaintProperty<>("circle-blur", function); + public static <T> PropertyValue<Function<T, Float>> circleBlur(Function<T, Float> function) { + return new PaintPropertyValue<>("circle-blur", function); } /** @@ -816,18 +870,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> circleOpacity(Float value) { - return new PaintProperty<>("circle-opacity", value); + public static PropertyValue<Float> circleOpacity(Float value) { + return new PaintPropertyValue<>("circle-opacity", value); } + /** * The opacity at which the circle will be drawn. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> circleOpacity(Function<Float> function) { - return new PaintProperty<>("circle-opacity", function); + public static <T> PropertyValue<Function<T, Float>> circleOpacity(Function<T, Float> function) { + return new PaintPropertyValue<>("circle-opacity", function); } /** @@ -836,18 +892,20 @@ public class PropertyFactory { * @param value a Float[] value * @return property wrapper around Float[] */ - public static Property<Float[]> circleTranslate(Float[] value) { - return new PaintProperty<>("circle-translate", value); + public static PropertyValue<Float[]> circleTranslate(Float[] value) { + return new PaintPropertyValue<>("circle-translate", value); } + /** * The geometry's offset. Values are [x, y] where negatives indicate left and up, respectively. * - * @param function a wrapper function for Float[] + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float[] * @return property wrapper around a Float[] function */ - public static Property<Function<Float[]>> circleTranslate(Function<Float[]> function) { - return new PaintProperty<>("circle-translate", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float[]>> circleTranslate(CameraFunction<Z, Float[]> function) { + return new PaintPropertyValue<>("circle-translate", function); } /** @@ -856,18 +914,20 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> circleTranslateAnchor(@Property.CIRCLE_TRANSLATE_ANCHOR String value) { - return new PaintProperty<>("circle-translate-anchor", value); + public static PropertyValue<String> circleTranslateAnchor(@Property.CIRCLE_TRANSLATE_ANCHOR String value) { + return new PaintPropertyValue<>("circle-translate-anchor", value); } + /** * Controls the translation reference point. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> circleTranslateAnchor(Function<String> function) { - return new PaintProperty<>("circle-translate-anchor", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> circleTranslateAnchor(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("circle-translate-anchor", function); } /** @@ -876,38 +936,42 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> circlePitchScale(@Property.CIRCLE_PITCH_SCALE String value) { - return new PaintProperty<>("circle-pitch-scale", value); + public static PropertyValue<String> circlePitchScale(@Property.CIRCLE_PITCH_SCALE String value) { + return new PaintPropertyValue<>("circle-pitch-scale", value); } + /** * Controls the scaling behavior of the circle when the map is pitched. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> circlePitchScale(Function<String> function) { - return new PaintProperty<>("circle-pitch-scale", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> circlePitchScale(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("circle-pitch-scale", function); } /** - * The width of the circle's stroke. Strokes are placed outside of the "circle-radius". + * The width of the circle's stroke. Strokes are placed outside of the {@link PropertyFactory#circleRadius}. * * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> circleStrokeWidth(Float value) { - return new PaintProperty<>("circle-stroke-width", value); + public static PropertyValue<Float> circleStrokeWidth(Float value) { + return new PaintPropertyValue<>("circle-stroke-width", value); } + /** - * The width of the circle's stroke. Strokes are placed outside of the "circle-radius". + * The width of the circle's stroke. Strokes are placed outside of the {@link PropertyFactory#circleRadius}. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> circleStrokeWidth(Function<Float> function) { - return new PaintProperty<>("circle-stroke-width", function); + public static <T> PropertyValue<Function<T, Float>> circleStrokeWidth(Function<T, Float> function) { + return new PaintPropertyValue<>("circle-stroke-width", function); } /** @@ -916,8 +980,8 @@ public class PropertyFactory { * @param value a int color value * @return property wrapper around String color */ - public static Property<String> circleStrokeColor(@ColorInt int value) { - return new PaintProperty<>("circle-stroke-color", colorToRgbaString(value)); + public static PropertyValue<String> circleStrokeColor(@ColorInt int value) { + return new PaintPropertyValue<>("circle-stroke-color", colorToRgbaString(value)); } /** @@ -926,18 +990,20 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> circleStrokeColor(String value) { - return new PaintProperty<>("circle-stroke-color", value); + public static PropertyValue<String> circleStrokeColor(String value) { + return new PaintPropertyValue<>("circle-stroke-color", value); } + /** * The stroke color of the circle. * + * @param <T> the function input type * @param function a wrapper function for String * @return property wrapper around a String function */ - public static Property<Function<String>> circleStrokeColor(Function<String> function) { - return new PaintProperty<>("circle-stroke-color", function); + public static <T> PropertyValue<Function<T, String>> circleStrokeColor(Function<T, String> function) { + return new PaintPropertyValue<>("circle-stroke-color", function); } /** @@ -946,18 +1012,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> circleStrokeOpacity(Float value) { - return new PaintProperty<>("circle-stroke-opacity", value); + public static PropertyValue<Float> circleStrokeOpacity(Float value) { + return new PaintPropertyValue<>("circle-stroke-opacity", value); } + /** * The opacity of the circle's stroke. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> circleStrokeOpacity(Function<Float> function) { - return new PaintProperty<>("circle-stroke-opacity", function); + public static <T> PropertyValue<Function<T, Float>> circleStrokeOpacity(Function<T, Float> function) { + return new PaintPropertyValue<>("circle-stroke-opacity", function); } /** @@ -966,18 +1034,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> rasterOpacity(Float value) { - return new PaintProperty<>("raster-opacity", value); + public static PropertyValue<Float> rasterOpacity(Float value) { + return new PaintPropertyValue<>("raster-opacity", value); } + /** * The opacity at which the image will be drawn. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> rasterOpacity(Function<Float> function) { - return new PaintProperty<>("raster-opacity", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> rasterOpacity(CameraFunction<Z, Float> function) { + return new PaintPropertyValue<>("raster-opacity", function); } /** @@ -986,18 +1056,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> rasterHueRotate(Float value) { - return new PaintProperty<>("raster-hue-rotate", value); + public static PropertyValue<Float> rasterHueRotate(Float value) { + return new PaintPropertyValue<>("raster-hue-rotate", value); } + /** * Rotates hues around the color wheel. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> rasterHueRotate(Function<Float> function) { - return new PaintProperty<>("raster-hue-rotate", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> rasterHueRotate(CameraFunction<Z, Float> function) { + return new PaintPropertyValue<>("raster-hue-rotate", function); } /** @@ -1006,18 +1078,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> rasterBrightnessMin(Float value) { - return new PaintProperty<>("raster-brightness-min", value); + public static PropertyValue<Float> rasterBrightnessMin(Float value) { + return new PaintPropertyValue<>("raster-brightness-min", value); } + /** * Increase or reduce the brightness of the image. The value is the minimum brightness. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> rasterBrightnessMin(Function<Float> function) { - return new PaintProperty<>("raster-brightness-min", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> rasterBrightnessMin(CameraFunction<Z, Float> function) { + return new PaintPropertyValue<>("raster-brightness-min", function); } /** @@ -1026,18 +1100,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> rasterBrightnessMax(Float value) { - return new PaintProperty<>("raster-brightness-max", value); + public static PropertyValue<Float> rasterBrightnessMax(Float value) { + return new PaintPropertyValue<>("raster-brightness-max", value); } + /** * Increase or reduce the brightness of the image. The value is the maximum brightness. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> rasterBrightnessMax(Function<Float> function) { - return new PaintProperty<>("raster-brightness-max", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> rasterBrightnessMax(CameraFunction<Z, Float> function) { + return new PaintPropertyValue<>("raster-brightness-max", function); } /** @@ -1046,18 +1122,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> rasterSaturation(Float value) { - return new PaintProperty<>("raster-saturation", value); + public static PropertyValue<Float> rasterSaturation(Float value) { + return new PaintPropertyValue<>("raster-saturation", value); } + /** * Increase or reduce the saturation of the image. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> rasterSaturation(Function<Float> function) { - return new PaintProperty<>("raster-saturation", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> rasterSaturation(CameraFunction<Z, Float> function) { + return new PaintPropertyValue<>("raster-saturation", function); } /** @@ -1066,18 +1144,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> rasterContrast(Float value) { - return new PaintProperty<>("raster-contrast", value); + public static PropertyValue<Float> rasterContrast(Float value) { + return new PaintPropertyValue<>("raster-contrast", value); } + /** * Increase or reduce the contrast of the image. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> rasterContrast(Function<Float> function) { - return new PaintProperty<>("raster-contrast", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> rasterContrast(CameraFunction<Z, Float> function) { + return new PaintPropertyValue<>("raster-contrast", function); } /** @@ -1086,18 +1166,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> rasterFadeDuration(Float value) { - return new PaintProperty<>("raster-fade-duration", value); + public static PropertyValue<Float> rasterFadeDuration(Float value) { + return new PaintPropertyValue<>("raster-fade-duration", value); } + /** * Fade duration when a new tile is added. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> rasterFadeDuration(Function<Float> function) { - return new PaintProperty<>("raster-fade-duration", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> rasterFadeDuration(CameraFunction<Z, Float> function) { + return new PaintPropertyValue<>("raster-fade-duration", function); } /** @@ -1106,8 +1188,8 @@ public class PropertyFactory { * @param value a int color value * @return property wrapper around String color */ - public static Property<String> backgroundColor(@ColorInt int value) { - return new PaintProperty<>("background-color", colorToRgbaString(value)); + public static PropertyValue<String> backgroundColor(@ColorInt int value) { + return new PaintPropertyValue<>("background-color", colorToRgbaString(value)); } /** @@ -1116,40 +1198,42 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> backgroundColor(String value) { - return new PaintProperty<>("background-color", value); + public static PropertyValue<String> backgroundColor(String value) { + return new PaintPropertyValue<>("background-color", value); } + /** * The color with which the background will be drawn. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> backgroundColor(Function<String> function) { - return new PaintProperty<>("background-color", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> backgroundColor(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("background-color", function); } /** - * Name of image in sprite to use for drawing an image background. For seamless patterns, image width and height must - * be a factor of two (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing an image background. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). * * @param value a String value * @return property wrapper around String */ - public static Property<String> backgroundPattern(String value) { - return new PaintProperty<>("background-pattern", value); + public static PropertyValue<String> backgroundPattern(String value) { + return new PaintPropertyValue<>("background-pattern", value); } + /** - * Name of image in sprite to use for drawing an image background. For seamless patterns, image width and height must - * be a factor of two (2, 4, 8, ..., 512). + * Name of image in sprite to use for drawing an image background. For seamless patterns, image width and height must be a factor of two (2, 4, 8, ..., 512). * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> backgroundPattern(Function<String> function) { - return new PaintProperty<>("background-pattern", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> backgroundPattern(CameraFunction<Z, String> function) { + return new PaintPropertyValue<>("background-pattern", function); } /** @@ -1158,18 +1242,20 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> backgroundOpacity(Float value) { - return new PaintProperty<>("background-opacity", value); + public static PropertyValue<Float> backgroundOpacity(Float value) { + return new PaintPropertyValue<>("background-opacity", value); } + /** * The opacity at which the background will be drawn. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> backgroundOpacity(Function<Float> function) { - return new PaintProperty<>("background-opacity", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> backgroundOpacity(CameraFunction<Z, Float> function) { + return new PaintPropertyValue<>("background-opacity", function); } /** @@ -1178,18 +1264,21 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> lineCap(@Property.LINE_CAP String value) { - return new LayoutProperty<>("line-cap", value); + public static PropertyValue<String> lineCap(@Property.LINE_CAP String value) { + return new LayoutPropertyValue<>("line-cap", value); } + + /** * The display of line endings. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> lineCap(Function<String> function) { - return new LayoutProperty<>("line-cap", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> lineCap(CameraFunction<Z, String> function) { + return new LayoutPropertyValue<>("line-cap", function); } /** @@ -1198,18 +1287,21 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> lineJoin(@Property.LINE_JOIN String value) { - return new LayoutProperty<>("line-join", value); + public static PropertyValue<String> lineJoin(@Property.LINE_JOIN String value) { + return new LayoutPropertyValue<>("line-join", value); } + + /** * The display of lines when joining. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> lineJoin(Function<String> function) { - return new LayoutProperty<>("line-join", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> lineJoin(CameraFunction<Z, String> function) { + return new LayoutPropertyValue<>("line-join", function); } /** @@ -1218,18 +1310,21 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> lineMiterLimit(Float value) { - return new LayoutProperty<>("line-miter-limit", value); + public static PropertyValue<Float> lineMiterLimit(Float value) { + return new LayoutPropertyValue<>("line-miter-limit", value); } + + /** * Used to automatically convert miter joins to bevel joins for sharp angles. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> lineMiterLimit(Function<Float> function) { - return new LayoutProperty<>("line-miter-limit", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> lineMiterLimit(CameraFunction<Z, Float> function) { + return new LayoutPropertyValue<>("line-miter-limit", function); } /** @@ -1238,18 +1333,21 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> lineRoundLimit(Float value) { - return new LayoutProperty<>("line-round-limit", value); + public static PropertyValue<Float> lineRoundLimit(Float value) { + return new LayoutPropertyValue<>("line-round-limit", value); } + + /** * Used to automatically convert round joins to miter joins for shallow angles. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> lineRoundLimit(Function<Float> function) { - return new LayoutProperty<>("line-round-limit", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> lineRoundLimit(CameraFunction<Z, Float> function) { + return new LayoutPropertyValue<>("line-round-limit", function); } /** @@ -1258,18 +1356,21 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> symbolPlacement(@Property.SYMBOL_PLACEMENT String value) { - return new LayoutProperty<>("symbol-placement", value); + public static PropertyValue<String> symbolPlacement(@Property.SYMBOL_PLACEMENT String value) { + return new LayoutPropertyValue<>("symbol-placement", value); } + + /** * Label placement relative to its geometry. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> symbolPlacement(Function<String> function) { - return new LayoutProperty<>("symbol-placement", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> symbolPlacement(CameraFunction<Z, String> function) { + return new LayoutPropertyValue<>("symbol-placement", function); } /** @@ -1278,42 +1379,44 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> symbolSpacing(Float value) { - return new LayoutProperty<>("symbol-spacing", value); + public static PropertyValue<Float> symbolSpacing(Float value) { + return new LayoutPropertyValue<>("symbol-spacing", value); } + + /** * Distance between two symbol anchors. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> symbolSpacing(Function<Float> function) { - return new LayoutProperty<>("symbol-spacing", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> symbolSpacing(CameraFunction<Z, Float> function) { + return new LayoutPropertyValue<>("symbol-spacing", function); } /** - * If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have - * enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line - * symbol layer. + * If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer. * * @param value a Boolean value * @return property wrapper around Boolean */ - public static Property<Boolean> symbolAvoidEdges(Boolean value) { - return new LayoutProperty<>("symbol-avoid-edges", value); + public static PropertyValue<Boolean> symbolAvoidEdges(Boolean value) { + return new LayoutPropertyValue<>("symbol-avoid-edges", value); } + + /** - * If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have - * enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line - * symbol layer. + * If true, the symbols will not cross tile edges to avoid mutual collisions. Recommended in layers that don't have enough padding in the vector tile to prevent collisions, or if it is a point symbol layer placed after a line symbol layer. * - * @param function a wrapper function for Boolean + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Boolean * @return property wrapper around a Boolean function */ - public static Property<Function<Boolean>> symbolAvoidEdges(Function<Boolean> function) { - return new LayoutProperty<>("symbol-avoid-edges", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Boolean>> symbolAvoidEdges(CameraFunction<Z, Boolean> function) { + return new LayoutPropertyValue<>("symbol-avoid-edges", function); } /** @@ -1322,18 +1425,21 @@ public class PropertyFactory { * @param value a Boolean value * @return property wrapper around Boolean */ - public static Property<Boolean> iconAllowOverlap(Boolean value) { - return new LayoutProperty<>("icon-allow-overlap", value); + public static PropertyValue<Boolean> iconAllowOverlap(Boolean value) { + return new LayoutPropertyValue<>("icon-allow-overlap", value); } + + /** * If true, the icon will be visible even if it collides with other previously drawn symbols. * - * @param function a wrapper function for Boolean + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Boolean * @return property wrapper around a Boolean function */ - public static Property<Function<Boolean>> iconAllowOverlap(Function<Boolean> function) { - return new LayoutProperty<>("icon-allow-overlap", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Boolean>> iconAllowOverlap(CameraFunction<Z, Boolean> function) { + return new LayoutPropertyValue<>("icon-allow-overlap", function); } /** @@ -1342,40 +1448,44 @@ public class PropertyFactory { * @param value a Boolean value * @return property wrapper around Boolean */ - public static Property<Boolean> iconIgnorePlacement(Boolean value) { - return new LayoutProperty<>("icon-ignore-placement", value); + public static PropertyValue<Boolean> iconIgnorePlacement(Boolean value) { + return new LayoutPropertyValue<>("icon-ignore-placement", value); } + + /** * If true, other symbols can be visible even if they collide with the icon. * - * @param function a wrapper function for Boolean + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Boolean * @return property wrapper around a Boolean function */ - public static Property<Function<Boolean>> iconIgnorePlacement(Function<Boolean> function) { - return new LayoutProperty<>("icon-ignore-placement", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Boolean>> iconIgnorePlacement(CameraFunction<Z, Boolean> function) { + return new LayoutPropertyValue<>("icon-ignore-placement", function); } /** - * If true, text will display without their corresponding icons when the icon collides with other symbols and the - * text does not. + * If true, text will display without their corresponding icons when the icon collides with other symbols and the text does not. * * @param value a Boolean value * @return property wrapper around Boolean */ - public static Property<Boolean> iconOptional(Boolean value) { - return new LayoutProperty<>("icon-optional", value); + public static PropertyValue<Boolean> iconOptional(Boolean value) { + return new LayoutPropertyValue<>("icon-optional", value); } + + /** - * If true, text will display without their corresponding icons when the icon collides with other symbols and the - * text does not. + * If true, text will display without their corresponding icons when the icon collides with other symbols and the text does not. * - * @param function a wrapper function for Boolean + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Boolean * @return property wrapper around a Boolean function */ - public static Property<Function<Boolean>> iconOptional(Function<Boolean> function) { - return new LayoutProperty<>("icon-optional", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Boolean>> iconOptional(CameraFunction<Z, Boolean> function) { + return new LayoutPropertyValue<>("icon-optional", function); } /** @@ -1384,18 +1494,21 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> iconRotationAlignment(@Property.ICON_ROTATION_ALIGNMENT String value) { - return new LayoutProperty<>("icon-rotation-alignment", value); + public static PropertyValue<String> iconRotationAlignment(@Property.ICON_ROTATION_ALIGNMENT String value) { + return new LayoutPropertyValue<>("icon-rotation-alignment", value); } + + /** * In combination with {@link Property.SYMBOL_PLACEMENT}, determines the rotation behavior of icons. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> iconRotationAlignment(Function<String> function) { - return new LayoutProperty<>("icon-rotation-alignment", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> iconRotationAlignment(CameraFunction<Z, String> function) { + return new LayoutPropertyValue<>("icon-rotation-alignment", function); } /** @@ -1404,18 +1517,21 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> iconSize(Float value) { - return new LayoutProperty<>("icon-size", value); + public static PropertyValue<Float> iconSize(Float value) { + return new LayoutPropertyValue<>("icon-size", value); } + + /** * Scale factor for icon. 1 is original size, 3 triples the size. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> iconSize(Function<Float> function) { - return new LayoutProperty<>("icon-size", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> iconSize(CameraFunction<Z, Float> function) { + return new LayoutPropertyValue<>("icon-size", function); } /** @@ -1424,40 +1540,44 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> iconTextFit(@Property.ICON_TEXT_FIT String value) { - return new LayoutProperty<>("icon-text-fit", value); + public static PropertyValue<String> iconTextFit(@Property.ICON_TEXT_FIT String value) { + return new LayoutPropertyValue<>("icon-text-fit", value); } + + /** * Scales the icon to fit around the associated text. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> iconTextFit(Function<String> function) { - return new LayoutProperty<>("icon-text-fit", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> iconTextFit(CameraFunction<Z, String> function) { + return new LayoutPropertyValue<>("icon-text-fit", function); } /** - * Size of the additional area added to dimensions determined by {@link Property.ICON_TEXT_FIT}, in clockwise order: - * top, right, bottom, left. + * Size of the additional area added to dimensions determined by {@link Property.ICON_TEXT_FIT}, in clockwise order: top, right, bottom, left. * * @param value a Float[] value * @return property wrapper around Float[] */ - public static Property<Float[]> iconTextFitPadding(Float[] value) { - return new LayoutProperty<>("icon-text-fit-padding", value); + public static PropertyValue<Float[]> iconTextFitPadding(Float[] value) { + return new LayoutPropertyValue<>("icon-text-fit-padding", value); } + + /** - * Size of the additional area added to dimensions determined by {@link Property.ICON_TEXT_FIT}, in clockwise order: - * top, right, bottom, left. + * Size of the additional area added to dimensions determined by {@link Property.ICON_TEXT_FIT}, in clockwise order: top, right, bottom, left. * - * @param function a wrapper function for Float[] + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float[] * @return property wrapper around a Float[] function */ - public static Property<Function<Float[]>> iconTextFitPadding(Function<Float[]> function) { - return new LayoutProperty<>("icon-text-fit-padding", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float[]>> iconTextFitPadding(CameraFunction<Z, Float[]> function) { + return new LayoutPropertyValue<>("icon-text-fit-padding", function); } /** @@ -1466,18 +1586,21 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> iconImage(String value) { - return new LayoutProperty<>("icon-image", value); + public static PropertyValue<String> iconImage(String value) { + return new LayoutPropertyValue<>("icon-image", value); } + + /** * A string with {tokens} replaced, referencing the data property to pull from. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> iconImage(Function<String> function) { - return new LayoutProperty<>("icon-image", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> iconImage(CameraFunction<Z, String> function) { + return new LayoutPropertyValue<>("icon-image", function); } /** @@ -1486,18 +1609,21 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> iconRotate(Float value) { - return new LayoutProperty<>("icon-rotate", value); + public static PropertyValue<Float> iconRotate(Float value) { + return new LayoutPropertyValue<>("icon-rotate", value); } + + /** * Rotates the icon clockwise. * + * @param <T> the function input type * @param function a wrapper function for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> iconRotate(Function<Float> function) { - return new LayoutProperty<>("icon-rotate", function); + public static <T> PropertyValue<Function<T, Float>> iconRotate(Function<T, Float> function) { + return new LayoutPropertyValue<>("icon-rotate", function); } /** @@ -1506,18 +1632,21 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> iconPadding(Float value) { - return new LayoutProperty<>("icon-padding", value); + public static PropertyValue<Float> iconPadding(Float value) { + return new LayoutPropertyValue<>("icon-padding", value); } + + /** * Size of the additional area around the icon bounding box used for detecting symbol collisions. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> iconPadding(Function<Float> function) { - return new LayoutProperty<>("icon-padding", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> iconPadding(CameraFunction<Z, Float> function) { + return new LayoutPropertyValue<>("icon-padding", function); } /** @@ -1526,40 +1655,44 @@ public class PropertyFactory { * @param value a Boolean value * @return property wrapper around Boolean */ - public static Property<Boolean> iconKeepUpright(Boolean value) { - return new LayoutProperty<>("icon-keep-upright", value); + public static PropertyValue<Boolean> iconKeepUpright(Boolean value) { + return new LayoutPropertyValue<>("icon-keep-upright", value); } + + /** * If true, the icon may be flipped to prevent it from being rendered upside-down. * - * @param function a wrapper function for Boolean + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Boolean * @return property wrapper around a Boolean function */ - public static Property<Function<Boolean>> iconKeepUpright(Function<Boolean> function) { - return new LayoutProperty<>("icon-keep-upright", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Boolean>> iconKeepUpright(CameraFunction<Z, Boolean> function) { + return new LayoutPropertyValue<>("icon-keep-upright", function); } /** - * Offset distance of icon from its anchor. Positive values indicate right and down, while negative values indicate - * left and up. + * Offset distance of icon from its anchor. Positive values indicate right and down, while negative values indicate left and up. When combined with {@link PropertyFactory#iconRotate} the offset will be as if the rotated direction was up. * * @param value a Float[] value * @return property wrapper around Float[] */ - public static Property<Float[]> iconOffset(Float[] value) { - return new LayoutProperty<>("icon-offset", value); + public static PropertyValue<Float[]> iconOffset(Float[] value) { + return new LayoutPropertyValue<>("icon-offset", value); } + + /** - * Offset distance of icon from its anchor. Positive values indicate right and down, while negative values indicate - * left and up. + * Offset distance of icon from its anchor. Positive values indicate right and down, while negative values indicate left and up. When combined with {@link PropertyFactory#iconRotate} the offset will be as if the rotated direction was up. * + * @param <T> the function input type * @param function a wrapper function for Float[] * @return property wrapper around a Float[] function */ - public static Property<Function<Float[]>> iconOffset(Function<Float[]> function) { - return new LayoutProperty<>("icon-offset", function); + public static <T> PropertyValue<Function<T, Float[]>> iconOffset(Function<T, Float[]> function) { + return new LayoutPropertyValue<>("icon-offset", function); } /** @@ -1568,60 +1701,67 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> textPitchAlignment(@Property.TEXT_PITCH_ALIGNMENT String value) { - return new LayoutProperty<>("text-pitch-alignment", value); + public static PropertyValue<String> textPitchAlignment(@Property.TEXT_PITCH_ALIGNMENT String value) { + return new LayoutPropertyValue<>("text-pitch-alignment", value); } + + /** * Orientation of text when map is pitched. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> textPitchAlignment(Function<String> function) { - return new LayoutProperty<>("text-pitch-alignment", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> textPitchAlignment(CameraFunction<Z, String> function) { + return new LayoutPropertyValue<>("text-pitch-alignment", function); } /** - * In combination with {@link Property.SYMBOL_PLACEMENT}, determines the rotation behavior of the individual glyphs - * forming the text. + * In combination with {@link Property.SYMBOL_PLACEMENT}, determines the rotation behavior of the individual glyphs forming the text. * * @param value a String value * @return property wrapper around String */ - public static Property<String> textRotationAlignment(@Property.TEXT_ROTATION_ALIGNMENT String value) { - return new LayoutProperty<>("text-rotation-alignment", value); + public static PropertyValue<String> textRotationAlignment(@Property.TEXT_ROTATION_ALIGNMENT String value) { + return new LayoutPropertyValue<>("text-rotation-alignment", value); } + + /** - * In combination with {@link Property.SYMBOL_PLACEMENT}, determines the rotation behavior of the individual glyphs - * forming the text. + * In combination with {@link Property.SYMBOL_PLACEMENT}, determines the rotation behavior of the individual glyphs forming the text. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> textRotationAlignment(Function<String> function) { - return new LayoutProperty<>("text-rotation-alignment", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> textRotationAlignment(CameraFunction<Z, String> function) { + return new LayoutPropertyValue<>("text-rotation-alignment", function); } /** - * Value to use for a text label. Feature properties are specified using tokens like {field_name}. + * Value to use for a text label. Feature properties are specified using tokens like {field_name}. (Token replacement is only supported for literal {@link PropertyFactory#textField} values--not for property functions.) * * @param value a String value * @return property wrapper around String */ - public static Property<String> textField(String value) { - return new LayoutProperty<>("text-field", value); + public static PropertyValue<String> textField(String value) { + return new LayoutPropertyValue<>("text-field", value); } + + /** - * Value to use for a text label. Feature properties are specified using tokens like {field_name}. + * Value to use for a text label. Feature properties are specified using tokens like {field_name}. (Token replacement is only supported for literal {@link PropertyFactory#textField} values--not for property functions.) * + * @param <T> the function input type * @param function a wrapper function for String * @return property wrapper around a String function */ - public static Property<Function<String>> textField(Function<String> function) { - return new LayoutProperty<>("text-field", function); + public static <T> PropertyValue<Function<T, String>> textField(Function<T, String> function) { + return new LayoutPropertyValue<>("text-field", function); } /** @@ -1630,18 +1770,21 @@ public class PropertyFactory { * @param value a String[] value * @return property wrapper around String[] */ - public static Property<String[]> textFont(String[] value) { - return new LayoutProperty<>("text-font", value); + public static PropertyValue<String[]> textFont(String[] value) { + return new LayoutPropertyValue<>("text-font", value); } + + /** * Font stack to use for displaying text. * - * @param function a wrapper function for String[] + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String[] * @return property wrapper around a String[] function */ - public static Property<Function<String[]>> textFont(Function<String[]> function) { - return new LayoutProperty<>("text-font", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String[]>> textFont(CameraFunction<Z, String[]> function) { + return new LayoutPropertyValue<>("text-font", function); } /** @@ -1650,18 +1793,21 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> textSize(Float value) { - return new LayoutProperty<>("text-size", value); + public static PropertyValue<Float> textSize(Float value) { + return new LayoutPropertyValue<>("text-size", value); } + + /** * Font size. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> textSize(Function<Float> function) { - return new LayoutProperty<>("text-size", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> textSize(CameraFunction<Z, Float> function) { + return new LayoutPropertyValue<>("text-size", function); } /** @@ -1670,18 +1816,21 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> textMaxWidth(Float value) { - return new LayoutProperty<>("text-max-width", value); + public static PropertyValue<Float> textMaxWidth(Float value) { + return new LayoutPropertyValue<>("text-max-width", value); } + + /** * The maximum line width for text wrapping. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> textMaxWidth(Function<Float> function) { - return new LayoutProperty<>("text-max-width", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> textMaxWidth(CameraFunction<Z, Float> function) { + return new LayoutPropertyValue<>("text-max-width", function); } /** @@ -1690,18 +1839,21 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> textLineHeight(Float value) { - return new LayoutProperty<>("text-line-height", value); + public static PropertyValue<Float> textLineHeight(Float value) { + return new LayoutPropertyValue<>("text-line-height", value); } + + /** * Text leading value for multi-line text. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> textLineHeight(Function<Float> function) { - return new LayoutProperty<>("text-line-height", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> textLineHeight(CameraFunction<Z, Float> function) { + return new LayoutPropertyValue<>("text-line-height", function); } /** @@ -1710,18 +1862,21 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> textLetterSpacing(Float value) { - return new LayoutProperty<>("text-letter-spacing", value); + public static PropertyValue<Float> textLetterSpacing(Float value) { + return new LayoutPropertyValue<>("text-letter-spacing", value); } + + /** * Text tracking amount. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> textLetterSpacing(Function<Float> function) { - return new LayoutProperty<>("text-letter-spacing", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> textLetterSpacing(CameraFunction<Z, Float> function) { + return new LayoutPropertyValue<>("text-letter-spacing", function); } /** @@ -1730,18 +1885,21 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> textJustify(@Property.TEXT_JUSTIFY String value) { - return new LayoutProperty<>("text-justify", value); + public static PropertyValue<String> textJustify(@Property.TEXT_JUSTIFY String value) { + return new LayoutPropertyValue<>("text-justify", value); } + + /** * Text justification options. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> textJustify(Function<String> function) { - return new LayoutProperty<>("text-justify", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> textJustify(CameraFunction<Z, String> function) { + return new LayoutPropertyValue<>("text-justify", function); } /** @@ -1750,18 +1908,21 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> textAnchor(@Property.TEXT_ANCHOR String value) { - return new LayoutProperty<>("text-anchor", value); + public static PropertyValue<String> textAnchor(@Property.TEXT_ANCHOR String value) { + return new LayoutPropertyValue<>("text-anchor", value); } + + /** * Part of the text placed closest to the anchor. * - * @param function a wrapper function for String + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for String * @return property wrapper around a String function */ - public static Property<Function<String>> textAnchor(Function<String> function) { - return new LayoutProperty<>("text-anchor", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, String>> textAnchor(CameraFunction<Z, String> function) { + return new LayoutPropertyValue<>("text-anchor", function); } /** @@ -1770,18 +1931,21 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> textMaxAngle(Float value) { - return new LayoutProperty<>("text-max-angle", value); + public static PropertyValue<Float> textMaxAngle(Float value) { + return new LayoutPropertyValue<>("text-max-angle", value); } + + /** * Maximum angle change between adjacent characters. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> textMaxAngle(Function<Float> function) { - return new LayoutProperty<>("text-max-angle", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> textMaxAngle(CameraFunction<Z, Float> function) { + return new LayoutPropertyValue<>("text-max-angle", function); } /** @@ -1790,18 +1954,21 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> textRotate(Float value) { - return new LayoutProperty<>("text-rotate", value); + public static PropertyValue<Float> textRotate(Float value) { + return new LayoutPropertyValue<>("text-rotate", value); } + + /** * Rotates the text clockwise. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> textRotate(Function<Float> function) { - return new LayoutProperty<>("text-rotate", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> textRotate(CameraFunction<Z, Float> function) { + return new LayoutPropertyValue<>("text-rotate", function); } /** @@ -1810,18 +1977,21 @@ public class PropertyFactory { * @param value a Float value * @return property wrapper around Float */ - public static Property<Float> textPadding(Float value) { - return new LayoutProperty<>("text-padding", value); + public static PropertyValue<Float> textPadding(Float value) { + return new LayoutPropertyValue<>("text-padding", value); } + + /** * Size of the additional area around the text bounding box used for detecting symbol collisions. * - * @param function a wrapper function for Float + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float * @return property wrapper around a Float function */ - public static Property<Function<Float>> textPadding(Function<Float> function) { - return new LayoutProperty<>("text-padding", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float>> textPadding(CameraFunction<Z, Float> function) { + return new LayoutPropertyValue<>("text-padding", function); } /** @@ -1830,18 +2000,21 @@ public class PropertyFactory { * @param value a Boolean value * @return property wrapper around Boolean */ - public static Property<Boolean> textKeepUpright(Boolean value) { - return new LayoutProperty<>("text-keep-upright", value); + public static PropertyValue<Boolean> textKeepUpright(Boolean value) { + return new LayoutPropertyValue<>("text-keep-upright", value); } + + /** * If true, the text may be flipped vertically to prevent it from being rendered upside-down. * - * @param function a wrapper function for Boolean + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Boolean * @return property wrapper around a Boolean function */ - public static Property<Function<Boolean>> textKeepUpright(Function<Boolean> function) { - return new LayoutProperty<>("text-keep-upright", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Boolean>> textKeepUpright(CameraFunction<Z, Boolean> function) { + return new LayoutPropertyValue<>("text-keep-upright", function); } /** @@ -1850,40 +2023,44 @@ public class PropertyFactory { * @param value a String value * @return property wrapper around String */ - public static Property<String> textTransform(@Property.TEXT_TRANSFORM String value) { - return new LayoutProperty<>("text-transform", value); + public static PropertyValue<String> textTransform(@Property.TEXT_TRANSFORM String value) { + return new LayoutPropertyValue<>("text-transform", value); } + + /** * Specifies how to capitalize text, similar to the CSS {@link PropertyFactory#textTransform} property. * + * @param <T> the function input type * @param function a wrapper function for String * @return property wrapper around a String function */ - public static Property<Function<String>> textTransform(Function<String> function) { - return new LayoutProperty<>("text-transform", function); + public static <T> PropertyValue<Function<T, String>> textTransform(Function<T, String> function) { + return new LayoutPropertyValue<>("text-transform", function); } /** - * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate - * left and up. + * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate left and up. * * @param value a Float[] value * @return property wrapper around Float[] */ - public static Property<Float[]> textOffset(Float[] value) { - return new LayoutProperty<>("text-offset", value); + public static PropertyValue<Float[]> textOffset(Float[] value) { + return new LayoutPropertyValue<>("text-offset", value); } + + /** - * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate - * left and up. + * Offset distance of text from its anchor. Positive values indicate right and down, while negative values indicate left and up. * - * @param function a wrapper function for Float[] + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Float[] * @return property wrapper around a Float[] function */ - public static Property<Function<Float[]>> textOffset(Function<Float[]> function) { - return new LayoutProperty<>("text-offset", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Float[]>> textOffset(CameraFunction<Z, Float[]> function) { + return new LayoutPropertyValue<>("text-offset", function); } /** @@ -1892,18 +2069,21 @@ public class PropertyFactory { * @param value a Boolean value * @return property wrapper around Boolean */ - public static Property<Boolean> textAllowOverlap(Boolean value) { - return new LayoutProperty<>("text-allow-overlap", value); + public static PropertyValue<Boolean> textAllowOverlap(Boolean value) { + return new LayoutPropertyValue<>("text-allow-overlap", value); } + + /** * If true, the text will be visible even if it collides with other previously drawn symbols. * - * @param function a wrapper function for Boolean + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Boolean * @return property wrapper around a Boolean function */ - public static Property<Function<Boolean>> textAllowOverlap(Function<Boolean> function) { - return new LayoutProperty<>("text-allow-overlap", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Boolean>> textAllowOverlap(CameraFunction<Z, Boolean> function) { + return new LayoutPropertyValue<>("text-allow-overlap", function); } /** @@ -1912,46 +2092,49 @@ public class PropertyFactory { * @param value a Boolean value * @return property wrapper around Boolean */ - public static Property<Boolean> textIgnorePlacement(Boolean value) { - return new LayoutProperty<>("text-ignore-placement", value); + public static PropertyValue<Boolean> textIgnorePlacement(Boolean value) { + return new LayoutPropertyValue<>("text-ignore-placement", value); } + + /** * If true, other symbols can be visible even if they collide with the text. * - * @param function a wrapper function for Boolean + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Boolean * @return property wrapper around a Boolean function */ - public static Property<Function<Boolean>> textIgnorePlacement(Function<Boolean> function) { - return new LayoutProperty<>("text-ignore-placement", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Boolean>> textIgnorePlacement(CameraFunction<Z, Boolean> function) { + return new LayoutPropertyValue<>("text-ignore-placement", function); } /** - * If true, icons will display without their corresponding text when the text collides with other symbols and the - * icon does not. + * If true, icons will display without their corresponding text when the text collides with other symbols and the icon does not. * * @param value a Boolean value * @return property wrapper around Boolean */ - public static Property<Boolean> textOptional(Boolean value) { - return new LayoutProperty<>("text-optional", value); + public static PropertyValue<Boolean> textOptional(Boolean value) { + return new LayoutPropertyValue<>("text-optional", value); } + + /** - * If true, icons will display without their corresponding text when the text collides with other symbols and the - * icon does not. + * If true, icons will display without their corresponding text when the text collides with other symbols and the icon does not. * - * @param function a wrapper function for Boolean + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for Boolean * @return property wrapper around a Boolean function */ - public static Property<Function<Boolean>> textOptional(Function<Boolean> function) { - return new LayoutProperty<>("text-optional", function); + public static <Z extends Number> PropertyValue<CameraFunction<Z, Boolean>> textOptional(CameraFunction<Z, Boolean> function) { + return new LayoutPropertyValue<>("text-optional", function); } @SuppressLint("DefaultLocale") - static String colorToRgbaString(@ColorInt int value) { - return String.format("rgba(%d, %d, %d, %d)", (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, - (value >> 24) & 0xFF); + public static String colorToRgbaString(@ColorInt int value) { + return String.format("rgba(%d, %d, %d, %d)", (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, (value >> 24) & 0xFF); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java index c404f07c76..5286e6916d 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/PropertyValue.java @@ -1,7 +1,10 @@ package com.mapbox.mapboxsdk.style.layers; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import com.mapbox.mapboxsdk.style.functions.Function; + import timber.log.Timber; /** @@ -9,9 +12,11 @@ import timber.log.Timber; */ public class PropertyValue<T> { - private final Object value; + public final String name; + public final T value; - /* package */ PropertyValue(Object value) { + /* package */ PropertyValue(@NonNull String name, T value) { + this.name = name; this.value = value; } @@ -28,10 +33,10 @@ public class PropertyValue<T> { } @Nullable - public Function<T> getFunction() { + public Function<?, T> getFunction() { if (isFunction()) { - //noinspection unchecked - return (Function<T>) value; + // noinspection unchecked + return (Function<?, T>) value; } else { Timber.w("not a function, try value"); return null; @@ -41,7 +46,7 @@ public class PropertyValue<T> { @Nullable public T getValue() { if (isValue()) { - //noinspection unchecked + // noinspection unchecked return (T) value; } else { Timber.w("not a value, try function"); @@ -51,7 +56,6 @@ public class PropertyValue<T> { @Override public String toString() { - return String.format("%s (%s)", getClass().getSimpleName(), value != null - ? value.getClass().getSimpleName() : null); + return String.format("%s: %s", name, value); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/RasterLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/RasterLayer.java index 785106c394..1871686429 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/RasterLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/RasterLayer.java @@ -1,9 +1,13 @@ -package com.mapbox.mapboxsdk.style.layers; // This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. +package com.mapbox.mapboxsdk.style.layers; + +import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.UiThread; +import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor; + /** * Raster map textures such as satellite imagery. * @@ -59,7 +63,7 @@ public class RasterLayer extends Layer { * @param properties the var-args properties * @return This */ - public RasterLayer withProperties(@NonNull Property<?>... properties) { + public RasterLayer withProperties(@NonNull PropertyValue<?>... properties) { setProperties(properties); return this; } @@ -73,7 +77,7 @@ public class RasterLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getRasterOpacity() { - return (PropertyValue<Float>) new PropertyValue(nativeGetRasterOpacity()); + return (PropertyValue<Float>) new PropertyValue("raster-opacity", nativeGetRasterOpacity()); } /** @@ -83,7 +87,7 @@ public class RasterLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getRasterHueRotate() { - return (PropertyValue<Float>) new PropertyValue(nativeGetRasterHueRotate()); + return (PropertyValue<Float>) new PropertyValue("raster-hue-rotate", nativeGetRasterHueRotate()); } /** @@ -93,7 +97,7 @@ public class RasterLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getRasterBrightnessMin() { - return (PropertyValue<Float>) new PropertyValue(nativeGetRasterBrightnessMin()); + return (PropertyValue<Float>) new PropertyValue("raster-brightness-min", nativeGetRasterBrightnessMin()); } /** @@ -103,7 +107,7 @@ public class RasterLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getRasterBrightnessMax() { - return (PropertyValue<Float>) new PropertyValue(nativeGetRasterBrightnessMax()); + return (PropertyValue<Float>) new PropertyValue("raster-brightness-max", nativeGetRasterBrightnessMax()); } /** @@ -113,7 +117,7 @@ public class RasterLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getRasterSaturation() { - return (PropertyValue<Float>) new PropertyValue(nativeGetRasterSaturation()); + return (PropertyValue<Float>) new PropertyValue("raster-saturation", nativeGetRasterSaturation()); } /** @@ -123,7 +127,7 @@ public class RasterLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getRasterContrast() { - return (PropertyValue<Float>) new PropertyValue(nativeGetRasterContrast()); + return (PropertyValue<Float>) new PropertyValue("raster-contrast", nativeGetRasterContrast()); } /** @@ -133,7 +137,7 @@ public class RasterLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getRasterFadeDuration() { - return (PropertyValue<Float>) new PropertyValue(nativeGetRasterFadeDuration()); + return (PropertyValue<Float>) new PropertyValue("raster-fade-duration", nativeGetRasterFadeDuration()); } private native Object nativeGetRasterOpacity(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java index abc516d6d0..c1efdc9636 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/SymbolLayer.java @@ -1,6 +1,7 @@ -package com.mapbox.mapboxsdk.style.layers; // This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. +package com.mapbox.mapboxsdk.style.layers; + import android.support.annotation.ColorInt; import android.support.annotation.NonNull; import android.support.annotation.UiThread; @@ -62,27 +63,7 @@ public class SymbolLayer extends Layer { * @param filter the filter to set */ public void setFilter(Filter.Statement filter) { - this.setFilter(filter.toArray()); - } - - /** - * Set an array of filters. - * - * @param filter the filter array to set - */ - public void setFilter(Object[] filter) { - nativeSetFilter(filter); - } - - /** - * Set an array of filters. - * - * @param filter tthe filter array to set - * @return This - */ - public SymbolLayer withFilter(Object[] filter) { - setFilter(filter); - return this; + nativeSetFilter(filter.toArray()); } /** @@ -96,14 +77,13 @@ public class SymbolLayer extends Layer { return this; } - /** * Set a property or properties. * * @param properties the var-args properties * @return This */ - public SymbolLayer withProperties(@NonNull Property<?>... properties) { + public SymbolLayer withProperties(@NonNull PropertyValue<?>... properties) { setProperties(properties); return this; } @@ -117,7 +97,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getSymbolPlacement() { - return (PropertyValue<String>) new PropertyValue(nativeGetSymbolPlacement()); + return (PropertyValue<String>) new PropertyValue("symbol-placement", nativeGetSymbolPlacement()); } /** @@ -127,7 +107,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getSymbolSpacing() { - return (PropertyValue<Float>) new PropertyValue(nativeGetSymbolSpacing()); + return (PropertyValue<Float>) new PropertyValue("symbol-spacing", nativeGetSymbolSpacing()); } /** @@ -137,7 +117,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Boolean> getSymbolAvoidEdges() { - return (PropertyValue<Boolean>) new PropertyValue(nativeGetSymbolAvoidEdges()); + return (PropertyValue<Boolean>) new PropertyValue("symbol-avoid-edges", nativeGetSymbolAvoidEdges()); } /** @@ -147,7 +127,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Boolean> getIconAllowOverlap() { - return (PropertyValue<Boolean>) new PropertyValue(nativeGetIconAllowOverlap()); + return (PropertyValue<Boolean>) new PropertyValue("icon-allow-overlap", nativeGetIconAllowOverlap()); } /** @@ -157,7 +137,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Boolean> getIconIgnorePlacement() { - return (PropertyValue<Boolean>) new PropertyValue(nativeGetIconIgnorePlacement()); + return (PropertyValue<Boolean>) new PropertyValue("icon-ignore-placement", nativeGetIconIgnorePlacement()); } /** @@ -167,7 +147,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Boolean> getIconOptional() { - return (PropertyValue<Boolean>) new PropertyValue(nativeGetIconOptional()); + return (PropertyValue<Boolean>) new PropertyValue("icon-optional", nativeGetIconOptional()); } /** @@ -177,7 +157,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getIconRotationAlignment() { - return (PropertyValue<String>) new PropertyValue(nativeGetIconRotationAlignment()); + return (PropertyValue<String>) new PropertyValue("icon-rotation-alignment", nativeGetIconRotationAlignment()); } /** @@ -187,7 +167,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getIconSize() { - return (PropertyValue<Float>) new PropertyValue(nativeGetIconSize()); + return (PropertyValue<Float>) new PropertyValue("icon-size", nativeGetIconSize()); } /** @@ -197,7 +177,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getIconTextFit() { - return (PropertyValue<String>) new PropertyValue(nativeGetIconTextFit()); + return (PropertyValue<String>) new PropertyValue("icon-text-fit", nativeGetIconTextFit()); } /** @@ -207,7 +187,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float[]> getIconTextFitPadding() { - return (PropertyValue<Float[]>) new PropertyValue(nativeGetIconTextFitPadding()); + return (PropertyValue<Float[]>) new PropertyValue("icon-text-fit-padding", nativeGetIconTextFitPadding()); } /** @@ -217,7 +197,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getIconImage() { - return (PropertyValue<String>) new PropertyValue(nativeGetIconImage()); + return (PropertyValue<String>) new PropertyValue("icon-image", nativeGetIconImage()); } /** @@ -227,7 +207,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getIconRotate() { - return (PropertyValue<Float>) new PropertyValue(nativeGetIconRotate()); + return (PropertyValue<Float>) new PropertyValue("icon-rotate", nativeGetIconRotate()); } /** @@ -237,7 +217,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getIconPadding() { - return (PropertyValue<Float>) new PropertyValue(nativeGetIconPadding()); + return (PropertyValue<Float>) new PropertyValue("icon-padding", nativeGetIconPadding()); } /** @@ -247,7 +227,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Boolean> getIconKeepUpright() { - return (PropertyValue<Boolean>) new PropertyValue(nativeGetIconKeepUpright()); + return (PropertyValue<Boolean>) new PropertyValue("icon-keep-upright", nativeGetIconKeepUpright()); } /** @@ -257,7 +237,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float[]> getIconOffset() { - return (PropertyValue<Float[]>) new PropertyValue(nativeGetIconOffset()); + return (PropertyValue<Float[]>) new PropertyValue("icon-offset", nativeGetIconOffset()); } /** @@ -267,7 +247,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getTextPitchAlignment() { - return (PropertyValue<String>) new PropertyValue(nativeGetTextPitchAlignment()); + return (PropertyValue<String>) new PropertyValue("text-pitch-alignment", nativeGetTextPitchAlignment()); } /** @@ -277,7 +257,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getTextRotationAlignment() { - return (PropertyValue<String>) new PropertyValue(nativeGetTextRotationAlignment()); + return (PropertyValue<String>) new PropertyValue("text-rotation-alignment", nativeGetTextRotationAlignment()); } /** @@ -287,7 +267,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getTextField() { - return (PropertyValue<String>) new PropertyValue(nativeGetTextField()); + return (PropertyValue<String>) new PropertyValue("text-field", nativeGetTextField()); } /** @@ -297,7 +277,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String[]> getTextFont() { - return (PropertyValue<String[]>) new PropertyValue(nativeGetTextFont()); + return (PropertyValue<String[]>) new PropertyValue("text-font", nativeGetTextFont()); } /** @@ -307,7 +287,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getTextSize() { - return (PropertyValue<Float>) new PropertyValue(nativeGetTextSize()); + return (PropertyValue<Float>) new PropertyValue("text-size", nativeGetTextSize()); } /** @@ -317,7 +297,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getTextMaxWidth() { - return (PropertyValue<Float>) new PropertyValue(nativeGetTextMaxWidth()); + return (PropertyValue<Float>) new PropertyValue("text-max-width", nativeGetTextMaxWidth()); } /** @@ -327,7 +307,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getTextLineHeight() { - return (PropertyValue<Float>) new PropertyValue(nativeGetTextLineHeight()); + return (PropertyValue<Float>) new PropertyValue("text-line-height", nativeGetTextLineHeight()); } /** @@ -337,7 +317,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getTextLetterSpacing() { - return (PropertyValue<Float>) new PropertyValue(nativeGetTextLetterSpacing()); + return (PropertyValue<Float>) new PropertyValue("text-letter-spacing", nativeGetTextLetterSpacing()); } /** @@ -347,7 +327,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getTextJustify() { - return (PropertyValue<String>) new PropertyValue(nativeGetTextJustify()); + return (PropertyValue<String>) new PropertyValue("text-justify", nativeGetTextJustify()); } /** @@ -357,7 +337,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getTextAnchor() { - return (PropertyValue<String>) new PropertyValue(nativeGetTextAnchor()); + return (PropertyValue<String>) new PropertyValue("text-anchor", nativeGetTextAnchor()); } /** @@ -367,7 +347,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getTextMaxAngle() { - return (PropertyValue<Float>) new PropertyValue(nativeGetTextMaxAngle()); + return (PropertyValue<Float>) new PropertyValue("text-max-angle", nativeGetTextMaxAngle()); } /** @@ -377,7 +357,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getTextRotate() { - return (PropertyValue<Float>) new PropertyValue(nativeGetTextRotate()); + return (PropertyValue<Float>) new PropertyValue("text-rotate", nativeGetTextRotate()); } /** @@ -387,7 +367,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getTextPadding() { - return (PropertyValue<Float>) new PropertyValue(nativeGetTextPadding()); + return (PropertyValue<Float>) new PropertyValue("text-padding", nativeGetTextPadding()); } /** @@ -397,7 +377,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Boolean> getTextKeepUpright() { - return (PropertyValue<Boolean>) new PropertyValue(nativeGetTextKeepUpright()); + return (PropertyValue<Boolean>) new PropertyValue("text-keep-upright", nativeGetTextKeepUpright()); } /** @@ -407,7 +387,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getTextTransform() { - return (PropertyValue<String>) new PropertyValue(nativeGetTextTransform()); + return (PropertyValue<String>) new PropertyValue("text-transform", nativeGetTextTransform()); } /** @@ -417,7 +397,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float[]> getTextOffset() { - return (PropertyValue<Float[]>) new PropertyValue(nativeGetTextOffset()); + return (PropertyValue<Float[]>) new PropertyValue("text-offset", nativeGetTextOffset()); } /** @@ -427,7 +407,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Boolean> getTextAllowOverlap() { - return (PropertyValue<Boolean>) new PropertyValue(nativeGetTextAllowOverlap()); + return (PropertyValue<Boolean>) new PropertyValue("text-allow-overlap", nativeGetTextAllowOverlap()); } /** @@ -437,7 +417,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Boolean> getTextIgnorePlacement() { - return (PropertyValue<Boolean>) new PropertyValue(nativeGetTextIgnorePlacement()); + return (PropertyValue<Boolean>) new PropertyValue("text-ignore-placement", nativeGetTextIgnorePlacement()); } /** @@ -447,7 +427,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Boolean> getTextOptional() { - return (PropertyValue<Boolean>) new PropertyValue(nativeGetTextOptional()); + return (PropertyValue<Boolean>) new PropertyValue("text-optional", nativeGetTextOptional()); } /** @@ -457,7 +437,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getIconOpacity() { - return (PropertyValue<Float>) new PropertyValue(nativeGetIconOpacity()); + return (PropertyValue<Float>) new PropertyValue("icon-opacity", nativeGetIconOpacity()); } /** @@ -467,7 +447,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getIconColor() { - return (PropertyValue<String>) new PropertyValue(nativeGetIconColor()); + return (PropertyValue<String>) new PropertyValue("icon-color", nativeGetIconColor()); } /** @@ -494,7 +474,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getIconHaloColor() { - return (PropertyValue<String>) new PropertyValue(nativeGetIconHaloColor()); + return (PropertyValue<String>) new PropertyValue("icon-halo-color", nativeGetIconHaloColor()); } /** @@ -521,7 +501,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getIconHaloWidth() { - return (PropertyValue<Float>) new PropertyValue(nativeGetIconHaloWidth()); + return (PropertyValue<Float>) new PropertyValue("icon-halo-width", nativeGetIconHaloWidth()); } /** @@ -531,7 +511,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getIconHaloBlur() { - return (PropertyValue<Float>) new PropertyValue(nativeGetIconHaloBlur()); + return (PropertyValue<Float>) new PropertyValue("icon-halo-blur", nativeGetIconHaloBlur()); } /** @@ -541,7 +521,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float[]> getIconTranslate() { - return (PropertyValue<Float[]>) new PropertyValue(nativeGetIconTranslate()); + return (PropertyValue<Float[]>) new PropertyValue("icon-translate", nativeGetIconTranslate()); } /** @@ -551,7 +531,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getIconTranslateAnchor() { - return (PropertyValue<String>) new PropertyValue(nativeGetIconTranslateAnchor()); + return (PropertyValue<String>) new PropertyValue("icon-translate-anchor", nativeGetIconTranslateAnchor()); } /** @@ -561,7 +541,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getTextOpacity() { - return (PropertyValue<Float>) new PropertyValue(nativeGetTextOpacity()); + return (PropertyValue<Float>) new PropertyValue("text-opacity", nativeGetTextOpacity()); } /** @@ -571,7 +551,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getTextColor() { - return (PropertyValue<String>) new PropertyValue(nativeGetTextColor()); + return (PropertyValue<String>) new PropertyValue("text-color", nativeGetTextColor()); } /** @@ -598,7 +578,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getTextHaloColor() { - return (PropertyValue<String>) new PropertyValue(nativeGetTextHaloColor()); + return (PropertyValue<String>) new PropertyValue("text-halo-color", nativeGetTextHaloColor()); } /** @@ -625,7 +605,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getTextHaloWidth() { - return (PropertyValue<Float>) new PropertyValue(nativeGetTextHaloWidth()); + return (PropertyValue<Float>) new PropertyValue("text-halo-width", nativeGetTextHaloWidth()); } /** @@ -635,7 +615,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float> getTextHaloBlur() { - return (PropertyValue<Float>) new PropertyValue(nativeGetTextHaloBlur()); + return (PropertyValue<Float>) new PropertyValue("text-halo-blur", nativeGetTextHaloBlur()); } /** @@ -645,7 +625,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<Float[]> getTextTranslate() { - return (PropertyValue<Float[]>) new PropertyValue(nativeGetTextTranslate()); + return (PropertyValue<Float[]>) new PropertyValue("text-translate", nativeGetTextTranslate()); } /** @@ -655,7 +635,7 @@ public class SymbolLayer extends Layer { */ @SuppressWarnings("unchecked") public PropertyValue<String> getTextTranslateAnchor() { - return (PropertyValue<String>) new PropertyValue(nativeGetTextTranslateAnchor()); + return (PropertyValue<String>) new PropertyValue("text-translate-anchor", nativeGetTextTranslateAnchor()); } private native Object nativeGetSymbolPlacement(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/UnknownLayer.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/UnknownLayer.java new file mode 100644 index 0000000000..4abafcdbeb --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/UnknownLayer.java @@ -0,0 +1,25 @@ +package com.mapbox.mapboxsdk.style.layers; + +import android.support.annotation.UiThread; + +/** + * An unknown type of layer + */ +@UiThread +public class UnknownLayer extends Layer { + + /** + * Creates a UnknownLayer. + * + * @param nativePtr pointer used by core + */ + UnknownLayer(long nativePtr) { + super(nativePtr); + } + + protected native void initialize(); + + @Override + protected native void finalize() throws Throwable; + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs index 4657037df8..5eab4c355e 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/layer.java.ejs @@ -4,14 +4,14 @@ const doc = locals.doc; -%> // This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. -package com.mapbox.mapboxsdk.style.layers; -import android.support.annotation.UiThread; +package com.mapbox.mapboxsdk.style.layers; import android.support.annotation.ColorInt; import android.support.annotation.NonNull; +import android.support.annotation.UiThread; -import static com.mapbox.mapboxsdk.utils.ColorUtils.*; +import static com.mapbox.mapboxsdk.utils.ColorUtils.rgbaToColor; /** * <%- doc %> @@ -21,151 +21,133 @@ import static com.mapbox.mapboxsdk.utils.ColorUtils.*; @UiThread public class <%- camelize(type) %>Layer extends Layer { - /** - * Creates a <%- camelize(type) %>Layer. - * - * @param nativePtr pointer used by core - */ - public <%- camelize(type) %>Layer(long nativePtr) { - super(nativePtr); - } + /** + * Creates a <%- camelize(type) %>Layer. + * + * @param nativePtr pointer used by core + */ + public <%- camelize(type) %>Layer(long nativePtr) { + super(nativePtr); + } <% if (type === 'background') { -%> - /** - * Creates a <%- camelize(type) %>Layer. - * - * @param layerId the id of the layer - */ - public <%- camelize(type) %>Layer(String layerId) { - initialize(layerId); - } + /** + * Creates a <%- camelize(type) %>Layer. + * + * @param layerId the id of the layer + */ + public <%- camelize(type) %>Layer(String layerId) { + initialize(layerId); + } - protected native void initialize(String layerId); -<% } else { -%> - /** - * Creates a <%- camelize(type) %>Layer. - * - * @param layerId the id of the layer - * @param sourceId the id of the source - */ - public <%- camelize(type) %>Layer(String layerId, String sourceId) { - initialize(layerId, sourceId); - } - - protected native void initialize(String layerId, String sourceId); + protected native void initialize(String layerId); - /** - * Set the source layer. - * - * @param sourceLayer the source layer to set - */ - public void setSourceLayer(String sourceLayer) { - nativeSetSourceLayer(sourceLayer); - } +<% } else { -%> + /** + * Creates a <%- camelize(type) %>Layer. + * + * @param layerId the id of the layer + * @param sourceId the id of the source + */ + public <%- camelize(type) %>Layer(String layerId, String sourceId) { + initialize(layerId, sourceId); + } + + protected native void initialize(String layerId, String sourceId); + + /** + * Set the source layer. + * + * @param sourceLayer the source layer to set + */ + public void setSourceLayer(String sourceLayer) { + nativeSetSourceLayer(sourceLayer); + } + + /** + * Set the source Layer. + * + * @param sourceLayer the source layer to set + * @return This + */ + public <%- camelize(type) %>Layer withSourceLayer(String sourceLayer) { + setSourceLayer(sourceLayer); + return this; + } - /** - * Set the source Layer. - * - * @param sourceLayer the source layer to set - * @return This - */ - public <%- camelize(type) %>Layer withSourceLayer(String sourceLayer) { - setSourceLayer(sourceLayer); - return this; - } <% } -%> <% if (type !== 'background' && type !== 'raster') { -%> - /** - * Set a single filter. - * - * @param filter the filter to set - */ - public void setFilter(Filter.Statement filter) { - this.setFilter(filter.toArray()); - } - - /** - * Set an array of filters. - * - * @param filter the filter array to set - */ - public void setFilter(Object[] filter) { - nativeSetFilter(filter); - } - - /** - * Set an array of filters. - * - * @param filter tthe filter array to set - * @return This - */ - public <%- camelize(type) %>Layer withFilter(Object[] filter) { - setFilter(filter); - return this; - } - - /** - * Set a single filter. - * - * @param filter the filter to set - * @return This - */ - public <%- camelize(type) %>Layer withFilter(Filter.Statement filter) { - setFilter(filter); - return this; - } + /** + * Set a single filter. + * + * @param filter the filter to set + */ + public void setFilter(Filter.Statement filter) { + nativeSetFilter(filter.toArray()); + } + + /** + * Set a single filter. + * + * @param filter the filter to set + * @return This + */ + public <%- camelize(type) %>Layer withFilter(Filter.Statement filter) { + setFilter(filter); + return this; + } <% } -%> - - /** - * Set a property or properties. - * - * @param properties the var-args properties - * @return This - */ - public <%- camelize(type) %>Layer withProperties(@NonNull Property<?>... properties) { - setProperties(properties); - return this; - } - - // Property getters + /** + * Set a property or properties. + * + * @param properties the var-args properties + * @return This + */ + public <%- camelize(type) %>Layer withProperties(@NonNull PropertyValue<?>... properties) { + setProperties(properties); + return this; + } + + // Property getters <% for (const property of properties) { -%> - /** - * Get the <%- camelize(property.name) %> property - * - * @return property wrapper value around <%- propertyType(property) %> - */ - @SuppressWarnings("unchecked") - public PropertyValue<<%- propertyType(property) %>> get<%- camelize(property.name) %>() { - return (PropertyValue<<%- propertyType(property) %>>) new PropertyValue(nativeGet<%- camelize(property.name) %>()); - } - <% if (property.type == 'color') { -%> - /** - * <%- property.doc %> - * - * @return int representation of a rgba string color - * @throws RuntimeException thrown if property isn't a value - */ - @ColorInt - public int get<%- camelize(property.name) %>AsInt() { - PropertyValue<<%- propertyType(property) %>> value = get<%- camelize(property.name) %>(); - if (value.isValue()) { - return rgbaToColor(value.getValue()); - } else { - throw new RuntimeException("<%- property.name %> was set as a Function"); - } + /** + * Get the <%- camelize(property.name) %> property + * + * @return property wrapper value around <%- propertyType(property) %> + */ + @SuppressWarnings("unchecked") + public PropertyValue<<%- propertyType(property) %>> get<%- camelize(property.name) %>() { + return (PropertyValue<<%- propertyType(property) %>>) new PropertyValue("<%- property.name %>", nativeGet<%- camelize(property.name) %>()); + } +<% if (property.type == 'color') { -%> + + /** + * <%- property.doc %> + * + * @return int representation of a rgba string color + * @throws RuntimeException thrown if property isn't a value + */ + @ColorInt + public int get<%- camelize(property.name) %>AsInt() { + PropertyValue<<%- propertyType(property) %>> value = get<%- camelize(property.name) %>(); + if (value.isValue()) { + return rgbaToColor(value.getValue()); + } else { + throw new RuntimeException("<%- property.name %> was set as a Function"); } + } - <% } -%> +<% } -%> <% } -%> <% for (const property of properties) { -%> - private native Object nativeGet<%- camelize(property.name) %>(); + private native Object nativeGet<%- camelize(property.name) %>(); <% } -%> - @Override - protected native void finalize() throws Throwable; + @Override + protected native void finalize() throws Throwable; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs index 3ce691775c..aaab1fe9f1 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property.java.ejs @@ -2,6 +2,7 @@ const properties = locals.properties; -%> // This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + package com.mapbox.mapboxsdk.style.layers; import android.support.annotation.StringDef; @@ -12,56 +13,49 @@ import java.lang.annotation.RetentionPolicy; /** * Paint/Layout properties for Layer */ -public abstract class Property<T> { - - //VISIBILITY: Whether this layer is displayed. - - /** - * The layer is shown. - */ - public static final String VISIBLE = "visible"; - /** - * The layer is hidden. - */ - public static final String NONE = "none"; - - @StringDef({ - VISIBLE, - NONE - }) - @Retention(RetentionPolicy.SOURCE) - public @interface VISIBILITY {} +public final class Property { + + // VISIBILITY: Whether this layer is displayed. + + /** + * The layer is shown. + */ + public static final String VISIBLE = "visible"; + /** + * The layer is hidden. + */ + public static final String NONE = "none"; + + @StringDef({ + VISIBLE, + NONE + }) + @Retention(RetentionPolicy.SOURCE) + public @interface VISIBILITY {} <% for (const property of properties) { -%> - //<%- snakeCaseUpper(property.name) %>: <%- property.doc %> + // <%- snakeCaseUpper(property.name) %>: <%- property.doc %> <% for (const value in property.values) { -%> - /** - * <%- propertyValueDoc(property, value) %> - */ - public static final String <%- snakeCaseUpper(property.name) %>_<%- snakeCaseUpper(value) %> = "<%- value %>"; + /** + * <%- propertyValueDoc(property, value) %> + */ + public static final String <%- snakeCaseUpper(property.name) %>_<%- snakeCaseUpper(value) %> = "<%- value %>"; <% } -%> - /** - * <%- property.doc %> - */ - @StringDef({ - <% for (const value of Object.keys(property.values)) { -%> - <%- snakeCaseUpper(property.name) %>_<%- snakeCaseUpper(value) %>, - <% } -%> - }) - @Retention(RetentionPolicy.SOURCE) - public @interface <%- snakeCaseUpper(property.name) %> {} + /** + * <%- property.doc %> + */ + @StringDef({ + <% for (const value of Object.keys(property.values)) { -%> + <%- snakeCaseUpper(property.name) %>_<%- snakeCaseUpper(value) %>, + <% } -%> + }) + @Retention(RetentionPolicy.SOURCE) + public @interface <%- snakeCaseUpper(property.name) %> {} <% } -%> - //Class definition - public final String name; - public final T value; - - /* package */ Property(String name, T value) { - this.name = name; - this.value = value; - } - + private Property() { + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs index e9b7b6dcd1..2d3421d1d9 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/layers/property_factory.java.ejs @@ -3,11 +3,15 @@ const layoutProperties = locals.layoutProperties; -%> // This file is generated. Edit android/platform/scripts/generate-style-code.js, then run `make android-style-code`. + package com.mapbox.mapboxsdk.style.layers; import android.annotation.SuppressLint; import android.support.annotation.ColorInt; +import com.mapbox.mapboxsdk.style.functions.Function; +import com.mapbox.mapboxsdk.style.functions.CameraFunction; + /** * Constructs paint/layout properties for Layers * @@ -15,85 +19,121 @@ import android.support.annotation.ColorInt; */ public class PropertyFactory { - /** - * Set the property visibility. - * - * @param value the visibility value - * @return property wrapper around visibility - */ - public static Property<String> visibility(@Property.VISIBILITY String value) { - return new LayoutProperty<>("visibility", value); - } - - /** - * Set the property visibility. - * - * @param function the visibility function - * @return property wrapper around a String function - */ - public static Property<Function<String>> visibility(Function<String> function) { - return new LayoutProperty<>("visibility", function); - } + /** + * Set the property visibility. + * + * @param value the visibility value + * @return property wrapper around visibility + */ + public static PropertyValue<String> visibility(@Property.VISIBILITY String value) { + return new LayoutPropertyValue<>("visibility", value); + } + + /** + * Set the property visibility. + * + * @param <T> the function input type + * @param function the visibility function + * @return property wrapper around a String function + */ + public static <T> PropertyValue<Function<T, String>> visibility(Function<T, String> function) { + return new LayoutPropertyValue<>("visibility", function); + } <% for (const property of paintProperties) { -%> <% if (property.type == 'color') { -%> - /** - * <%- propertyFactoryMethodDoc(property) %> - * - * @param value a int color value - * @return property wrapper around String color - */ - public static Property<String> <%- camelizeWithLeadingLowercase(property.name) %>(@ColorInt int value) { - return new PaintProperty<>("<%- property.name %>", colorToRgbaString(value)); - } + /** + * <%- propertyFactoryMethodDoc(property) %> + * + * @param value a int color value + * @return property wrapper around String color + */ + public static PropertyValue<String> <%- camelizeWithLeadingLowercase(property.name) %>(@ColorInt int value) { + return new PaintPropertyValue<>("<%- property.name %>", colorToRgbaString(value)); + } <% } -%> - /** - * <%- propertyFactoryMethodDoc(property) %> - * - * @param value a <%- propertyType(property) %> value - * @return property wrapper around <%- propertyType(property) %> - */ - public static Property<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> value) { - return new PaintProperty<>("<%- property.name %>", value); - } - - /** - * <%- propertyFactoryMethodDoc(property) %> - * - * @param function a wrapper function for <%- propertyType(property) %> - * @return property wrapper around a <%- propertyType(property) %> function - */ - public static Property<Function<<%- propertyType(property) %>>> <%- camelizeWithLeadingLowercase(property.name) %>(Function<<%- propertyType(property) %>> function) { - return new PaintProperty<>("<%- property.name %>", function); - } + /** + * <%- propertyFactoryMethodDoc(property) %> + * + * @param value a <%- propertyType(property) %> value + * @return property wrapper around <%- propertyType(property) %> + */ + public static PropertyValue<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> value) { + return new PaintPropertyValue<>("<%- property.name %>", value); + } + +<% if (supportsPropertyFunction(property)) { -%> + + /** + * <%- propertyFactoryMethodDoc(property) %> + * + * @param <T> the function input type + * @param function a wrapper function for <%- propertyType(property) %> + * @return property wrapper around a <%- propertyType(property) %> function + */ + public static <T> PropertyValue<Function<T, <%- propertyType(property) %>>> <%- camelizeWithLeadingLowercase(property.name) %>(Function<T, <%- propertyType(property) %>> function) { + return new PaintPropertyValue<>("<%- property.name %>", function); + } + +<% } else if (supportsZoomFunction(property)) { -%> + + /** + * <%- propertyFactoryMethodDoc(property) %> + * + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for <%- propertyType(property) %> + * @return property wrapper around a <%- propertyType(property) %> function + */ + public static <Z extends Number> PropertyValue<CameraFunction<Z, <%- propertyType(property) %>>> <%- camelizeWithLeadingLowercase(property.name) %>(CameraFunction<Z, <%- propertyType(property) %>> function) { + return new PaintPropertyValue<>("<%- property.name %>", function); + } <% } -%> +<% } -%> <% for (const property of layoutProperties) { -%> - /** - * <%- propertyFactoryMethodDoc(property) %> - * - * @param value a <%- propertyType(property) %> value - * @return property wrapper around <%- propertyType(property) %> - */ - public static Property<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> value) { - return new LayoutProperty<>("<%- property.name %>", value); - } - - /** - * <%- propertyFactoryMethodDoc(property) %> - * - * @param function a wrapper function for <%- propertyType(property) %> - * @return property wrapper around a <%- propertyType(property) %> function - */ - public static Property<Function<<%- propertyType(property) %>>> <%- camelizeWithLeadingLowercase(property.name) %>(Function<<%- propertyType(property) %>> function) { - return new LayoutProperty<>("<%- property.name %>", function); - } + /** + * <%- propertyFactoryMethodDoc(property) %> + * + * @param value a <%- propertyType(property) %> value + * @return property wrapper around <%- propertyType(property) %> + */ + public static PropertyValue<<%- propertyType(property) %>> <%- camelizeWithLeadingLowercase(property.name) %>(<%- propertyTypeAnnotation(property) %><%- iff(() => propertyTypeAnnotation(property), " ") %><%- propertyType(property) %> value) { + return new LayoutPropertyValue<>("<%- property.name %>", value); + } + + +<% if (supportsPropertyFunction(property)) { -%> + + /** + * <%- propertyFactoryMethodDoc(property) %> + * + * @param <T> the function input type + * @param function a wrapper function for <%- propertyType(property) %> + * @return property wrapper around a <%- propertyType(property) %> function + */ + public static <T> PropertyValue<Function<T, <%- propertyType(property) %>>> <%- camelizeWithLeadingLowercase(property.name) %>(Function<T, <%- propertyType(property) %>> function) { + return new LayoutPropertyValue<>("<%- property.name %>", function); + } +<% } else if (supportsZoomFunction(property)) { -%> + + /** + * <%- propertyFactoryMethodDoc(property) %> + * + * @param <Z> the zoom parameter type + * @param function a wrapper {@link CameraFunction} for <%- propertyType(property) %> + * @return property wrapper around a <%- propertyType(property) %> function + */ + public static <Z extends Number> PropertyValue<CameraFunction<Z, <%- propertyType(property) %>>> <%- camelizeWithLeadingLowercase(property.name) %>(CameraFunction<Z, <%- propertyType(property) %>> function) { + return new LayoutPropertyValue<>("<%- property.name %>", function); + } + +<% } -%> <% } -%> - @SuppressLint("DefaultLocale") - static String colorToRgbaString(@ColorInt int value) { - return String.format("rgba(%d, %d, %d, %d)", (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, (value >> 24) & 0xFF); - } + @SuppressLint("DefaultLocale") + public static String colorToRgbaString(@ColorInt int value) { + return String.format("rgba(%d, %d, %d, %d)", (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF, (value >> 24) & 0xFF); + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java index 0c2ee42ea0..f9875c7242 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/GeoJsonSource.java @@ -160,8 +160,8 @@ public class GeoJsonSource extends Source { } protected void setRawJson(String geoJson) { - //Wrap the String in a map as an Object is expected by the - //style conversion template + // Wrap the String in a map as an Object is expected by the + // style conversion template HashMap<String, String> wrapper = new HashMap<>(); wrapper.put("data", geoJson); nativeSetGeoJson(wrapper); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/NoSuchSourceException.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/NoSuchSourceException.java deleted file mode 100644 index 06d35b598b..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/NoSuchSourceException.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.mapbox.mapboxsdk.style.sources; - -/** - * No such source. - */ -public class NoSuchSourceException extends Exception { - - public NoSuchSourceException(String message) { - super(message); - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/UnknownSource.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/UnknownSource.java new file mode 100644 index 0000000000..4a97d71f9a --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/UnknownSource.java @@ -0,0 +1,25 @@ +package com.mapbox.mapboxsdk.style.sources; + +import android.support.annotation.UiThread; + +/** + * An unknown type of source + */ +@UiThread +public class UnknownSource extends Source { + + /** + * Creates a UnknownSource. + * + * @param nativePtr pointer used by core + */ + UnknownSource(long nativePtr) { + super(nativePtr); + } + + protected native void initialize(); + + @Override + protected native void finalize() throws Throwable; + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/GzipRequestInterceptor.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/GzipRequestInterceptor.java deleted file mode 100644 index 8457d24ff2..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/GzipRequestInterceptor.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.mapbox.mapboxsdk.telemetry; - -import timber.log.Timber; - -import java.io.IOException; - -import okhttp3.Interceptor; -import okhttp3.MediaType; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import okio.BufferedSink; -import okio.GzipSink; -import okio.Okio; - -/** - * OkHttp Interceptor for Gzipping Telemetry Data requests to the server. - * Based on: https://github.com/square/okhttp/wiki/Interceptors - */ -public final class GzipRequestInterceptor implements Interceptor { - - @Override - public Response intercept(Interceptor.Chain chain) throws IOException { - Request originalRequest = chain.request(); - if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) { - Timber.d("Not compressing"); - return chain.proceed(originalRequest); - } - - Timber.d("Compressing"); - Request compressedRequest = originalRequest.newBuilder() - .header("Content-Encoding", "gzip") - .method(originalRequest.method(), gzip(originalRequest.body())) - .build(); - return chain.proceed(compressedRequest); - } - - private RequestBody gzip(final RequestBody body) { - return new RequestBody() { - @Override - public MediaType contentType() { - return body.contentType(); - } - - @Override - public long contentLength() { - return -1; // We don't know the compressed length in advance! - } - - @Override - public void writeTo(BufferedSink sink) throws IOException { - BufferedSink gzipSink = Okio.buffer(new GzipSink(sink)); - body.writeTo(gzipSink); - gzipSink.close(); - } - }; - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java deleted file mode 100644 index b5203bc02a..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.mapbox.mapboxsdk.telemetry; - -import android.graphics.PointF; -import android.support.annotation.NonNull; - -import com.mapbox.mapboxsdk.geometry.LatLng; -import com.mapbox.mapboxsdk.maps.Projection; - -import java.io.Serializable; -import java.util.Hashtable; - -import timber.log.Timber; - -/** - * Constants for Telemetry Metadata - */ -public class MapboxEvent implements Serializable { - public static final int VERSION_NUMBER = 2; - public static final String MAPBOX_EVENTS_BASE_URL = "https://events.mapbox.com"; - public static final String SOURCE_MAPBOX = "mapbox"; - - // Event Types - public static final String TYPE_TURNSTILE = "appUserTurnstile"; - public static final String TYPE_MAP_LOAD = "map.load"; - public static final String TYPE_MAP_CLICK = "map.click"; - public static final String TYPE_MAP_DRAGEND = "map.dragend"; - public static final String TYPE_LOCATION = "location"; - public static final String TYPE_VISIT = "visit"; - - // Event Keys - public static final String KEY_LATITUDE = "lat"; - public static final String KEY_LONGITUDE = "lng"; - public static final String KEY_SPEED = "speed"; - public static final String KEY_COURSE = "course"; - public static final String KEY_ALTITUDE = "altitude"; - public static final String KEY_HORIZONTAL_ACCURACY = "horizontalAccuracy"; - public static final String KEY_ZOOM = "zoom"; - - public static final String KEY_PUSH_ENABLED = "enabled.push"; - public static final String KEY_EMAIL_ENABLED = "enabled.email"; - public static final String KEY_GESTURE_ID = "gesture"; - public static final String KEY_ARRIVAL_DATE = "arrivalDate"; - public static final String KEY_DEPARTURE_DATE = "departureDate"; - - public static final String GESTURE_SINGLETAP = "SingleTap"; - public static final String GESTURE_DOUBLETAP = "DoubleTap"; - public static final String GESTURE_TWO_FINGER_SINGLETAP = "TwoFingerTap"; - public static final String GESTURE_QUICK_ZOOM = "QuickZoom"; - public static final String GESTURE_PAN_START = "Pan"; - public static final String GESTURE_PINCH_START = "Pinch"; - public static final String GESTURE_ROTATION_START = "Rotation"; - public static final String GESTURE_PITCH_START = "Pitch"; - - // Event Attributes - public static final String ATTRIBUTE_EVENT = "event"; - public static final String ATTRIBUTE_USERID = "userId"; - public static final String ATTRIBUTE_SOURCE = "source"; - public static final String ATTRIBUTE_ENABLED_TELEMETRY = "enabled.telemetry"; - public static final String ATTRIBUTE_SESSION_ID = "sessionId"; - public static final String ATTRIBUTE_VERSION = "version"; - public static final String ATTRIBUTE_CREATED = "created"; - public static final String ATTRIBUTE_VENDOR_ID = "vendorId"; - public static final String ATTRIBUTE_APP_BUNDLE_ID = "appBundleId"; - public static final String ATTRIBUTE_MODEL = "model"; - public static final String ATTRIBUTE_OPERATING_SYSTEM = "operatingSystem"; - public static final String ATTRIBUTE_ORIENTATION = "orientation"; - public static final String ATTRIBUTE_BATTERY_LEVEL = "batteryLevel"; - public static final String ATTRIBUTE_PLUGGED_IN = "pluggedIn"; - public static final String ATTRIBUTE_APPLICATION_STATE = "applicationState"; - public static final String ATTRIBUTE_RESOLUTION = "resolution"; - public static final String ATTRIBUTE_ACCESSIBILITY_FONT_SCALE = "accessibilityFontScale"; - public static final String ATTRIBUTE_CARRIER = "carrier"; - public static final String ATTRIBUTE_CELLULAR_NETWORK_TYPE = "cellularNetworkType"; - public static final String ATTRIBUTE_WIFI = "wifi"; - - /** - * Helper method for tracking gesture events - * - * @param projection Projection of the Map object - * @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 - * @param zoom Zoom level to be registered - */ - public static void trackGestureEvent(@NonNull Projection projection, @NonNull String gestureId, float xCoordinate, - float yCoordinate, double zoom) { - LatLng tapLatLng = projection.fromScreenLocation(new PointF(xCoordinate, yCoordinate)); - - // NaN and Infinite checks to prevent JSON errors at send to server time - if (Double.isNaN(tapLatLng.getLatitude()) || Double.isNaN(tapLatLng.getLongitude())) { - Timber.d("trackGestureEvent() has a NaN lat or lon. Returning."); - return; - } - - if (Double.isInfinite(tapLatLng.getLatitude()) || Double.isInfinite(tapLatLng.getLongitude())) { - Timber.d("trackGestureEvent() has an Infinite lat or lon. Returning."); - return; - } - - Hashtable<String, Object> evt = new Hashtable<>(); - evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_CLICK); - evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate()); - 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, zoom); - - MapboxEventManager.getMapboxEventManager().pushEvent(evt); - } - - /** - * Helper method for tracking DragEnd gesture event - * See {@see MapboxEvent#TYPE_MAP_DRAGEND} - * - * @param projection projection of the Map object. - * @param xCoordinate Original x screen coordinate at end of drag - * @param yCoordinate Orginal y screen coordinate at end of drag - * @param zoom Zoom level to be registered - */ - public static void trackGestureDragEndEvent(@NonNull Projection projection, float xCoordinate, float yCoordinate, - double zoom) { - LatLng tapLatLng = projection.fromScreenLocation(new PointF(xCoordinate, yCoordinate)); - - // NaN and Infinite checks to prevent JSON errors at send to server time - if (Double.isNaN(tapLatLng.getLatitude()) || Double.isNaN(tapLatLng.getLongitude())) { - Timber.d("trackGestureDragEndEvent() has a NaN lat or lon. Returning."); - return; - } - - if (Double.isInfinite(tapLatLng.getLatitude()) || Double.isInfinite(tapLatLng.getLongitude())) { - Timber.d("trackGestureDragEndEvent() has an Infinite lat or lon. Returning."); - return; - } - - Hashtable<String, Object> evt = new Hashtable<>(); - evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_DRAGEND); - evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate()); - evt.put(MapboxEvent.KEY_LATITUDE, tapLatLng.getLatitude()); - evt.put(MapboxEvent.KEY_LONGITUDE, tapLatLng.getLongitude()); - evt.put(MapboxEvent.KEY_ZOOM, zoom); - - MapboxEventManager.getMapboxEventManager().pushEvent(evt); - } - - /** - * Helper method for tracking map load event - */ - public static void trackMapLoadEvent() { - Hashtable<String, Object> evt = new Hashtable<>(); - evt.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_MAP_LOAD); - evt.put(MapboxEvent.ATTRIBUTE_CREATED, MapboxEventManager.generateCreateDate()); - MapboxEventManager.getMapboxEventManager().pushEvent(evt); - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java deleted file mode 100644 index 4a0ef248b7..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java +++ /dev/null @@ -1,828 +0,0 @@ -package com.mapbox.mapboxsdk.telemetry; - -import android.app.ActivityManager; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.SharedPreferences; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ServiceInfo; -import android.content.res.Configuration; -import android.location.Location; -import android.net.wifi.WifiInfo; -import android.net.wifi.WifiManager; -import android.os.AsyncTask; -import android.os.BatteryManager; -import android.os.Build; -import android.os.Handler; -import android.support.annotation.NonNull; -import android.telephony.TelephonyManager; -import android.text.TextUtils; -import android.util.DisplayMetrics; -import android.view.WindowManager; - -import com.mapbox.mapboxsdk.BuildConfig; -import com.mapbox.mapboxsdk.Mapbox; -import com.mapbox.mapboxsdk.constants.GeoConstants; -import com.mapbox.mapboxsdk.constants.MapboxConstants; -import com.mapbox.mapboxsdk.exceptions.TelemetryServiceNotConfiguredException; -import com.mapbox.mapboxsdk.location.LocationServices; -import com.mapbox.mapboxsdk.utils.MathUtils; - -import org.json.JSONArray; -import org.json.JSONObject; - -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Hashtable; -import java.util.List; -import java.util.Timer; -import java.util.TimerTask; -import java.util.UUID; -import java.util.Vector; - -import okhttp3.CertificatePinner; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; -import okhttp3.Response; -import okhttp3.internal.Util; -import timber.log.Timber; - -/** - * Singleton control center for managing Telemetry Data. - * Primary access is via MapboxEventManager.getMapboxEventManager() - */ -public class MapboxEventManager { - - private static MapboxEventManager mapboxEventManager = null; - - private boolean initialized = false; - private boolean stagingEnv; - private boolean telemetryEnabled; - - private final Vector<Hashtable<String, Object>> events = new Vector<>(); - private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); - private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ", - MapboxConstants.MAPBOX_LOCALE); - - private Context context = null; - private String accessToken = null; - private String eventsURL = MapboxEvent.MAPBOX_EVENTS_BASE_URL; - - private String userAgent = BuildConfig.MAPBOX_EVENTS_USER_AGENT_BASE; - - private Intent batteryStatus = null; - private final String operatingSystem = "Android - " + Build.VERSION.RELEASE; - - private DisplayMetrics displayMetrics = null; - - private String mapboxVendorId = null; - - private String mapboxSessionId = null; - private long mapboxSessionIdLastSet = 0; - private static long hourInMillis = 1000 * 60 * 60; - private static long flushDelayInitialInMillis = 1000 * 10; // 10 Seconds - private static long flushDelayInMillis = 1000 * 60 * 3; // 3 Minutes - private static final int SESSION_ID_ROTATION_HOURS = 24; - - private static final int FLUSH_EVENTS_CAP = 1000; - - private static MessageDigest messageDigest = null; - - private static final double locationEventAccuracy = 10000000; - - private Timer timer = null; - - /** - * Private Constructor for configuring the single instance per app. - */ - private MapboxEventManager() { - super(); - } - - /** - * Internal setup of MapboxEventsManager. It needs to be called once before @link - * MapboxEventManager#getMapboxEventManager - * <p> - * This allows for a cleaner getMapboxEventManager() that doesn't require context and accessToken - * - * @param context The context associated with MapView - * @param accessToken The accessToken to load MapView - */ - public void initialize(@NonNull Context context, @NonNull String accessToken) { - - //Timber.i("Telemetry initialize() called..."); - - if (initialized) { - //Timber.i("Mapbox Telemetry has already been initialized."); - return; - } - - this.context = context.getApplicationContext(); - this.accessToken = accessToken; - - validateTelemetryServiceConfigured(); - - // Setup Message Digest - try { - messageDigest = MessageDigest.getInstance("SHA-1"); - } catch (NoSuchAlgorithmException exception) { - Timber.w("Error getting Encryption Algorithm: ", exception); - } - - // Create Initial Session Id - rotateSessionId(); - - SharedPreferences prefs = context.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES_FILE, - Context.MODE_PRIVATE); - - // Determine if Telemetry Should Be Enabled - ///Timber.i("Right before Telemetry set enabled in initialized()"); - setTelemetryEnabled(prefs.getBoolean(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED, true)); - - // Load / Create Vendor Id - if (prefs.contains(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID)) { - mapboxVendorId = prefs.getString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID, ""); - } - if (TextUtils.isEmpty(mapboxVendorId)) { - String vendorId = UUID.randomUUID().toString(); - mapboxVendorId = encodeString(vendorId); - SharedPreferences.Editor editor = prefs.edit(); - editor.putString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_VENDORID, mapboxVendorId); - editor.apply(); - editor.commit(); - } - - // Get DisplayMetrics Setup - displayMetrics = new DisplayMetrics(); - ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(displayMetrics); - - // Check for Staging Server Information - try { - ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), - PackageManager.GET_META_DATA); - String stagingURL = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_STAGING_SERVER); - String stagingAccessToken = appInfo.metaData.getString(MapboxConstants.KEY_META_DATA_STAGING_ACCESS_TOKEN); - - if (TextUtils.isEmpty(stagingURL) || TextUtils.isEmpty(stagingAccessToken)) { - //Timber.d("Looking in SharedPreferences for Staging Credentials"); - stagingURL = prefs.getString(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_URL, null); - stagingAccessToken = prefs.getString( - MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_ACCESS_TOKEN, null); - } - - if (!TextUtils.isEmpty(stagingURL) && !TextUtils.isEmpty(stagingAccessToken)) { - eventsURL = stagingURL; - this.accessToken = accessToken; - stagingEnv = true; - } - - // Build User Agent - String appIdentifier = getApplicationIdentifier(); - if (TextUtils.equals(userAgent, BuildConfig.MAPBOX_EVENTS_USER_AGENT_BASE) && !TextUtils.isEmpty(appIdentifier)) { - userAgent = Util - .toHumanReadableAscii(String.format(MapboxConstants.MAPBOX_LOCALE, "%s %s", appIdentifier, userAgent)); - } - - } catch (Exception exception) { - //Timber.e("Error Trying to load Staging Credentials: ", exception); - } - - // Register for battery updates - IntentFilter iFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); - batteryStatus = context.registerReceiver(null, iFilter); - - initialized = true; - } - - /** - * Primary Access method using Singleton pattern - * - * @return MapboxEventManager - */ - public static MapboxEventManager getMapboxEventManager() { - if (mapboxEventManager == null) { - mapboxEventManager = new MapboxEventManager(); - } - return mapboxEventManager; - } - - // Checks that TelemetryService has been configured by developer - private void validateTelemetryServiceConfigured() { - try { - // Check Implementing app's AndroidManifest.xml - PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.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 exception) { - //Timber.w("Error checking for Telemetry Service Config: ", exception); - } - throw new TelemetryServiceNotConfiguredException(); - } - - public static String generateCreateDate() { - return dateFormat.format(new Date()); - } - - public boolean isTelemetryEnabled() { - return telemetryEnabled; - } - - /** - * Enables / Disables Telemetry - * - * @param telemetryEnabled True to start telemetry, false to stop it - */ - public void setTelemetryEnabled(boolean telemetryEnabled) { - //Timber.i("this.telemetryEnabled = " + this.telemetryEnabled + "; telemetryEnabled = " + telemetryEnabled); - if (this.telemetryEnabled == telemetryEnabled) { - //Timber.d("No need to start / stop telemetry as it's already in that state."); - return; - } - - if (telemetryEnabled) { - //Timber.d("Starting Telemetry Up!"); - // Start It Up - context.startService(new Intent(context, TelemetryService.class)); - - // Make sure Ambient Mode is started at a minimum - if (LocationServices.getLocationServices(context).areLocationPermissionsGranted()) { - //Timber.i("Permissions are good, see if GPS is enabled and if not then setup Ambient."); - if (LocationServices.getLocationServices(context).isGpsEnabled()) { - LocationServices.getLocationServices(context).toggleGPS(false); - } - } else { - // Start timer that checks for Permissions - //Timber.i("Permissions are not good. Need to do some looping to check on stuff."); - - final Handler permsHandler = new Handler(); - Runnable runnable = new Runnable() { - - private final ExponentialBackoffCounter exponentialBackoffCounter = new ExponentialBackoffCounter(); - - @Override - public void run() { - if (LocationServices.getLocationServices(context).areLocationPermissionsGranted()) { - //Timber.i("Permissions finally granted, so starting Ambient if GPS isn't already enabled"); - // Start Ambient - if (LocationServices.getLocationServices(context).isGpsEnabled()) { - LocationServices.getLocationServices(context).toggleGPS(false); - } - } else { - // Restart Handler - long nextWaitTime = exponentialBackoffCounter.getNextCount(); - //Timber.i("Permissions not granted yet... let's try again in " + nextWaitTime/1000 + " seconds"); - permsHandler.postDelayed(this, nextWaitTime); - } - } - }; - permsHandler.postDelayed(runnable, 1000 * 10); - } - - // Manage Timer Flush - timer = new Timer(); - timer.schedule(new FlushEventsTimerTask(), flushDelayInitialInMillis, flushDelayInMillis); - } else { - //Timber.d("Shutting Telemetry Down"); - // Shut It Down - events.removeAllElements(); - context.stopService(new Intent(context, TelemetryService.class)); - - if (timer != null) { - timer.cancel(); - timer = null; - } - } - - // Persist - this.telemetryEnabled = telemetryEnabled; - SharedPreferences prefs = context.getSharedPreferences(MapboxConstants.MAPBOX_SHARED_PREFERENCES_FILE, - Context.MODE_PRIVATE); - SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean(MapboxConstants.MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_ENABLED, telemetryEnabled); - editor.apply(); - editor.commit(); - } - - /** - * Immediately attempt to send all events data in the queue to the server. - * <p> - * NOTE: Permission set to package private to enable only telemetry code to use this. - */ - void flushEventsQueueImmediately() { - //Timber.i("flushEventsQueueImmediately() called..."); - new FlushTheEventsTask().execute(); - } - - /** - * Centralized method for adding populated event to the queue allowing for cap size checking - * - * @param event Event to add to the Events Queue - */ - private void putEventOnQueue(@NonNull Hashtable<String, Object> event) { - if (event == null) { - return; - } - events.add(event); - if (events.size() == FLUSH_EVENTS_CAP) { - //Timber.d("eventsSize == flushCap so send data."); - flushEventsQueueImmediately(); - } - } - - /** - * Adds a Location Event to the system for processing - * - * @param location Location event - */ - public void addLocationEvent(Location location) { - - // NaN and Infinite checks to prevent JSON errors at send to server time - if (Double.isNaN(location.getLatitude()) || Double.isNaN(location.getLongitude()) - || Double.isNaN(location.getAltitude()) || Float.isNaN(location.getAccuracy())) { - return; - } - - if (Double.isInfinite(location.getLatitude()) || Double.isInfinite(location.getLongitude()) - || Double.isInfinite(location.getAltitude()) || Float.isInfinite(location.getAccuracy())) { - return; - } - - // Add Location even to queue - Hashtable<String, Object> event = new Hashtable<>(); - event.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_LOCATION); - event.put(MapboxEvent.ATTRIBUTE_CREATED, generateCreateDate()); - event.put(MapboxEvent.ATTRIBUTE_SOURCE, MapboxEvent.SOURCE_MAPBOX); - event.put(MapboxEvent.ATTRIBUTE_SESSION_ID, encodeString(mapboxSessionId)); - event.put(MapboxEvent.KEY_LATITUDE, - Math.floor(location.getLatitude() * locationEventAccuracy) / locationEventAccuracy); - event.put(MapboxEvent.KEY_LONGITUDE, - Math.floor(location.getLongitude() * locationEventAccuracy) / locationEventAccuracy); - event.put(MapboxEvent.KEY_ALTITUDE, location.getAltitude()); - event.put(MapboxEvent.KEY_HORIZONTAL_ACCURACY, Math.round(location.getAccuracy())); - event.put(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM, operatingSystem); - event.put(MapboxEvent.ATTRIBUTE_APPLICATION_STATE, getApplicationState()); - - putEventOnQueue(event); - - rotateSessionId(); - } - - /** - * Push Interactive Events to the system for processing - * - * @param eventWithAttributes Event with attributes - */ - public void pushEvent(Hashtable<String, Object> eventWithAttributes) { - if (context == null || accessToken == null) { - return; - } - - if (eventWithAttributes == null) { - return; - } - - String eventType = (String) eventWithAttributes.get(MapboxEvent.ATTRIBUTE_EVENT); - if (TextUtils.isEmpty(eventType)) { - return; - } - - if (eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_LOAD)) { - // Map Load Data Model - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_USERID, mapboxVendorId); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_MODEL, Build.MODEL); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM, operatingSystem); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_RESOLUTION, displayMetrics.density); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ACCESSIBILITY_FONT_SCALE, getAccesibilityFontScaleSize()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ORIENTATION, getOrientation()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, getBatteryLevel()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_PLUGGED_IN, isPluggedIn()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CARRIER, getCellularCarrier()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, getCellularNetworkType()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_WIFI, getConnectedToWifi()); - - // Put Map Load on events before Turnstile clears it - putEventOnQueue(eventWithAttributes); - - // Turnstile - pushTurnstileEvent(); - - // Return immediately to avoid double adding of event - return; - - } else if (eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_CLICK)) { - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ORIENTATION, getOrientation()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, getBatteryLevel()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_PLUGGED_IN, isPluggedIn()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CARRIER, getCellularCarrier()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, getCellularNetworkType()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_WIFI, getConnectedToWifi()); - } else if (eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_DRAGEND)) { - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_ORIENTATION, getOrientation()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, getBatteryLevel()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_PLUGGED_IN, isPluggedIn()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CARRIER, getCellularCarrier()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, getCellularNetworkType()); - eventWithAttributes.put(MapboxEvent.ATTRIBUTE_WIFI, getConnectedToWifi()); - } else { - //Timber.w("This is not an event type in the Events Data Model."); - return; - } - - putEventOnQueue(eventWithAttributes); - } - - /** - * Pushes turnstile event for internal billing purposes - */ - private void pushTurnstileEvent() { - - Hashtable<String, Object> event = new Hashtable<>(); - event.put(MapboxEvent.ATTRIBUTE_EVENT, MapboxEvent.TYPE_TURNSTILE); - event.put(MapboxEvent.ATTRIBUTE_CREATED, generateCreateDate()); - event.put(MapboxEvent.ATTRIBUTE_USERID, mapboxVendorId); - event.put(MapboxEvent.ATTRIBUTE_ENABLED_TELEMETRY, telemetryEnabled); - - events.add(event); - - // Send to Server Immediately - flushEventsQueueImmediately(); - //Timber.d("turnstile event pushed."); - } - - /** - * SHA-1 Encoding for strings - * - * @param string String to encode - * @return String encoded if no error, original string if error - */ - private String encodeString(String string) { - try { - if (messageDigest != null) { - messageDigest.reset(); - messageDigest.update(string.getBytes("UTF-8")); - byte[] bytes = messageDigest.digest(); - - // Get the Hex version of the digest - StringBuilder sb = new StringBuilder(); - for (byte b : bytes) { - sb.append(String.format("%02X", b)); - } - String hex = sb.toString(); - - return hex; - } - } catch (Exception exception) { - //Timber.w("Error encoding string, will return in original form.", exception); - } - return string; - } - - /** - * Changes Session Id based on time boundary - */ - private void rotateSessionId() { - long now = System.currentTimeMillis(); - if ((TextUtils.isEmpty(mapboxSessionId)) - || (now - mapboxSessionIdLastSet > (SESSION_ID_ROTATION_HOURS * hourInMillis))) { - mapboxSessionId = UUID.randomUUID().toString(); - mapboxSessionIdLastSet = System.currentTimeMillis(); - } - } - - private String getOrientation() { - switch (context.getResources().getConfiguration().orientation) { - case Configuration.ORIENTATION_LANDSCAPE: - return "Landscape"; - case Configuration.ORIENTATION_PORTRAIT: - return "Portrait"; - default: - return ""; - } - } - - private int getBatteryLevel() { - int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); - int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1); - - return Math.round((level / (float) scale) * 100); - } - - /** - * Determine if device is plugged in to power via USB or AC or not. - * <p> - * http://developer.android.com/reference/android/os/BatteryManager.html#EXTRA_PLUGGED - * - * @return true if plugged in, false if not - */ - private boolean isPluggedIn() { - - int chargePlug = batteryStatus.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); - if (chargePlug == BatteryManager.BATTERY_PLUGGED_USB || chargePlug == BatteryManager.BATTERY_PLUGGED_AC) { - return true; - } - - return false; - } - - private String getApplicationState() { - - ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); - List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses(); - if (appProcesses == null) { - return ""; - } - final String packageName = context.getPackageName(); - for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) { - if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND - && appProcess.processName.equals(packageName)) { - return "Foreground"; - } - } - return "Background"; - } - - private float getAccesibilityFontScaleSize() { - // Values - // Small = 0.85 - // Normal = 1.0 - // Large = 1.15 - // Huge = 1.3 - - return context.getResources().getConfiguration().fontScale; - } - - private String getCellularCarrier() { - TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - String carrierName = manager.getNetworkOperatorName(); - if (TextUtils.isEmpty(carrierName)) { - carrierName = ""; - } - return carrierName; - } - - private String getCellularNetworkType() { - TelephonyManager manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); - switch (manager.getNetworkType()) { - case TelephonyManager.NETWORK_TYPE_1xRTT: - return "1xRTT"; - case TelephonyManager.NETWORK_TYPE_CDMA: - return "CDMA"; - case TelephonyManager.NETWORK_TYPE_EDGE: - return "EDGE"; - case TelephonyManager.NETWORK_TYPE_EHRPD: - return "EHRPD"; - case TelephonyManager.NETWORK_TYPE_EVDO_0: - return "EVDO_0"; - case TelephonyManager.NETWORK_TYPE_EVDO_A: - return "EVDO_A"; - case TelephonyManager.NETWORK_TYPE_EVDO_B: - return "EVDO_B"; - case TelephonyManager.NETWORK_TYPE_GPRS: - return "GPRS"; - case TelephonyManager.NETWORK_TYPE_HSDPA: - return "HSDPA"; - case TelephonyManager.NETWORK_TYPE_HSPA: - return "HSPA"; - case TelephonyManager.NETWORK_TYPE_HSPAP: - return "HSPAP"; - case TelephonyManager.NETWORK_TYPE_HSUPA: - return "HSUPA"; - case TelephonyManager.NETWORK_TYPE_IDEN: - return "IDEN"; - case TelephonyManager.NETWORK_TYPE_LTE: - return "LTE"; - case TelephonyManager.NETWORK_TYPE_UMTS: - return "UMTS"; - case TelephonyManager.NETWORK_TYPE_UNKNOWN: - return "Unknown"; - default: - return ""; - } - } - - public Boolean getConnectedToWifi() { - - Boolean status = false; - WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); - if (wifiMgr.isWifiEnabled()) { - try { - WifiInfo wifiInfo = wifiMgr.getConnectionInfo(); - if (wifiInfo.getNetworkId() != -1) { - status = true; - } - } catch (Exception exception) { - //Timber.w("Error getting Wifi Connection Status: ", exception); - status = false; - } - } - - return status; - } - - - /** - * Task responsible for converting stored events and sending them to the server - */ - private class FlushTheEventsTask extends AsyncTask<Void, Void, Void> { - - @Override - protected Void doInBackground(Void... voids) { - - if (events.isEmpty()) { - //Timber.d("No events in the queue to send so returning."); - return null; - } - - // Check for NetworkConnectivity - if (!Mapbox.isConnected()) { - //Timber.w("Not connected to network, so empty events cache and return without attempting to send events"); - // Make sure that events don't pile up when Offline - // and thus impact available memory over time. - events.removeAllElements(); - return null; - } - - Response response = null; - - try { - // Send data - // ========= - JSONArray jsonArray = new JSONArray(); - - Vector<Hashtable<String, Object>> eventsClone = (Vector<Hashtable<String, Object>>) events.clone(); - - for (Hashtable<String, Object> evt : eventsClone) { - JSONObject jsonObject = new JSONObject(); - - // Build the JSON but only if there's a value for it in the evt - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_EVENT, evt.get(MapboxEvent.ATTRIBUTE_EVENT)); - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_CREATED, evt.get(MapboxEvent.ATTRIBUTE_CREATED)); - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_USERID, evt.get(MapboxEvent.ATTRIBUTE_USERID)); - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_ENABLED_TELEMETRY, evt.get(MapboxEvent.ATTRIBUTE_ENABLED_TELEMETRY)); - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_SOURCE, evt.get(MapboxEvent.ATTRIBUTE_SOURCE)); - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_SESSION_ID, evt.get(MapboxEvent.ATTRIBUTE_SESSION_ID)); - jsonObject.putOpt(MapboxEvent.KEY_LATITUDE, evt.get(MapboxEvent.KEY_LATITUDE)); - - // Make sure Longitude Is Wrapped - if (evt.containsKey(MapboxEvent.KEY_LONGITUDE)) { - double lon = (double) evt.get(MapboxEvent.KEY_LONGITUDE); - if ((lon < GeoConstants.MIN_LONGITUDE) || (lon > GeoConstants.MAX_LONGITUDE)) { - lon = MathUtils.wrap(lon, GeoConstants.MIN_LONGITUDE, GeoConstants.MAX_LONGITUDE); - } - jsonObject.put(MapboxEvent.KEY_LONGITUDE, lon); - } - - jsonObject.putOpt(MapboxEvent.KEY_ALTITUDE, evt.get(MapboxEvent.KEY_ALTITUDE)); - jsonObject.putOpt(MapboxEvent.KEY_ZOOM, evt.get(MapboxEvent.KEY_ZOOM)); - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM, evt.get(MapboxEvent.ATTRIBUTE_OPERATING_SYSTEM)); - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_USERID, evt.get(MapboxEvent.ATTRIBUTE_USERID)); - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_MODEL, evt.get(MapboxEvent.ATTRIBUTE_MODEL)); - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_RESOLUTION, evt.get(MapboxEvent.ATTRIBUTE_RESOLUTION)); - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_ACCESSIBILITY_FONT_SCALE, - evt.get(MapboxEvent.ATTRIBUTE_ACCESSIBILITY_FONT_SCALE)); - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL, evt.get(MapboxEvent.ATTRIBUTE_BATTERY_LEVEL)); - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_PLUGGED_IN, evt.get(MapboxEvent.ATTRIBUTE_PLUGGED_IN)); - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_WIFI, evt.get(MapboxEvent.ATTRIBUTE_WIFI)); - - // Special Cases where empty string is denoting null and therefore should not be sent at all - // This arises as thread safe Hashtable does not accept null values (nor keys) - if (evt.containsKey(MapboxEvent.ATTRIBUTE_ORIENTATION)) { - String orientation = (String) evt.get(MapboxEvent.ATTRIBUTE_ORIENTATION); - if (!TextUtils.isEmpty(orientation)) { - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_ORIENTATION, orientation); - } - } - if (evt.containsKey(MapboxEvent.ATTRIBUTE_CARRIER)) { - String carrier = (String) evt.get(MapboxEvent.ATTRIBUTE_CARRIER); - if (!TextUtils.isEmpty(carrier)) { - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_CARRIER, carrier); - } - } - if (evt.containsKey(MapboxEvent.ATTRIBUTE_APPLICATION_STATE)) { - String appState = (String) evt.get(MapboxEvent.ATTRIBUTE_APPLICATION_STATE); - if (!TextUtils.isEmpty(appState)) { - jsonObject.putOpt(MapboxEvent.ATTRIBUTE_APPLICATION_STATE, - evt.get(MapboxEvent.ATTRIBUTE_APPLICATION_STATE)); - } - } - - // Special Cases where null has to be passed if no value exists - // Requires using put() instead of putOpt() - String eventType = (String) evt.get(MapboxEvent.ATTRIBUTE_EVENT); - if (!TextUtils.isEmpty(eventType) && eventType.equalsIgnoreCase(MapboxEvent.TYPE_MAP_CLICK)) { - jsonObject.put(MapboxEvent.KEY_GESTURE_ID, evt.get(MapboxEvent.KEY_GESTURE_ID)); - } - if (evt.containsKey(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE)) { - String cellularNetworkType = (String) evt.get(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE); - if (TextUtils.isEmpty(cellularNetworkType)) { - jsonObject.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, null); - } else { - jsonObject.put(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE, - evt.get(MapboxEvent.ATTRIBUTE_CELLULAR_NETWORK_TYPE)); - } - } - - jsonArray.put(jsonObject); - } - - // Based on http://square.github.io/okhttp/3.x/okhttp/okhttp3/CertificatePinner.html - CertificatePinner.Builder certificatePinnerBuilder = new CertificatePinner.Builder(); - if (stagingEnv) { - // Staging - Geotrust - certificatePinnerBuilder - .add("cloudfront-staging.tilestream.net", "sha256/3euxrJOrEZI15R4104UsiAkDqe007EPyZ6eTL/XxdAY=") - .add("cloudfront-staging.tilestream.net", "sha256/5kJvNEMw0KjrCAu7eXY5HZdvyCS13BbA0VJG1RSP91w=") - .add("cloudfront-staging.tilestream.net", "sha256/r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E="); - } else { - certificatePinnerBuilder - // Prod - Geotrust - .add("events.mapbox.com", "sha256/BhynraKizavqoC5U26qgYuxLZst6pCu9J5stfL6RSYY=") - .add("events.mapbox.com", "sha256/owrR9U9FWDWtrFF+myoRIu75JwU4sJwzvhCNLZoY37g=") - .add("events.mapbox.com", "sha256/SQVGZiOrQXi+kqxcvWWE96HhfydlLVqFr4lQTqI5qqo=") - // Prod - DigiCert - .add("events.mapbox.com", "sha256/Tb0uHZ/KQjWh8N9+CZFLc4zx36LONQ55l6laDi1qtT4=") - .add("events.mapbox.com", "sha256/RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=") - .add("events.mapbox.com", "sha256/WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="); - } - - OkHttpClient client = new OkHttpClient.Builder() - .certificatePinner(certificatePinnerBuilder.build()) - .addInterceptor(new GzipRequestInterceptor()) - .build(); - RequestBody body = RequestBody.create(JSON, jsonArray.toString()); - - String url = eventsURL + "/events/v2?access_token=" + accessToken; - - Request request = new Request.Builder() - .url(url) - .header("User-Agent", userAgent) - .post(body) - .build(); - response = client.newCall(request).execute(); - //Timber.d("response code = " + response.code() + " for events " + events.size()); - - } catch (Exception exception) { - Timber.e("FlushTheEventsTask borked: ", exception); - } finally { - if (response != null && response.body() != null) { - response.body().close(); - } - // Reset Events - // ============ - events.removeAllElements(); - } - - return null; - } - - } - - - /** - * TimerTask responsible for sending event data to server - */ - private class FlushEventsTimerTask extends TimerTask { - /** - * The task to run should be specified in the implementation of the {@code run()} - * method. - */ - @Override - public void run() { - new FlushTheEventsTask().execute(); - } - } - - private String getApplicationIdentifier() { - try { - PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); - return String.format(MapboxConstants.MAPBOX_LOCALE, "%s/%s/%s", context.getPackageName(), - packageInfo.versionName, packageInfo.versionCode); - } catch (Exception exception) { - return ""; - } - } - - static class ExponentialBackoffCounter { - - private static final long BASE_TIME = 30000 /*30 seconds*/; - private int attempt; - - long getNextCount() { - attempt++; - return attempt * BASE_TIME; - } - } -}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java deleted file mode 100644 index 2274fb2b82..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryLocationReceiver.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.mapbox.mapboxsdk.telemetry; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.location.Location; -import android.location.LocationManager; - -/** - * Listener for Location updates generated by implementing app. - */ -public class TelemetryLocationReceiver extends BroadcastReceiver { - - public static final String INTENT_STRING = "com.mapbox.mapboxsdk.telemetry.TelemetryLocationReceiver"; - - /** - * Default Constructor - */ - public TelemetryLocationReceiver() { - super(); - } - - /** - * This method is called when the BroadcastReceiver is receiving an Intent - * broadcast. During this time you can use the other methods on - * BroadcastReceiver to view/modify the current result values. This method - * is always called within the main thread of its process, unless you - * explicitly asked for it to be scheduled on a different thread using - * {@link Context#registerReceiver(BroadcastReceiver, - * android.content.IntentFilter, String, android.os.Handler)}. When it runs on the main - * thread you should - * never perform long-running operations in it (there is a timeout of - * 10 seconds that the system allows before considering the receiver to - * be blocked and a candidate to be killed). You cannot launch a popup dialog - * in your implementation of onReceive(). - * <p> - * <p><b>If this BroadcastReceiver was launched through a <receiver> tag, - * then the object is no longer alive after returning from this - * function.</b> This means you should not perform any operations that - * return a result to you asynchronously -- in particular, for interacting - * with services, you should use - * {@link Context#startService(Intent)} instead of - * {@link Context#bindService(Intent, android.content.ServiceConnection, int)}. If you wish - * to interact with a service that is already running, you can use - * {@link #peekService}. - * <p> - * <p>The Intent filters used in {@link Context#registerReceiver} - * and in application manifests are <em>not</em> guaranteed to be exclusive. They - * are hints to the operating system about how to find suitable recipients. It is - * possible for senders to force delivery to specific recipients, bypassing filter - * resolution. For this reason, {@link #onReceive(Context, Intent) onReceive()} - * implementations should respond only to known actions, ignoring any unexpected - * Intents that they may receive. - * - * @param context The Context in which the receiver is running. - * @param intent The Intent being received. - */ - @Override - public void onReceive(Context context, Intent intent) { - if (intent == null || intent.getExtras() == null) { - // see https://github.com/mapbox/mapbox-gl-native/issues/6934 - return; - } - - Location location = (Location) intent.getExtras().get(LocationManager.KEY_LOCATION_CHANGED); - if (location != null) { - MapboxEventManager.getMapboxEventManager().addLocationEvent(location); - } - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java deleted file mode 100644 index c667c1199d..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/TelemetryService.java +++ /dev/null @@ -1,156 +0,0 @@ -package com.mapbox.mapboxsdk.telemetry; - -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ServiceInfo; -import android.os.AsyncTask; -import android.os.IBinder; -import android.support.annotation.Nullable; -import android.support.v4.content.LocalBroadcastManager; - -import timber.log.Timber; - -/** - * Manages Startup and Shutdown of Telemetry resources - */ -public class TelemetryService extends Service { - - private TelemetryLocationReceiver telemetryLocationReceiver = null; - - /** - * Return the communication channel to the service. May return null if - * clients can not bind to the service. The returned - * {@link IBinder} is usually for a complex interface - * that has been <a href="{@docRoot}guide/components/aidl.html">described using - * aidl</a>. - * <p> - * <p><em>Note that unlike other application components, calls on to the - * IBinder interface returned here may not happen on the main thread - * of the process</em>. More information about the main thread can be found in - * <a href="{@docRoot}guide/topics/fundamentals/processes-and-threads.html">Processes and - * Threads</a>.</p> - * - * @param intent The Intent that was used to bind to this service, - * as given to {@link Context#bindService - * Context.bindService}. Note that any extras that were included with - * the Intent at that point will <em>not</em> be seen here. - * @return Return an IBinder through which clients can call on to the - * service. - */ - @Nullable - @Override - public IBinder onBind(Intent intent) { - return null; - } - - - /** - * Called by the system when the service is first created. Do not call this method directly. - */ - @Override - public void onCreate() { - super.onCreate(); - - Timber.i("onCreate() called"); - - // Enable Location Listening for lifecycle of app - LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver( - new TelemetryLocationReceiver(), - new IntentFilter(TelemetryLocationReceiver.INTENT_STRING) - ); - } - - /** - * Called by the system to notify a Service that it is no longer used and is being removed. The - * service should clean up any resources it holds (threads, registered - * receivers, etc) at this point. Upon return, there will be no more calls - * in to this Service object and it is effectively dead. Do not call this method directly. - */ - @Override - public void onDestroy() { - shutdownTelemetry(); - super.onDestroy(); - } - - /** - * This is called if the service is currently running and the user has - * removed a task that comes from the service's application. If you have - * set {@link ServiceInfo#FLAG_STOP_WITH_TASK ServiceInfo.FLAG_STOP_WITH_TASK} - * then you will not receive this callback; instead, the service will simply - * be stopped. - * - * @param rootIntent The original root Intent that was used to launch - * the task that is being removed. - */ - @Override - public void onTaskRemoved(Intent rootIntent) { - shutdownTelemetry(); - super.onTaskRemoved(rootIntent); - } - - /** - * Called by the system every time a client explicitly starts the service by calling - * {@link Context#startService}, providing the arguments it supplied and a - * unique integer token representing the start request. Do not call this method directly. - * <p> - * <p>For backwards compatibility, the default implementation calls - * {@link #onStart} and returns either {@link #START_STICKY} - * or {@link #START_STICKY_COMPATIBILITY}. - * </p> - * <p>If you need your application to run on platform versions prior to API - * level 5, you can use the following model to handle the older {@link #onStart} - * callback in that case. The <code>handleCommand</code> method is implemented by - * you as appropriate: - * </p> - * <p> - * <p class="caution">Note that the system calls this on your - * service's main thread. A service's main thread is the same - * thread where UI operations take place for Activities running in the - * same process. You should always avoid stalling the main - * thread's event loop. When doing long-running operations, - * network calls, or heavy disk I/O, you should kick off a new - * thread, or use {@link AsyncTask}.</p> - * - * @param intent The Intent supplied to {@link Context#startService}, - * as given. This may be null if the service is being restarted after - * its process has gone away, and it had previously returned anything - * except {@link #START_STICKY_COMPATIBILITY}. - * @param flags Additional data about this start request. Currently either - * 0, {@link #START_FLAG_REDELIVERY}, or {@link #START_FLAG_RETRY}. - * @param startId A unique integer representing this specific request to - * start. Use with {@link #stopSelfResult(int)}. - * @return The return value indicates what semantics the system should - * use for the service's current started state. It may be one of the - * constants associated with the {@link #START_CONTINUATION_MASK} bits. - * @see #stopSelfResult(int) - */ - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - - Timber.i("onStartCommand() called"); - - return START_NOT_STICKY; - } - - private void shutdownTelemetry() { - - // Send Any Remaining events to the server - MapboxEventManager.getMapboxEventManager().flushEventsQueueImmediately(); - - // Undesired, but needed trick to keep app alive long enough for data to get to server - try { - Thread.sleep(1000); - } catch (Exception exception) { - Timber.e("Error while trying to sleep for 1 second: " + exception); - } - - try { - unregisterReceiver(telemetryLocationReceiver); - } catch (IllegalArgumentException illegalArgumentException) { - Timber.e("Error when unregisterReceiver: " + illegalArgumentException); - } - - } -} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/package-info.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/package-info.java deleted file mode 100644 index 725cf016be..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Contains the Mapbox Maps Android Telemetry API classes. - */ -package com.mapbox.mapboxsdk.telemetry; diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java index d45d647247..2da2472d69 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/ColorUtils.java @@ -119,4 +119,4 @@ public class ColorUtils { throw new ConversionException("Not a valid rgb/rgba value"); } } -}
\ No newline at end of file +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java deleted file mode 100644 index 30ec214798..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/utils/MathUtils.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.mapbox.mapboxsdk.utils; - -public class MathUtils { - - /** - * Test a value in specified range, returning minimum if it's below, and maximum if it's above - * - * @param value Value to test - * @param min Minimum value of range - * @param max Maximum value of range - * @return value if it's between min and max, min if it's below, max if it's above - */ - public static double clamp(double value, double min, double max) { - return Math.max(min, Math.min(max, value)); - } - - /** - * Test a value in specified range, returning minimum if it's below, and maximum if it's above - * - * @param value Value to test - * @param min Minimum value of range - * @param max Maximum value of range - * @return value if it's between min and max, min if it's below, max if it's above - */ - public static float clamp(float value, float min, float max) { - return Math.max(min, Math.min(max, value)); - } - - /** - * Constrains value to the given range (including min, excluding max) via modular arithmetic. - * <p> - * Same formula as used in Core GL (wrap.hpp) - * std::fmod((std::fmod((value - min), d) + d), d) + min; - * - * @param value Value to wrap - * @param min Minimum value - * @param max Maximum value - * @return Wrapped value - */ - public static double wrap(double value, double min, double max) { - double delta = max - min; - - double firstMod = (value - min) % delta; - double secondMod = (firstMod + delta) % delta; - - return secondMod + min; - } - - /** - * Convert bearing from core to match Android SDK value. - * - * @param nativeBearing bearing value coming from core - * @return bearing in degrees starting from 0 rotating clockwise - */ - public static double convertNativeBearing(double nativeBearing) { - double direction = -nativeBearing; - - while (direction > 360) { - direction -= 360; - } - while (direction < 0) { - direction += 360; - } - return direction; - } -} |