summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml3
-rw-r--r--include/mbgl/storage/network_status.hpp5
-rw-r--r--include/mbgl/util/run_loop.hpp10
-rw-r--r--platform/android/CHANGELOG.md16
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java17
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java55
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Marker.java24
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java100
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java216
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewOptions.java10
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java189
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/location/LocationServices.java2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java20
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java97
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMapOptions.java10
-rwxr-xr-xplatform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java7
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java161
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java120
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEvent.java2
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/telemetry/MapboxEventManager.java13
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml4
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/layout/view_image_marker.xml5
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml1
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml7
-rw-r--r--platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java56
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java8
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java280
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java2
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java4
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java7
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ManualZoomActivity.java5
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java3
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java3
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/geocoding/GeocoderActivity.java7
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java13
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DoubleMapActivity.java5
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java6
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java4
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerViewOptions.java14
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerView.java18
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerViewOptions.java87
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/view_custom_marker.xml4
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml9
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerViewTest.java28
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettingsTest.java4
-rw-r--r--platform/android/bitrise.yml2
-rw-r--r--platform/android/src/async_task.cpp13
-rwxr-xr-xplatform/android/src/jni.cpp24
-rw-r--r--platform/android/src/run_loop_impl.hpp4
-rw-r--r--src/mbgl/geometry/glyph_atlas.hpp2
-rw-r--r--src/mbgl/geometry/vao.hpp4
-rw-r--r--src/mbgl/map/map.cpp2
-rw-r--r--src/mbgl/map/transform_state.cpp2
-rw-r--r--src/mbgl/renderer/bucket.hpp5
-rw-r--r--src/mbgl/sprite/sprite_atlas.hpp4
-rw-r--r--src/mbgl/storage/network_status.cpp2
-rw-r--r--src/mbgl/style/bucket_parameters.hpp6
-rw-r--r--src/mbgl/text/glyph_pbf.hpp4
-rw-r--r--src/mbgl/tile/tile_worker.cpp2
-rw-r--r--src/mbgl/tile/tile_worker.hpp6
-rw-r--r--src/mbgl/tile/vector_tile_data.hpp4
-rw-r--r--src/mbgl/util/atomic.hpp45
-rw-r--r--src/mbgl/util/math.cpp12
-rw-r--r--src/mbgl/util/math.hpp2
-rw-r--r--src/mbgl/util/thread.hpp1
66 files changed, 1170 insertions, 639 deletions
diff --git a/.travis.yml b/.travis.yml
index 5ae5baac60..eb779e2454 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -63,9 +63,6 @@ matrix:
- nvm use 4
- make node
- make test-node
- after_script:
- - ccache --show-stats
- - ./platform/node/scripts/after_script.sh ${TRAVIS_JOB_NUMBER} ${TRAVIS_TAG:-}
# GCC 5 - Debug - Coverage
- os: linux
diff --git a/include/mbgl/storage/network_status.hpp b/include/mbgl/storage/network_status.hpp
index d7f502a3b2..1b5471a44e 100644
--- a/include/mbgl/storage/network_status.hpp
+++ b/include/mbgl/storage/network_status.hpp
@@ -1,6 +1,7 @@
#pragma once
-#include <atomic>
+#include <mbgl/util/atomic.hpp>
+
#include <mutex>
#include <set>
@@ -26,7 +27,7 @@ public:
static void Unsubscribe(util::AsyncTask* async);
private:
- static std::atomic<bool> online;
+ static util::Atomic<bool> online;
static std::mutex mtx;
static std::set<util::AsyncTask*> observers;
};
diff --git a/include/mbgl/util/run_loop.hpp b/include/mbgl/util/run_loop.hpp
index 9703fe7bcb..56965c97e6 100644
--- a/include/mbgl/util/run_loop.hpp
+++ b/include/mbgl/util/run_loop.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include <mbgl/util/atomic.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/util.hpp>
#include <mbgl/util/work_task.hpp>
@@ -9,7 +10,6 @@
#include <utility>
#include <queue>
#include <mutex>
-#include <atomic>
namespace mbgl {
namespace util {
@@ -59,7 +59,7 @@ public:
template <class Fn, class... Args>
std::unique_ptr<AsyncRequest>
invokeCancellable(Fn&& fn, Args&&... args) {
- auto flag = std::make_shared<std::atomic<bool>>();
+ auto flag = std::make_shared<util::Atomic<bool>>();
*flag = false;
auto tuple = std::make_tuple(std::move(args)...);
@@ -77,7 +77,7 @@ public:
template <class Fn, class Cb, class... Args>
std::unique_ptr<AsyncRequest>
invokeWithCallback(Fn&& fn, Cb&& callback, Args&&... args) {
- auto flag = std::make_shared<std::atomic<bool>>();
+ auto flag = std::make_shared<util::Atomic<bool>>();
*flag = false;
// Create a lambda L1 that invokes another lambda L2 on the current RunLoop R, that calls
@@ -114,7 +114,7 @@ private:
template <class F, class P>
class Invoker : public WorkTask {
public:
- Invoker(F&& f, P&& p, std::shared_ptr<std::atomic<bool>> canceled_ = nullptr)
+ Invoker(F&& f, P&& p, std::shared_ptr<util::Atomic<bool>> canceled_ = nullptr)
: canceled(std::move(canceled_)),
func(std::move(f)),
params(std::move(p)) {
@@ -148,7 +148,7 @@ private:
}
std::recursive_mutex mutex;
- std::shared_ptr<std::atomic<bool>> canceled;
+ std::shared_ptr<util::Atomic<bool>> canceled;
F func;
P params;
diff --git a/platform/android/CHANGELOG.md b/platform/android/CHANGELOG.md
index f73c5ba198..aac115c5d2 100644
--- a/platform/android/CHANGELOG.md
+++ b/platform/android/CHANGELOG.md
@@ -2,6 +2,22 @@
Mapbox welcomes participation and contributions from everyone. If you'd like to do so please see the [`Contributing Guide`](https://github.com/mapbox/mapbox-gl-native/blob/master/CONTRIBUTING.md) first to get started.
+## 4.1.0-beta.2
+
+* Dynamically Update InfoWindow ([#5237](https://github.com/mapbox/mapbox-gl-native/issues/5237))
+* armeabi ABI Work On armv7 Devices ([#3985](https://github.com/mapbox/mapbox-gl-native/issues/3985))
+* Remove Adapter Requirement For MarkerView ([#5214](https://github.com/mapbox/mapbox-gl-native/issues/5214))
+* Always Current Version Style URL Constants ([#5193](https://github.com/mapbox/mapbox-gl-native/issues/5193))
+* Random NullPointerException On Telemetry ([#5186](https://github.com/mapbox/mapbox-gl-native/issues/5186))
+
+## 4.1.0-beta.1
+
+Mapbox Android 4.1.0 builds off our ambitious 4.0.0 version with 3 major new features being released. To help us produce the highest quality SDK possible we're releasing an official Beta release first so that everyone has time to explore it and help hardened it before the official 4.1.0 Final Release.
+
+* View Based Annotations ([#3276](https://github.com/mapbox/mapbox-gl-native/issues/3276))
+* UserLocationView Refactor ([#4396](https://github.com/mapbox/mapbox-gl-native/issues/4396))
+* MapboxAccountManager ([#5004](https://github.com/mapbox/mapbox-gl-native/issues/5004))
+
## 4.0.1
Mapbox Android 4.0.1 is a patch release to make this bug fix available sooner.
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java
index 36d56591c8..3c4868c84b 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/Annotation.java
@@ -23,6 +23,7 @@ public abstract class Annotation implements Comparable<Annotation> {
*/
private long id = -1; // -1 unless added to a MapView
protected MapboxMap mapboxMap;
+ protected MapView mapView;
protected Annotation() {
}
@@ -68,6 +69,22 @@ public abstract class Annotation implements Comparable<Annotation> {
return mapboxMap;
}
+ /**
+ * Don not use this method. Used internally by the SDK.
+ */
+ public void setMapView(MapView mapView) {
+ this.mapView = mapView;
+ }
+
+ /**
+ * Gets the associated MapView
+ *
+ * @return The MapView
+ */
+ protected MapView getMapView() {
+ return mapView;
+ }
+
@Override
public int compareTo(@NonNull Annotation annotation) {
if (id < annotation.getId()) {
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java
index 0cd54fc0f0..2a41fad234 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java
@@ -1,7 +1,7 @@
package com.mapbox.mapboxsdk.annotations;
import android.os.Parcelable;
-import android.support.annotation.AnimatorRes;
+import android.support.annotation.FloatRange;
import android.support.annotation.NonNull;
import com.mapbox.mapboxsdk.geometry.LatLng;
@@ -26,10 +26,9 @@ public abstract class BaseMarkerViewOptions<U extends MarkerView, T extends Base
protected float anchorV = 1f;
protected float infoWindowAnchorU = 0.5f;
protected float infoWindowAnchorV = 0.0f;
- protected int selectAnimRes;
- protected int deselectAnimRes;
- protected int rotation;
+ protected float rotation;
protected boolean visible = true;
+ protected boolean selected;
/**
* Default constructor
@@ -99,7 +98,7 @@ public abstract class BaseMarkerViewOptions<U extends MarkerView, T extends Base
* @param v the v-value
* @return the object for which the method was called
*/
- public T anchor(float u, float v) {
+ public T anchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
this.anchorU = u;
this.anchorV = v;
return getThis();
@@ -112,41 +111,19 @@ public abstract class BaseMarkerViewOptions<U extends MarkerView, T extends Base
* @param v the v-values
* @return the object for which the method was called
*/
- public T infoWindowAnchor(float u, float v) {
+ public T infoWindowAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
this.infoWindowAnchorU = u;
this.infoWindowAnchorV = v;
return getThis();
}
/**
- * Set the animator resource to be used when an MarkerView is selected.
- *
- * @param selectAnimRes the used animator resource
- * @return the object for which the method was called
- */
- public T selectAnimatorResource(@AnimatorRes int selectAnimRes) {
- this.selectAnimRes = selectAnimRes;
- return getThis();
- }
-
- /**
- * Set the animator resource to be used when an MarkerView is deselected.
- *
- * @param deselectAnimRes the used animator resource
- * @return the object for which the method was called
- */
- public T deselectAnimatorResource(@AnimatorRes int deselectAnimRes) {
- this.deselectAnimRes = deselectAnimRes;
- return getThis();
- }
-
- /**
* Set the rotation of the MarkerView.
*
* @param rotation the rotation value
* @return the object for which the method was called
*/
- public T rotation(int rotation) {
+ public T rotation(float rotation) {
this.rotation = rotation;
return getThis();
}
@@ -244,29 +221,11 @@ public abstract class BaseMarkerViewOptions<U extends MarkerView, T extends Base
}
/**
- * Get the animator resource used for selecting the MarkerView.
- *
- * @return the animator resource
- */
- public int getSelectAnimRes() {
- return selectAnimRes;
- }
-
- /**
- * Get the animator resource used for deselecting the MarkerView.
- *
- * @return the animator resource
- */
- public int getDeselectAnimRes() {
- return deselectAnimRes;
- }
-
- /**
* Get the rotation of the MarkerView.
*
* @return the rotation value
*/
- public int getRotation() {
+ public float getRotation() {
return rotation;
}
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 16b219684f..2d4ec4257e 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
@@ -3,7 +3,6 @@ package com.mapbox.mapboxsdk.annotations;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.View;
-
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
@@ -91,8 +90,9 @@ public class Marker extends Annotation {
}
}
- void setSnippet(String snippet) {
+ public void setSnippet(String snippet) {
this.snippet = snippet;
+ refreshInfoWindowContent();
}
/**
@@ -112,8 +112,25 @@ public class Marker extends Annotation {
return icon;
}
- void setTitle(String title) {
+ public void setTitle(String title) {
this.title = title;
+ refreshInfoWindowContent();
+ }
+
+ /**
+ * Update only for default Marker's InfoWindow content for Title and Snippet
+ */
+ private void refreshInfoWindowContent() {
+ if (isInfoWindowShown() && mapView != null && mapboxMap != null && mapboxMap.getInfoWindowAdapter() == null) {
+ InfoWindow infoWindow = getInfoWindow(mapView);
+ if (mapView.getContext() != null) {
+ infoWindow.adaptDefaultMarker(this, mapboxMap, mapView);
+ }
+ MapboxMap map = getMapboxMap();
+ if (map != null) {
+ map.updateMarker(this);
+ }
+ }
}
/**
@@ -121,6 +138,7 @@ public class Marker extends Annotation {
*/
public InfoWindow showInfoWindow(@NonNull MapboxMap mapboxMap, @NonNull MapView mapView) {
setMapboxMap(mapboxMap);
+ setMapView(mapView);
MapboxMap.InfoWindowAdapter infoWindowAdapter = getMapboxMap().getInfoWindowAdapter();
if (infoWindowAdapter != null) {
// end developer is using a custom InfoWindowAdapter
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 3e51044643..49d7a061d0 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
@@ -1,5 +1,12 @@
package com.mapbox.mapboxsdk.annotations;
+import android.graphics.Bitmap;
+import android.support.annotation.FloatRange;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.view.View;
+
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.maps.MapboxMap;
/**
@@ -28,13 +35,14 @@ public class MarkerView extends Marker {
private boolean flat;
private boolean visible = true;
- private int selectAnimRes;
- private int deselectAnimRes;
-
private float tiltValue;
private float rotation;
private float alpha = 1;
+ private Icon markerViewIcon;
+
+ private boolean selected;
+
/**
* Publicly hidden default constructor
*/
@@ -53,12 +61,11 @@ public class MarkerView extends Marker {
this.infoWindowAnchorU = baseMarkerViewOptions.getInfoWindowAnchorU();
this.infoWindowAnchorV = baseMarkerViewOptions.getInfoWindowAnchorV();
this.flat = baseMarkerViewOptions.isFlat();
- this.selectAnimRes = baseMarkerViewOptions.getSelectAnimRes();
- this.deselectAnimRes = baseMarkerViewOptions.getDeselectAnimRes();
this.infoWindowAnchorU = baseMarkerViewOptions.infoWindowAnchorU;
this.infoWindowAnchorV = baseMarkerViewOptions.infoWindowAnchorV;
this.anchorU = baseMarkerViewOptions.anchorU;
this.anchorV = baseMarkerViewOptions.anchorV;
+ this.selected = baseMarkerViewOptions.selected;
}
/**
@@ -71,7 +78,7 @@ public class MarkerView extends Marker {
* @param u u-coordinate of the anchor, as a ratio of the image width (in the range [0, 1])
* @param v v-coordinate of the anchor, as a ratio of the image height (in the range [0, 1])
*/
- public void setAnchor(float u, float v) {
+ public void setAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
this.anchorU = u;
this.anchorV = v;
}
@@ -149,7 +156,7 @@ public class MarkerView extends Marker {
* @param v v-coordinate of the info window anchor, as a ratio of the image height (in the range [0, 1])
* @see #setAnchor(float, float) for more details.
*/
- public void setInfoWindowAnchor(float u, float v) {
+ public void setInfoWindowAnchor(@FloatRange(from = 0.0, to = 1.0) float u, @FloatRange(from = 0.0, to = 1.0) float v) {
this.infoWindowAnchorU = u;
this.infoWindowAnchorV = v;
}
@@ -191,42 +198,6 @@ public class MarkerView extends Marker {
}
/**
- * Get the animator resource used to animate to the selected state of a MarkerView.
- *
- * @return the animator resource used
- */
- public int getSelectAnimRes() {
- return selectAnimRes;
- }
-
- /**
- * Set the animator resource used to animate to the deselected state of a MarkerView.
- *
- * @param selectAnimRes the animator resource used
- */
- public void setSelectAnimRes(int selectAnimRes) {
- this.selectAnimRes = selectAnimRes;
- }
-
- /**
- * Get the animator resource used to animate to the deslected state of a MarkerView.
- *
- * @return the animator resource used
- */
- public int getDeselectAnimRes() {
- return deselectAnimRes;
- }
-
- /**
- * Set the animator resource used to animate to the selected state of a MarkerView.
- *
- * @param deselectAnimRes the animator resource used
- */
- public void setDeselectAnimRes(int deselectAnimRes) {
- this.deselectAnimRes = deselectAnimRes;
- }
-
- /**
* Internal method to get the current tilted value of a MarkerView.
*
* @return the tilted value
@@ -240,7 +211,7 @@ public class MarkerView extends Marker {
*
* @param tiltValue the tilted value to set
*/
- void setTilt(float tiltValue) {
+ void setTilt(@FloatRange(from = 0.0, to = MapboxConstants.MAXIMUM_TILT) float tiltValue) {
this.tiltValue = tiltValue;
}
@@ -308,7 +279,7 @@ public class MarkerView extends Marker {
*
* @param alpha the alpha value to animate to
*/
- public void setAlpha(float alpha) {
+ public void setAlpha(@FloatRange(from=0.0, to=255.0)float alpha) {
this.alpha = alpha;
if (markerViewManager != null) {
markerViewManager.animateAlpha(this, alpha);
@@ -316,6 +287,45 @@ public class MarkerView extends Marker {
}
/**
+ * Set the icon of the MarkerView.
+ *
+ * @param icon the icon to be used as Marker image
+ */
+ @Override
+ public void setIcon(@Nullable Icon icon) {
+ if (icon != null) {
+ markerViewIcon = IconFactory.recreate("icon", icon.getBitmap());
+ }
+ Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
+ Icon transparentIcon = IconFactory.recreate("markerViewSettings", bitmap);
+ if (markerViewManager != null) {
+ markerViewManager.updateIcon(this);
+ }
+ super.setIcon(transparentIcon);
+ }
+
+ public boolean isSelected() {
+ return selected;
+ }
+
+ /**
+ * For internal use only, use {@link MapboxMap#selectMarker(Marker)} instead.
+ */
+ void setSelected(boolean selected) {
+ this.selected = selected;
+ }
+
+ /**
+ * Get the icon of the MarkerView.
+ *
+ * @return the icon use as Marker image
+ */
+ @Override
+ public Icon getIcon() {
+ return markerViewIcon;
+ }
+
+ /**
* Set the MapboxMap associated tot the MapView containing the MarkerView.
* <p>
* This method is used to instantiate the MarkerView and provide an instance of {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter}
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 d9fc9e62ae..bcb3176bfd 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
@@ -1,12 +1,17 @@
package com.mapbox.mapboxsdk.annotations;
+import android.content.Context;
import android.graphics.PointF;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.util.Pools;
+import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.Projection;
@@ -26,12 +31,13 @@ import java.util.Map;
*/
public class MarkerViewManager {
- private Map<MarkerView, View> mMarkerViewMap;
+ private Map<MarkerView, View> markerViewMap;
private MapboxMap mapboxMap;
private MapView mapView;
private List<MapboxMap.MarkerViewAdapter> markerViewAdapters;
- private long mViewMarkerBoundsUpdateTime;
+ private long viewMarkerBoundsUpdateTime;
private MapboxMap.OnMarkerViewClickListener onMarkerViewClickListener;
+ private ImageMarkerViewAdapter defaultMarkerViewAdapter;
/**
* Creates an instance of MarkerViewManager.
@@ -43,7 +49,9 @@ public class MarkerViewManager {
this.mapboxMap = mapboxMap;
this.markerViewAdapters = new ArrayList<>();
this.mapView = mapView;
- mMarkerViewMap = new HashMap<>();
+ this.markerViewMap = new HashMap<>();
+ this.defaultMarkerViewAdapter = new ImageMarkerViewAdapter(mapView.getContext());
+ this.markerViewAdapters.add(defaultMarkerViewAdapter);
}
/**
@@ -56,7 +64,7 @@ public class MarkerViewManager {
* @param rotation the rotation value
*/
public void animateRotation(@NonNull MarkerView marker, float rotation) {
- View convertView = mMarkerViewMap.get(marker);
+ View convertView = markerViewMap.get(marker);
if (convertView != null) {
AnimatorUtils.rotate(convertView, rotation);
}
@@ -72,7 +80,7 @@ public class MarkerViewManager {
* @param alpha the alpha value
*/
public void animateAlpha(@NonNull MarkerView marker, float alpha) {
- View convertView = mMarkerViewMap.get(marker);
+ View convertView = markerViewMap.get(marker);
if (convertView != null) {
AnimatorUtils.alpha(convertView, alpha);
}
@@ -88,7 +96,7 @@ public class MarkerViewManager {
* @param visible the flag indicating if MarkerView is visible
*/
public void animateVisible(@NonNull MarkerView marker, boolean visible) {
- View convertView = mMarkerViewMap.get(marker);
+ View convertView = markerViewMap.get(marker);
if (convertView != null) {
convertView.setVisibility(visible ? View.VISIBLE : View.GONE);
}
@@ -104,8 +112,8 @@ public class MarkerViewManager {
*/
public void update() {
View convertView;
- for (MarkerView marker : mMarkerViewMap.keySet()) {
- convertView = mMarkerViewMap.get(marker);
+ for (MarkerView marker : markerViewMap.keySet()) {
+ convertView = markerViewMap.get(marker);
if (convertView != null) {
PointF point = mapboxMap.getProjection().toScreenLocation(marker.getPosition());
int x = (int) (marker.getAnchorU() * convertView.getMeasuredWidth());
@@ -133,9 +141,9 @@ public class MarkerViewManager {
*/
public void setTilt(float tilt) {
View convertView;
- for (MarkerView markerView : mMarkerViewMap.keySet()) {
+ for (MarkerView markerView : markerViewMap.keySet()) {
if (markerView.isFlat()) {
- convertView = mMarkerViewMap.get(markerView);
+ convertView = markerViewMap.get(markerView);
if (convertView != null) {
markerView.setTilt(tilt);
convertView.setRotationX(tilt);
@@ -145,69 +153,118 @@ public class MarkerViewManager {
}
/**
+ *
+ */
+ public void updateIcon(@NonNull MarkerView markerView) {
+ View convertView = markerViewMap.get(markerView);
+ if (convertView != null && convertView instanceof ImageView) {
+ ((ImageView) convertView).setImageBitmap(markerView.getIcon().getBitmap());
+ }
+ }
+
+ /**
* Animate a MarkerView to a deselected state.
* <p>
- * The {@link MarkerView#getDeselectAnimRes()} will be called to get the related animation.
- * If non are provided, no animation will be started.
+ * The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onDeselect(MarkerView, View)} will be called to execute an animation.
* </p>
*
* @param marker the MarkerView to deselect
*/
public void deselect(@NonNull MarkerView marker) {
- final View convertView = mMarkerViewMap.get(marker);
+ final View convertView = markerViewMap.get(marker);
+ if (convertView != null) {
+ for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
+ if (adapter.getMarkerClass().equals(marker.getClass())) {
+ adapter.onDeselect(marker, convertView);
+ }
+ }
+ }
+ }
+
+ /**
+ * Animate a MarkerView to a selected state.
+ *
+ * @param marker the MarkerView object to select
+ */
+ public void select(@NonNull MarkerView marker) {
+ final View convertView = markerViewMap.get(marker);
+ for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
+ if (adapter.getMarkerClass().equals(marker.getClass())) {
+ select(marker, convertView, adapter);
+ }
+ }
+ }
+
+ /**
+ * Animate a MarkerView to a selected state.
+ * <p>
+ * The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onSelect(MarkerView, View, boolean)} will be called to execute an animation.
+ * </p>
+ * @param marker the MarkerView object to select
+ * @param convertView the View presentation of the MarkerView
+ * @param adapter the adapter used to adapt the marker to the convertView
+ */
+ public void select(@NonNull MarkerView marker, View convertView, MapboxMap.MarkerViewAdapter adapter) {
if (convertView != null) {
- int deselectAnimatorRes = marker.getDeselectAnimRes();
- if (deselectAnimatorRes != 0) {
- AnimatorUtils.animate(convertView, deselectAnimatorRes);
+ if (adapter.onSelect(marker, convertView, false)) {
+ mapboxMap.selectMarker(marker);
}
+ marker.setSelected(true);
}
}
/**
+ * Get view representation from a MarkerView.
+ * <p>
+ * If marker is not found in current viewport, null is returned.
+ * </p>
+ *
+ * @param marker the marker to get the view for
+ * @return the android SDK View object
+ */
+ @Nullable
+ public View getView(MarkerView marker) {
+ return markerViewMap.get(marker);
+ }
+
+ /**
* Remove a MarkerView from a map.
* <p>
* The {@link MarkerView} will be removed using an alpha animation and related {@link View}
- * will be released to the {@link android.support.v4.util.Pools.SimplePool} from the related
+ * will be released to the android.support.v4.util.Pools.SimplePool from the related
* {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter}. It's possible to remove
* the {@link MarkerView} from the underlying collection if needed.
* </p>
*
- * @param marker the MarkerView to remove
- * @param removeFromMap flag indicating if a MarkerView will be removed from the collection.
+ * @param marker the MarkerView to remove
*/
- public void removeMarkerView(MarkerView marker, boolean removeFromMap) {
- final View viewHolder = mMarkerViewMap.get(marker);
+ public void removeMarkerView(MarkerView marker) {
+ final View viewHolder = markerViewMap.get(marker);
if (viewHolder != null && marker != null) {
for (final MapboxMap.MarkerViewAdapter<?> adapter : markerViewAdapters) {
- if (adapter.getMarkerClass() == marker.getClass()) {
-
- // get pool of Views associated to an adapter
- final Pools.SimplePool<View> viewPool = adapter.getViewReusePool();
-
- // cancel ongoing animations
- viewHolder.animate().cancel();
- viewHolder.setAlpha(1);
- AnimatorUtils.alpha(viewHolder, 0, new AnimatorUtils.OnAnimationEndListener() {
- @Override
- public void onAnimationEnd() {
- viewHolder.setVisibility(View.GONE);
- viewPool.release(viewHolder);
- }
- });
+ if (adapter.getMarkerClass().equals(marker.getClass())) {
+ if (adapter.prepareViewForReuse(marker, viewHolder)) {
+ adapter.releaseView(viewHolder);
+ }
}
}
}
- if (removeFromMap) {
- mMarkerViewMap.remove(marker);
- }
+ markerViewMap.remove(marker);
}
/**
- * Add a MarkerViewAdapter.
+ * Add a MarkerViewAdapter to the MarkerViewManager.
+ * <p>
+ * The provided MarkerViewAdapter must use supply a generic subclass of MarkerView.
+ * </p>
*
* @param markerViewAdapter the MarkerViewAdapter to add
*/
- public void addMarkerViewAdapter(@Nullable MapboxMap.MarkerViewAdapter markerViewAdapter) {
+ public void addMarkerViewAdapter(MapboxMap.MarkerViewAdapter markerViewAdapter) {
+ if (markerViewAdapter.getMarkerClass().equals(MarkerView.class)) {
+ throw new RuntimeException("Providing a custom MarkerViewAdapter requires subclassing MarkerView");
+ }
+
if (!markerViewAdapters.contains(markerViewAdapter)) {
markerViewAdapters.add(markerViewAdapter);
invalidateViewMarkersInBounds();
@@ -223,7 +280,6 @@ public class MarkerViewManager {
return markerViewAdapters;
}
-
/**
* Register a callback to be invoked when this view is clicked.
*
@@ -243,11 +299,11 @@ public class MarkerViewManager {
public void scheduleViewMarkerInvalidation() {
if (!markerViewAdapters.isEmpty()) {
long currentTime = SystemClock.elapsedRealtime();
- if (currentTime < mViewMarkerBoundsUpdateTime) {
+ if (currentTime < viewMarkerBoundsUpdateTime) {
return;
}
invalidateViewMarkersInBounds();
- mViewMarkerBoundsUpdateTime = currentTime + 250;
+ viewMarkerBoundsUpdateTime = currentTime + 250;
}
}
@@ -264,26 +320,27 @@ public class MarkerViewManager {
View convertView;
// remove old markers
- Iterator<MarkerView> iterator = mMarkerViewMap.keySet().iterator();
+ Iterator<MarkerView> iterator = markerViewMap.keySet().iterator();
while (iterator.hasNext()) {
MarkerView m = iterator.next();
if (!markers.contains(m)) {
// remove marker
- convertView = mMarkerViewMap.get(m);
- int deselectAnimRes = m.getDeselectAnimRes();
- if (deselectAnimRes != 0) {
- AnimatorUtils.animate(convertView, deselectAnimRes, 0);
+ convertView = markerViewMap.get(m);
+ for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
+ if (adapter.getMarkerClass().equals(m.getClass())) {
+ adapter.prepareViewForReuse(m, convertView);
+ adapter.releaseView(convertView);
+ iterator.remove();
+ }
}
- removeMarkerView(m, false);
- iterator.remove();
}
}
// introduce new markers
for (final MarkerView marker : markers) {
- if (!mMarkerViewMap.containsKey(marker)) {
+ if (!markerViewMap.containsKey(marker)) {
for (final MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) {
- if (adapter.getMarkerClass() == marker.getClass()) {
+ if (adapter.getMarkerClass().equals(marker.getClass())) {
convertView = (View) adapter.getViewReusePool().acquire();
final View adaptedView = adapter.getView(marker, convertView, mapView);
if (adaptedView != null) {
@@ -303,13 +360,11 @@ public class MarkerViewManager {
if (mapboxMap.getSelectedMarkers().contains(marker)) {
// if a marker to be shown was selected
// replay that animation with duration 0
- int selectAnimRes = marker.getSelectAnimRes();
- if (selectAnimRes != 0) {
- AnimatorUtils.animate(convertView, selectAnimRes, 0);
+ if (adapter.onSelect(marker, adaptedView, true)) {
+ mapboxMap.selectMarker(marker);
}
}
- final int animSelectRes = marker.getSelectAnimRes();
adaptedView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View v) {
@@ -324,22 +379,12 @@ public class MarkerViewManager {
int infoWindowOffsetY = (int) ((adaptedView.getHeight() * marker.getInfoWindowAnchorV()) - marker.getOffsetY());
marker.setTopOffsetPixels(infoWindowOffsetY);
marker.setRightOffsetPixels(infoWindowOffsetX);
-
- if (animSelectRes != 0) {
- AnimatorUtils.animate(v, animSelectRes, new AnimatorUtils.OnAnimationEndListener() {
- @Override
- public void onAnimationEnd() {
- mapboxMap.selectMarker(marker);
- }
- });
- } else {
- mapboxMap.selectMarker(marker);
- }
+ select(marker, v, adapter);
}
}
});
- mMarkerViewMap.put(marker, adaptedView);
+ markerViewMap.put(marker, adaptedView);
if (convertView == null) {
mapView.addView(adaptedView);
}
@@ -349,4 +394,37 @@ public class MarkerViewManager {
}
}
}
+
+ /**
+ * Default MarkerViewAdapter used for base class of MarkerView to adapt a MarkerView to an ImageView
+ */
+ public static class ImageMarkerViewAdapter extends MapboxMap.MarkerViewAdapter<MarkerView> {
+
+ private LayoutInflater inflater;
+
+ public ImageMarkerViewAdapter(Context context) {
+ super(context);
+ inflater = LayoutInflater.from(context);
+ }
+
+ @Nullable
+ @Override
+ public View getView(@NonNull MarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
+ ViewHolder viewHolder;
+ if (convertView == null) {
+ viewHolder = new ViewHolder();
+ convertView = inflater.inflate(R.layout.view_image_marker, parent, false);
+ viewHolder.imageView = (ImageView) convertView.findViewById(R.id.image);
+ convertView.setTag(viewHolder);
+ } else {
+ viewHolder = (ViewHolder) convertView.getTag();
+ }
+ viewHolder.imageView.setImageBitmap(marker.getIcon().getBitmap());
+ return convertView;
+ }
+
+ private static class ViewHolder {
+ ImageView imageView;
+ }
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewOptions.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewOptions.java
index 0c9faed355..c6735a3c8d 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewOptions.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewOptions.java
@@ -28,9 +28,7 @@ public class MarkerViewOptions extends BaseMarkerViewOptions<MarkerView, MarkerV
flat(in.readByte() != 0);
anchor(in.readFloat(), in.readFloat());
infoWindowAnchor(in.readFloat(), in.readFloat());
- selectAnimatorResource(in.readInt());
- deselectAnimatorResource(in.readInt());
- rotation(in.readInt());
+ rotation(in.readFloat());
visible(in.readByte() != 0);
if (in.readByte() != 0) {
// this means we have an icon
@@ -61,9 +59,7 @@ public class MarkerViewOptions extends BaseMarkerViewOptions<MarkerView, MarkerV
out.writeFloat(getAnchorV());
out.writeFloat(getInfoWindowAnchorU());
out.writeFloat(getInfoWindowAnchorV());
- out.writeInt(getSelectAnimRes());
- out.writeInt(getDeselectAnimRes());
- out.writeInt(getRotation());
+ out.writeFloat(getRotation());
out.writeByte((byte) (isVisible() ? 1 : 0));
Icon icon = getIcon();
out.writeByte((byte) (icon != null ? 1 : 0));
@@ -82,8 +78,6 @@ public class MarkerViewOptions extends BaseMarkerViewOptions<MarkerView, MarkerV
marker.setFlat(flat);
marker.setAnchor(anchorU, anchorV);
marker.setInfoWindowAnchor(infoWindowAnchorU, infoWindowAnchorV);
- marker.setSelectAnimRes(selectAnimRes);
- marker.setDeselectAnimRes(deselectAnimRes);
marker.setRotation(rotation);
marker.setVisible(visible);
return marker;
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java
index aa24d58656..51eb038052 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java
+++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/Style.java
@@ -1,7 +1,9 @@
package com.mapbox.mapboxsdk.constants;
import android.support.annotation.StringDef;
+
import com.mapbox.mapboxsdk.maps.MapView;
+
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -15,169 +17,33 @@ import java.lang.annotation.RetentionPolicy;
*/
public class Style {
- /**
- * Mapbox Streets: A complete basemap, perfect for incorporating your own data.
- */
- private static final String MAPBOX_STREETS_BASE = "mapbox://styles/mapbox/streets-v%d";
- /**
- * Outdoors: A general-purpose style tailored to outdoor activities.
- */
- private static final String OUTDOORS_BASE = "mapbox://styles/mapbox/outdoors-v%d";
- /**
- * Light: Subtle light backdrop for data visualizations.
- */
- private static final String LIGHT_BASE = "mapbox://styles/mapbox/light-v%d";
- /**
- * Dark: Subtle dark backdrop for data visualizations.
- */
- private static final String DARK_BASE = "mapbox://styles/mapbox/dark-v%d";
- /**
- * Satellite: A beautiful global satellite and aerial imagery layer.
- */
- private static final String SATELLITE_BASE = "mapbox://styles/mapbox/satellite-v%d";
- /**
- * Satellite Streets: Global satellite and aerial imagery with unobtrusive labels.
- */
- private static final String SATELLITE_STREETS_BASE = "mapbox://styles/mapbox/satellite-streets-v%d";
-
- /**
- * Satellite Streets: Global satellite and aerial imagery with unobtrusive labels (Version 8).
- */
- private static final String SATELLITE_STREETS_V8 = "mapbox://styles/mapbox/satellite-hybrid-v8";
-
- /**
- * Get versioned url of Mapbox streets style.
- * <p>
- * <ul>
- * <li>Current default version is 9.</li>
- * </ul
- * </p>
- * <p>
- * More information on the Mapbox styles API can be found on https://www.mapbox.com/api-documentation/#styles
- * </p>
- *
- * @param version the version of the style.
- * @return uri to load style from
- */
- public static String getMapboxStreetsUrl(int version) {
- return String.format(MapboxConstants.MAPBOX_LOCALE, MAPBOX_STREETS_BASE, version);
- }
-
- /**
- * Get versioned url of Outdoors streets style.
- * <p>
- * <ul>
- * <li>Current version is 9.</li>
- * </ul>
- * </p>
- * <p>
- * More information on the Mapbox styles API can be found on https://www.mapbox.com/api-documentation/#styles
- * </p>
- *
- * @param version the version of the style.
- * @return uri to load style from
- */
- public static String getOutdoorsStyleUrl(int version) {
- return String.format(MapboxConstants.MAPBOX_LOCALE, OUTDOORS_BASE, version);
- }
-
- /**
- * Get versioned url of Light style.
- * <p>
- * <ul>
- * <li>Current default version is 9.</li>
- * </ul>
- * </p>
- * <p>
- * More information on the Mapbox styles API can be found on https://www.mapbox.com/api-documentation/#styles
- * </p>
- *
- * @param version the version of the style.
- * @return uri to load style from
- */
- public static String getLightStyleUrl(int version) {
- return String.format(MapboxConstants.MAPBOX_LOCALE, LIGHT_BASE, version);
- }
-
- /**
- * Get versioned url of Dark style.
- * <p>
- * <ul>
- * <li>Current default version is 9.</li>
- * </ul>
- * </p>
- * <p>
- * More information on the Mapbox styles API can be found on https://www.mapbox.com/api-documentation/#styles
- * </p>
- *
- * @param version the version of the style.
- * @return uri to load style from
- */
- public static String getDarkStyleUrl(int version) {
- return String.format(MapboxConstants.MAPBOX_LOCALE, DARK_BASE, version);
- }
-
- /**
- * Get versioned url of Satellite style.
- * <p>
- * <ul>
- * <li>Current version is 9.</li>
- * </ul>
- * </p>
- * <p>
- * More information on the Mapbox styles API can be found on https://www.mapbox.com/api-documentation/#styles
- * </p>
- *
- * @param version the version of the style.
- * @return uri to load style from
- */
- public static String getSatelliteStyleUrl(int version) {
- return String.format(MapboxConstants.MAPBOX_LOCALE, SATELLITE_BASE, version);
- }
/**
- * Get versioned url of Satellite streets style.
- * <p>
- * <ul>
- * <li>Current version is 9.</li>
- * </ul>
- * </p>
- * <p>
- * More information on the Mapbox styles API can be found on https://www.mapbox.com/api-documentation/#styles
- * </p>
- *
- * @param version the version of the style.
- * @return uri to load style from
+ * Indicates the parameter accepts one of the values from {@link Style}. Using one of these
+ * constants means your map style will always use the latest version and may change as we
+ * improve the style
*/
- public static String getSatelliteStreetsStyleUrl(int version) {
- if (version == 8) {
- return SATELLITE_STREETS_V8;
- }
- return String.format(MapboxConstants.MAPBOX_LOCALE, SATELLITE_STREETS_BASE, version);
- }
-
- /**
- * Indicates the parameter accepts one of the values from {@link Style}.
- *
- * @deprecated use dedicated versioned methods in {@link Style} instead.
- */
- @StringDef({MAPBOX_STREETS, EMERALD, LIGHT, DARK, SATELLITE, SATELLITE_STREETS})
+ @StringDef({MAPBOX_STREETS, OUTDOORS, EMERALD, LIGHT, DARK, SATELLITE, SATELLITE_STREETS})
@Retention(RetentionPolicy.SOURCE)
- @Deprecated
public @interface StyleUrl {
}
// IMPORTANT: If you change any of these you also need to edit them in strings.xml
/**
- * Mapbox Streets: A complete basemap, perfect for incorporating your own data.
- *
- * @deprecated use {@link #getMapboxStreetsUrl(int)} instead.
+ * Mapbox Streets: A complete basemap, perfect for incorporating your own data. Using this
+ * constant means your map style will always use the latest version and may change as we
+ * improve the style.
*/
- @Deprecated
public static final String MAPBOX_STREETS = "mapbox://styles/mapbox/streets-v9";
/**
+ * Outdoors: A general-purpose style tailored to outdoor activities. Using this constant means
+ * your map style will always use the latest version and may change as we improve the style.
+ */
+ public static final String OUTDOORS = "mapbox://styles/mapbox/outdoors-v9";
+
+ /**
* Emerald: A versatile style, with emphasis on road networks and public transit.
*
* @deprecated this style has been deprecated and will be removed in future versions.
@@ -186,34 +52,27 @@ public class Style {
public static final String EMERALD = "mapbox://styles/mapbox/emerald-v8";
/**
- * Light: Subtle light backdrop for data visualizations.
- *
- * @deprecated use {@link #getLightStyleUrl(int)} instead.
+ * Light: Subtle light backdrop for data visualizations. Using this constant means your map
+ * style will always use the latest version and may change as we improve the style.
*/
- @Deprecated
public static final String LIGHT = "mapbox://styles/mapbox/light-v9";
/**
- * Dark: Subtle dark backdrop for data visualizations.
- *
- * @deprecated use {@link #getDarkStyleUrl(int)} (int)} instead.
+ * Dark: Subtle dark backdrop for data visualizations. Using this constant means your map style
+ * will always use the latest version and may change as we improve the style.
*/
- @Deprecated
public static final String DARK = "mapbox://styles/mapbox/dark-v9";
/**
- * Satellite: A beautiful global satellite and aerial imagery layer.
- *
- * @deprecated use {@link #getSatelliteStyleUrl(int)} instead.
+ * Satellite: A beautiful global satellite and aerial imagery layer. Using this constant means
+ * your map style will always use the latest version and may change as we improve the style.
*/
- @Deprecated
public static final String SATELLITE = "mapbox://styles/mapbox/satellite-v9";
/**
- * Satellite Streets: Global satellite and aerial imagery with unobtrusive labels.
- *
- * @deprecated use {@link #getSatelliteStreetsStyleUrl(int)} (int)} instead.
+ * Satellite Streets: Global satellite and aerial imagery with unobtrusive labels. Using this
+ * constant means your map style will always use the latest version and may change as we
+ * improve the style.
*/
- @Deprecated
public static final String SATELLITE_STREETS = "mapbox://styles/mapbox/satellite-streets-v9";
}
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
index 08f18892d2..4fade484b4 100644
--- 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
@@ -18,12 +18,10 @@ import java.util.concurrent.CopyOnWriteArrayList;
/**
* Manages locational updates. Contains methods to register and unregister location listeners.
- * <p>
* <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/>
* <p>
* Note: If registering a listener in your Activity.onResume() implementation, you should unregister it in Activity.onPause().
* (You won't receive location updates when paused, and this will cut down on unnecessary system overhead).
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 b34b947a2a..68a2a47cf7 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
@@ -252,6 +252,7 @@ public class MapView extends FrameLayout {
CameraPosition position = options.getCamera();
if (position != null) {
mMapboxMap.moveCamera(CameraUpdateFactory.newCameraPosition(position));
+ mMyLocationView.setTilt(position.tilt);
}
String accessToken = null;
@@ -407,7 +408,6 @@ public class MapView extends FrameLayout {
// User location
try {
- //noinspection ResourceType
mMapboxMap.setMyLocationEnabled(savedInstanceState.getBoolean(MapboxConstants.STATE_MY_LOCATION_ENABLED));
} catch (SecurityException ignore) {
// User did not accept location permissions
@@ -445,6 +445,7 @@ public class MapView extends FrameLayout {
callback.onMapReady(mMapboxMap);
iterator.remove();
}
+ mMapboxMap.getMarkerViewManager().scheduleViewMarkerInvalidation();
}
} else if (change == REGION_IS_CHANGING || change == REGION_DID_CHANGE || change == DID_FINISH_LOADING_MAP) {
mMapboxMap.getMarkerViewManager().scheduleViewMarkerInvalidation();
@@ -672,11 +673,11 @@ public class MapView extends FrameLayout {
return mContentPaddingBottom;
}
- int getContentWidth(){
+ int getContentWidth() {
return getWidth() - mContentPaddingLeft - mContentPaddingRight;
}
- int getContentHeight(){
+ int getContentHeight() {
return getHeight() - mContentPaddingBottom - mContentPaddingTop;
}
@@ -783,7 +784,7 @@ public class MapView extends FrameLayout {
* <li>{@code asset://...}:
* reads the style from the APK {@code assets/} directory.
* This is used to load a style bundled with your app.</li>
- * <li>{@code null}: loads the default {@link Style#getMapboxStreetsUrl(int)} style.</li>
+ * <li>{@code null}: loads the default {@link Style#MAPBOX_STREETS} style.</li>
* </ul>
* <p>
* This method is asynchronous and will return immediately before the style finishes loading.
@@ -874,7 +875,7 @@ public class MapView extends FrameLayout {
* <p>
* DEPRECATED @see MapboxAccountManager#getAccessToken()
* </p>
- * <p/>
+ * <p>
* Returns the current Mapbox access token used to load map styles and tiles.
* </p>
*
@@ -993,7 +994,10 @@ public class MapView extends FrameLayout {
Log.w(MapboxConstants.TAG, "marker has an id of -1, possibly was not added yet, doing nothing");
}
- ensureIconLoaded(updatedMarker);
+ if (!(updatedMarker instanceof MarkerView)) {
+ ensureIconLoaded(updatedMarker);
+ }
+
mNativeMapView.updateMarker(updatedMarker);
}
@@ -1021,7 +1025,7 @@ public class MapView extends FrameLayout {
}
long addMarker(@NonNull Marker marker) {
- if(mDestroyed){
+ if (mDestroyed) {
return 0l;
}
return mNativeMapView.addMarker(marker);
@@ -2708,7 +2712,7 @@ public class MapView extends FrameLayout {
private boolean mDefaultStyle;
StyleInitializer(@NonNull Context context) {
- mStyle = Style.getMapboxStreetsUrl(context.getResources().getInteger(R.integer.style_version));
+ mStyle = Style.MAPBOX_STREETS;
mDefaultStyle = true;
}
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 fbe6a31f6a..3fbdebe2b7 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
@@ -20,7 +20,6 @@ import com.mapbox.mapboxsdk.annotations.Annotation;
import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
import com.mapbox.mapboxsdk.annotations.Icon;
-import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.InfoWindow;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
@@ -72,7 +71,6 @@ public class MapboxMap {
private List<InfoWindow> mInfoWindows;
private MapboxMap.InfoWindowAdapter mInfoWindowAdapter;
- private Bitmap mViewMarkerBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
private boolean mMyLocationEnabled;
private boolean mAllowConcurrentMultipleInfoWindows;
@@ -291,7 +289,7 @@ public class MapboxMap {
* it will return the current location of the camera in flight.
*
* @param update The change that should be applied to the camera.
- * @see {@link CameraUpdateFactory} for a set of updates.
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
@UiThread
public final void easeCamera(CameraUpdate update) {
@@ -306,7 +304,7 @@ public class MapboxMap {
* @param update The change that should be applied to the camera.
* @param durationMs The duration of the animation in milliseconds. This must be strictly
* positive, otherwise an IllegalArgumentException will be thrown.
- * @see {@link CameraUpdateFactory} for a set of updates.
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
@UiThread
public final void easeCamera(CameraUpdate update, int durationMs) {
@@ -327,7 +325,7 @@ public class MapboxMap {
* will be notified with onFinish(). If the animation stops due to interruption
* by a later camera movement or a user gesture, onCancel() will be called.
* Do not update or ease the camera from within onCancel().
- * @see {@link CameraUpdateFactory} for a set of camera updates.
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
@UiThread
public final void easeCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
@@ -368,7 +366,7 @@ public class MapboxMap {
* of the camera in flight.
*
* @param update The change that should be applied to the camera.
- * @see {@link CameraUpdateFactory} for a set of updates.
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
@UiThread
public final void animateCamera(CameraUpdate update) {
@@ -385,7 +383,7 @@ public class MapboxMap {
* @param callback The callback to invoke from the main thread when the animation stops. If the
* animation completes normally, onFinish() is called; otherwise, onCancel() is
* called. Do not update or animate the camera from within onCancel().
- * @see {@link CameraUpdateFactory} for a set of updates.
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
@UiThread
public final void animateCamera(CameraUpdate update, MapboxMap.CancelableCallback callback) {
@@ -401,7 +399,7 @@ public class MapboxMap {
* @param update The change that should be applied to the camera.
* @param durationMs The duration of the animation in milliseconds. This must be strictly
* positive, otherwise an IllegalArgumentException will be thrown.
- * @see {@link CameraUpdateFactory} for a set of updates.
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
@UiThread
public final void animateCamera(CameraUpdate update, int durationMs) {
@@ -424,7 +422,7 @@ public class MapboxMap {
* by a later camera movement or a user gesture, onCancel() will be called.
* Do not update or animate the camera from within onCancel(). If a callback
* isn't required, leave it as null.
- * @see {@link CameraUpdateFactory} for a set of updates.
+ * @see com.mapbox.mapboxsdk.camera.CameraUpdateFactory for a set of updates.
*/
@UiThread
public final void animateCamera(CameraUpdate update, int durationMs, final MapboxMap.CancelableCallback callback) {
@@ -550,7 +548,7 @@ public class MapboxMap {
* <li>{@code asset://...}:
* reads the style from the APK {@code assets/} directory.
* This is used to load a style bundled with your app.</li>
- * <li>{@code null}: loads the default {@link Style#getMapboxStreetsUrl(int)} style.</li>
+ * <li>{@code null}: loads the default {@link Style#MAPBOX_STREETS} style.</li>
* </ul>
* <p>
* This method is asynchronous and will return immediately before the style finishes loading.
@@ -703,10 +701,11 @@ public class MapboxMap {
@NonNull
public MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions) {
MarkerView marker = prepareViewMarker(markerOptions);
- long id = mMapView.addMarker(marker);
marker.setMapboxMap(this);
+ long id = mMapView.addMarker(marker);
marker.setId(id);
mAnnotations.put(id, marker);
+ mMarkerViewManager.invalidateViewMarkersInBounds();
return marker;
}
@@ -952,7 +951,7 @@ public class MapboxMap {
Marker marker = (Marker) annotation;
marker.hideInfoWindow();
if (marker instanceof MarkerView) {
- mMarkerViewManager.removeMarkerView((MarkerView) marker, true);
+ mMarkerViewManager.removeMarkerView((MarkerView) marker);
}
}
long id = annotation.getId();
@@ -986,7 +985,7 @@ public class MapboxMap {
Marker marker = (Marker) annotation;
marker.hideInfoWindow();
if (marker instanceof MarkerView) {
- mMarkerViewManager.removeMarkerView((MarkerView) marker, true);
+ mMarkerViewManager.removeMarkerView((MarkerView) marker);
}
}
ids[i] = annotationList.get(i).getId();
@@ -1012,7 +1011,7 @@ public class MapboxMap {
Marker marker = (Marker) annotation;
marker.hideInfoWindow();
if (marker instanceof MarkerView) {
- mMarkerViewManager.removeMarkerView((MarkerView) marker, true);
+ mMarkerViewManager.removeMarkerView((MarkerView) marker);
}
}
}
@@ -1209,8 +1208,7 @@ public class MapboxMap {
private MarkerView prepareViewMarker(BaseMarkerViewOptions markerViewOptions) {
MarkerView marker = markerViewOptions.getMarker();
- Icon icon = IconFactory.recreate("markerViewSettings", mViewMarkerBitmap);
- marker.setIcon(icon);
+ marker.setIcon(markerViewOptions.getIcon());
return marker;
}
@@ -1287,9 +1285,11 @@ public class MapboxMap {
//
/**
+ * <p>
* Sets the distance from the edges of the map view’s frame to the edges of the map
* view’s logical viewport.
- * <p/>
+ * </p>
+ * <p>
* When the value of this property is equal to {0,0,0,0}, viewport
* properties such as `centerCoordinate` assume a viewport that matches the map
* view’s frame. Otherwise, those properties are inset, excluding part of the
@@ -1826,7 +1826,7 @@ public class MapboxMap {
public MarkerViewAdapter(Context context) {
this.context = context;
persistentClass = (Class<U>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
- mViewReusePool = new Pools.SimplePool<>(20);
+ mViewReusePool = new Pools.SimplePool<>(10000);
}
/**
@@ -1841,11 +1841,56 @@ public class MapboxMap {
public abstract View getView(@NonNull U marker, @NonNull View convertView, @NonNull ViewGroup parent);
/**
+ * Called when an MarkerView is removed from the MapView or the View object is going to be reused.
+ * <p>
+ * <p>
+ * This method should be used to reset an animated view back to it's original state for view reuse.
+ * </p>
+ * <p>
+ * Returning true indicates you want to the view reuse to be handled automatically.
+ * Returning false indicates you want to perform an animation and you are required calling {@link #releaseView(View)} yourself.
+ * </p>
+ *
+ * @param marker the model representing the MarkerView
+ * @param convertView the reusable view
+ * @return true if you want reuse to occur automatically, false if you want to manage this yourself.
+ */
+ public boolean prepareViewForReuse(@NonNull MarkerView marker, @NonNull View convertView) {
+ return true;
+ }
+
+ /**
+ * Called when a MarkerView is selected from the MapView.
+ * <p>
+ * Returning true from this method indicates you want to move the MarkerView to the selected state.
+ * Returning false indicates you want to animate the View first an manually select the MarkerView when appropriate.
+ * </p>
+ *
+ * @param marker the model representing the MarkerView
+ * @param convertView the reusable view
+ * @param reselectionFromRecycling indicates if the onSelect callback is the initial selection
+ * callback or that selection occurs due to recreation of selected marker
+ * @return true if you want to select the Marker immediately, false if you want to manage this yourself.
+ */
+ public boolean onSelect(@NonNull U marker, @NonNull View convertView, boolean reselectionFromRecycling) {
+ return true;
+ }
+
+ /**
+ * Called when a MarkerView is deselected from the MapView.
+ *
+ * @param marker the model representing the MarkerView
+ * @param convertView the reusable view
+ */
+ public void onDeselect(@NonNull U marker, @NonNull View convertView) {
+ }
+
+ /**
* Returns the generic type of the used MarkerView.
*
* @return the generic type
*/
- public Class<U> getMarkerClass() {
+ public final Class<U> getMarkerClass() {
return persistentClass;
}
@@ -1854,7 +1899,7 @@ public class MapboxMap {
*
* @return the pool associated to this adapter
*/
- public Pools.SimplePool<View> getViewReusePool() {
+ public final Pools.SimplePool<View> getViewReusePool() {
return mViewReusePool;
}
@@ -1863,9 +1908,19 @@ public class MapboxMap {
*
* @return the context used
*/
- public Context getContext() {
+ public final Context getContext() {
return context;
}
+
+ /**
+ * Release a View to the ViewPool.
+ *
+ * @param view the view to be released
+ */
+ public final void releaseView(View view) {
+ view.setVisibility(View.GONE);
+ mViewReusePool.release(view);
+ }
}
/**
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 17593129e7..25f1a255e8 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
@@ -463,6 +463,16 @@ public class MapboxMapOptions implements Parcelable {
}
/**
+ *
+ * @param myLocationForegroundDrawable
+ * @return This
+ */
+ public MapboxMapOptions myLocationForegroundDrawable(Drawable myLocationForegroundDrawable) {
+ this.myLocationForegroundDrawable = myLocationForegroundDrawable;
+ return this;
+ }
+
+ /**
* @param myLocationBackgroundDrawable
* @return This
*/
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 6c092ee0c8..e92e310c63 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
@@ -7,6 +7,7 @@ import android.graphics.RectF;
import android.os.Build;
import android.view.Surface;
+import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.Polygon;
import com.mapbox.mapboxsdk.annotations.Polyline;
@@ -370,7 +371,9 @@ final class NativeMapView {
}
public void updateMarker(Marker marker) {
- nativeUpdateMarker(mNativeMapViewPtr, marker);
+ LatLng position = marker.getPosition();
+ Icon icon = marker.getIcon();
+ nativeUpdateMarker(mNativeMapViewPtr, marker.getId(), position.getLatitude(), position.getLongitude(), icon.getId());
}
public void removeAnnotation(long id) {
@@ -462,7 +465,7 @@ final class NativeMapView {
nativeRemoveCustomLayer(mNativeMapViewPtr, id);
}
- public double[] getCameraValues(){
+ public double[] getCameraValues() {
return nativeGetCameraValues(mNativeMapViewPtr);
}
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 aed4e87c07..a1515b39c9 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
@@ -3,8 +3,10 @@ package com.mapbox.mapboxsdk.maps.widgets;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
+import android.graphics.Camera;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.PorterDuff;
@@ -15,6 +17,8 @@ import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
+import android.os.Bundle;
+import android.os.Parcelable;
import android.os.SystemClock;
import android.support.annotation.ColorInt;
import android.support.annotation.FloatRange;
@@ -22,6 +26,7 @@ import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.View;
+import android.view.ViewGroup;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.camera.CameraPosition;
@@ -33,7 +38,6 @@ import com.mapbox.mapboxsdk.location.LocationListener;
import com.mapbox.mapboxsdk.location.LocationServices;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.Projection;
-import com.mapbox.mapboxsdk.maps.UiSettings;
import java.lang.ref.WeakReference;
@@ -45,7 +49,6 @@ public class MyLocationView extends View {
private MyLocationBehavior myLocationBehavior;
private MapboxMap mapboxMap;
private Projection projection;
- private int maxSize;
private int[] contentPadding = new int[4];
private Location location;
@@ -57,12 +60,12 @@ public class MyLocationView extends View {
private float gpsDirection;
private float previousDirection;
- private float accuracy = 0;
- private Paint accuracyPaint = new Paint();
+ private float accuracy;
+ private Paint accuracyPaint;
private ValueAnimator locationChangeAnimator;
private ValueAnimator accuracyAnimator;
- private ObjectAnimator directionAnimator;
+ private ValueAnimator directionAnimator;
private Drawable foregroundDrawable;
private Drawable foregroundBearingDrawable;
@@ -79,6 +82,11 @@ public class MyLocationView extends View {
private int backgroundOffsetRight;
private int backgroundOffsetBottom;
+ private Matrix matrix;
+ private Camera camera;
+ private PointF screenLocation;
+ private float tilt;
+
@MyLocationTracking.Mode
private int myLocationTrackingMode;
@@ -105,15 +113,39 @@ public class MyLocationView extends View {
private void init(Context context) {
setEnabled(false);
+
+ // setup LayoutParams
+ ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ setLayoutParams(lp);
+
+ matrix = new Matrix();
+ camera = new Camera();
+ camera.setLocation(0, 0, -1000);
+ accuracyPaint = new Paint();
+
myLocationBehavior = new MyLocationBehaviorFactory().getBehavioralModel(MyLocationTracking.TRACKING_NONE);
compassListener = new CompassListener(context);
- maxSize = (int) context.getResources().getDimension(R.dimen.my_locationview_size);
}
public final void setForegroundDrawables(Drawable defaultDrawable, Drawable bearingDrawable) {
- if (defaultDrawable == null || bearingDrawable == null) {
+ if (defaultDrawable == null) {
return;
}
+
+ if (bearingDrawable == null) {
+ // if user only provided one resource
+ // use same for bearing mode
+ bearingDrawable = defaultDrawable.getConstantState().newDrawable();
+ }
+
+ if (backgroundDrawable == null) {
+ // if the user didn't provide a background resource we will use the foreground resource instead,
+ // we need to create a new drawable to handle tinting correctly
+ backgroundDrawable = defaultDrawable.getConstantState().newDrawable();
+ }
+
if (defaultDrawable.getIntrinsicWidth() != bearingDrawable.getIntrinsicWidth() || defaultDrawable.getIntrinsicHeight() != bearingDrawable.getIntrinsicHeight()) {
throw new RuntimeException("The dimensions from location and bearing drawables should be match");
}
@@ -151,7 +183,6 @@ public class MyLocationView extends View {
backgroundOffsetTop = top;
backgroundOffsetRight = right;
backgroundOffsetBottom = bottom;
-
setShadowDrawableTint(backgroundTintColor);
invalidateBounds();
@@ -187,19 +218,18 @@ public class MyLocationView extends View {
int backgroundWidth = backgroundDrawable.getIntrinsicWidth();
int backgroundHeight = backgroundDrawable.getIntrinsicHeight();
-
- int foregroundWidth = foregroundDrawable.getIntrinsicWidth();
- int foregroundHeight = foregroundDrawable.getIntrinsicHeight();
-
int horizontalOffset = backgroundOffsetLeft - backgroundOffsetRight;
int verticalOffset = backgroundOffsetTop - backgroundOffsetBottom;
+ backgroundBounds = new Rect(-backgroundWidth / 2 + horizontalOffset, -backgroundHeight / 2 + verticalOffset, backgroundWidth / 2 + horizontalOffset, backgroundHeight / 2 + verticalOffset);
+ backgroundDrawable.setBounds(backgroundBounds);
- int accuracyWidth = 2 * maxSize;
-
- backgroundBounds = new Rect(accuracyWidth - (backgroundWidth / 2) + horizontalOffset, accuracyWidth + verticalOffset - (backgroundWidth / 2), accuracyWidth + (backgroundWidth / 2) + horizontalOffset, accuracyWidth + (backgroundHeight / 2) + verticalOffset);
- foregroundBounds = new Rect(accuracyWidth - (foregroundWidth / 2), accuracyWidth - (foregroundHeight / 2), accuracyWidth + (foregroundWidth / 2), accuracyWidth + (foregroundHeight / 2));
+ int foregroundWidth = foregroundDrawable.getIntrinsicWidth();
+ int foregroundHeight = foregroundDrawable.getIntrinsicHeight();
+ foregroundBounds = new Rect(-foregroundWidth / 2, -foregroundHeight / 2, foregroundWidth / 2, foregroundHeight / 2);
+ foregroundDrawable.setBounds(foregroundBounds);
+ foregroundBearingDrawable.setBounds(foregroundBounds);
- // invoke a new measure
+ // invoke a new draw
invalidate();
}
@@ -207,23 +237,51 @@ public class MyLocationView extends View {
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
- if (location == null || foregroundBounds == null || backgroundBounds == null || accuracyAnimator == null) {
+ if (location == null || foregroundBounds == null || backgroundBounds == null || accuracyAnimator == null || screenLocation == null) {
// Not ready yet
return;
}
- // Draw circle
+ final PointF pointF = screenLocation;
+
float metersPerPixel = (float) projection.getMetersPerPixelAtLatitude(location.getLatitude());
- float accuracyPixels = (Float) accuracyAnimator.getAnimatedValue() / metersPerPixel;
+ float accuracyPixels = (Float) accuracyAnimator.getAnimatedValue() / metersPerPixel / 2;
float maxRadius = getWidth() / 2;
- canvas.drawCircle(foregroundBounds.centerX(), foregroundBounds.centerY(), accuracyPixels <= maxRadius ? accuracyPixels : maxRadius, accuracyPaint);
+ accuracyPixels = accuracyPixels <= maxRadius ? accuracyPixels : maxRadius;
+
+ // put matrix in origin
+ matrix.reset();
+
+ // apply tilt to camera
+ camera.save();
+ camera.rotate(tilt, 0, 0);
+
+ // map camera matrix on our matrix
+ camera.getMatrix(matrix);
+
+ //
+ if (myBearingTrackingMode != MyBearingTracking.NONE) {
+ matrix.postRotate((Float) directionAnimator.getAnimatedValue());
+ }
- // Draw shadow
+ // put matrix at location of MyLocationView
+ matrix.postTranslate(pointF.x, pointF.y);
+
+ // concat our matrix on canvas
+ canvas.concat(matrix);
+
+ // restore orientation from camera
+ camera.restore();
+
+ // draw circle
+ canvas.drawCircle(0, 0, accuracyPixels, accuracyPaint);
+
+ // draw shadow
if (backgroundDrawable != null) {
backgroundDrawable.draw(canvas);
}
- // Draw foreground
+ // draw foreground
if (myBearingTrackingMode == MyBearingTracking.NONE) {
if (foregroundDrawable != null) {
foregroundDrawable.draw(canvas);
@@ -233,27 +291,8 @@ public class MyLocationView extends View {
}
}
- @Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
- super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
- if (foregroundDrawable != null && foregroundBounds != null) {
- foregroundDrawable.setBounds(foregroundBounds);
- }
-
- if (foregroundBearingDrawable != null && foregroundBounds != null) {
- foregroundBearingDrawable.setBounds(foregroundBounds);
- }
-
- if (backgroundDrawable != null && backgroundBounds != null) {
- backgroundDrawable.setBounds(backgroundBounds);
- }
-
- setMeasuredDimension(4 * maxSize, 4 * maxSize);
- }
-
public void setTilt(@FloatRange(from = 0, to = 60.0f) double tilt) {
- setRotationX((float) tilt);
+ this.tilt = (float) tilt;
}
void updateOnNextFrame() {
@@ -294,6 +333,24 @@ public class MyLocationView extends View {
toggleGps(enabled);
}
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable("superState", super.onSaveInstanceState());
+ bundle.putFloat("tilt", tilt);
+ return bundle;
+ }
+
+ @Override
+ public void onRestoreInstanceState(Parcelable state){
+ if (state instanceof Bundle){
+ Bundle bundle = (Bundle) state;
+ tilt = bundle.getFloat("tilt");
+ state = bundle.getParcelable("superState");
+ }
+ super.onRestoreInstanceState(state);
+ }
+
/**
* Enabled / Disable GPS location updates along with updating the UI
*
@@ -385,8 +442,8 @@ public class MyLocationView extends View {
}
previousDirection = newDir;
- directionAnimator = ObjectAnimator.ofFloat(this, View.ROTATION, oldDir, newDir);
- directionAnimator.setDuration(1000);
+ directionAnimator = ValueAnimator.ofFloat(oldDir, newDir);
+ directionAnimator.setDuration(375);
directionAnimator.start();
}
@@ -626,9 +683,9 @@ public class MyLocationView extends View {
@Override
void invalidate() {
int[] mapPadding = mapboxMap.getPadding();
- UiSettings uiSettings = mapboxMap.getUiSettings();
- setX((uiSettings.getWidth() - getWidth() + mapPadding[0] - mapPadding[2]) / 2 + (contentPadding[0] - contentPadding[2]) / 2);
- setY((uiSettings.getHeight() - getHeight() - mapPadding[3] + mapPadding[1]) / 2 + (contentPadding[1] - contentPadding[3]) / 2);
+ float x = (getWidth() + mapPadding[0] - mapPadding[2]) / 2 + (contentPadding[0] - contentPadding[2]) / 2;
+ float y = (getHeight() - mapPadding[3] + mapPadding[1]) / 2 + (contentPadding[1] - contentPadding[3]) / 2;
+ screenLocation = new PointF(x, y);
MyLocationView.this.invalidate();
}
}
@@ -659,7 +716,7 @@ public class MyLocationView extends View {
// calculate updateLatLng time + add some extra offset to improve animation
long previousUpdateTimeStamp = locationUpdateTimestamp;
locationUpdateTimestamp = SystemClock.elapsedRealtime();
- long locationUpdateDuration = (long) ((locationUpdateTimestamp - previousUpdateTimeStamp) * 1.1);
+ long locationUpdateDuration = (long) ((locationUpdateTimestamp - previousUpdateTimeStamp) * 1.3);
// calculate interpolated entity
interpolatedLocation = new LatLng((latLng.getLatitude() + previousLocation.getLatitude()) / 2, (latLng.getLongitude() + previousLocation.getLongitude()) / 2);
@@ -694,11 +751,7 @@ public class MyLocationView extends View {
@Override
void invalidate() {
- PointF screenLocation = projection.toScreenLocation(latLng);
- if (screenLocation != null) {
- setX((screenLocation.x - getWidth() / 2));
- setY((screenLocation.y - getHeight() / 2));
- }
+ screenLocation = projection.toScreenLocation(latLng);
MyLocationView.this.invalidate();
}
}
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 9ae96ebf7b..80bd1b3bef 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
@@ -6,6 +6,9 @@ import android.support.annotation.IntRange;
import com.mapbox.mapboxsdk.maps.MapView;
+/**
+ * Settings to configure the visual appearance of the MyLocationView.
+ */
public class MyLocationViewSettings {
private MapView mapView;
@@ -52,43 +55,101 @@ public class MyLocationViewSettings {
private int[] padding = new int[4];
+ /**
+ * Creates an instance of MyLocationViewSettings
+ *
+ * @param mapView the MapView that hosts the MyLocationView
+ * @param myLocationView the MyLocationView to apply the settings to
+ * @see MyLocationView
+ */
public MyLocationViewSettings(MapView mapView, MyLocationView myLocationView) {
this.mapView = mapView;
this.myLocationView = myLocationView;
}
+ /**
+ * Returns if the MyLocationView is enabled
+ *
+ * @return true if MyLocationView is enabled,
+ */
public boolean isEnabled() {
return enabled;
}
+ /**
+ * Set the enabled state of MyLocationView
+ *
+ * @param enabled true shows the MyLocationView on the map
+ */
public void setEnabled(boolean enabled) {
this.enabled = enabled;
myLocationView.setEnabled(enabled);
}
+ /**
+ * Set the foreground drawable of the MyLocationView
+ * <p>
+ * The foreground drawable is the image visible on screen
+ * </p>
+ *
+ * @param foregroundDrawable the drawable to show as foreground without bearing
+ * @param foregroundBearingDrawable the drawable to show as foreground when bearing is enabled
+ */
public void setForegroundDrawable(Drawable foregroundDrawable, Drawable foregroundBearingDrawable) {
this.foregroundDrawable = foregroundDrawable;
this.foregroundBearingDrawable = foregroundBearingDrawable;
myLocationView.setForegroundDrawables(foregroundDrawable, foregroundBearingDrawable);
}
+ /**
+ * Get the foreground drawable when bearing is disabled.
+ *
+ * @return the drawable used as foreground
+ */
public Drawable getForegroundDrawable() {
return foregroundDrawable;
}
+ /**
+ * Get the foreground drawable when bearing is enabled.
+ *
+ * @return the bearing drawable used as foreground
+ */
public Drawable getForegroundBearingDrawable() {
return foregroundBearingDrawable;
}
+ /**
+ * Set the foreground tint color.
+ * <p>
+ * The color will tint both the foreground and the bearing foreground drawable.
+ * </p>
+ *
+ * @param foregroundTintColor the color to tint the foreground drawable
+ */
public void setForegroundTintColor(@ColorInt int foregroundTintColor) {
this.foregroundTintColor = foregroundTintColor;
myLocationView.setForegroundDrawableTint(foregroundTintColor);
}
+ /**
+ * Get the foreground tint color.
+ *
+ * @return the foreground tint color
+ */
public int getForegroundTintColor() {
return foregroundTintColor;
}
+ /**
+ * Set the background drawable of MyLocationView
+ * <p>
+ * Padding can be added to provide an offset to the background
+ * </p>
+ *
+ * @param backgroundDrawable the drawable to show as background
+ * @param padding the padding added to the background
+ */
public void setBackgroundDrawable(Drawable backgroundDrawable, int[] padding) {
this.backgroundDrawable = backgroundDrawable;
this.backgroundOffset = padding;
@@ -99,46 +160,99 @@ public class MyLocationViewSettings {
}
}
+ /**
+ * Get the background drawable of MyLocationView.
+ *
+ * @return the drawable used as background
+ */
public Drawable getBackgroundDrawable() {
return backgroundDrawable;
}
+ /**
+ * Set the background tint color.
+ *
+ * @param backgroundTintColor the color to tint the background
+ */
public void setBackgroundTintColor(@ColorInt int backgroundTintColor) {
this.backgroundTintColor = backgroundTintColor;
myLocationView.setShadowDrawableTint(backgroundTintColor);
}
+ /**
+ * Get the background tint color.
+ *
+ * @return the background tint color
+ */
public int getBackgroundTintColor() {
return backgroundTintColor;
}
+ /**
+ * Get the background offset.
+ *
+ * @return the background offset
+ */
public int[] getBackgroundOffset() {
return backgroundOffset;
}
+ /**
+ * Set the MyLocationView padding.
+ *
+ * @param left the padding left of MyLocationView
+ * @param top the padding top of MyLocationView
+ * @param right the padding right of MyLocationView
+ * @param bottom the padding bottom of MyLocaionView
+ */
public void setPadding(int left, int top, int right, int bottom) {
padding = new int[]{left, top, right, bottom};
myLocationView.setContentPadding(padding);
mapView.invalidateContentPadding();
}
+ /**
+ * Get the MyLocationView padding.
+ *
+ * @return an array describing the padding in a LTRB manner
+ */
public int[] getPadding() {
return padding;
}
+ /**
+ * Get the alpha value of the accuracy circle of MyLocationView
+ *
+ * @return the alpha value
+ */
public int getAccuracyAlpha() {
return accuracyAlpha;
}
- public void setAccuracyAlpha(@IntRange(from = 0, to = 255) int arruracyAlpha) {
- this.accuracyAlpha = arruracyAlpha;
- myLocationView.setAccuracyAlpha(arruracyAlpha);
+ /**
+ * Set the alpha value of the accuracy circle of MyLocationView
+ *
+ * @param accuracyAlpha the alpha value to set
+ */
+ public void setAccuracyAlpha(@IntRange(from = 0, to = 255) int accuracyAlpha) {
+ this.accuracyAlpha = accuracyAlpha;
+ myLocationView.setAccuracyAlpha(accuracyAlpha);
}
+ /**
+ * Get the accuracy tint color of MyLocationView.
+ *
+ * @return the tint color used for accuracy
+ */
public int getAccuracyTintColor() {
return accuracyTintColor;
}
+ /**
+ * Set the accuracy tint color of MyLocationView.
+ *
+ * @param accuracyTintColor the accuracy tint color
+ */
public void setAccuracyTintColor(@ColorInt int accuracyTintColor) {
this.accuracyTintColor = accuracyTintColor;
myLocationView.setAccuracyTint(accuracyTintColor);
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
index 41dec08ee9..22e37ec539 100644
--- 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
@@ -7,7 +7,7 @@ import java.io.Serializable;
*/
public class MapboxEvent implements Serializable {
public static final int VERSION_NUMBER = 2;
- public static final String MAPBOX_EVENTS_BASE_URL = "https://api.mapbox.com";
+ public static final String MAPBOX_EVENTS_BASE_URL = "https://events.mapbox.com";
public static final String SOURCE_MAPBOX = "mapbox";
// Event Types
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 b386ed6549..907e34f878 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
@@ -686,19 +686,20 @@ public class MapboxEventManager {
.add("cloudfront-staging.tilestream.net", "sha256/sPbNCVpVasMJxps3IqFfLTRKkVnRCLrTlZVc5kspqlkw=")
.add("cloudfront-staging.tilestream.net", "sha256/h6801m+z8v3zbgkRHpq6L29Esgfzhj89C1SyUCOQmqU=")
// Prod - Geotrust
- .add("api.mapbox.com", "sha256/svaiYM/ZVIfxC+CMDe4kj1KsviQmzyZ9To8nQqUJwFI=")
- .add("api.mapbox.com", "sha256/owrR9U9FWDWtrFF+myoRIu75JwU4sJwzvhCNLZoY37g=")
- .add("api.mapbox.com", "sha256/SQVGZiOrQXi+kqxcvWWE96HhfydlLVqFr4lQTqI5qqo=")
+ .add("events.mapbox.com", "sha256/BhynraKizavqoC5U26qgYuxLZst6pCu9J5stfL6RSYY=")
+ .add("events.mapbox.com", "sha256/owrR9U9FWDWtrFF+myoRIu75JwU4sJwzvhCNLZoY37g=")
+ .add("events.mapbox.com", "sha256/SQVGZiOrQXi+kqxcvWWE96HhfydlLVqFr4lQTqI5qqo=")
// Prod - DigiCert
- .add("api.mapbox.com", "sha256/JL+uwAwpA2U1UVl/AFdZy1ZnvkZJ1P1hRfmfPaPVSLU=")
- .add("api.mapbox.com", "sha256/RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=")
- .add("api.mapbox.com", "sha256/WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=")
+ .add("events.mapbox.com", "sha256/Tb0uHZ/KQjWh8N9+CZFLc4zx36LONQ55l6laDi1qtT4=")
+ .add("events.mapbox.com", "sha256/RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=")
+ .add("events.mapbox.com", "sha256/WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=")
.build();
OkHttpClient client = new OkHttpClient.Builder().certificatePinner(certificatePinner).build();
RequestBody body = RequestBody.create(JSON, jsonArray.toString());
String url = eventsURL + "/events/v2?access_token=" + accessToken;
+// Log.d(TAG, "Events URL = " + url);
Request request = new Request.Builder()
.url(url)
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml
index 9799487f12..e944a5b4d1 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/mapview_internal.xml
@@ -31,7 +31,7 @@
<com.mapbox.mapboxsdk.maps.widgets.MyLocationView
android:id="@+id/userLocationView"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" />
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
</merge> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/layout/view_image_marker.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/view_image_marker.xml
new file mode 100644
index 0000000000..7e4a079063
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/layout/view_image_marker.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/image"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml
index d6cca7090f..fd0f4b98e7 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/dimens.xml
@@ -9,6 +9,5 @@
<dimen name="ten_dp">10dp</dimen>
<dimen name="sixteen_dp">16dp</dimen>
<dimen name="seventy_six_dp">76dp</dimen>
- <dimen name="my_locationview_size">64dp</dimen>
<dimen name="my_locationview_outer_circle">18dp</dimen>
</resources>
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml
index becbcce0b0..687b85b2d8 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml
@@ -11,11 +11,14 @@
<string name="infoWindowAddress">Address</string>
<!-- these are public -->
- <!-- {@deprecated Use Style.getXStyleUrl(int version) instead.} -->
+ <!-- Using one of these constants means your map style will always use the latest version and
+ may change as we improve the style. -->
<string name="style_mapbox_streets">mapbox://styles/mapbox/streets-v9</string>
+ <string name="style_outdoors">mapbox://styles/mapbox/outdoors-v9</string>
+ <!-- Note: Emerald style has been deprecated and will be removed in a future release-->
<string name="style_emerald">mapbox://styles/mapbox/emerald-v8</string>
<string name="style_light">mapbox://styles/mapbox/light-v9</string>
<string name="style_dark">mapbox://styles/mapbox/dark-v9</string>
<string name="style_satellite">mapbox://styles/mapbox/satellite-v9</string>
- <string name="style_satellite_streets">mapbox://styles/mapbox/satellite-hybrid-v9</string>
+ <string name="style_satellite_streets">mapbox://styles/mapbox/satellite-streets-v9</string>
</resources>
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties b/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties
index 8c1dcc38ce..cb468434c0 100644
--- a/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties
+++ b/platform/android/MapboxGLAndroidSDK/src/main/resources/fabric/com.mapbox.mapboxsdk.mapbox-android-sdk.properties
@@ -1,3 +1,3 @@
fabric-identifier=com.mapbox.mapboxsdk.mapbox-android-sdk
-fabric-version=4.0.0
+fabric-version=4.1.0-beta.2
fabric-build-type=binary
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java
index 7a2241a84c..e4bf383c96 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java
@@ -3,28 +3,28 @@ package com.mapbox.mapboxsdk.testapp.activity.annotation;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.ProgressDialog;
-import android.content.Context;
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import android.support.v4.content.res.ResourcesCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
-import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
-import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
+import com.mapbox.mapboxsdk.annotations.Icon;
+import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
-import com.mapbox.mapboxsdk.annotations.MarkerView;
import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.MapView;
@@ -86,36 +86,6 @@ public class BulkMarkerActivity extends AppCompatActivity implements AdapterView
}
}
- public static class TextAdapter extends MapboxMap.MarkerViewAdapter<MarkerView> {
-
- private LayoutInflater inflater;
-
- public TextAdapter(@NonNull Context context) {
- super(context);
- this.inflater = LayoutInflater.from(context);
- }
-
- @Nullable
- @Override
- public View getView(@NonNull MarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
- ViewHolder viewHolder;
- if (convertView == null) {
- viewHolder = new ViewHolder();
- convertView = inflater.inflate(R.layout.view_text_marker, parent, false);
- viewHolder.title = (TextView) convertView.findViewById(R.id.textView);
- convertView.setTag(viewHolder);
- } else {
- viewHolder = (ViewHolder) convertView.getTag();
- }
- viewHolder.title.setText(marker.getTitle());
- return convertView;
- }
-
- private static class ViewHolder {
- TextView title;
- }
- }
-
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
int amount = Integer.valueOf(getResources().getStringArray(R.array.bulk_marker_list)[position]);
@@ -126,7 +96,6 @@ public class BulkMarkerActivity extends AppCompatActivity implements AdapterView
}
}
-
private void onLatLngListLoaded(List<LatLng> latLngs, int amount) {
mLocations = latLngs;
showMarkers(amount);
@@ -140,26 +109,32 @@ public class BulkMarkerActivity extends AppCompatActivity implements AdapterView
}
if (mCustomMarkerView) {
- showNativeMarkers(amount);
+ showViewMarkers(amount);
} else {
showGlMarkers(amount);
}
}
- private void showNativeMarkers(int amount) {
+ private void showViewMarkers(int amount) {
DecimalFormat formatter = new DecimalFormat("#.#####");
Random random = new Random();
int randomIndex;
+ Drawable drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_droppin_24dp, getTheme());
+ int redColor = ResourcesCompat.getColor(getResources(), android.R.color.holo_red_dark, getTheme());
+ drawable.setColorFilter(redColor, PorterDuff.Mode.SRC_IN);
+ Icon icon = IconFactory.getInstance(this).fromDrawable(drawable);
+
for (int i = 0; i < amount; i++) {
randomIndex = random.nextInt(mLocations.size());
LatLng latLng = mLocations.get(randomIndex);
mMapboxMap.addMarker(new MarkerViewOptions()
.position(latLng)
+ .icon(icon)
.title(String.valueOf(i))
.snippet(formatter.format(latLng.getLatitude()) + ", " + formatter.format(latLng.getLongitude())));
}
- }
+ }
private void showGlMarkers(int amount) {
List<MarkerOptions> markerOptionsList = new ArrayList<>();
@@ -247,9 +222,6 @@ public class BulkMarkerActivity extends AppCompatActivity implements AdapterView
showMarkers(amount);
}
- // add adapter
- mMapboxMap.getMarkerViewManager().addMarkerViewAdapter(new TextAdapter(BulkMarkerActivity.this));
-
mMapView.addOnMapChangedListener(new MapView.OnMapChangedListener() {
@Override
public void onMapChanged(@MapView.MapChange int change) {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java
index fcddf8ca54..e7d60a6fae 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java
@@ -9,7 +9,6 @@ import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
-
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
@@ -58,12 +57,13 @@ public class DynamicMarkerChangeActivity extends AppCompatActivity {
// Create marker
MarkerOptions markerOptions = new MarkerOptions()
.position(LAT_LNG_CHELSEA)
- .icon(mIconFactory.fromResource(R.drawable.ic_chelsea));
+ .icon(mIconFactory.fromResource(R.drawable.ic_chelsea))
+ .title(getString(R.string.dynamic_marker_chelsea_title))
+ .snippet(getString(R.string.dynamic_marker_chelsea_snippet));
mMarker = mapboxMap.addMarker(markerOptions);
}
});
-
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setColorFilter(ContextCompat.getColor(this, R.color.primary));
fab.setOnClickListener(new View.OnClickListener() {
@@ -84,6 +84,8 @@ public class DynamicMarkerChangeActivity extends AppCompatActivity {
// update marker
mMarker.setPosition(first ? LAT_LNG_CHELSEA : LAT_LNG_ARSENAL);
mMarker.setIcon(mIconFactory.fromResource(first ? R.drawable.ic_chelsea : R.drawable.ic_arsenal));
+ mMarker.setTitle(first ? getString(R.string.dynamic_marker_chelsea_title) : getString(R.string.dynamic_marker_arsenal_title));
+ mMarker.setSnippet(first ? getString(R.string.dynamic_marker_chelsea_snippet) : getString(R.string.dynamic_marker_arsenal_snippet));
}
@Override
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java
index 65a5afa602..2b5ec2ef80 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java
@@ -1,7 +1,10 @@
package com.mapbox.mapboxsdk.testapp.activity.annotation;
+import android.animation.Animator;
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
import android.content.Context;
-import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
@@ -17,7 +20,10 @@ import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
+import com.mapbox.mapboxsdk.annotations.Icon;
+import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.Marker;
+import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.MarkerView;
import com.mapbox.mapboxsdk.annotations.MarkerViewManager;
import com.mapbox.mapboxsdk.annotations.MarkerViewOptions;
@@ -26,23 +32,29 @@ import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.model.annotations.CountryMarkerOptions;
import com.mapbox.mapboxsdk.testapp.model.annotations.CountryMarkerView;
import com.mapbox.mapboxsdk.testapp.model.annotations.CountryMarkerViewOptions;
+import com.mapbox.mapboxsdk.testapp.model.annotations.TextMarkerView;
+import com.mapbox.mapboxsdk.testapp.model.annotations.TextMarkerViewOptions;
+
+import java.util.Random;
public class MarkerViewActivity extends AppCompatActivity {
private MapboxMap mMapboxMap;
private MapView mMapView;
+ private MarkerView movingMarkerOne, movingMarkerTwo;
+ private Random randomAnimator = new Random();
+ private Handler locationUpdateHandler = new Handler();
+ private Runnable moveMarkerRunnable = new MoveMarkerRunnable();
+ private int rotation = 0;
+
private final static LatLng[] LAT_LNGS = new LatLng[]{
- new LatLng(38.907327, -77.041293),
+ new LatLng(38.897424, -77.036508),
new LatLng(38.909698, -77.029642),
new LatLng(38.907227, -77.036530),
new LatLng(38.905607, -77.031916),
- new LatLng(38.897424, -77.036508),
- new LatLng(38.897642, -77.041980),
- new LatLng(38.889876, -77.008849),
new LatLng(38.889441, -77.050134)
};
@@ -68,38 +80,55 @@ public class MarkerViewActivity extends AppCompatActivity {
public void onMapReady(@NonNull MapboxMap mapboxMap) {
mMapboxMap = mapboxMap;
- // add text markers
+ final MarkerViewManager markerViewManager = mapboxMap.getMarkerViewManager();
+
+ Icon usFlag = IconFactory.getInstance(MarkerViewActivity.this)
+ .fromResource(R.drawable.ic_us);
+
+ // add default ViewMarker markers
for (int i = 0; i < LAT_LNGS.length; i++) {
mMapboxMap.addMarker(new MarkerViewOptions()
.position(LAT_LNGS[i])
.title(String.valueOf(i))
- .selectAnimatorResource(R.animator.scale_up)
- .deselectAnimatorResource(R.animator.scale_down)
+ .icon(usFlag)
);
}
- // add flag marker
+ // add custom ViewMarker
CountryMarkerViewOptions options = new CountryMarkerViewOptions();
- options.title("United States");
- options.abbrevName("us");
- options.flagRes(R.drawable.ic_us);
+ options.flagRes(R.drawable.icon_burned);
+ options.abbrevName("Mapbox");
+ options.title("Hello");
options.position(new LatLng(38.899774, -77.023237));
- options.selectAnimatorResource(R.animator.rotate_360);
- options.deselectAnimatorResource(R.animator.rotate_360);
options.flat(true);
mapboxMap.addMarker(options);
- // default GL marker
- mMapboxMap.addMarker(new CountryMarkerOptions()
+ mMapboxMap.addMarker(new MarkerOptions()
.title("United States")
.position(new LatLng(38.902580, -77.050102))
);
- // set adapters
- final MarkerViewManager markerViewManager = mapboxMap.getMarkerViewManager();
- markerViewManager.addMarkerViewAdapter(new TextAdapter(MarkerViewActivity.this));
- markerViewManager.addMarkerViewAdapter(new CountryAdapter(MarkerViewActivity.this));
+ mMapboxMap.addMarker(new TextMarkerViewOptions()
+ .text("A")
+ .position(new LatLng(38.889876, -77.008849))
+ );
+
+ mMapboxMap.addMarker(new TextMarkerViewOptions()
+ .text("B")
+ .position(new LatLng(38.907327, -77.041293))
+ );
+ mMapboxMap.addMarker(new TextMarkerViewOptions()
+ .text("C")
+ .position(new LatLng(38.897642, -77.041980))
+ );
+
+ // if you want to customise a ViewMarker you need to extend ViewMarker and provide an adapter implementation
+ // set adapters for child classes of ViewMarker
+ markerViewManager.addMarkerViewAdapter(new CountryAdapter(MarkerViewActivity.this, mapboxMap));
+ markerViewManager.addMarkerViewAdapter(new TextAdapter(MarkerViewActivity.this, mapboxMap));
+
+ // add a change listener to validate the size of amount of child views
mMapView.addOnMapChangedListener(new MapView.OnMapChangedListener() {
@Override
public void onMapChanged(@MapView.MapChange int change) {
@@ -111,6 +140,7 @@ public class MarkerViewActivity extends AppCompatActivity {
}
});
+ // add a OnMarkerView click listener
mMapboxMap.getMarkerViewManager().setOnMarkerViewClickListener(new MapboxMap.OnMarkerViewClickListener() {
@Override
public boolean onMarkerClick(@NonNull Marker marker, @NonNull View view, @NonNull MapboxMap.MarkerViewAdapter adapter) {
@@ -118,73 +148,219 @@ public class MarkerViewActivity extends AppCompatActivity {
return false;
}
});
+
+ movingMarkerOne = mMapboxMap.addMarker(new MarkerViewOptions()
+ .position(CarLocation.CAR_0_LNGS[0])
+ .icon(IconFactory.getInstance(mMapView.getContext())
+ .fromResource(R.drawable.ic_chelsea))
+ );
+
+ movingMarkerTwo = mapboxMap.addMarker(new MarkerViewOptions()
+ .position(CarLocation.CAR_1_LNGS[0])
+ .icon(IconFactory.getInstance(mMapView.getContext())
+ .fromResource(R.drawable.ic_arsenal))
+ );
}
});
}
- private static class TextAdapter extends MapboxMap.MarkerViewAdapter<MarkerView> {
+ @Override
+ protected void onStart() {
+ super.onStart();
+ loopMarkerMove();
+ }
+
+ private void loopMarkerMove() {
+ locationUpdateHandler.postDelayed(moveMarkerRunnable, randomAnimator.nextInt(3000) + 1000);
+ }
+
+ @Override
+ protected void onStop() {
+ super.onStop();
+ locationUpdateHandler.removeCallbacks(moveMarkerRunnable);
+ }
+
+ private class MoveMarkerRunnable implements Runnable {
+ @Override
+ public void run() {
+ int i = randomAnimator.nextInt(9);
+ if (randomAnimator.nextInt() % 2 == 0) {
+ movingMarkerOne.setPosition(CarLocation.CAR_0_LNGS[i]);
+ movingMarkerOne.setRotation(rotation = rotation + 45);
+ } else {
+ movingMarkerTwo.setPosition(CarLocation.CAR_1_LNGS[i]);
+ movingMarkerTwo.setRotation(rotation = rotation + 90);
+ }
+ loopMarkerMove();
+ }
+ }
+
+ private static class CountryAdapter extends MapboxMap.MarkerViewAdapter<CountryMarkerView> {
private LayoutInflater inflater;
+ private MapboxMap mapboxMap;
- public TextAdapter(@NonNull Context context) {
+ public CountryAdapter(@NonNull Context context, @NonNull MapboxMap mapboxMap) {
super(context);
this.inflater = LayoutInflater.from(context);
+ this.mapboxMap = mapboxMap;
}
@Nullable
@Override
- public View getView(@NonNull MarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
+ public View getView(@NonNull CountryMarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
- convertView = inflater.inflate(R.layout.view_text_marker, parent, false);
- viewHolder.title = (TextView) convertView.findViewById(R.id.textView);
+ convertView = inflater.inflate(R.layout.view_custom_marker, parent, false);
+ viewHolder.flag = (ImageView) convertView.findViewById(R.id.imageView);
+ viewHolder.abbrev = (TextView) convertView.findViewById(R.id.textView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
- viewHolder.title.setText(marker.getTitle());
+ viewHolder.flag.setImageResource(marker.getFlagRes());
+ viewHolder.abbrev.setText(marker.getAbbrevName());
return convertView;
}
+ @Override
+ public boolean onSelect(@NonNull final CountryMarkerView marker, @NonNull final View convertView, boolean reselectionForViewReuse) {
+ convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(convertView, View.ROTATION, 0, 360);
+ rotateAnimator.setDuration(reselectionForViewReuse ? 0 : 350);
+ rotateAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ convertView.setLayerType(View.LAYER_TYPE_NONE, null);
+ mapboxMap.selectMarker(marker);
+ }
+ });
+ rotateAnimator.start();
+
+ // false indicates that we are calling selectMarker after our animation ourselves
+ // true will let the system call it for you, which will result in showing an InfoWindow instantly
+ return false;
+ }
+
+ @Override
+ public void onDeselect(@NonNull CountryMarkerView marker, @NonNull final View convertView) {
+ convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ ObjectAnimator rotateAnimator = ObjectAnimator.ofFloat(convertView, View.ROTATION, 360, 0);
+ rotateAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ convertView.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+ });
+ rotateAnimator.start();
+ }
+
private static class ViewHolder {
- TextView title;
+ ImageView flag;
+ TextView abbrev;
}
}
- private static class CountryAdapter extends MapboxMap.MarkerViewAdapter<CountryMarkerView> {
+
+ private static class TextAdapter extends MapboxMap.MarkerViewAdapter<TextMarkerView> {
private LayoutInflater inflater;
+ private MapboxMap mapboxMap;
- public CountryAdapter(@NonNull Context context) {
+ public TextAdapter(@NonNull Context context, @NonNull MapboxMap mapboxMap) {
super(context);
this.inflater = LayoutInflater.from(context);
+ this.mapboxMap = mapboxMap;
}
@Nullable
@Override
- public View getView(@NonNull CountryMarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
+ public View getView(@NonNull TextMarkerView marker, @Nullable View convertView, @NonNull ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder();
- convertView = inflater.inflate(R.layout.view_custom_marker, parent, false);
- viewHolder.flag = (ImageView) convertView.findViewById(R.id.imageView);
- viewHolder.abbrev = (TextView) convertView.findViewById(R.id.textView);
+ convertView = inflater.inflate(R.layout.view_text_marker, parent, false);
+ viewHolder.textView = (TextView) convertView.findViewById(R.id.textView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
- viewHolder.flag.setImageResource(marker.getFlagRes());
- viewHolder.abbrev.setText(marker.getAbbrevName());
+ viewHolder.textView.setText(marker.getText());
return convertView;
}
+ @Override
+ public boolean onSelect(@NonNull final TextMarkerView marker, @NonNull final View convertView, boolean reselectionForViewReuse) {
+ animateGrow(marker, convertView, 0);
+
+ // false indicates that we are calling selectMarker after our animation ourselves
+ // true will let the system call it for you, which will result in showing an InfoWindow instantly
+ return false;
+ }
+
+ @Override
+ public void onDeselect(@NonNull TextMarkerView marker, @NonNull final View convertView) {
+ animateShrink(convertView, 350);
+ }
+
+ @Override
+ public boolean prepareViewForReuse(@NonNull MarkerView marker, @NonNull View convertView) {
+ // this method is called before a view will be reused, we need to restore view state
+ // as we have scaled the view in onSelect. If not correctly applied other MarkerView will
+ // become large since these have been recycled
+
+ // cancel ongoing animation
+ convertView.animate().cancel();
+
+ if (marker.isSelected()) {
+ // shrink view to be able to be reused
+ animateShrink(convertView, 0);
+ }
+
+ // true if you want reuse to occur automatically, false if you want to manage this yourself
+ return true;
+ }
+
+ private void animateGrow(@NonNull final MarkerView marker, @NonNull final View convertView, int duration) {
+ convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ Animator animator = AnimatorInflater.loadAnimator(convertView.getContext(), R.animator.scale_up);
+ animator.setDuration(duration);
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ convertView.setLayerType(View.LAYER_TYPE_NONE, null);
+ mapboxMap.selectMarker(marker);
+ }
+ });
+ animator.setTarget(convertView);
+ animator.start();
+ }
+
+ private void animateShrink(@NonNull final View convertView, int duration) {
+ convertView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ Animator animator = AnimatorInflater.loadAnimator(convertView.getContext(), R.animator.scale_down);
+ animator.setDuration(duration);
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ convertView.setLayerType(View.LAYER_TYPE_NONE, null);
+ }
+ });
+ animator.setTarget(convertView);
+ animator.start();
+ }
+
private static class ViewHolder {
- ImageView flag;
- TextView abbrev;
+ TextView textView;
}
}
+
@Override
public void onResume() {
super.onResume();
@@ -225,4 +401,32 @@ public class MarkerViewActivity extends AppCompatActivity {
return super.onOptionsItemSelected(item);
}
}
+
+ private static class CarLocation {
+
+ public static LatLng[] CAR_0_LNGS = new LatLng[]{
+ new LatLng(38.92334425495122, -77.0533673443786),
+ new LatLng(38.9234737236897, -77.05389484528261),
+ new LatLng(38.9257094658146, -76.98819752280579),
+ new LatLng(38.8324328369647, -77.00690648325929),
+ new LatLng(38.87540698725855, -77.0093148713099),
+ new LatLng(38.96499498141065, -77.07707916040054),
+ new LatLng(38.90794910679896, -76.99695304153806),
+ new LatLng(38.86234025281626, -76.9950528034839),
+ new LatLng(38.862930274733635, -76.99647808241964)
+ };
+
+ public static LatLng[] CAR_1_LNGS = new LatLng[]{
+ new LatLng(38.94237975070426, -76.98324549005675),
+ new LatLng(38.941520236084486, -76.98234257804742),
+ new LatLng(38.85972219720714, -76.98955808483929),
+ new LatLng(38.944289166113776, -76.98584257252891),
+ new LatLng(38.94375860578053, -76.98470344318412),
+ new LatLng(38.943167431929645, -76.98373163938666),
+ new LatLng(38.882834728904605, -77.02862535635137),
+ new LatLng(38.882869724926245, -77.02992539231113),
+ new LatLng(38.9371988177896, -76.97786740676564)
+ };
+
+ }
}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java
index f08d65163b..68a5b642c4 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java
@@ -44,7 +44,7 @@ public class PolygonActivity extends AppCompatActivity {
MapboxMapOptions options = new MapboxMapOptions()
.attributionTintColor(Color.RED)
.accessToken(getString(R.string.mapbox_access_token))
- .styleUrl(Style.getMapboxStreetsUrl(AppConstant.STYLE_VERSION))
+ .styleUrl(Style.MAPBOX_STREETS)
.camera(new CameraPosition.Builder()
.target(new LatLng(45.520486, -122.673541))
.zoom(12)
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java
index 88008d64fb..114304188d 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java
@@ -9,6 +9,7 @@ import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
+
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
@@ -17,6 +18,7 @@ import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.R;
+
import java.text.DecimalFormat;
import java.util.ArrayList;
@@ -50,7 +52,7 @@ public class PressForMarkerActivity extends AppCompatActivity {
@Override
public void onMapReady(final MapboxMap map) {
mapboxMap = map;
- mapboxMap.setStyleUrl(Style.getOutdoorsStyleUrl(9));
+ mapboxMap.setStyleUrl(Style.OUTDOORS);
resetMap();
mapboxMap.setOnMapLongClickListener(new MapboxMap.OnMapLongClickListener() {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java
index b9a438b7d5..bc7ef3c596 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java
@@ -9,17 +9,16 @@ import android.util.Log;
import android.view.MenuItem;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
-import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
+import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.geometry.LatLngBounds;
+import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.UiSettings;
import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.testapp.model.constants.AppConstant;
public class LatLngBoundsActivity extends AppCompatActivity {
@@ -43,7 +42,7 @@ public class LatLngBoundsActivity extends AppCompatActivity {
}
mMapView = (MapView) findViewById(R.id.mapView);
- mMapView.setStyleUrl(Style.getDarkStyleUrl(AppConstant.STYLE_VERSION));
+ mMapView.setStyleUrl(Style.DARK);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(new OnMapReadyCallback() {
@Override
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ManualZoomActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ManualZoomActivity.java
index bc3691a2f7..897380d1aa 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ManualZoomActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/ManualZoomActivity.java
@@ -12,12 +12,11 @@ import android.view.View;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
+import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.UiSettings;
import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.testapp.model.constants.AppConstant;
public class ManualZoomActivity extends AppCompatActivity {
@@ -39,7 +38,7 @@ public class ManualZoomActivity extends AppCompatActivity {
}
mMapView = (MapView) findViewById(R.id.manualZoomMapView);
- mMapView.setStyleUrl(Style.getSatelliteStyleUrl(AppConstant.STYLE_VERSION));
+ mMapView.setStyleUrl(Style.SATELLITE);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(new OnMapReadyCallback() {
@Override
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java
index 5987855aac..9d72c2b02a 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/MapFragmentActivity.java
@@ -17,7 +17,6 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.model.constants.AppConstant;
public class MapFragmentActivity extends AppCompatActivity {
@@ -40,7 +39,7 @@ public class MapFragmentActivity extends AppCompatActivity {
FragmentTransaction transaction = getFragmentManager().beginTransaction();
MapboxMapOptions options = new MapboxMapOptions();
- options.styleUrl(Style.getOutdoorsStyleUrl(AppConstant.STYLE_VERSION));
+ options.styleUrl(Style.OUTDOORS);
options.scrollGesturesEnabled(false);
options.zoomGesturesEnabled(false);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java
index bb391fc93d..cc61eb4698 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/fragment/SupportMapFragmentActivity.java
@@ -17,7 +17,6 @@ import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.SupportMapFragment;
import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.model.constants.AppConstant;
public class SupportMapFragmentActivity extends AppCompatActivity {
@@ -40,7 +39,7 @@ public class SupportMapFragmentActivity extends AppCompatActivity {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
MapboxMapOptions options = new MapboxMapOptions();
- options.styleUrl(Style.getSatelliteStreetsStyleUrl(AppConstant.STYLE_VERSION));
+ options.styleUrl(Style.SATELLITE_STREETS);
options.scrollGesturesEnabled(false);
options.zoomGesturesEnabled(false);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/geocoding/GeocoderActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/geocoding/GeocoderActivity.java
index fc03066a4e..99d2f81aad 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/geocoding/GeocoderActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/geocoding/GeocoderActivity.java
@@ -19,15 +19,14 @@ import com.mapbox.geocoder.GeocoderCriteria;
import com.mapbox.geocoder.MapboxGeocoder;
import com.mapbox.geocoder.service.models.GeocoderFeature;
import com.mapbox.geocoder.service.models.GeocoderResponse;
-import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.geometry.LatLng;
+import com.mapbox.mapboxsdk.maps.MapView;
+import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.Projection;
import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.maps.MapView;
-import com.mapbox.mapboxsdk.testapp.model.constants.AppConstant;
import java.util.List;
@@ -60,7 +59,7 @@ public class GeocoderActivity extends AppCompatActivity {
setMessage(getString(R.string.geocoder_instructions));
mapView = (MapView) findViewById(R.id.mapView);
- mapView.setStyleUrl(Style.getMapboxStreetsUrl(AppConstant.STYLE_VERSION));
+ mapView.setStyleUrl(Style.MAPBOX_STREETS);
mapView.onCreate(savedInstanceState);
final ImageView dropPinView = new ImageView(this);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java
index f5835ab7bd..760501c17c 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DebugModeActivity.java
@@ -15,7 +15,6 @@ import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.model.constants.AppConstant;
public class DebugModeActivity extends AppCompatActivity {
@@ -27,12 +26,12 @@ public class DebugModeActivity extends AppCompatActivity {
private int currentStyleIndex = 0;
private static final String[] STYLES = new String[]{
- Style.getMapboxStreetsUrl(AppConstant.STYLE_VERSION),
- Style.getOutdoorsStyleUrl(AppConstant.STYLE_VERSION),
- Style.getLightStyleUrl(AppConstant.STYLE_VERSION),
- Style.getDarkStyleUrl(AppConstant.STYLE_VERSION),
- Style.getSatelliteStyleUrl(AppConstant.STYLE_VERSION),
- Style.getSatelliteStreetsStyleUrl(AppConstant.STYLE_VERSION)
+ Style.MAPBOX_STREETS,
+ Style.OUTDOORS,
+ Style.LIGHT,
+ Style.DARK,
+ Style.SATELLITE,
+ Style.SATELLITE_STREETS
};
@Override
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DoubleMapActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DoubleMapActivity.java
index 288817d670..a3517df205 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DoubleMapActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/maplayout/DoubleMapActivity.java
@@ -23,7 +23,6 @@ import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.maps.TrackingSettings;
import com.mapbox.mapboxsdk.maps.UiSettings;
import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.model.constants.AppConstant;
public class DoubleMapActivity extends AppCompatActivity {
@@ -73,7 +72,7 @@ public class DoubleMapActivity extends AppCompatActivity {
mMapView.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(@NonNull MapboxMap mapboxMap) {
- mapboxMap.setStyleUrl(Style.getDarkStyleUrl(AppConstant.STYLE_VERSION));
+ mapboxMap.setStyleUrl(Style.DARK);
mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(18));
try {
@@ -92,7 +91,7 @@ public class DoubleMapActivity extends AppCompatActivity {
mMapViewMini.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(@NonNull MapboxMap mapboxMap) {
- mapboxMap.setStyleUrl(Style.getLightStyleUrl(AppConstant.STYLE_VERSION));
+ mapboxMap.setStyleUrl(Style.LIGHT);
mapboxMap.moveCamera(CameraUpdateFactory.zoomTo(4));
UiSettings uiSettings = mapboxMap.getUiSettings();
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java
index fde46b1cab..8819168478 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java
@@ -12,6 +12,7 @@ import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.Toast;
+
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
@@ -26,10 +27,11 @@ import com.mapbox.mapboxsdk.offline.OfflineRegionError;
import com.mapbox.mapboxsdk.offline.OfflineRegionStatus;
import com.mapbox.mapboxsdk.offline.OfflineTilePyramidRegionDefinition;
import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.model.constants.AppConstant;
import com.mapbox.mapboxsdk.testapp.model.other.OfflineDownloadRegionDialog;
import com.mapbox.mapboxsdk.testapp.model.other.OfflineListRegionsDialog;
+
import org.json.JSONObject;
+
import java.util.ArrayList;
public class OfflineActivity extends AppCompatActivity
@@ -74,7 +76,7 @@ public class OfflineActivity extends AppCompatActivity
// Set up map
mMapView = (MapView) findViewById(R.id.mapView);
- mMapView.setStyleUrl(Style.getMapboxStreetsUrl(AppConstant.STYLE_VERSION));
+ mMapView.setStyleUrl(Style.MAPBOX_STREETS);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(new OnMapReadyCallback() {
@Override
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java
index a4a283907e..e5e21fd03e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MyLocationDrawableActivity.java
@@ -11,6 +11,7 @@ import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
+
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
import com.mapbox.mapboxsdk.constants.Style;
@@ -22,7 +23,6 @@ import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.MapboxMapOptions;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.R;
-import com.mapbox.mapboxsdk.testapp.model.constants.AppConstant;
public class MyLocationDrawableActivity extends AppCompatActivity implements LocationListener {
@@ -49,7 +49,7 @@ public class MyLocationDrawableActivity extends AppCompatActivity implements Loc
MapboxMapOptions mapboxMapOptions = new MapboxMapOptions();
mapboxMapOptions.accessToken(getString(R.string.mapbox_access_token));
- mapboxMapOptions.styleUrl(Style.getMapboxStreetsUrl(AppConstant.STYLE_VERSION));
+ mapboxMapOptions.styleUrl(Style.MAPBOX_STREETS);
mapboxMapOptions.locationEnabled(true);
mapboxMapOptions.camera(new CameraPosition.Builder()
.target(location != null ? new LatLng(location) : new LatLng(0, 0))
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerViewOptions.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerViewOptions.java
index c4ef4a8d13..abf5f19aca 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerViewOptions.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/CountryMarkerViewOptions.java
@@ -1,15 +1,12 @@
package com.mapbox.mapboxsdk.testapp.model.annotations;
import android.graphics.Bitmap;
-import android.graphics.Point;
-import android.graphics.PointF;
import android.os.Parcel;
import android.os.Parcelable;
import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.IconFactory;
-import com.mapbox.mapboxsdk.annotations.MarkerView;
import com.mapbox.mapboxsdk.geometry.LatLng;
public class CountryMarkerViewOptions extends BaseMarkerViewOptions<CountryMarkerView, CountryMarkerViewOptions> {
@@ -26,10 +23,8 @@ public class CountryMarkerViewOptions extends BaseMarkerViewOptions<CountryMarke
title(in.readString());
flat(in.readByte() != 0);
anchor(in.readFloat(), in.readFloat());
- infoWindowAnchor(in.readFloat(), in.readFloat());
- selectAnimatorResource(in.readInt());
- deselectAnimatorResource(in.readInt());
- rotation(in.readInt());
+ selected = in.readByte() != 0;
+ rotation(in.readFloat());
if (in.readByte() != 0) {
// this means we have an icon
String iconId = in.readString();
@@ -61,9 +56,8 @@ public class CountryMarkerViewOptions extends BaseMarkerViewOptions<CountryMarke
out.writeFloat(getAnchorV());
out.writeFloat(getInfoWindowAnchorU());
out.writeFloat(getInfoWindowAnchorV());
- out.writeInt(getSelectAnimRes());
- out.writeInt(getDeselectAnimRes());
- out.writeInt(getRotation());
+ out.writeByte((byte) (selected ? 1 : 0));
+ out.writeFloat(getRotation());
Icon icon = getIcon();
out.writeByte((byte) (icon != null ? 1 : 0));
if (icon != null) {
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerView.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerView.java
new file mode 100644
index 0000000000..c0a589cb57
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerView.java
@@ -0,0 +1,18 @@
+package com.mapbox.mapboxsdk.testapp.model.annotations;
+
+import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
+import com.mapbox.mapboxsdk.annotations.MarkerView;
+
+public class TextMarkerView extends MarkerView {
+
+ private String text;
+
+ public TextMarkerView(BaseMarkerViewOptions baseMarkerViewOptions, String text) {
+ super(baseMarkerViewOptions);
+ this.text = text;
+ }
+
+ public String getText() {
+ return text;
+ }
+} \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerViewOptions.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerViewOptions.java
new file mode 100644
index 0000000000..0b2a365e5d
--- /dev/null
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/model/annotations/TextMarkerViewOptions.java
@@ -0,0 +1,87 @@
+package com.mapbox.mapboxsdk.testapp.model.annotations;
+
+import android.graphics.Bitmap;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions;
+import com.mapbox.mapboxsdk.annotations.Icon;
+import com.mapbox.mapboxsdk.annotations.IconFactory;
+import com.mapbox.mapboxsdk.geometry.LatLng;
+
+public class TextMarkerViewOptions extends BaseMarkerViewOptions<TextMarkerView, TextMarkerViewOptions> {
+
+ private String text;
+
+ public TextMarkerViewOptions() {
+ }
+
+ protected TextMarkerViewOptions(Parcel in) {
+ position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
+ snippet(in.readString());
+ title(in.readString());
+ flat(in.readByte() != 0);
+ anchor(in.readFloat(), in.readFloat());
+ infoWindowAnchor(in.readFloat(), in.readFloat());
+ rotation(in.readFloat());
+ if (in.readByte() != 0) {
+ // this means we have an icon
+ String iconId = in.readString();
+ Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
+ Icon icon = IconFactory.recreate(iconId, iconBitmap);
+ icon(icon);
+ }
+ text(in.readString());
+ }
+
+ @Override
+ public TextMarkerViewOptions getThis() {
+ return this;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeParcelable(getPosition(), flags);
+ out.writeString(getSnippet());
+ out.writeString(getTitle());
+ out.writeByte((byte) (isFlat() ? 1 : 0));
+ out.writeFloat(getAnchorU());
+ out.writeFloat(getAnchorV());
+ out.writeFloat(getInfoWindowAnchorU());
+ out.writeFloat(getInfoWindowAnchorV());
+ out.writeFloat(getRotation());
+ Icon icon = getIcon();
+ out.writeByte((byte) (icon != null ? 1 : 0));
+ if (icon != null) {
+ out.writeString(getIcon().getId());
+ out.writeParcelable(getIcon().getBitmap(), flags);
+ }
+ out.writeString(text);
+ }
+
+ @Override
+ public TextMarkerView getMarker() {
+ return new TextMarkerView(this, text);
+ }
+
+ public TextMarkerViewOptions text(String text) {
+ this.text = text;
+ return getThis();
+ }
+
+ public static final Parcelable.Creator<CountryMarkerViewOptions> CREATOR
+ = new Parcelable.Creator<CountryMarkerViewOptions>() {
+ public CountryMarkerViewOptions createFromParcel(Parcel in) {
+ return new CountryMarkerViewOptions(in);
+ }
+
+ public CountryMarkerViewOptions[] newArray(int size) {
+ return new CountryMarkerViewOptions[size];
+ }
+ };
+}
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/view_custom_marker.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/view_custom_marker.xml
index 08caf1df66..98050c061f 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/view_custom_marker.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/layout/view_custom_marker.xml
@@ -14,6 +14,8 @@
android:textColor="@android:color/white"
android:layout_height="wrap_content"
android:textStyle="bold"
- android:layout_centerInParent="true" />
+ android:layout_alignBottom="@id/imageView"
+ android:layout_centerHorizontal="true"
+ android:padding="2dp"/>
</RelativeLayout> \ No newline at end of file
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
index a84035aa58..ce57e160c3 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/res/values/strings.xml
@@ -36,9 +36,10 @@
<!-- Other -->
<string name="activity_double_map">Double Map Activity</string>
+ <string name="activity_back_to_map">Back to map activity</string>
<string name="activity_snapshot">Snapshot Activity</string>
<string name="activity_user_tracking_mode">User tracking mode</string>
- <string name="activity_user_tracking_customization">User location customization</string>
+ <string name="activity_user_tracking_customization">User location drawable</string>
<string name="activity_user_dot_color">User location tint color</string>
<string name="activity_user_location_toggle">User location toggle</string>
<string name="activity_custom_layer">Custom Layer</string>
@@ -77,6 +78,7 @@
<string name="description_scroll_by">Scroll with pixels in x,y direction</string>
<string name="description_snapshot">Example to make a snapshot of the map</string>
<string name="description_doublemap">2 maps in a view hierarchy</string>
+ <string name="description_back_to_map">Restart map view after temporarily leaving to another activity</string>
<string name="description_view_marker">Use an Android SDK View as marker</string>
<string name="menuitem_title_concurrent_infowindow">Concurrent Open InfoWindows</string>r
@@ -152,4 +154,9 @@
<string name="geocoder_instructions">Tap Map To Geocode Where Black Marker Is Currently Located</string>
+ <string name="dynamic_marker_chelsea_title">Chelsea</string>
+ <string name="dynamic_marker_chelsea_snippet">Stamford Bridge</string>
+ <string name="dynamic_marker_arsenal_title">Arsenal</string>
+ <string name="dynamic_marker_arsenal_snippet">Emirates Stadium</string>
+
</resources>
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerViewTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerViewTest.java
index ed8e4ff323..a4b3248f2e 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerViewTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/annotations/MarkerViewTest.java
@@ -1,10 +1,8 @@
package com.mapbox.mapboxsdk.annotations;
-import android.graphics.Bitmap;
import android.os.Parcelable;
import com.mapbox.mapboxsdk.geometry.LatLng;
-import com.mapbox.mapboxsdk.testapp.R;
import com.mapbox.mapboxsdk.utils.MockParcel;
import org.junit.Test;
@@ -53,16 +51,6 @@ public class MarkerViewTest {
}
@Test
- public void testIcon() {
- Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_4444);
- Icon icon = IconFactory.recreate("test", bitmap);
- MarkerViewOptions markerOptions = new MarkerViewOptions().icon(icon);
- MarkerView marker = markerOptions.getMarker();
- assertEquals("Icon should match", icon, marker.getIcon());
- assertEquals("Icon should match", icon, markerOptions.getIcon());
- }
-
- @Test
public void testFlat() {
MarkerViewOptions markerOptions = new MarkerViewOptions().flat(true);
MarkerView marker = markerOptions.getMarker();
@@ -109,22 +97,6 @@ public class MarkerViewTest {
}
@Test
- public void testSelectAnimRes() {
- int animatorRes = R.animator.rotate_360;
- MarkerViewOptions markerOptions = new MarkerViewOptions().selectAnimatorResource(animatorRes);
- MarkerView marker = markerOptions.getMarker();
- assertEquals("select animator resource should match ", animatorRes, marker.getSelectAnimRes(), 0);
- }
-
- @Test
- public void testDeselectAnimRes() {
- int animatorRes = R.animator.rotate_360;
- MarkerViewOptions markerOptions = new MarkerViewOptions().deselectAnimatorResource(animatorRes);
- MarkerView marker = markerOptions.getMarker();
- assertEquals("deselect animator resource should match ", animatorRes, marker.getDeselectAnimRes(), 0);
- }
-
- @Test
public void testRotation() {
int rotation = 90;
MarkerViewOptions markerOptions = new MarkerViewOptions().rotation(rotation);
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettingsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettingsTest.java
index a03eb6acae..fd70308931 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettingsTest.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettingsTest.java
@@ -16,6 +16,7 @@ import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public class MyLocationViewSettingsTest {
@@ -41,6 +42,9 @@ public class MyLocationViewSettingsTest {
public void testForegroundDrawables() {
Drawable foregroundDrawable = mock(Drawable.class);
Drawable foregroundBearingDrawable = mock(Drawable.class);
+ Drawable.ConstantState constantState = mock(Drawable.ConstantState.class);
+ when(foregroundDrawable.getConstantState()).thenReturn(constantState);
+ when(constantState.newDrawable()).thenReturn(foregroundDrawable);
locationViewSettings.setForegroundDrawable(foregroundDrawable, foregroundBearingDrawable);
assertEquals("foreground should match", foregroundDrawable, locationViewSettings.getForegroundDrawable());
assertEquals("foreground bearing should match", foregroundBearingDrawable, locationViewSettings.getForegroundBearingDrawable());
diff --git a/platform/android/bitrise.yml b/platform/android/bitrise.yml
index 3c06a04675..5eb5cfa508 100644
--- a/platform/android/bitrise.yml
+++ b/platform/android/bitrise.yml
@@ -75,7 +75,7 @@ workflows:
signing.secretKeyRingFile=secring.gpg" >> platform/android/MapboxGLAndroidSDK/gradle.properties
export BUILDTYPE=Release
- make apackage -j4
+ make apackage
cd platform/android
./gradlew uploadArchives
diff --git a/platform/android/src/async_task.cpp b/platform/android/src/async_task.cpp
index 4a68c1c093..6a9263baff 100644
--- a/platform/android/src/async_task.cpp
+++ b/platform/android/src/async_task.cpp
@@ -1,9 +1,9 @@
#include "run_loop_impl.hpp"
#include <mbgl/util/async_task.hpp>
+#include <mbgl/util/atomic.hpp>
#include <mbgl/util/run_loop.hpp>
-#include <atomic>
#include <functional>
namespace mbgl {
@@ -12,7 +12,7 @@ namespace util {
class AsyncTask::Impl : public RunLoop::Impl::Runnable {
public:
Impl(std::function<void()>&& fn)
- : task(std::move(fn)) {
+ : queued(true), task(std::move(fn)) {
loop->initRunnable(this);
}
@@ -21,7 +21,8 @@ public:
}
void maySend() {
- if (!queued.test_and_set()) {
+ if (queued) {
+ queued = false;
loop->addRunnable(this);
}
}
@@ -32,7 +33,7 @@ public:
void runTask() override {
loop->removeRunnable(this);
- queued.clear();
+ queued = true;
task();
}
@@ -42,7 +43,9 @@ private:
RunLoop::Impl* loop = reinterpret_cast<RunLoop::Impl*>(RunLoop::getLoopHandle());
- std::atomic_flag queued = ATOMIC_FLAG_INIT;
+ // TODO: Use std::atomic_flag if we ever drop
+ // support for ARMv5
+ util::Atomic<bool> queued;
std::function<void()> task;
};
diff --git a/platform/android/src/jni.cpp b/platform/android/src/jni.cpp
index e79689d7ad..6f1b892c7e 100755
--- a/platform/android/src/jni.cpp
+++ b/platform/android/src/jni.cpp
@@ -660,7 +660,25 @@ void nativeResetNorth(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr) {
nativeMapView->getMap().resetNorth();
}
-void nativeUpdateMarker(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* marker) {
+jlong nativeAddMarker(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jni::jobject* marker) {
+ mbgl::Log::Debug(mbgl::Event::JNI, "nativeAddMarker");
+ assert(nativeMapViewPtr != 0);
+ NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
+
+ jni::jobject* position = jni::GetField<jni::jobject*>(*env, marker, *markerPositionId);
+ jni::jobject* icon = jni::GetField<jni::jobject*>(*env, marker, *markerIconId);
+
+ jni::jstring* jid = reinterpret_cast<jni::jstring*>(jni::GetField<jni::jobject*>(*env, icon, *iconIdId));
+ std::string id = std_string_from_jstring(env, jid);
+
+ jdouble latitude = jni::GetField<jdouble>(*env, position, *latLngLatitudeId);
+ jdouble longitude = jni::GetField<jdouble>(*env, position, *latLngLongitudeId);
+
+ // Because Java only has int, not unsigned int, we need to bump the annotation id up to a long.
+ return nativeMapView->getMap().addPointAnnotation(mbgl::PointAnnotation(mbgl::LatLng(latitude, longitude), id));
+}
+
+void nativeUpdateMarker(JNIEnv *env, jni::jobject* obj, jlong nativeMapViewPtr, jlong markerId, jdouble lat, jdouble lon, jni::jstring* jid) {
mbgl::Log::Debug(mbgl::Event::JNI, "nativeUpdateMarker");
assert(nativeMapViewPtr != 0);
NativeMapView *nativeMapView = reinterpret_cast<NativeMapView *>(nativeMapViewPtr);
@@ -1188,7 +1206,7 @@ void listOfflineRegions(JNIEnv *env, jni::jobject* obj, jlong defaultFileSourceP
jni::SetField<jni::jobject*>(*env2, jregion, *offlineRegionOfflineManagerId, obj);
jni::SetField<jlong>(*env2, jregion, *offlineRegionIdId, region.getID());
-
+
// Definition object
mbgl::OfflineTilePyramidRegionDefinition definition = region.getDefinition();
jni::jobject* jdefinition = &jni::NewObject(*env2, *offlineRegionDefinitionClass, *offlineRegionDefinitionConstructorId);
@@ -1198,7 +1216,7 @@ void listOfflineRegions(JNIEnv *env, jni::jobject* obj, jlong defaultFileSourceP
jni::SetField<jdouble>(*env2, jdefinition, *offlineRegionDefinitionMaxZoomId, definition.maxZoom);
jni::SetField<jfloat>(*env2, jdefinition, *offlineRegionDefinitionPixelRatioId, definition.pixelRatio);
jni::SetField<jni::jobject*>(*env2, jregion, *offlineRegionDefinitionId, jdefinition);
-
+
// Metadata object
jni::jarray<jbyte>* metadata = metadata_from_native(env2, region.getMetadata());
jni::SetField<jni::jobject*>(*env2, jregion, *offlineRegionMetadataId, metadata);
diff --git a/platform/android/src/run_loop_impl.hpp b/platform/android/src/run_loop_impl.hpp
index 5cf7231175..d855728b60 100644
--- a/platform/android/src/run_loop_impl.hpp
+++ b/platform/android/src/run_loop_impl.hpp
@@ -2,10 +2,10 @@
#include "jni.hpp"
+#include <mbgl/util/atomic.hpp>
#include <mbgl/util/chrono.hpp>
#include <mbgl/util/run_loop.hpp>
-#include <atomic>
#include <list>
#include <memory>
#include <mutex>
@@ -47,7 +47,7 @@ private:
bool detach = false;
ALooper* loop = nullptr;
- std::atomic<bool> running;
+ util::Atomic<bool> running;
std::recursive_mutex mtx;
std::list<Runnable*> runnables;
diff --git a/src/mbgl/geometry/glyph_atlas.hpp b/src/mbgl/geometry/glyph_atlas.hpp
index d4a51761a1..3f9a87809f 100644
--- a/src/mbgl/geometry/glyph_atlas.hpp
+++ b/src/mbgl/geometry/glyph_atlas.hpp
@@ -2,6 +2,7 @@
#include <mbgl/geometry/binpack.hpp>
#include <mbgl/text/glyph_store.hpp>
+#include <mbgl/util/atomic.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/optional.hpp>
#include <mbgl/gl/gl.hpp>
@@ -11,7 +12,6 @@
#include <set>
#include <unordered_map>
#include <mutex>
-#include <atomic>
namespace mbgl {
diff --git a/src/mbgl/geometry/vao.hpp b/src/mbgl/geometry/vao.hpp
index 150a6badbd..979bc2a54c 100644
--- a/src/mbgl/geometry/vao.hpp
+++ b/src/mbgl/geometry/vao.hpp
@@ -25,7 +25,7 @@ public:
if (bound_shader == 0) {
vertexBuffer.bind(store);
shader.bind(offset);
- if (vao) {
+ if (vao.created()) {
storeBinding(shader, vertexBuffer.getID(), 0, offset);
}
} else {
@@ -40,7 +40,7 @@ public:
vertexBuffer.bind(store);
elementsBuffer.bind(store);
shader.bind(offset);
- if (vao) {
+ if (vao.created()) {
storeBinding(shader, vertexBuffer.getID(), elementsBuffer.getID(), offset);
}
} else {
diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp
index 194a98153b..b08d3ef710 100644
--- a/src/mbgl/map/map.cpp
+++ b/src/mbgl/map/map.cpp
@@ -510,7 +510,7 @@ CameraOptions Map::cameraForLatLngs(const std::vector<LatLng>& latLngs, optional
scaleY -= (padding->top + padding->bottom) / height;
}
double minScale = ::fmin(scaleX, scaleY);
- double zoom = ::log2(getScale() * minScale);
+ double zoom = util::log2(getScale() * minScale);
zoom = util::clamp(zoom, getMinZoom(), getMaxZoom());
// Calculate the center point of a virtual bounds that is extended in all directions by padding.
diff --git a/src/mbgl/map/transform_state.cpp b/src/mbgl/map/transform_state.cpp
index ac8b6396c7..fab5991de8 100644
--- a/src/mbgl/map/transform_state.cpp
+++ b/src/mbgl/map/transform_state.cpp
@@ -222,7 +222,7 @@ double TransformState::zoomScale(double zoom) const {
}
double TransformState::scaleZoom(double s) const {
- return ::log2(s);
+ return util::log2(s);
}
double TransformState::worldSize() const {
diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp
index c7ebe480ed..f12ed1fb96 100644
--- a/src/mbgl/renderer/bucket.hpp
+++ b/src/mbgl/renderer/bucket.hpp
@@ -2,11 +2,10 @@
#include <mbgl/gl/gl.hpp>
#include <mbgl/renderer/render_pass.hpp>
+#include <mbgl/util/atomic.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/mat4.hpp>
-#include <atomic>
-
#define BUFFER_OFFSET_0 ((GLbyte*)nullptr)
#define BUFFER_OFFSET(i) ((BUFFER_OFFSET_0) + (i))
@@ -50,7 +49,7 @@ public:
virtual void swapRenderData() {}
protected:
- std::atomic<bool> uploaded;
+ util::Atomic<bool> uploaded;
};
diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp
index 249b863c92..3d91f5c9d8 100644
--- a/src/mbgl/sprite/sprite_atlas.hpp
+++ b/src/mbgl/sprite/sprite_atlas.hpp
@@ -3,6 +3,7 @@
#include <mbgl/geometry/binpack.hpp>
#include <mbgl/gl/gl.hpp>
#include <mbgl/gl/object_store.hpp>
+#include <mbgl/util/atomic.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/ptr.hpp>
#include <mbgl/util/optional.hpp>
@@ -10,7 +11,6 @@
#include <string>
#include <map>
#include <mutex>
-#include <atomic>
#include <set>
#include <array>
@@ -92,7 +92,7 @@ private:
std::map<Key, Holder> images;
std::set<std::string> uninitialized;
std::unique_ptr<uint32_t[]> data;
- std::atomic<bool> dirty;
+ util::Atomic<bool> dirty;
bool fullUploadRequired = true;
mbgl::optional<gl::UniqueTexture> texture;
uint32_t filter = 0;
diff --git a/src/mbgl/storage/network_status.cpp b/src/mbgl/storage/network_status.cpp
index 1ef5619bd6..bc538a5f38 100644
--- a/src/mbgl/storage/network_status.cpp
+++ b/src/mbgl/storage/network_status.cpp
@@ -9,7 +9,7 @@
namespace mbgl {
-std::atomic<bool> NetworkStatus::online(true);
+util::Atomic<bool> NetworkStatus::online(true);
std::mutex NetworkStatus::mtx;
std::set<util::AsyncTask *> NetworkStatus::observers;
diff --git a/src/mbgl/style/bucket_parameters.hpp b/src/mbgl/style/bucket_parameters.hpp
index f85e1e17ef..8c1da72f25 100644
--- a/src/mbgl/style/bucket_parameters.hpp
+++ b/src/mbgl/style/bucket_parameters.hpp
@@ -3,9 +3,9 @@
#include <mbgl/map/mode.hpp>
#include <mbgl/tile/tile_id.hpp>
#include <mbgl/style/filter.hpp>
+#include <mbgl/util/atomic.hpp>
#include <functional>
-#include <atomic>
namespace mbgl {
@@ -24,7 +24,7 @@ class BucketParameters {
public:
BucketParameters(const OverscaledTileID& tileID_,
const GeometryTileLayer& layer_,
- const std::atomic<bool>& obsolete_,
+ const util::Atomic<bool>& obsolete_,
uintptr_t tileUID_,
bool& partialParse_,
SpriteStore& spriteStore_,
@@ -51,7 +51,7 @@ public:
const OverscaledTileID& tileID;
const GeometryTileLayer& layer;
- const std::atomic<bool>& obsolete;
+ const util::Atomic<bool>& obsolete;
uintptr_t tileUID;
bool& partialParse;
SpriteStore& spriteStore;
diff --git a/src/mbgl/text/glyph_pbf.hpp b/src/mbgl/text/glyph_pbf.hpp
index 85f4b62e6f..c238cbb5d7 100644
--- a/src/mbgl/text/glyph_pbf.hpp
+++ b/src/mbgl/text/glyph_pbf.hpp
@@ -2,10 +2,10 @@
#include <mbgl/text/glyph.hpp>
#include <mbgl/text/glyph_store.hpp>
+#include <mbgl/util/atomic.hpp>
#include <mbgl/util/font_stack.hpp>
#include <mbgl/util/noncopyable.hpp>
-#include <atomic>
#include <functional>
#include <string>
#include <memory>
@@ -29,7 +29,7 @@ public:
}
private:
- std::atomic<bool> parsed;
+ util::Atomic<bool> parsed;
std::unique_ptr<AsyncRequest> req;
GlyphStoreObserver* observer = nullptr;
};
diff --git a/src/mbgl/tile/tile_worker.cpp b/src/mbgl/tile/tile_worker.cpp
index b2283043da..1890aa7c47 100644
--- a/src/mbgl/tile/tile_worker.cpp
+++ b/src/mbgl/tile/tile_worker.cpp
@@ -24,7 +24,7 @@ TileWorker::TileWorker(const OverscaledTileID& id_,
SpriteStore& spriteStore_,
GlyphAtlas& glyphAtlas_,
GlyphStore& glyphStore_,
- const std::atomic<bool>& obsolete_,
+ const util::Atomic<bool>& obsolete_,
const MapMode mode_)
: id(id_),
sourceID(std::move(sourceID_)),
diff --git a/src/mbgl/tile/tile_worker.hpp b/src/mbgl/tile/tile_worker.hpp
index 2757c0f9ba..631a8c929f 100644
--- a/src/mbgl/tile/tile_worker.hpp
+++ b/src/mbgl/tile/tile_worker.hpp
@@ -2,6 +2,7 @@
#include <mbgl/map/mode.hpp>
#include <mbgl/tile/tile_id.hpp>
+#include <mbgl/util/atomic.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/variant.hpp>
#include <mbgl/util/ptr.hpp>
@@ -12,7 +13,6 @@
#include <memory>
#include <mutex>
#include <list>
-#include <atomic>
#include <unordered_map>
namespace mbgl {
@@ -50,7 +50,7 @@ public:
SpriteStore&,
GlyphAtlas&,
GlyphStore&,
- const std::atomic<bool>&,
+ const util::Atomic<bool>&,
const MapMode);
~TileWorker();
@@ -75,7 +75,7 @@ private:
SpriteStore& spriteStore;
GlyphAtlas& glyphAtlas;
GlyphStore& glyphStore;
- const std::atomic<bool>& obsolete;
+ const util::Atomic<bool>& obsolete;
const MapMode mode;
bool partialParse = false;
diff --git a/src/mbgl/tile/vector_tile_data.hpp b/src/mbgl/tile/vector_tile_data.hpp
index e7de39e038..df2a23fda6 100644
--- a/src/mbgl/tile/vector_tile_data.hpp
+++ b/src/mbgl/tile/vector_tile_data.hpp
@@ -3,9 +3,9 @@
#include <mbgl/tile/tile_data.hpp>
#include <mbgl/tile/tile_worker.hpp>
#include <mbgl/text/placement_config.hpp>
+#include <mbgl/util/atomic.hpp>
#include <mbgl/util/feature.hpp>
-#include <atomic>
#include <memory>
#include <unordered_map>
@@ -69,7 +69,7 @@ private:
PlacementConfig targetConfig;
// Used to signal the worker that it should abandon parsing this tile as soon as possible.
- std::atomic<bool> obsolete { false };
+ util::Atomic<bool> obsolete { false };
};
} // namespace mbgl
diff --git a/src/mbgl/util/atomic.hpp b/src/mbgl/util/atomic.hpp
new file mode 100644
index 0000000000..3f68bf46a5
--- /dev/null
+++ b/src/mbgl/util/atomic.hpp
@@ -0,0 +1,45 @@
+#pragma once
+
+#include <atomic>
+#include <mutex>
+
+namespace mbgl {
+namespace util {
+
+// std::atomic<bool> is implemented lock free which
+// is not supported by ARMv5 but the code generated
+// seems to be using that and not working at all,
+// thus, this naive implementation using mutexes.
+#if defined(__ANDROID__) && defined(__ARM_ARCH_5TE__)
+
+template <typename T>
+class Atomic {
+public:
+ Atomic() = default;
+ explicit Atomic(const T& data_) : data(data_) {}
+
+ void operator=(const T& other) {
+ std::lock_guard<std::mutex> lock(mtx);
+ data = other;
+ }
+
+ operator bool() const {
+ std::lock_guard<std::mutex> lock(mtx);
+
+ return data;
+ }
+
+private:
+ T data;
+ mutable std::mutex mtx;
+};
+
+#else
+
+template <typename T>
+using Atomic = std::atomic<T>;
+
+#endif
+
+} // namespace util
+} // namespace mbgl
diff --git a/src/mbgl/util/math.cpp b/src/mbgl/util/math.cpp
index a524754109..0e86849ad3 100644
--- a/src/mbgl/util/math.cpp
+++ b/src/mbgl/util/math.cpp
@@ -21,5 +21,15 @@ uint32_t ceil_log2(uint64_t x) {
return y;
}
+double log2(double x) {
+// log2() is producing wrong results on ARMv5 binaries
+// running on ARMv7+ CPUs.
+#if defined(__ANDROID__) && defined(__ARM_ARCH_5TE__)
+ return std::log(x) / 0.6931471805599453; // log(x) / log(2)
+#else
+ return ::log2(x);
+#endif
+}
+
} // namespace util
-} // namespace mbgl \ No newline at end of file
+} // namespace mbgl
diff --git a/src/mbgl/util/math.hpp b/src/mbgl/util/math.hpp
index ef60f76ffe..bfedc2a421 100644
--- a/src/mbgl/util/math.hpp
+++ b/src/mbgl/util/math.hpp
@@ -110,5 +110,7 @@ T smoothstep(T edge0, T edge1, T x) {
// (== number of bits required to store x)
uint32_t ceil_log2(uint64_t x);
+double log2(double x);
+
} // namespace util
} // namespace mbgl
diff --git a/src/mbgl/util/thread.hpp b/src/mbgl/util/thread.hpp
index 9efd5ea92f..c5f9d7338a 100644
--- a/src/mbgl/util/thread.hpp
+++ b/src/mbgl/util/thread.hpp
@@ -6,6 +6,7 @@
#include <utility>
#include <functional>
+#include <mbgl/util/atomic.hpp>
#include <mbgl/util/run_loop.hpp>
#include <mbgl/util/thread_context.hpp>
#include <mbgl/platform/platform.hpp>