From 077ab87b4e0dd53ec6bb515d0006a44142cf7187 Mon Sep 17 00:00:00 2001 From: lorntao Date: Fri, 20 Jan 2017 13:43:43 +0800 Subject: fix for the china Publish ID --- .../mapboxsdk/constants/MapboxConstants.java | 12 +- .../java/com/mapbox/mapboxsdk/maps/MapView.java | 4 +- .../java/com/mapbox/mapboxsdk/maps/MapboxMap.java | 2 +- .../mapbox/mapboxsdk/maps/MapboxMapOptions.java | 169 +- .../java/com/mapbox/mapboxsdk/maps/Transform.java | 28 +- .../java/com/mapbox/mapboxsdk/maps/UiSettings.java | 1854 +++++++++++--------- .../maps/widgets/scaleview/DistanceUtils.java | 34 + .../maps/widgets/scaleview/MapScaleModel.java | 57 + .../maps/widgets/scaleview/MapScaleView.java | 114 ++ .../mapboxsdk/maps/widgets/scaleview/Scale.java | 20 + .../maps/widgets/scaleview/ViewConfig.java | 36 + .../mapboxsdk/telemetry/MapboxEventManager.java | 2 +- 12 files changed, 1505 insertions(+), 827 deletions(-) create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/DistanceUtils.java create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/MapScaleModel.java create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/MapScaleView.java create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/Scale.java create mode 100644 platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/ViewConfig.java 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..af858db12b 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 @@ -60,12 +60,12 @@ public class MapboxConstants { /** * The currently supported minimum zoom level. */ - public static final float MINIMUM_ZOOM = 0.0f; + public static final float MINIMUM_ZOOM = 2f; /** * The currently supported maximum zoom level. */ - public static final float MAXIMUM_ZOOM = 20.0f; + public static final float MAXIMUM_ZOOM = 15f; /** * The currently supported maximum tilt value. @@ -128,6 +128,14 @@ public class MapboxConstants { 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_SCALE_ENABLED = "scaleEnabled"; + public static final String STATE_SCALE_GRAVITY = "scaleGravity"; + public static final String STATE_SCALE_MARGIN_LEFT = "scaleMarginLeft"; + public static final String STATE_SCALE_MARGIN_TOP = "scaleMarginTop"; + public static final String STATE_SCALE_MARGIN_RIGHT = "scaleMarginRight"; + public static final String STATE_SCALE_MARGIN_BOTTOM = "scaleMarginBottom"; + public static final String STATE_SCALE_WIDTH = "scaleWidth"; + public static final String STATE_SCALE_UNIT = "scaleUnit"; 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"; 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..5e8c40e564 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 @@ -45,6 +45,7 @@ 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.maps.widgets.scaleview.MapScaleView; import com.mapbox.mapboxsdk.telemetry.MapboxEvent; import com.mapbox.mapboxsdk.telemetry.MapboxEventManager; @@ -119,6 +120,7 @@ public class MapView extends FrameLayout { // inflate view View view = LayoutInflater.from(context).inflate(R.layout.mapbox_mapview_internal, this); CompassView compassView = (CompassView) view.findViewById(R.id.compassView); + MapScaleView scaleView = (MapScaleView) view.findViewById(R.id.scaleView); MyLocationView myLocationView = (MyLocationView) view.findViewById(R.id.userLocationView); ImageView attrView = (ImageView) view.findViewById(R.id.attributionView); initalizeDrawingSurface(context, options); @@ -134,7 +136,7 @@ public class MapView extends FrameLayout { // setup components for MapboxMap creation Projection proj = new Projection(nativeMapView); - UiSettings uiSettings = new UiSettings(proj, focalPoint, compassView, attrView, view.findViewById(R.id.logoView)); + UiSettings uiSettings = new UiSettings(proj, focalPoint, compassView,scaleView, attrView, view.findViewById(R.id.logoView)); TrackingSettings trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPoint); MyLocationViewSettings myLocationViewSettings = new MyLocationViewSettings(myLocationView, proj, focalPoint); MarkerViewManager markerViewManager = new MarkerViewManager((ViewGroup) findViewById(R.id.markerViewContainer)); 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..c0f7d02566 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 @@ -2032,4 +2032,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..6fef24ee54 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 @@ -10,6 +10,7 @@ import android.graphics.drawable.Drawable; import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.ColorInt; +import android.support.annotation.FloatRange; import android.support.annotation.IntRange; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -34,10 +35,13 @@ import java.util.Arrays; */ public class MapboxMapOptions implements Parcelable { - private static final float DIMENSION_SEVEN_DP = 7f; - private static final float DIMENSION_TEN_DP = 10f; - private static final float DIMENSION_SIXTEEN_DP = 16f; - private static final float DIMENSION_SEVENTY_SIX_DP = 76f; + // to avoid reliance on knowledge of ordinals, map values from xml here. + private static UiSettings.ScaleUnit[] scaleUnits = {UiSettings.ScaleUnit.KM, UiSettings.ScaleUnit.MILE, UiSettings.ScaleUnit.NM}; + + private static final float DIMENSION_SEVEN_DP = 7f; + private static final float DIMENSION_TEN_DP = 10f; + private static final float DIMENSION_SIXTEEN_DP = 16f; + private static final float DIMENSION_SEVENTY_SIX_DP = 76f; private CameraPosition cameraPosition; @@ -48,9 +52,16 @@ public class MapboxMapOptions implements Parcelable { private int compassGravity = Gravity.TOP | Gravity.END; private int[] compassMargins; - private boolean logoEnabled = true; - private int logoGravity = Gravity.BOTTOM | Gravity.START; - private int[] logoMargins; + private boolean scaleEnabled = true; + private float scaleWidth = 0.34f; + private int scaleGravity = Gravity.BOTTOM | Gravity.RIGHT; + private int[] scaleMargins; + private UiSettings.ScaleUnit scaleUnit = UiSettings.ScaleUnit.KM; + private int scaleColor = 0; + + private boolean logoEnabled = true; + private int logoGravity = Gravity.BOTTOM | Gravity.START; + private int[] logoMargins; @ColorInt private int attributionTintColor = -1; @@ -204,6 +215,15 @@ public class MapboxMapOptions implements Parcelable { DIMENSION_TEN_DP * pxlRatio))}); mapboxMapOptions.compassFadesWhenFacingNorth(typedArray.getBoolean( R.styleable.mapbox_MapView_mapbox_uiCompassFadeFacingNorth, true)); +mapboxMapOptions.scaleEnabled(typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_uiScaleEnabled, true)); + mapboxMapOptions.scaleColor(typedArray.getInt(R.styleable.mapbox_MapView_mapbox_uiScaleColor, MapboxConstants.SCALE_COLOR_BLACK)); + mapboxMapOptions.scaleWidth(typedArray.getFloat(R.styleable.mapbox_MapView_mapbox_uiScaleWidth, 0.34f)); + mapboxMapOptions.scaleUnit(scaleUnits[typedArray.getInt(R.styleable.mapbox_MapView_mapbox_uiScaleUnit, 0)]); + mapboxMapOptions.scaleGravity(typedArray.getInt(R.styleable.mapbox_MapView_mapbox_uiScaleGravity, Gravity.BOTTOM | Gravity.RIGHT)); + mapboxMapOptions.scaleMargins(new int[]{(int) (typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiScaleMarginLeft, DIMENSION_SEVEN_DP) * pxlRatio) + , ((int) typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiScaleMarginTop, DIMENSION_SEVEN_DP * pxlRatio)) + , ((int) typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiScaleMarginRight, DIMENSION_SEVEN_DP * pxlRatio)) + , ((int) typedArray.getDimension(R.styleable.mapbox_MapView_mapbox_uiScaleMarginBottom, DIMENSION_SEVEN_DP * pxlRatio))}); mapboxMapOptions.logoEnabled(typedArray.getBoolean(R.styleable.mapbox_MapView_mapbox_uiLogo, true)); mapboxMapOptions.logoGravity(typedArray.getInt(R.styleable.mapbox_MapView_mapbox_uiLogoGravity, @@ -1030,6 +1050,12 @@ public class MapboxMapOptions implements Parcelable { if (compassGravity != options.compassGravity) { return false; } + if (scaleColor != options.scaleColor) return false; + if (scaleEnabled != options.scaleEnabled) return false; + if (scaleGravity != options.scaleGravity) return false; + if (scaleWidth != options.scaleWidth) return false; + if (scaleUnit != options.scaleUnit) return false; + if (logoEnabled != options.logoEnabled) { return false; } @@ -1130,6 +1156,11 @@ public class MapboxMapOptions implements Parcelable { result = 31 * result + (fadeCompassFacingNorth ? 1 : 0); result = 31 * result + compassGravity; result = 31 * result + Arrays.hashCode(compassMargins); + result = 31 * result + (scaleEnabled ? 1 : 0); + result = 31 * result + scaleColor; + result = 31 * result + scaleGravity; + result = 31 * result + scaleUnit.ordinal(); + result = 31 * result + Arrays.hashCode(scaleMargins); result = 31 * result + (logoEnabled ? 1 : 0); result = 31 * result + logoGravity; result = 31 * result + Arrays.hashCode(logoMargins); @@ -1161,4 +1192,128 @@ public class MapboxMapOptions implements Parcelable { result = 31 * result + (style != null ? style.hashCode() : 0); return result; } + /** + * Is the map scale widget enabled? + * + * @return the current enabled state + */ + public boolean getScaleEnabled() { + return scaleEnabled; + } + + /** + * Control whether the map scale widget is shown. + * The scale widget shows a scale of distance on the map + * + * @param scaleEnabled + * @return this + */ + public MapboxMapOptions scaleEnabled(boolean scaleEnabled) { + this.scaleEnabled = scaleEnabled; + return this; + } + + /** + * Get the color index of the scale widget. + * + * @return the scale unit + */ + public int getScaleColor() { + return scaleColor; + } + + /** + * Set the color for the scale widget. Choices are: + * MapboxConstants.SCALE_COLOR_BLACK (default) + * MapboxConstants.SCALE_COLOR_WHITE + * + * @param scaleColor + * @return + */ + public MapboxMapOptions scaleColor(int scaleColor) { + this.scaleColor = scaleColor; + return this; + } + + /** + * Get the current unit used to label the scale widget + * + * @return the scale unit + */ + public UiSettings.ScaleUnit getScaleUnit() { + return scaleUnit; + } + + /** + * Set the unit used for labelling the scale widget. + *

+ * See {@link UiSettings.ScaleUnit} + * + * @param scaleUnit + * @return + */ + public MapboxMapOptions scaleUnit(UiSettings.ScaleUnit scaleUnit) { + this.scaleUnit = scaleUnit; + return this; + } + + /** + * Get the width of the scale widget. + * + * @return The scale width as a fraction of the display width + */ + public float getScaleWidth() { + return scaleWidth; + } + + /** + * Set the width of the scale widget as a fraction of the display width. + * + * @param scaleWidth + * @return this + */ + public MapboxMapOptions scaleWidth(@FloatRange(from = 0f, to = 1f) float scaleWidth) { + this.scaleWidth = scaleWidth; + return this; + } + + /** + * Get the gravity settings for the scale widget. + * + * @return a bit mask of gravity contstants + */ + public int getScaleGravity() { + return scaleGravity; + } + + /** + * Set the gravity of the scale widget. See + * + * @param scaleGravity see {@link android.view.Gravity} + * @return this + */ + + public MapboxMapOptions scaleGravity(int scaleGravity) { + this.scaleGravity = scaleGravity; + return this; + } + + /** + * Get the margins for the scale widget + * + * @return 4 long array for LTRB margins + */ + public int[] getScaleMargins() { + return scaleMargins; + } + + /** + * Set the margins for the scale widget + * + * @param scaleMargins 4 long array for LTRB margins + */ + public MapboxMapOptions scaleMargins(int[] scaleMargins) { + this.scaleMargins = scaleMargins; + return this; + } } \ No newline at end of file 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..6a5b2526de 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 @@ -172,6 +172,11 @@ final class Transform implements MapView.OnMapChangedListener { } void zoom(boolean zoomIn) { + if(getZoom()>MapboxConstants.MAXIMUM_ZOOM) { + mapView.setZoom(MapboxConstants.MAXIMUM_ZOOM); + }else if (getZoom() - * Enables or disables the compass. The compass is an icon on the map that indicates the - * direction of north on the map. When a user clicks - * the compass, the camera orients itself to its default orientation and fades away shortly - * after. If disabled, the compass will never be displayed. - *

- * By default, the compass is enabled. - * - * @param compassEnabled True to enable the compass; false to disable the compass. - */ - public void setCompassEnabled(boolean compassEnabled) { - compassView.setEnabled(compassEnabled); - } - - /** - * Returns whether the compass is enabled. - * - * @return True if the compass is enabled; false if the compass is disabled. - */ - public boolean isCompassEnabled() { - return compassView.isEnabled(); - } - - /** - *

- * Sets the gravity of the compass view. Use this to change the corner of the map view that the - * compass is displayed in. - *

- * By default, the compass is in the top right corner. - * - * @param gravity One of the values from {@link Gravity}. - * @see Gravity - */ - @UiThread - public void setCompassGravity(int gravity) { - setWidgetGravity(compassView, gravity); - } - - /** - * Enables or disables fading of the compass when facing north. - *

- * By default this feature is enabled - *

- * - * @param compassFadeFacingNorth True to enable the fading animation; false to disable it - */ - public void setCompassFadeFacingNorth(boolean compassFadeFacingNorth) { - compassView.fadeCompassViewFacingNorth(compassFadeFacingNorth); - } - - /** - * Returns whether the compass performs a fading animation out when facing north. - * - * @return True if the compass will fade, false if it remains visible - */ - public boolean isCompassFadeWhenFacingNorth() { - return compassView.isFadeCompassViewFacingNorth(); - } - - /** - * Returns the gravity value of the CompassView - * - * @return The gravity - */ - public int getCompassGravity() { - return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).gravity; - } - - /** - * Sets the margins of the compass view. Use this to change the distance of the compass from the - * map view edge. - * - * @param left The left margin in pixels. - * @param top The top margin in pixels. - * @param right The right margin in pixels. - * @param bottom The bottom margin in pixels. - */ - @UiThread - public void setCompassMargins(int left, int top, int right, int bottom) { - setWidgetMargins(compassView, left, top, right, bottom); - } - - /** - * Returns the left side margin of CompassView - * - * @return The left margin in pixels - */ - public int getCompassMarginLeft() { - return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).leftMargin; - } - - /** - * Returns the top side margin of CompassView - * - * @return The top margin in pixels - */ - public int getCompassMarginTop() { - return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).topMargin; - } - - /** - * Returns the right side margin of CompassView - * - * @return The right margin in pixels - */ - public int getCompassMarginRight() { - return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).rightMargin; - } - - /** - * Returns the bottom side margin of CompassView - * - * @return The bottom margin in pixels - */ - public int getCompassMarginBottom() { - return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).bottomMargin; - } - - void update(@NonNull CameraPosition cameraPosition) { - if (!isCompassEnabled()) { - return; - } - - compassView.update(cameraPosition.bearing); - } - - /** - *

- * Enables or disables the Mapbox logo. - *

- * By default, the logo is enabled. - * - * @param enabled True to enable the logo; false to disable the logo. - */ - public void setLogoEnabled(boolean enabled) { - logoView.setVisibility(enabled ? View.VISIBLE : View.GONE); - } - - /** - * Returns whether the logo is enabled. - * - * @return True if the logo is enabled; false if the logo is disabled. - */ - public boolean isLogoEnabled() { - return logoView.getVisibility() == View.VISIBLE; - } - - /** - *

- * Sets the gravity of the logo view. Use this to change the corner of the map view that the - * Mapbox logo is displayed in. - *

- * By default, the logo is in the bottom left corner. - * - * @param gravity One of the values from {@link Gravity}. - * @see Gravity - */ - public void setLogoGravity(int gravity) { - setWidgetGravity(logoView, gravity); - } - - /** - * Returns the gravity value of the logo - * - * @return The gravity - */ - public int getLogoGravity() { - return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).gravity; - } - - /** - * Sets the margins of the logo view. Use this to change the distance of the Mapbox logo from the - * map view edge. - * - * @param left The left margin in pixels. - * @param top The top margin in pixels. - * @param right The right margin in pixels. - * @param bottom The bottom margin in pixels. - */ - public void setLogoMargins(int left, int top, int right, int bottom) { - setWidgetMargins(logoView, left, top, right, bottom); - } - - /** - * Returns the left side margin of the logo - * - * @return The left margin in pixels - */ - public int getLogoMarginLeft() { - return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).leftMargin; - } - - /** - * Returns the top side margin of the logo - * - * @return The top margin in pixels - */ - public int getLogoMarginTop() { - return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).topMargin; - } - - /** - * Returns the right side margin of the logo - * - * @return The right margin in pixels - */ - public int getLogoMarginRight() { - return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).rightMargin; - } - - /** - * Returns the bottom side margin of the logo - * - * @return The bottom margin in pixels - */ - public int getLogoMarginBottom() { - return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).bottomMargin; - } - - /** - *

- * Enables or disables the attribution. - *

- * By default, the attribution is enabled. - * - * @param enabled True to enable the attribution; false to disable the attribution. - */ - public void setAttributionEnabled(boolean enabled) { - attributionsView.setVisibility(enabled ? View.VISIBLE : View.GONE); - } - - /** - * Returns whether the attribution is enabled. - * - * @return True if the attribution is enabled; false if the attribution is disabled. - */ - public boolean isAttributionEnabled() { - return attributionsView.getVisibility() == View.VISIBLE; - } - - /** - *

- * Sets the gravity of the attribution. - *

- * By default, the attribution is in the bottom left corner next to the Mapbox logo. - * - * @param gravity One of the values from {@link Gravity}. - * @see Gravity - */ - public void setAttributionGravity(int gravity) { - setWidgetGravity(attributionsView, gravity); - } - - /** - * Returns the gravity value of the logo - * - * @return The gravity - */ - public int getAttributionGravity() { - return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).gravity; - } - - /** - * Sets the margins of the attribution view. - * - * @param left The left margin in pixels. - * @param top The top margin in pixels. - * @param right The right margin in pixels. - * @param bottom The bottom margin in pixels. - */ - public void setAttributionMargins(int left, int top, int right, int bottom) { - setWidgetMargins(attributionsView, left, top, right, bottom); - } - - /** - *

- * Sets the tint of the attribution view. Use this to change the color of the attribution. - *

- * By default, the logo is tinted with the primary color of your theme. - * - * @param tintColor Color to tint the attribution. - */ - public void setAttributionTintColor(@ColorInt int tintColor) { - // Check that the tint color being passed in isn't transparent. - if (Color.alpha(tintColor) == 0) { - ColorUtils.setTintList(attributionsView, - ContextCompat.getColor(attributionsView.getContext(), R.color.mapbox_blue)); - } else { - ColorUtils.setTintList(attributionsView, tintColor); - } - } - - /** - * Returns the left side margin of the attribution view. - * - * @return The left margin in pixels - */ - public int getAttributionMarginLeft() { - return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).leftMargin; - } - - /** - * Returns the top side margin of the attribution view. - * - * @return The top margin in pixels - */ - public int getAttributionMarginTop() { - return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).topMargin; - } - - /** - * Returns the right side margin of the attribution view. - * - * @return The right margin in pixels - */ - public int getAttributionMarginRight() { - return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).rightMargin; - } - - /** - * Returns the bottom side margin of the logo - * - * @return The bottom margin in pixels - */ - public int getAttributionMarginBottom() { - return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).bottomMargin; - } - - /** - *

- * Changes whether the user may rotate the map. - *

- *

- * This setting controls only user interactions with the map. If you set the value to false, - * you may still change the map location programmatically. - *

- * The default value is true. - * - * @param rotateGesturesEnabled If true, rotating is enabled. - */ - public void setRotateGesturesEnabled(boolean rotateGesturesEnabled) { - if (rotateGestureChangeAllowed) { - this.rotateGesturesEnabled = rotateGesturesEnabled; - } - } - - /** - * Returns whether the user may rotate the map. - * - * @return If true, rotating is enabled. - */ - public boolean isRotateGesturesEnabled() { - return rotateGesturesEnabled; - } - - void setRotateGestureChangeAllowed(boolean rotateGestureChangeAllowed) { - this.rotateGestureChangeAllowed = rotateGestureChangeAllowed; - } - - boolean isRotateGestureChangeAllowed() { - return rotateGestureChangeAllowed; - } - - /** - *

- * Changes whether the user may tilt the map. - *

- *

- * This setting controls only user interactions with the map. If you set the value to false, - * you may still change the map location programmatically. - *

- * The default value is true. - * - * @param tiltGesturesEnabled If true, tilting is enabled. - */ - public void setTiltGesturesEnabled(boolean tiltGesturesEnabled) { - if (tiltGestureChangeAllowed) { - this.tiltGesturesEnabled = tiltGesturesEnabled; - } - } - - /** - * Returns whether the user may tilt the map. - * - * @return If true, tilting is enabled. - */ - public boolean isTiltGesturesEnabled() { - return tiltGesturesEnabled; - } - - void setTiltGestureChangeAllowed(boolean tiltGestureChangeAllowed) { - this.tiltGestureChangeAllowed = tiltGestureChangeAllowed; - } - - boolean isTiltGestureChangeAllowed() { - return tiltGestureChangeAllowed; - } - - /** - *

- * Changes whether the user may zoom the map. - *

- *

- * This setting controls only user interactions with the map. If you set the value to false, - * you may still change the map location programmatically. - *

- * The default value is true. - * - * @param zoomGesturesEnabled If true, zooming is enabled. - */ - public void setZoomGesturesEnabled(boolean zoomGesturesEnabled) { - if (zoomGestureChangeAllowed) { - this.zoomGesturesEnabled = zoomGesturesEnabled; - } - } - - /** - * Returns whether the user may zoom the map. - * - * @return If true, zooming is enabled. - */ - public boolean isZoomGesturesEnabled() { - return zoomGesturesEnabled; - } - - void setZoomGestureChangeAllowed(boolean zoomGestureChangeAllowed) { - this.zoomGestureChangeAllowed = zoomGestureChangeAllowed; - } - - boolean isZoomGestureChangeAllowed() { - return zoomGestureChangeAllowed; - } - - /** - *

- * Sets whether the zoom controls are enabled. - * If enabled, the zoom controls are a pair of buttons - * (one for zooming in, one for zooming out) that appear on the screen. - * When pressed, they cause the camera to zoom in (or out) by one zoom level. - * If disabled, the zoom controls are not shown. - *

- * By default the zoom controls are enabled if the device is only single touch capable; - * - * @param zoomControlsEnabled If true, the zoom controls are enabled. - */ - public void setZoomControlsEnabled(boolean zoomControlsEnabled) { - this.zoomControlsEnabled = zoomControlsEnabled; - } - - /** - * Gets whether the zoom controls are enabled. - * - * @return If true, the zoom controls are enabled. - */ - public boolean isZoomControlsEnabled() { - return zoomControlsEnabled; - } - - /** - * Gets whether the markers are automatically deselected (and therefore, their infowindows - * closed) when a map tap is detected. - * - * @return If true, markers are deselected on a map tap. - */ - public boolean isDeselectMarkersOnTap() { - return deselectMarkersOnTap; - } - - /** - * Sets whether the markers are automatically deselected (and therefore, their infowindows - * closed) when a map tap is detected. - * - * @param deselectMarkersOnTap determines if markers should be deslected on tap - */ - public void setDeselectMarkersOnTap(boolean deselectMarkersOnTap) { - this.deselectMarkersOnTap = deselectMarkersOnTap; - } - - /** - *

- * Changes whether the user may scroll around the map. - *

- *

- * This setting controls only user interactions with the map. If you set the value to false, - * you may still change the map location programmatically. - *

- * The default value is true. - * - * @param scrollGesturesEnabled If true, scrolling is enabled. - */ - public void setScrollGesturesEnabled(boolean scrollGesturesEnabled) { - if (scrollGestureChangeAllowed) { - this.scrollGesturesEnabled = scrollGesturesEnabled; - } - } - - /** - * Returns whether the user may scroll around the map. - * - * @return If true, scrolling is enabled. - */ - public boolean isScrollGesturesEnabled() { - return scrollGesturesEnabled; - } - - void setScrollGestureChangeAllowed(boolean scrollGestureChangeAllowed) { - this.scrollGestureChangeAllowed = scrollGestureChangeAllowed; - } - - boolean isScrollGestureChangeAllowed() { - return scrollGestureChangeAllowed; - } - - /** - *

- * Sets the preference for whether all gestures should be enabled or disabled. - *

- *

- * This setting controls only user interactions with the map. If you set the value to false, - * you may still change the map location programmatically. - *

- * The default value is true. - * - * @param enabled If true, all gestures are available; otherwise, all gestures are disabled. - * @see #setZoomGesturesEnabled(boolean) ) - * @see #setScrollGesturesEnabled(boolean) - * @see #setRotateGesturesEnabled(boolean) - * @see #setTiltGesturesEnabled(boolean) - */ - public void setAllGesturesEnabled(boolean enabled) { - setScrollGesturesEnabled(enabled); - setRotateGesturesEnabled(enabled); - setTiltGesturesEnabled(enabled); - setZoomGesturesEnabled(enabled); - } - - /** - * Sets the focal point used as center for a gesture - * - * @param focalPoint the focal point to be used. - */ - public void setFocalPoint(@Nullable PointF focalPoint) { - this.userProvidedFocalPoint = focalPoint; - focalPointChangeListener.onFocalPointChanged(focalPoint); - } - - /** - * Returns the gesture focal point - * - * @return The focal point - */ - public PointF getFocalPoint() { - return userProvidedFocalPoint; - } - - /** - * Returns the measured height of the MapView - * - * @return height in pixels - */ - public float getHeight() { - return projection.getHeight(); - } - - /** - * Returns the measured width of the MapView - * - * @return widht in pixels - */ - public float getWidth() { - return projection.getWidth(); - } - - float getPixelRatio() { - return pixelRatio; - } - - /** - * Invalidates the ViewSettings instances shown on top of the MapView - */ - public void invalidate() { - setLogoMargins(getLogoMarginLeft(), getLogoMarginTop(), getLogoMarginRight(), getLogoMarginBottom()); - setCompassMargins(getCompassMarginLeft(), getCompassMarginTop(), getCompassMarginRight(), getCompassMarginBottom()); - setAttributionMargins(getAttributionMarginLeft(), getAttributionMarginTop(), getAttributionMarginRight(), - getAttributionMarginBottom()); - } - - private void setWidgetGravity(@NonNull final View view, int gravity) { - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams(); - layoutParams.gravity = gravity; - view.setLayoutParams(layoutParams); - } - - private void setWidgetMargins(@NonNull final View view, int left, int top, int right, int bottom) { - int[] contentPadding = projection.getContentPadding(); - FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams(); - left += contentPadding[0]; - top += contentPadding[1]; - right += contentPadding[2]; - bottom += contentPadding[3]; - layoutParams.setMargins(left, top, right, bottom); - view.setLayoutParams(layoutParams); - } + private final FocalPointChangeListener focalPointChangeListener; + private final Projection projection; + private final CompassView compassView; + private final MapScaleView scaleView; + private final ImageView attributionsView; + private final View logoView; + private float pixelRatio; + + private boolean rotateGesturesEnabled = true; + private boolean rotateGestureChangeAllowed = true; + + private boolean tiltGesturesEnabled = true; + private boolean tiltGestureChangeAllowed = true; + + private boolean zoomGesturesEnabled = true; + private boolean zoomGestureChangeAllowed = true; + + private boolean scrollGesturesEnabled = true; + private boolean scrollGestureChangeAllowed = true; + + private boolean zoomControlsEnabled; + + private boolean deselectMarkersOnTap = true; + + private PointF userProvidedFocalPoint; + + UiSettings(@NonNull Projection projection, @NonNull FocalPointChangeListener listener, + @NonNull CompassView compassView, @NonNull MapScaleView scaleView, @NonNull ImageView attributionsView, @NonNull View logoView) { + this.projection = projection; + this.focalPointChangeListener = listener; + this.compassView = compassView; + this.scaleView = scaleView; + this.attributionsView = attributionsView; + this.logoView = logoView; + if (logoView.getResources() != null) { + this.pixelRatio = logoView.getResources().getDisplayMetrics().density; + } + } + + void initialise(@NonNull Context context, @NonNull MapboxMapOptions options) { + Resources resources = context.getResources(); + initialiseGestures(options); + initialiseCompass(options, resources); + initialiseScale(options, resources); + initialiseLogo(options, resources); + initialiseAttribution(context, options); + initialiseZoomControl(context); + } + + void onSaveInstanceState(Bundle outState) { + saveGestures(outState); + saveCompass(outState); + saveScale(outState); + saveLogo(outState); + saveAttribution(outState); + saveZoomControl(outState); + } + + void onRestoreInstanceState(@NonNull Bundle savedInstanceState) { + restoreGestures(savedInstanceState); + restoreCompass(savedInstanceState); + restoreScale(savedInstanceState); + restoreLogo(savedInstanceState); + restoreAttribution(savedInstanceState); + restoreZoomControl(savedInstanceState); + } + + private void initialiseGestures(MapboxMapOptions options) { + setZoomGesturesEnabled(options.getZoomGesturesEnabled()); + setZoomGestureChangeAllowed(options.getZoomGesturesEnabled()); + setScrollGesturesEnabled(options.getScrollGesturesEnabled()); + setScrollGestureChangeAllowed(options.getScrollGesturesEnabled()); + setRotateGesturesEnabled(options.getRotateGesturesEnabled()); + setRotateGestureChangeAllowed(options.getRotateGesturesEnabled()); + setTiltGesturesEnabled(options.getTiltGesturesEnabled()); + setTiltGestureChangeAllowed(options.getTiltGesturesEnabled()); + setZoomControlsEnabled(options.getZoomControlsEnabled()); + } + + private void saveGestures(Bundle outState) { + outState.putBoolean(MapboxConstants.STATE_ZOOM_ENABLED, isZoomGesturesEnabled()); + outState.putBoolean(MapboxConstants.STATE_ZOOM_ENABLED_CHANGE, isZoomGestureChangeAllowed()); + outState.putBoolean(MapboxConstants.STATE_SCROLL_ENABLED, isScrollGesturesEnabled()); + outState.putBoolean(MapboxConstants.STATE_SCROLL_ENABLED_CHANGE, isScrollGestureChangeAllowed()); + outState.putBoolean(MapboxConstants.STATE_ROTATE_ENABLED, isRotateGesturesEnabled()); + outState.putBoolean(MapboxConstants.STATE_ROTATE_ENABLED_CHANGE, isRotateGestureChangeAllowed()); + outState.putBoolean(MapboxConstants.STATE_TILT_ENABLED, isTiltGesturesEnabled()); + outState.putBoolean(MapboxConstants.STATE_TILT_ENABLED_CHANGE, isTiltGestureChangeAllowed()); + } + + private void restoreGestures(Bundle savedInstanceState) { + setZoomGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_ENABLED)); + setZoomGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_ENABLED_CHANGE)); + setScrollGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_SCROLL_ENABLED)); + setScrollGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_SCROLL_ENABLED_CHANGE)); + setRotateGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ROTATE_ENABLED)); + setRotateGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_ROTATE_ENABLED_CHANGE)); + setTiltGesturesEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_TILT_ENABLED)); + setTiltGestureChangeAllowed(savedInstanceState.getBoolean(MapboxConstants.STATE_TILT_ENABLED_CHANGE)); + } + + private void initialiseCompass(MapboxMapOptions options, Resources resources) { + setCompassEnabled(options.getCompassEnabled()); + setCompassGravity(options.getCompassGravity()); + int[] compassMargins = options.getCompassMargins(); + if (compassMargins != null) { + setCompassMargins(compassMargins[0], compassMargins[1], compassMargins[2], compassMargins[3]); + } else { + int tenDp = (int) resources.getDimension(R.dimen.mapbox_ten_dp); + setCompassMargins(tenDp, tenDp, tenDp, tenDp); + } + setCompassFadeFacingNorth(options.getCompassFadeFacingNorth()); + } + + private void saveCompass(Bundle outState) { + outState.putBoolean(MapboxConstants.STATE_COMPASS_ENABLED, isCompassEnabled()); + outState.putInt(MapboxConstants.STATE_COMPASS_GRAVITY, getCompassGravity()); + outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_LEFT, getCompassMarginLeft()); + outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_TOP, getCompassMarginTop()); + outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_BOTTOM, getCompassMarginBottom()); + outState.putInt(MapboxConstants.STATE_COMPASS_MARGIN_RIGHT, getCompassMarginRight()); + outState.putBoolean(MapboxConstants.STATE_COMPASS_FADE_WHEN_FACING_NORTH, isCompassFadeWhenFacingNorth()); + } + + private void restoreCompass(Bundle savedInstanceState) { + setCompassEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_COMPASS_ENABLED)); + setCompassGravity(savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_GRAVITY)); + setCompassMargins(savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_LEFT), + savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_TOP), + savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_RIGHT), + savedInstanceState.getInt(MapboxConstants.STATE_COMPASS_MARGIN_BOTTOM)); + setCompassFadeFacingNorth(savedInstanceState.getBoolean(MapboxConstants.STATE_COMPASS_FADE_WHEN_FACING_NORTH)); + } + + private void initialiseScale(MapboxMapOptions options, Resources resources) { + setScaleEnabled(options.getScaleEnabled()); + setScaleGravity(options.getScaleGravity()); + int[] scaleMargins = options.getScaleMargins(); + if (scaleMargins != null) { + setScaleMargins(scaleMargins[0], scaleMargins[1], scaleMargins[2], scaleMargins[3]); + } else { + int tenDp = (int) resources.getDimension(R.dimen.mapbox_ten_dp); + setScaleMargins(tenDp, tenDp, tenDp, tenDp); + } + } + + private void saveScale(Bundle outState) { + outState.putBoolean(MapboxConstants.STATE_SCALE_ENABLED, isScaleEnabled()); + outState.putInt(MapboxConstants.STATE_SCALE_GRAVITY, getScaleGravity()); + outState.putInt(MapboxConstants.STATE_SCALE_MARGIN_LEFT, getScaleMarginLeft()); + outState.putInt(MapboxConstants.STATE_SCALE_MARGIN_TOP, getScaleMarginTop()); + outState.putInt(MapboxConstants.STATE_SCALE_MARGIN_BOTTOM, getScaleMarginBottom()); + outState.putInt(MapboxConstants.STATE_SCALE_MARGIN_RIGHT, getScaleMarginRight()); + } + + private void restoreScale(Bundle savedInstanceState) { + setScaleEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_SCALE_ENABLED)); + setScaleGravity(savedInstanceState.getInt(MapboxConstants.STATE_SCALE_GRAVITY)); + setScaleMargins(savedInstanceState.getInt(MapboxConstants.STATE_SCALE_MARGIN_LEFT), + savedInstanceState.getInt(MapboxConstants.STATE_SCALE_MARGIN_TOP), + savedInstanceState.getInt(MapboxConstants.STATE_SCALE_MARGIN_RIGHT), + savedInstanceState.getInt(MapboxConstants.STATE_SCALE_MARGIN_BOTTOM)); + } + + private void initialiseLogo(MapboxMapOptions options, Resources resources) { + setLogoEnabled(options.getLogoEnabled()); + setLogoGravity(options.getLogoGravity()); + int[] logoMargins = options.getLogoMargins(); + if (logoMargins != null) { + setLogoMargins(logoMargins[0], logoMargins[1], logoMargins[2], logoMargins[3]); + } else { + int sixteenDp = (int) resources.getDimension(R.dimen.mapbox_sixteen_dp); + setLogoMargins(sixteenDp, sixteenDp, sixteenDp, sixteenDp); + } + } + + private void saveLogo(Bundle outState) { + outState.putInt(MapboxConstants.STATE_LOGO_GRAVITY, getLogoGravity()); + outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_LEFT, getLogoMarginLeft()); + outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_TOP, getLogoMarginTop()); + outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_RIGHT, getLogoMarginRight()); + outState.putInt(MapboxConstants.STATE_LOGO_MARGIN_BOTTOM, getLogoMarginBottom()); + outState.putBoolean(MapboxConstants.STATE_LOGO_ENABLED, isLogoEnabled()); + } + + private void restoreLogo(Bundle savedInstanceState) { + setLogoEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_LOGO_ENABLED)); + setLogoGravity(savedInstanceState.getInt(MapboxConstants.STATE_LOGO_GRAVITY)); + setLogoMargins(savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_LEFT), + savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_TOP), + savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_RIGHT), + savedInstanceState.getInt(MapboxConstants.STATE_LOGO_MARGIN_BOTTOM)); + } + + private void initialiseAttribution(Context context, MapboxMapOptions options) { + Resources resources = context.getResources(); + setAttributionEnabled(options.getAttributionEnabled()); + setAttributionGravity(options.getAttributionGravity()); + int[] attributionMargins = options.getAttributionMargins(); + if (attributionMargins != null) { + setAttributionMargins(attributionMargins[0], attributionMargins[1], attributionMargins[2], attributionMargins[3]); + } else { + int sevenDp = (int) resources.getDimension(R.dimen.mapbox_seven_dp); + int seventySixDp = (int) resources.getDimension(R.dimen.mapbox_seventy_six_dp); + setAttributionMargins(seventySixDp, sevenDp, sevenDp, sevenDp); + } + + int attributionTintColor = options.getAttributionTintColor(); + setAttributionTintColor(attributionTintColor != -1 + ? attributionTintColor : ColorUtils.getPrimaryColor(context)); + } + + private void saveAttribution(Bundle outState) { + outState.putInt(MapboxConstants.STATE_ATTRIBUTION_GRAVITY, getAttributionGravity()); + outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_LEFT, getAttributionMarginLeft()); + outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_TOP, getAttributionMarginTop()); + outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_RIGHT, getAttributionMarginRight()); + outState.putInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_BOTTOM, getAttributionMarginBottom()); + outState.putBoolean(MapboxConstants.STATE_ATTRIBUTION_ENABLED, isAttributionEnabled()); + } + + private void restoreAttribution(Bundle savedInstanceState) { + setAttributionEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ATTRIBUTION_ENABLED)); + setAttributionGravity(savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_GRAVITY)); + setAttributionMargins(savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_LEFT), + savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_TOP), + savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_RIGHT), + savedInstanceState.getInt(MapboxConstants.STATE_ATTRIBUTION_MARGIN_BOTTOM)); + } + + private void initialiseZoomControl(Context context) { + if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH)) { + setZoomControlsEnabled(true); + } + } + + private void saveZoomControl(Bundle outState) { + outState.putBoolean(MapboxConstants.STATE_ZOOM_CONTROLS_ENABLED, isZoomControlsEnabled()); + } + + private void restoreZoomControl(Bundle savedInstanceState) { + setZoomControlsEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_ZOOM_CONTROLS_ENABLED)); + } + + /** + *

+ * Enables or disables the compass. The compass is an icon on the map that indicates the + * direction of north on the map. When a user clicks + * the compass, the camera orients itself to its default orientation and fades away shortly + * after. If disabled, the compass will never be displayed. + *

+ * By default, the compass is enabled. + * + * @param compassEnabled True to enable the compass; false to disable the compass. + */ + public void setCompassEnabled(boolean compassEnabled) { + compassView.setEnabled(compassEnabled); + } + + /** + * Returns whether the compass is enabled. + * + * @return True if the compass is enabled; false if the compass is disabled. + */ + public boolean isCompassEnabled() { + return compassView.isEnabled(); + } + + /** + *

+ * Sets the gravity of the compass view. Use this to change the corner of the map view that the + * compass is displayed in. + *

+ * By default, the compass is in the top right corner. + * + * @param gravity One of the values from {@link Gravity}. + * @see Gravity + */ + @UiThread + public void setCompassGravity(int gravity) { + setWidgetGravity(compassView, gravity); + } + + /** + * Enables or disables fading of the compass when facing north. + *

+ * By default this feature is enabled + *

+ * + * @param compassFadeFacingNorth True to enable the fading animation; false to disable it + */ + public void setCompassFadeFacingNorth(boolean compassFadeFacingNorth) { + compassView.fadeCompassViewFacingNorth(compassFadeFacingNorth); + } + + /** + * Returns whether the compass performs a fading animation out when facing north. + * + * @return True if the compass will fade, false if it remains visible + */ + public boolean isCompassFadeWhenFacingNorth() { + return compassView.isFadeCompassViewFacingNorth(); + } + + /** + * Returns the gravity value of the CompassView + * + * @return The gravity + */ + public int getCompassGravity() { + return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).gravity; + } + + /** + * Sets the margins of the compass view. Use this to change the distance of the compass from the + * map view edge. + * + * @param left The left margin in pixels. + * @param top The top margin in pixels. + * @param right The right margin in pixels. + * @param bottom The bottom margin in pixels. + */ + @UiThread + public void setCompassMargins(int left, int top, int right, int bottom) { + setWidgetMargins(compassView, left, top, right, bottom); + } + + /** + * Returns the left side margin of CompassView + * + * @return The left margin in pixels + */ + public int getCompassMarginLeft() { + return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).leftMargin; + } + + /** + * Returns the top side margin of CompassView + * + * @return The top margin in pixels + */ + public int getCompassMarginTop() { + return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).topMargin; + } + + /** + * Returns the right side margin of CompassView + * + * @return The right margin in pixels + */ + public int getCompassMarginRight() { + return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).rightMargin; + } + + /** + * Returns the bottom side margin of CompassView + * + * @return The bottom margin in pixels + */ + public int getCompassMarginBottom() { + return ((FrameLayout.LayoutParams) compassView.getLayoutParams()).bottomMargin; + } + + void update(@NonNull CameraPosition cameraPosition) { + if (!isCompassEnabled()) { + return; + } + + compassView.update(cameraPosition.bearing); +// scaleView.setZoomLevel(cameraPosition.zoom); + scaleView.update(projection,cameraPosition); + } + + /** + *

+ * Enables or disables the scale. The scale is a widget on the map that shows a dynamically + * updated distance scale + * If disabled, the scale will never be displayed. + *

+ * By default, the scale is enabled. + * + * @param scaleEnabled True to enable the scale; false to disable the scale. + */ + public void setScaleEnabled(boolean scaleEnabled) { + scaleView.setEnabled(scaleEnabled); + } + + /** + * Returns whether the scale is enabled. + * + * @return True if the scale is enabled; false if the scale is disabled. + */ + public boolean isScaleEnabled() { + return scaleView.isEnabled(); + } + + /** + * Set the color of the scale widget. Choices are: + * MapboxConstants.SCALE_COLOR_BLACK (default) + * MapboxConstants.SCALE_COLOR_WHITE + * + * @param scaleColor + */ + +// public void setScaleColor(int scaleColor) { +// scaleView.setColor(scaleColor); +// } + + /** + * Returns whether the scale is enabled. + * + * @return True if the scale is enabled; false if the scale is disabled. + */ +// public int getScaleColor() { +// return scaleView.getScaleColor(); +// } + + /** + *

+ * Sets the gravity of the scale view. Use this to change the corner of the map view that the + * scale is displayed in. + *

+ * By default, the scale is in the top right corner. + * + * @param gravity One of the values from {@link Gravity}. + * @see Gravity + */ + @UiThread + public void setScaleGravity(int gravity) { + setWidgetGravity(scaleView, gravity); + } + + /** + * Returns the gravity value of the MapScaleView + * + * @return The gravity + */ + public int getScaleGravity() { + return ((FrameLayout.LayoutParams) scaleView.getLayoutParams()).gravity; + } + + /** + *

+ * Sets the width of the scale view as a fraction of the display. + *

+ * By default, the scale occupies up to 0.4 (40%) of the width + * + * @param - should be in the range 0.0 to 1.0 + */ +// @UiThread +// public void setScaleWidth(@FloatRange(from = 0f, to = 1f) float width) { +// scaleView.setWidth(width); +// } + + /** + * Returns the width of the scaleView + * + * @return The width as a fraction of the display width + */ +// public float getScaleWidth() { +// return scaleView.getWidth(); +// } + + /** + *

+ * Sets the unit to use when displaying the scale. Choices are KM, MILE or NM + *

+ * By default, the unit used is km + * + * @param + * @see ScaleUnit {@link ScaleUnit} + */ +// @UiThread +// public void setScaleUnit(ScaleUnit unit) { +// scaleView.setScaleUnit(unit); +// } + + /** + * Returns the unit currently used for the scale + * + * @return The ScaleUnit + */ +// public ScaleUnit getScaleUnit() { +// return scaleView.getScaleUnit(); +// } + + /** + * Sets the margins of the scale view. Use this to change the distance of the scale from the + * map view edge. + * + * @param left The left margin in pixels. + * @param top The top margin in pixels. + * @param right The right margin in pixels. + * @param bottom The bottom margin in pixels. + */ + @UiThread + public void setScaleMargins(int left, int top, int right, int bottom) { + setWidgetMargins(scaleView, left, top, right, bottom); + } + + /** + * Returns the left side margin of MapScaleView + * + * @return The left margin in pixels + */ + public int getScaleMarginLeft() { + return ((FrameLayout.LayoutParams) scaleView.getLayoutParams()).leftMargin; + } + + /** + * Returns the top side margin of MapScaleView + * + * @return The top margin in pixels + */ + public int getScaleMarginTop() { + return ((FrameLayout.LayoutParams) scaleView.getLayoutParams()).topMargin; + } + + /** + * Returns the right side margin of MapScaleView + * + * @return The right margin in pixels + */ + public int getScaleMarginRight() { + return ((FrameLayout.LayoutParams) scaleView.getLayoutParams()).rightMargin; + } + + /** + * Returns the bottom side margin of MapScaleView + * + * @return The bottom margin in pixels + */ + public int getScaleMarginBottom() { + return ((FrameLayout.LayoutParams) scaleView.getLayoutParams()).bottomMargin; + } + + /** + *

+ * Enables or disables the Mapbox logo. + *

+ * By default, the compass is enabled. + * + * @param enabled True to enable the logo; false to disable the logo. + */ + public void setLogoEnabled(boolean enabled) { + logoView.setVisibility(enabled ? View.VISIBLE : View.GONE); + } + + /** + * Returns whether the logo is enabled. + * + * @return True if the logo is enabled; false if the logo is disabled. + */ + public boolean isLogoEnabled() { + return logoView.getVisibility() == View.VISIBLE; + } + + /** + *

+ * Sets the gravity of the logo view. Use this to change the corner of the map view that the + * Mapbox logo is displayed in. + *

+ * By default, the logo is in the bottom left corner. + * + * @param gravity One of the values from {@link Gravity}. + * @see Gravity + */ + public void setLogoGravity(int gravity) { + setWidgetGravity(logoView, gravity); + } + + /** + * Returns the gravity value of the logo + * + * @return The gravity + */ + public int getLogoGravity() { + return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).gravity; + } + + /** + * Sets the margins of the logo view. Use this to change the distance of the Mapbox logo from the + * map view edge. + * + * @param left The left margin in pixels. + * @param top The top margin in pixels. + * @param right The right margin in pixels. + * @param bottom The bottom margin in pixels. + */ + public void setLogoMargins(int left, int top, int right, int bottom) { + setWidgetMargins(logoView, left, top, right, bottom); + } + + /** + * Returns the left side margin of the logo + * + * @return The left margin in pixels + */ + public int getLogoMarginLeft() { + return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).leftMargin; + } + + /** + * Returns the top side margin of the logo + * + * @return The top margin in pixels + */ + public int getLogoMarginTop() { + return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).topMargin; + } + + /** + * Returns the right side margin of the logo + * + * @return The right margin in pixels + */ + public int getLogoMarginRight() { + return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).rightMargin; + } + + /** + * Returns the bottom side margin of the logo + * + * @return The bottom margin in pixels + */ + public int getLogoMarginBottom() { + return ((FrameLayout.LayoutParams) logoView.getLayoutParams()).bottomMargin; + } + + /** + *

+ * Enables or disables the attribution. + *

+ * By default, the attribution is enabled. + * + * @param enabled True to enable the attribution; false to disable the attribution. + */ + public void setAttributionEnabled(boolean enabled) { + attributionsView.setVisibility(enabled ? View.VISIBLE : View.GONE); + } + + /** + * Returns whether the attribution is enabled. + * + * @return True if the attribution is enabled; false if the attribution is disabled. + */ + public boolean isAttributionEnabled() { + return attributionsView.getVisibility() == View.VISIBLE; + } + + /** + *

+ * Sets the gravity of the attribution. + *

+ * By default, the attribution is in the bottom left corner next to the Mapbox logo. + * + * @param gravity One of the values from {@link Gravity}. + * @see Gravity + */ + public void setAttributionGravity(int gravity) { + setWidgetGravity(attributionsView, gravity); + } + + /** + * Returns the gravity value of the logo + * + * @return The gravity + */ + public int getAttributionGravity() { + return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).gravity; + } + + /** + * Sets the margins of the attribution view. + * + * @param left The left margin in pixels. + * @param top The top margin in pixels. + * @param right The right margin in pixels. + * @param bottom The bottom margin in pixels. + */ + public void setAttributionMargins(int left, int top, int right, int bottom) { + setWidgetMargins(attributionsView, left, top, right, bottom); + } + + /** + *

+ * Sets the tint of the attribution view. Use this to change the color of the attribution. + *

+ * By default, the logo is tinted with the primary color of your theme. + * + * @param tintColor Color to tint the attribution. + */ + public void setAttributionTintColor(@ColorInt int tintColor) { + // Check that the tint color being passed in isn't transparent. + if (Color.alpha(tintColor) == 0) { + ColorUtils.setTintList(attributionsView, + ContextCompat.getColor(attributionsView.getContext(), R.color.mapbox_blue)); + } else { + ColorUtils.setTintList(attributionsView, tintColor); + } + } + + /** + * Returns the left side margin of the attribution view. + * + * @return The left margin in pixels + */ + public int getAttributionMarginLeft() { + return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).leftMargin; + } + + /** + * Returns the top side margin of the attribution view. + * + * @return The top margin in pixels + */ + public int getAttributionMarginTop() { + return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).topMargin; + } + + /** + * Returns the right side margin of the attribution view. + * + * @return The right margin in pixels + */ + public int getAttributionMarginRight() { + return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).rightMargin; + } + + /** + * Returns the bottom side margin of the logo + * + * @return The bottom margin in pixels + */ + public int getAttributionMarginBottom() { + return ((FrameLayout.LayoutParams) attributionsView.getLayoutParams()).bottomMargin; + } + + /** + *

+ * Changes whether the user may rotate the map. + *

+ *

+ * This setting controls only user interactions with the map. If you set the value to false, + * you may still change the map location programmatically. + *

+ * The default value is true. + * + * @param rotateGesturesEnabled If true, rotating is enabled. + */ + public void setRotateGesturesEnabled(boolean rotateGesturesEnabled) { + if (rotateGestureChangeAllowed) { + this.rotateGesturesEnabled = rotateGesturesEnabled; + } + } + + /** + * Returns whether the user may rotate the map. + * + * @return If true, rotating is enabled. + */ + public boolean isRotateGesturesEnabled() { + return rotateGesturesEnabled; + } + + void setRotateGestureChangeAllowed(boolean rotateGestureChangeAllowed) { + this.rotateGestureChangeAllowed = rotateGestureChangeAllowed; + } + + boolean isRotateGestureChangeAllowed() { + return rotateGestureChangeAllowed; + } + + /** + *

+ * Changes whether the user may tilt the map. + *

+ *

+ * This setting controls only user interactions with the map. If you set the value to false, + * you may still change the map location programmatically. + *

+ * The default value is true. + * + * @param tiltGesturesEnabled If true, tilting is enabled. + */ + public void setTiltGesturesEnabled(boolean tiltGesturesEnabled) { + if (tiltGestureChangeAllowed) { + this.tiltGesturesEnabled = tiltGesturesEnabled; + } + } + + /** + * Returns whether the user may tilt the map. + * + * @return If true, tilting is enabled. + */ + public boolean isTiltGesturesEnabled() { + return tiltGesturesEnabled; + } + + void setTiltGestureChangeAllowed(boolean tiltGestureChangeAllowed) { + this.tiltGestureChangeAllowed = tiltGestureChangeAllowed; + } + + boolean isTiltGestureChangeAllowed() { + return tiltGestureChangeAllowed; + } + + /** + *

+ * Changes whether the user may zoom the map. + *

+ *

+ * This setting controls only user interactions with the map. If you set the value to false, + * you may still change the map location programmatically. + *

+ * The default value is true. + * + * @param zoomGesturesEnabled If true, zooming is enabled. + */ + public void setZoomGesturesEnabled(boolean zoomGesturesEnabled) { + if (zoomGestureChangeAllowed) { + this.zoomGesturesEnabled = zoomGesturesEnabled; + } + } + + /** + * Returns whether the user may zoom the map. + * + * @return If true, zooming is enabled. + */ + public boolean isZoomGesturesEnabled() { + return zoomGesturesEnabled; + } + + void setZoomGestureChangeAllowed(boolean zoomGestureChangeAllowed) { + this.zoomGestureChangeAllowed = zoomGestureChangeAllowed; + } + + boolean isZoomGestureChangeAllowed() { + return zoomGestureChangeAllowed; + } + + /** + *

+ * Sets whether the zoom controls are enabled. + * If enabled, the zoom controls are a pair of buttons + * (one for zooming in, one for zooming out) that appear on the screen. + * When pressed, they cause the camera to zoom in (or out) by one zoom level. + * If disabled, the zoom controls are not shown. + *

+ * By default the zoom controls are enabled if the device is only single touch capable; + * + * @param zoomControlsEnabled If true, the zoom controls are enabled. + */ + public void setZoomControlsEnabled(boolean zoomControlsEnabled) { + this.zoomControlsEnabled = zoomControlsEnabled; + } + + /** + * Gets whether the zoom controls are enabled. + * + * @return If true, the zoom controls are enabled. + */ + public boolean isZoomControlsEnabled() { + return zoomControlsEnabled; + } + + /** + * Gets whether the markers are automatically deselected (and therefore, their infowindows + * closed) when a map tap is detected. + * + * @return If true, markers are deselected on a map tap. + */ + public boolean isDeselectMarkersOnTap() { + return deselectMarkersOnTap; + } + + /** + * Sets whether the markers are automatically deselected (and therefore, their infowindows + * closed) when a map tap is detected. + * + * @param deselectMarkersOnTap determines if markers should be deslected on tap + */ + public void setDeselectMarkersOnTap(boolean deselectMarkersOnTap) { + this.deselectMarkersOnTap = deselectMarkersOnTap; + } + + /** + *

+ * Changes whether the user may scroll around the map. + *

+ *

+ * This setting controls only user interactions with the map. If you set the value to false, + * you may still change the map location programmatically. + *

+ * The default value is true. + * + * @param scrollGesturesEnabled If true, scrolling is enabled. + */ + public void setScrollGesturesEnabled(boolean scrollGesturesEnabled) { + if (scrollGestureChangeAllowed) { + this.scrollGesturesEnabled = scrollGesturesEnabled; + } + } + + /** + * Returns whether the user may scroll around the map. + * + * @return If true, scrolling is enabled. + */ + public boolean isScrollGesturesEnabled() { + return scrollGesturesEnabled; + } + + void setScrollGestureChangeAllowed(boolean scrollGestureChangeAllowed) { + this.scrollGestureChangeAllowed = scrollGestureChangeAllowed; + } + + boolean isScrollGestureChangeAllowed() { + return scrollGestureChangeAllowed; + } + + /** + *

+ * Sets the preference for whether all gestures should be enabled or disabled. + *

+ *

+ * This setting controls only user interactions with the map. If you set the value to false, + * you may still change the map location programmatically. + *

+ * The default value is true. + * + * @param enabled If true, all gestures are available; otherwise, all gestures are disabled. + * @see #setZoomGesturesEnabled(boolean) ) + * @see #setScrollGesturesEnabled(boolean) + * @see #setRotateGesturesEnabled(boolean) + * @see #setTiltGesturesEnabled(boolean) + */ + public void setAllGesturesEnabled(boolean enabled) { + setScrollGesturesEnabled(enabled); + setRotateGesturesEnabled(enabled); + setTiltGesturesEnabled(enabled); + setZoomGesturesEnabled(enabled); + } + + /** + * Sets the focal point used as center for a gesture + * + * @param focalPoint the focal point to be used. + */ + public void setFocalPoint(@Nullable PointF focalPoint) { + this.userProvidedFocalPoint = focalPoint; + focalPointChangeListener.onFocalPointChanged(focalPoint); + } + + /** + * Returns the gesture focal point + * + * @return The focal point + */ + public PointF getFocalPoint() { + return userProvidedFocalPoint; + } + + /** + * Returns the measured height of the MapView + * + * @return height in pixels + */ + public float getHeight() { + return projection.getHeight(); + } + + /** + * Returns the measured width of the MapView + * + * @return widht in pixels + */ + public float getWidth() { + return projection.getWidth(); + } + + float getPixelRatio() { + return pixelRatio; + } + + /** + * Invalidates the ViewSettings instances shown on top of the MapView + */ + public void invalidate() { + setScaleMargins(getScaleMarginLeft(), getScaleMarginTop(), getScaleMarginRight(), getScaleMarginBottom()); + setLogoMargins(getLogoMarginLeft(), getLogoMarginTop(), getLogoMarginRight(), getLogoMarginBottom()); + setCompassMargins(getCompassMarginLeft(), getCompassMarginTop(), getCompassMarginRight(), getCompassMarginBottom()); + setAttributionMargins(getAttributionMarginLeft(), getAttributionMarginTop(), getAttributionMarginRight(), + getAttributionMarginBottom()); + } + + private void setWidgetGravity(@NonNull final View view, int gravity) { + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams(); + layoutParams.gravity = gravity; + view.setLayoutParams(layoutParams); + } + + private void setWidgetMargins(@NonNull final View view, int left, int top, int right, int bottom) { + int[] contentPadding = projection.getContentPadding(); + FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) view.getLayoutParams(); + left += contentPadding[0]; + top += contentPadding[1]; + right += contentPadding[2]; + bottom += contentPadding[3]; + layoutParams.setMargins(left, top, right, bottom); + view.setLayoutParams(layoutParams); + } + + /** + * Choices for the distance unit displayed on the map scale. + */ + + public enum ScaleUnit { + KM("km", 1000.0f), // kilometer + MILE("mi", 1609.344f), // statute mile + NM("nm", 1852.0f); // nautical mile + + ScaleUnit(String unit, float ratio) { + this.unit = unit; + this.ratio = ratio; + } + + /** + * The string to display as the unit name. + */ + public String unit; + /** + * The number of meters in one of these units. + * Convert meters to this unit by dividing by the ratio. + */ + + public float ratio; + } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/DistanceUtils.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/DistanceUtils.java new file mode 100644 index 0000000000..9a3b2da415 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/DistanceUtils.java @@ -0,0 +1,34 @@ +package com.mapbox.mapboxsdk.maps.widgets.scaleview; + + +import com.mapbox.mapboxsdk.geometry.LatLng; + +public class DistanceUtils { + + public static final double EARTH = 6371.137; //Radius of the Earth in km + + public static LatLng translatePoint(LatLng point, double distance, double bearing) { + distance = distance / 1000d; + + //converts the Latitude, Longitude and bearings into radians + double lat = Math.toRadians(point.getLatitude()); + double lng = Math.toRadians(point.getLongitude()); + bearing = Math.toRadians(bearing); + + //Give the distance and the first Latitude, computes the second latitude + double Lat2 = Math.asin((Math.sin(lat) * Math.cos(distance / EARTH)) + + (Math.cos(lat) * Math.sin(distance / EARTH) * Math.cos(bearing))); + + //Give the distance and the first longitude, computes the second longitude + double Long2 = lng + Math.atan2(Math.sin(bearing) * Math.sin(distance / EARTH) * Math.cos(lat), + Math.cos(distance / EARTH) - (Math.sin(lat) * Math.sin(Lat2))); + + //Converting the new Latitude and Longitude from radians to degrees + Lat2 = Math.toDegrees(Lat2); + Long2 = Math.toDegrees(Long2); + + //Creates a point object to return back. X is the longitude, Y is the Latitude + return new LatLng(Lat2, Long2); + } + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/MapScaleModel.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/MapScaleModel.java new file mode 100644 index 0000000000..2245d1d40a --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/MapScaleModel.java @@ -0,0 +1,57 @@ +package com.mapbox.mapboxsdk.maps.widgets.scaleview; + +import android.graphics.PointF; + +import com.mapbox.mapboxsdk.camera.CameraPosition; +import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.Projection; + + +class MapScaleModel { + + private final int[] meters = { + 150,350,700, 1500, 2500, 5000, 10000, 20000, 40000, 100000, 150000, 350000, 700000, 1500000, 2500000}; + + private final LatLng src = new LatLng(31, 121); + + private int maxWidth; + + private double zoom = -1; + private Scale scale; + + MapScaleModel() { + } + + void setMaxWidth(int width) { + maxWidth = width; + } + + Scale setProjection(Projection projection, CameraPosition cameraPosition) { + if (zoom == cameraPosition.zoom) return scale; + + int distance = 0; + int distanceIndex = meters.length; + double screenDistance = maxWidth + 1; + + while (screenDistance > maxWidth && distanceIndex > 0) { + distance = meters[--distanceIndex]; + + LatLng dest = DistanceUtils.translatePoint(src, distance, 120); + + PointF pointSrc = projection.toScreenLocation(src); + PointF pointDest = projection.toScreenLocation(dest); + + screenDistance = Math.sqrt(Math.pow(pointSrc.x - pointDest.x, 2) + Math.pow(pointSrc.y - pointDest.y, 2)); + } + + zoom = cameraPosition.zoom; + scale = new Scale(text(distance), (float) screenDistance); + + return scale; + } + + private String text(int distance) { + if (distance < 1000) return distance + " m"; + else return distance / 1000 + " km"; + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/MapScaleView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/MapScaleView.java new file mode 100644 index 0000000000..02cb09a575 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/MapScaleView.java @@ -0,0 +1,114 @@ +package com.mapbox.mapboxsdk.maps.widgets.scaleview; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.view.View; + +import com.mapbox.mapboxsdk.camera.CameraPosition; +import com.mapbox.mapboxsdk.maps.Projection; + + +public class MapScaleView extends View { + + private final Paint paint; + private final ViewConfig viewConfig; + private final MapScaleModel mapScaleModel; + + private final float textHeight; + private final float strokeWidth; + private final float horizontalLineY; + + private Scale scale; + + public MapScaleView(Context context) { + this(context, null); + } + + public MapScaleView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public MapScaleView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + + mapScaleModel = new MapScaleModel(); + + viewConfig = new ViewConfig(context, attrs); + + paint = new Paint(); + paint.setAntiAlias(true); + paint.setTextSize(viewConfig.textSize); + paint.setStrokeWidth(viewConfig.strokeWidth); + paint.setColor(viewConfig.color); + + strokeWidth = viewConfig.strokeWidth; + + Rect textRect = new Rect(); + paint.getTextBounds("A", 0, 1, textRect); + textHeight = textRect.height(); + + horizontalLineY = textHeight + textHeight / 2; + } + + public void update(Projection projection, CameraPosition cameraPosition) { + scale = mapScaleModel.setProjection(projection, cameraPosition); + invalidate(); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int width = measureDimension(desiredWidth(), widthMeasureSpec); + int height = measureDimension(desiredHeight(), heightMeasureSpec); + + mapScaleModel.setMaxWidth(width); + + setMeasuredDimension(width, height); + } + + private int desiredWidth() { + return viewConfig.desiredWidth; + } + + private int desiredHeight() { + return (int) (paint.getTextSize() * 1.5 + paint.getStrokeWidth()); + } + + private int measureDimension(int desiredSize, int measureSpec) { + int mode = View.MeasureSpec.getMode(measureSpec); + int size = View.MeasureSpec.getSize(measureSpec); + + if (mode == View.MeasureSpec.EXACTLY) { + return size; + } else if (mode == View.MeasureSpec.AT_MOST) { + return Math.min(desiredSize, size); + } else { + return desiredSize; + } + } + + @Override + public void onDraw(Canvas canvas) { + canvas.save(); + + drawView(canvas, paint); + + canvas.restore(); + } + + private void drawView(Canvas canvas, Paint paint) { + if (scale == null) return; + + final float lineLength = scale.length(); + final String text = scale.text(); + + canvas.drawText(text, 0, textHeight, paint); + + float verticalLineX = lineLength - strokeWidth / 2; + + canvas.drawLine(0, horizontalLineY, lineLength, horizontalLineY, paint); + canvas.drawLine(verticalLineX, horizontalLineY, verticalLineX, textHeight, paint); + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/Scale.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/Scale.java new file mode 100644 index 0000000000..32cb867107 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/Scale.java @@ -0,0 +1,20 @@ +package com.mapbox.mapboxsdk.maps.widgets.scaleview; + +class Scale { + + private final String text; + private final float length; + + Scale(String text, float length) { + this.text = text; + this.length = length; + } + + public String text() { + return text; + } + + public float length() { + return length; + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/ViewConfig.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/ViewConfig.java new file mode 100644 index 0000000000..f1b5e9ad71 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/scaleview/ViewConfig.java @@ -0,0 +1,36 @@ +package com.mapbox.mapboxsdk.maps.widgets.scaleview; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.util.AttributeSet; + +import com.mapbox.mapboxsdk.R; + +class ViewConfig { + + final int color; + final float textSize; + final float strokeWidth; + + final int desiredWidth; + + + ViewConfig(Context context, AttributeSet attrs) { +// float fontScale = context.getResources().getDisplayMetrics().scaledDensity; + float density = context.getResources().getDisplayMetrics().density; + + desiredWidth = (int) (100 * density); + + TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.mapbox_MapView_MapScaleView, 0, 0); + try { + color = a.getColor(R.styleable.mapbox_MapView_MapScaleView_mapbox_uiScale_color, Color.parseColor("#333333")); + textSize = a.getDimension(R.styleable.mapbox_MapView_MapScaleView_mapbox_uiScale_textSize, 12 * density); + strokeWidth = a.getDimension(R.styleable.mapbox_MapView_MapScaleView_mapbox_uiScale_strokeWidth, 1.5f * density); + } finally { + a.recycle(); + } + + } + +} 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 index 4a0ef248b7..d1c681aa15 100644 --- 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 @@ -825,4 +825,4 @@ public class MapboxEventManager { return attempt * BASE_TIME; } } -} \ No newline at end of file +} -- cgit v1.2.1