Merge branch 'release-android-v4.1.0'

# Conflicts:
#	platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/BaseMarkerViewOptions.java
#	platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java
#	platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java
#	platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java
#	platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java
#	platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java
#	platform/android/src/jni.cpp
#	src/mbgl/geometry/buffer.hpp
#	src/mbgl/geometry/glyph_atlas.cpp
#	src/mbgl/geometry/glyph_atlas.hpp
#	src/mbgl/geometry/line_atlas.cpp
#	src/mbgl/geometry/vao.cpp
#	src/mbgl/gl/gl_object_store.cpp
#	src/mbgl/gl/gl_object_store.hpp
#	src/mbgl/renderer/frame_history.cpp
#	src/mbgl/shader/shader.cpp
#	src/mbgl/sprite/sprite_atlas.cpp
#	src/mbgl/sprite/sprite_atlas.hpp
#	src/mbgl/text/glyph_pbf.hpp
This commit is contained in:
Brad Leege
2016-06-09 14:00:49 -05:00
66 changed files with 1177 additions and 646 deletions

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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.

View File

@@ -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()) {

View File

@@ -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();
}
@@ -243,30 +220,12 @@ public abstract class BaseMarkerViewOptions<U extends MarkerView, T extends Base
return infoWindowAnchorV;
}
/**
* 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;
}

View File

@@ -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

View File

@@ -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;
}
@@ -190,42 +197,6 @@ public class MarkerView extends Marker {
this.flat = flat;
}
/**
* 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.
*
@@ -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,13 +279,52 @@ 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);
}
}
/**
* 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>

View File

@@ -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);
@@ -144,70 +152,119 @@ 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) {
int deselectAnimatorRes = marker.getDeselectAnimRes();
if (deselectAnimatorRes != 0) {
AnimatorUtils.animate(convertView, deselectAnimatorRes);
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) {
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;
}
}
}

View File

@@ -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;

View File

@@ -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,168 +17,32 @@ 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).
* 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
*/
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
*/
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.
*
@@ -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";
}

View File

@@ -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).

View File

@@ -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;
}

View File

@@ -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);
}
/**
@@ -1840,12 +1840,57 @@ public class MapboxMap {
@Nullable
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);
}
}
/**

View File

@@ -462,6 +462,16 @@ public class MapboxMapOptions implements Parcelable {
return this;
}
/**
*
* @param myLocationForegroundDrawable
* @return This
*/
public MapboxMapOptions myLocationForegroundDrawable(Drawable myLocationForegroundDrawable) {
this.myLocationForegroundDrawable = myLocationForegroundDrawable;
return this;
}
/**
* @param myLocationBackgroundDrawable
* @return This

View File

@@ -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);
}

View File

@@ -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 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 foregroundWidth = foregroundDrawable.getIntrinsicWidth();
int foregroundHeight = foregroundDrawable.getIntrinsicHeight();
foregroundBounds = new Rect(-foregroundWidth / 2, -foregroundHeight / 2, foregroundWidth / 2, foregroundHeight / 2);
foregroundDrawable.setBounds(foregroundBounds);
foregroundBearingDrawable.setBounds(foregroundBounds);
int horizontalOffset = backgroundOffsetLeft - backgroundOffsetRight;
int verticalOffset = backgroundOffsetTop - backgroundOffsetBottom;
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));
// 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
float metersPerPixel = (float) projection.getMetersPerPixelAtLatitude(location.getLatitude());
float accuracyPixels = (Float) accuracyAnimator.getAnimatedValue() / metersPerPixel;
float maxRadius = getWidth() / 2;
canvas.drawCircle(foregroundBounds.centerX(), foregroundBounds.centerY(), accuracyPixels <= maxRadius ? accuracyPixels : maxRadius, accuracyPaint);
final PointF pointF = screenLocation;
// Draw shadow
float metersPerPixel = (float) projection.getMetersPerPixelAtLatitude(location.getLatitude());
float accuracyPixels = (Float) accuracyAnimator.getAnimatedValue() / metersPerPixel / 2;
float maxRadius = getWidth() / 2;
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());
}
// 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();
}
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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)

View File

@@ -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>

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View File

@@ -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) {

View File

@@ -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

View File

@@ -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,47 +148,62 @@ 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 LayoutInflater inflater;
private void loopMarkerMove() {
locationUpdateHandler.postDelayed(moveMarkerRunnable, randomAnimator.nextInt(3000) + 1000);
}
public TextAdapter(@NonNull Context context) {
super(context);
this.inflater = LayoutInflater.from(context);
}
@Override
protected void onStop() {
super.onStop();
locationUpdateHandler.removeCallbacks(moveMarkerRunnable);
}
@Nullable
private class MoveMarkerRunnable implements Runnable {
@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);
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 {
viewHolder = (ViewHolder) convertView.getTag();
movingMarkerTwo.setPosition(CarLocation.CAR_1_LNGS[i]);
movingMarkerTwo.setRotation(rotation = rotation + 90);
}
viewHolder.title.setText(marker.getTitle());
return convertView;
}
private static class ViewHolder {
TextView title;
loopMarkerMove();
}
}
private static class CountryAdapter extends MapboxMap.MarkerViewAdapter<CountryMarkerView> {
private LayoutInflater inflater;
private MapboxMap mapboxMap;
public CountryAdapter(@NonNull Context context) {
public CountryAdapter(@NonNull Context context, @NonNull MapboxMap mapboxMap) {
super(context);
this.inflater = LayoutInflater.from(context);
this.mapboxMap = mapboxMap;
}
@Nullable
@@ -179,12 +224,143 @@ public class MarkerViewActivity extends AppCompatActivity {
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 {
ImageView flag;
TextView abbrev;
}
}
private static class TextAdapter extends MapboxMap.MarkerViewAdapter<TextMarkerView> {
private LayoutInflater inflater;
private MapboxMap mapboxMap;
public TextAdapter(@NonNull Context context, @NonNull MapboxMap mapboxMap) {
super(context);
this.inflater = LayoutInflater.from(context);
this.mapboxMap = mapboxMap;
}
@Nullable
@Override
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_text_marker, parent, false);
viewHolder.textView = (TextView) convertView.findViewById(R.id.textView);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
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 {
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)
};
}
}

View File

@@ -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)

View File

@@ -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() {

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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();

View File

@@ -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

View File

@@ -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))

View File

@@ -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) {

View File

@@ -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;
}
}

View File

@@ -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];
}
};
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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;
@@ -52,16 +50,6 @@ public class MarkerViewTest {
assertEquals(markerOptions.getTitle(), "Mapbox");
}
@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);
@@ -108,22 +96,6 @@ public class MarkerViewTest {
assertEquals("anchorU should match ", 0, marker.getInfoWindowAnchorV(), 0);
}
@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;

View File

@@ -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());

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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);

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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.

View File

@@ -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 {

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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_)),

View File

@@ -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;

View File

@@ -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

45
src/mbgl/util/atomic.hpp Normal file
View File

@@ -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

View File

@@ -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
} // namespace mbgl

View File

@@ -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

View File

@@ -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>