diff options
author | Tobrun Van Nuland <tobrun.van.nuland@gmail.com> | 2017-02-06 15:34:48 +0100 |
---|---|---|
committer | Tobrun <tobrun.van.nuland@gmail.com> | 2017-02-10 22:32:24 +0100 |
commit | 3423275ca65236706e931b1b7edc3627a722176c (patch) | |
tree | d2d5a6df44e945a411679bdf9093b3daebb1f5e1 | |
parent | 2fc070ca9995bf4ceb4599ce7a94bee7a03b10b4 (diff) | |
download | qtlocation-mapboxgl-3423275ca65236706e931b1b7edc3627a722176c.tar.gz |
[android] - add state keeping
47 files changed, 2661 insertions, 1634 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java index 57e9373a42..c801720fa1 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/InfoWindow.java @@ -13,6 +13,7 @@ import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.Callback; import java.lang.ref.WeakReference; @@ -113,14 +114,15 @@ public class InfoWindow { * the view from the object position. * @return this {@link InfoWindow}. */ - InfoWindow open(MapView mapView, Marker boundMarker, LatLng position, int offsetX, int offsetY) { + InfoWindow open(final MapView mapView, final Marker boundMarker, final LatLng position, final int offsetX, + final int offsetY) { setBoundMarker(boundMarker); - MapView.LayoutParams lp = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT, + final MapView.LayoutParams lp = new MapView.LayoutParams(MapView.LayoutParams.WRAP_CONTENT, MapView.LayoutParams.WRAP_CONTENT); MapboxMap mapboxMap = this.mapboxMap.get(); - View view = this.view.get(); + final View view = this.view.get(); if (view != null && mapboxMap != null) { view.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); @@ -129,78 +131,83 @@ public class InfoWindow { markerWidthOffset = -offsetX; // Calculate default Android x,y coordinate - coordinates = mapboxMap.getProjection().toScreenLocation(position); - float x = coordinates.x - (view.getMeasuredWidth() / 2) + offsetX; - float y = coordinates.y - view.getMeasuredHeight() + offsetY; - - if (view instanceof InfoWindowView) { - // only apply repositioning/margin for InfoWindowView - Resources resources = mapView.getContext().getResources(); - - // get right/left popup window - float rightSideInfowWindow = x + view.getMeasuredWidth(); - float leftSideInfoWindow = x; - - // get right/left map view - final float mapRight = mapView.getRight(); - final float mapLeft = mapView.getLeft(); - - float marginHorizontal = resources.getDimension(R.dimen.mapbox_infowindow_margin); - float tipViewOffset = resources.getDimension(R.dimen.mapbox_infowindow_tipview_width) / 2; - float tipViewMarginLeft = view.getMeasuredWidth() / 2 - tipViewOffset; - - boolean outOfBoundsLeft = false; - boolean outOfBoundsRight = false; - - // only optimise margins if view is inside current viewport - if (coordinates.x >= 0 && coordinates.x <= mapView.getWidth() - && coordinates.y >= 0 && coordinates.y <= mapView.getHeight()) { - - // if out of bounds right - if (rightSideInfowWindow > mapRight) { - outOfBoundsRight = true; - x -= rightSideInfowWindow - mapRight; - tipViewMarginLeft += rightSideInfowWindow - mapRight + tipViewOffset; - rightSideInfowWindow = x + view.getMeasuredWidth(); + mapboxMap.getProjection().toScreenLocation(position, new Callback<PointF>() { + @Override + public void onResult(PointF pointF) { + coordinates = pointF; + float x = coordinates.x - (view.getMeasuredWidth() / 2) + offsetX; + float y = coordinates.y - view.getMeasuredHeight() + offsetY; + + if (view instanceof InfoWindowView) { + // only apply repositioning/margin for InfoWindowView + Resources resources = mapView.getContext().getResources(); + + // get right/left popup window + float rightSideInfowWindow = x + view.getMeasuredWidth(); + float leftSideInfoWindow = x; + + // get right/left map view + final float mapRight = mapView.getRight(); + final float mapLeft = mapView.getLeft(); + + float marginHorizontal = resources.getDimension(R.dimen.mapbox_infowindow_margin); + float tipViewOffset = resources.getDimension(R.dimen.mapbox_infowindow_tipview_width) / 2; + float tipViewMarginLeft = view.getMeasuredWidth() / 2 - tipViewOffset; + + boolean outOfBoundsLeft = false; + boolean outOfBoundsRight = false; + + // only optimise margins if view is inside current viewport + if (coordinates.x >= 0 && coordinates.x <= mapView.getWidth() + && coordinates.y >= 0 && coordinates.y <= mapView.getHeight()) { + + // if out of bounds right + if (rightSideInfowWindow > mapRight) { + outOfBoundsRight = true; + x -= rightSideInfowWindow - mapRight; + tipViewMarginLeft += rightSideInfowWindow - mapRight + tipViewOffset; + rightSideInfowWindow = x + view.getMeasuredWidth(); + } + + // fit screen left + if (leftSideInfoWindow < mapLeft) { + outOfBoundsLeft = true; + x += mapLeft - leftSideInfoWindow; + tipViewMarginLeft -= mapLeft - leftSideInfoWindow + tipViewOffset; + leftSideInfoWindow = x; + } + + // Add margin right + if (outOfBoundsRight && mapRight - rightSideInfowWindow < marginHorizontal) { + x -= marginHorizontal - (mapRight - rightSideInfowWindow); + tipViewMarginLeft += marginHorizontal - (mapRight - rightSideInfowWindow) - tipViewOffset; + leftSideInfoWindow = x; + } + + // Add margin left + if (outOfBoundsLeft && leftSideInfoWindow - mapLeft < marginHorizontal) { + x += marginHorizontal - (leftSideInfoWindow - mapLeft); + tipViewMarginLeft -= (marginHorizontal - (leftSideInfoWindow - mapLeft)) - tipViewOffset; + } + } + + // Adjust tipView + InfoWindowView infoWindowView = (InfoWindowView) view; + infoWindowView.setTipViewMarginLeft((int) tipViewMarginLeft); } - // fit screen left - if (leftSideInfoWindow < mapLeft) { - outOfBoundsLeft = true; - x += mapLeft - leftSideInfoWindow; - tipViewMarginLeft -= mapLeft - leftSideInfoWindow + tipViewOffset; - leftSideInfoWindow = x; - } + // set anchor popupwindowview + view.setX(x); + view.setY(y); - // Add margin right - if (outOfBoundsRight && mapRight - rightSideInfowWindow < marginHorizontal) { - x -= marginHorizontal - (mapRight - rightSideInfowWindow); - tipViewMarginLeft += marginHorizontal - (mapRight - rightSideInfowWindow) - tipViewOffset; - leftSideInfoWindow = x; - } + // Calculate x-offset for update method + viewWidthOffset = x - coordinates.x - offsetX; - // Add margin left - if (outOfBoundsLeft && leftSideInfoWindow - mapLeft < marginHorizontal) { - x += marginHorizontal - (leftSideInfoWindow - mapLeft); - tipViewMarginLeft -= (marginHorizontal - (leftSideInfoWindow - mapLeft)) - tipViewOffset; - } + close(); // if it was already opened + mapView.addView(view, lp); + isVisible = true; } - - // Adjust tipView - InfoWindowView infoWindowView = (InfoWindowView) view; - infoWindowView.setTipViewMarginLeft((int) tipViewMarginLeft); - } - - // set anchor popupwindowview - view.setX(x); - view.setY(y); - - // Calculate x-offset for update method - viewWidthOffset = x - coordinates.x - offsetX; - - close(); // if it was already opened - mapView.addView(view, lp); - isVisible = true; + }); } return this; } @@ -214,9 +221,14 @@ public class InfoWindow { MapboxMap mapboxMap = this.mapboxMap.get(); if (isVisible && mapboxMap != null) { isVisible = false; - View view = this.view.get(); + final View view = this.view.get(); if (view != null && view.getParent() != null) { - ((ViewGroup) view.getParent()).removeView(view); + view.post(new Runnable() { + @Override + public void run() { + ((ViewGroup) view.getParent()).removeView(view); + } + }); } Marker marker = getBoundMarker(); @@ -280,16 +292,20 @@ public class InfoWindow { public void update() { MapboxMap mapboxMap = this.mapboxMap.get(); Marker marker = boundMarker.get(); - View view = this.view.get(); + final View view = this.view.get(); if (mapboxMap != null && marker != null && view != null) { - coordinates = mapboxMap.getProjection().toScreenLocation(marker.getPosition()); - - if (view instanceof InfoWindowView) { - view.setX(coordinates.x + viewWidthOffset - markerWidthOffset); - } else { - view.setX(coordinates.x - (view.getMeasuredWidth() / 2) - markerWidthOffset); - } - view.setY(coordinates.y + markerHeightOffset); + mapboxMap.getProjection().toScreenLocation(marker.getPosition(), new Callback<PointF>() { + @Override + public void onResult(PointF pointF) { + coordinates = pointF; + if (view instanceof InfoWindowView) { + view.setX(coordinates.x + viewWidthOffset - markerWidthOffset); + } else { + view.setX(coordinates.x - (view.getMeasuredWidth() / 2) - markerWidthOffset); + } + view.setY(coordinates.y + markerHeightOffset); + } + }); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java index e6d7843d9f..b47407f571 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java @@ -16,6 +16,7 @@ import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.utils.AnimatorUtils; import java.util.ArrayList; @@ -34,7 +35,7 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { private final ViewGroup markerViewContainer; private final Map<MarkerView, View> markerViewMap = new HashMap<>(); - private final LongSparseArray<OnMarkerViewAddedListener> markerViewAddedListenerMap = new LongSparseArray<>(); + private final LongSparseArray<Callback<MarkerView>> markerViewAddedListenerMap = new LongSparseArray<>(); private final List<MapboxMap.MarkerViewAdapter> markerViewAdapters = new ArrayList<>(); // TODO refactor MapboxMap out for Projection and Transform @@ -177,30 +178,34 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { for (final MarkerView marker : markerViewMap.keySet()) { final View convertView = markerViewMap.get(marker); if (convertView != null) { - PointF point = mapboxMap.getProjection().toScreenLocation(marker.getPosition()); - if (marker.getOffsetX() == MapboxConstants.UNMEASURED) { - // ensure view is measured first - if (marker.getWidth() == 0) { - convertView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - if (convertView.getMeasuredWidth() != 0) { - marker.setWidth(convertView.getMeasuredWidth()); - marker.setHeight(convertView.getMeasuredHeight()); + mapboxMap.getProjection().toScreenLocation(marker.getPosition(), new Callback<PointF>() { + @Override + public void onResult(PointF point) { + if (marker.getOffsetX() == MapboxConstants.UNMEASURED) { + // ensure view is measured first + if (marker.getWidth() == 0) { + convertView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); + if (convertView.getMeasuredWidth() != 0) { + marker.setWidth(convertView.getMeasuredWidth()); + marker.setHeight(convertView.getMeasuredHeight()); + } + } + } + if (marker.getWidth() != 0) { + int x = (int) (marker.getAnchorU() * marker.getWidth()); + int y = (int) (marker.getAnchorV() * marker.getHeight()); + marker.setOffset(x, y); } - } - } - if (marker.getWidth() != 0) { - int x = (int) (marker.getAnchorU() * marker.getWidth()); - int y = (int) (marker.getAnchorV() * marker.getHeight()); - marker.setOffset(x, y); - } - convertView.setX(point.x - marker.getOffsetX()); - convertView.setY(point.y - marker.getOffsetY()); + convertView.setX(point.x - marker.getOffsetX()); + convertView.setY(point.y - marker.getOffsetY()); - // animate visibility - if (marker.isVisible() && convertView.getVisibility() == View.GONE) { - animateVisible(marker, true); - } + // animate visibility + if (marker.isVisible() && convertView.getVisibility() == View.GONE) { + animateVisible(marker, true); + } + } + }); } } } @@ -239,7 +244,7 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { * Animate a MarkerView to a deselected state. * <p> * The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onDeselect(MarkerView, View)} - * will be called to execute an animation. + * will be called to executeOnRenderThread an animation. * </p> * * @param marker the MarkerView to deselect. @@ -252,7 +257,7 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { * Animate a MarkerView to a deselected state. * <p> * The {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter#onDeselect(MarkerView, View)} - * will be called to execute an animation. + * will be called to executeOnRenderThread an animation. * </p> * * @param marker the MarkerView to deselect. @@ -301,7 +306,7 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { * 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. + * will be called to executeOnRenderThread an animation. * </p> * * @param marker the MarkerView object to select. @@ -317,7 +322,7 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { * 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. + * will be called to executeOnRenderThread an animation. * </p> * * @param marker the MarkerView object to select. @@ -460,75 +465,79 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { */ public void invalidateViewMarkersInVisibleRegion() { RectF mapViewRect = new RectF(0, 0, markerViewContainer.getWidth(), markerViewContainer.getHeight()); - List<MarkerView> markers = mapboxMap.getMarkerViewsInRect(mapViewRect); - View convertView; - - // remove old markers - Iterator<MarkerView> iterator = markerViewMap.keySet().iterator(); - while (iterator.hasNext()) { - MarkerView marker = iterator.next(); - if (!markers.contains(marker)) { - // remove marker - convertView = markerViewMap.get(marker); - for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) { - if (adapter.getMarkerClass().equals(marker.getClass())) { - adapter.prepareViewForReuse(marker, convertView); - adapter.releaseView(convertView); - marker.setMapboxMap(null); - iterator.remove(); + mapboxMap.getMarkerViewsInRect(mapViewRect, new Callback<List<MarkerView>>() { + @Override + public void onResult(List<MarkerView> markers) { + View convertView; + + // remove old markers + Iterator<MarkerView> iterator = markerViewMap.keySet().iterator(); + while (iterator.hasNext()) { + MarkerView marker = iterator.next(); + if (!markers.contains(marker)) { + // remove marker + convertView = markerViewMap.get(marker); + for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) { + if (adapter.getMarkerClass().equals(marker.getClass())) { + adapter.prepareViewForReuse(marker, convertView); + adapter.releaseView(convertView); + marker.setMapboxMap(null); + iterator.remove(); + } + } } } - } - } - // introduce new markers - for (final MarkerView marker : markers) { - if (!markerViewMap.containsKey(marker)) { - for (final MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) { - if (adapter.getMarkerClass().equals(marker.getClass())) { - - // Inflate View - convertView = (View) adapter.getViewReusePool().acquire(); - final View adaptedView = adapter.getView(marker, convertView, markerViewContainer); - if (adaptedView != null) { - adaptedView.setRotationX(marker.getTilt()); - adaptedView.setRotation(marker.getRotation()); - adaptedView.setAlpha(marker.getAlpha()); - adaptedView.setVisibility(View.GONE); - - if (mapboxMap.getSelectedMarkers().contains(marker)) { - // if a marker to be shown was selected - // replay that animation with duration 0 - if (adapter.onSelect(marker, adaptedView, true)) { - mapboxMap.selectMarker(marker); + // introduce new markers + for (final MarkerView marker : markers) { + if (!markerViewMap.containsKey(marker)) { + for (final MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) { + if (adapter.getMarkerClass().equals(marker.getClass())) { + + // Inflate View + convertView = (View) adapter.getViewReusePool().acquire(); + final View adaptedView = adapter.getView(marker, convertView, markerViewContainer); + if (adaptedView != null) { + adaptedView.setRotationX(marker.getTilt()); + adaptedView.setRotation(marker.getRotation()); + adaptedView.setAlpha(marker.getAlpha()); + adaptedView.setVisibility(View.GONE); + + if (mapboxMap.getSelectedMarkers().contains(marker)) { + // if a marker to be shown was selected + // replay that animation with duration 0 + if (adapter.onSelect(marker, adaptedView, true)) { + mapboxMap.selectMarker(marker); + } + } + + marker.setMapboxMap(mapboxMap); + markerViewMap.put(marker, adaptedView); + if (convertView == null) { + adaptedView.setVisibility(View.GONE); + markerViewContainer.addView(adaptedView); + } } - } - marker.setMapboxMap(mapboxMap); - markerViewMap.put(marker, adaptedView); - if (convertView == null) { - adaptedView.setVisibility(View.GONE); - markerViewContainer.addView(adaptedView); + // notify listener is marker view is rendered + Callback<MarkerView> onViewAddedListener = markerViewAddedListenerMap.get(marker.getId()); + if (onViewAddedListener != null) { + onViewAddedListener.onResult(marker); + markerViewAddedListenerMap.remove(marker.getId()); + } } } - - // notify listener is marker view is rendered - OnMarkerViewAddedListener onViewAddedListener = markerViewAddedListenerMap.get(marker.getId()); - if (onViewAddedListener != null) { - onViewAddedListener.onViewAdded(marker); - markerViewAddedListenerMap.remove(marker.getId()); - } } } - } - } - // clear map, don't keep references to MarkerView listeners that are not found in the bounds of the map. - markerViewAddedListenerMap.clear(); + // clear map, don't keep references to MarkerView listeners that are not found in the bounds of the map. + markerViewAddedListenerMap.clear(); - // trigger update to make newly added ViewMarker visible, - // these would only be updated when the map is moved. - updateMarkerViewsPosition(); + // trigger update to make newly added ViewMarker visible, + // these would only be updated when the map is moved. + updateMarkerViewsPosition(); + } + }); } /** @@ -607,7 +616,7 @@ public class MarkerViewManager implements MapView.OnMapChangedListener { return markerViewContainer; } - public void addOnMarkerViewAddedListener(MarkerView markerView, OnMarkerViewAddedListener onMarkerViewAddedListener) { + public void addOnMarkerViewAddedListener(MarkerView markerView, Callback<MarkerView> onMarkerViewAddedListener) { markerViewAddedListenerMap.put(markerView.getId(), onMarkerViewAddedListener); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java index 74170bb72b..afe0e2272a 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraPosition.java @@ -249,6 +249,14 @@ public final class CameraPosition implements Parcelable { } } + public Builder(LatLng latLng, double zoom, double tilt, double bearing) { + super(); + this.target = latLng; + this.zoom = zoom; + this.tilt = tilt; + this.bearing = bearing; + } + /** * Sets the direction that the camera is pointing in, in degrees clockwise from north. * diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java index 7e0dbf08fb..2c6aa3160e 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdate.java @@ -1,6 +1,7 @@ package com.mapbox.mapboxsdk.camera; import android.support.annotation.NonNull; +import android.support.annotation.WorkerThread; import com.mapbox.mapboxsdk.maps.MapboxMap; @@ -9,6 +10,7 @@ import com.mapbox.mapboxsdk.maps.MapboxMap; */ public interface CameraUpdate { + @WorkerThread CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap); } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java index fb0614c4a4..59fcb8e3e8 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/camera/CameraUpdateFactory.java @@ -1,7 +1,6 @@ package com.mapbox.mapboxsdk.camera; import android.graphics.Point; -import android.graphics.PointF; import android.graphics.RectF; import android.support.annotation.IntDef; import android.support.annotation.NonNull; @@ -9,9 +8,6 @@ import android.support.annotation.NonNull; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; import com.mapbox.mapboxsdk.maps.MapboxMap; -import com.mapbox.mapboxsdk.maps.Projection; -import com.mapbox.mapboxsdk.maps.UiSettings; -import com.mapbox.services.android.telemetry.utils.MathUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -224,58 +220,60 @@ public final class CameraUpdateFactory { @Override public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) { - // Get required objects - Projection projection = mapboxMap.getProjection(); - UiSettings uiSettings = mapboxMap.getUiSettings(); - - // calculate correct padding - int[] mapPadding = mapboxMap.getPadding(); - RectF latLngPadding = getPadding(); - RectF padding = new RectF(latLngPadding.left + mapPadding[0], - latLngPadding.top + mapPadding[1], - latLngPadding.right + mapPadding[2], - latLngPadding.bottom + mapPadding[3]); - - // Calculate the bounds of the possibly rotated shape with respect to the viewport - PointF nePixel = new PointF(-Float.MAX_VALUE, -Float.MAX_VALUE); - PointF swPixel = new PointF(Float.MAX_VALUE, Float.MAX_VALUE); - float viewportHeight = uiSettings.getHeight(); - for (LatLng latLng : getBounds().toLatLngs()) { - PointF pixel = projection.toScreenLocation(latLng); - swPixel.x = Math.min(swPixel.x, pixel.x); - nePixel.x = Math.max(nePixel.x, pixel.x); - swPixel.y = Math.min(swPixel.y, viewportHeight - pixel.y); - nePixel.y = Math.max(nePixel.y, viewportHeight - pixel.y); - } - - // Calculate width/height - float width = nePixel.x - swPixel.x; - float height = nePixel.y - swPixel.y; - - double zoom = 0; - float minScale = 1; - // Calculate the zoom level - if (padding != null) { - float scaleX = (uiSettings.getWidth() - padding.left - padding.right) / width; - float scaleY = (uiSettings.getHeight() - padding.top - padding.bottom) / height; - minScale = scaleX < scaleY ? scaleX : scaleY; - zoom = calculateZoom(mapboxMap, minScale); - zoom = MathUtils.clamp(zoom, mapboxMap.getMinZoomLevel(), mapboxMap.getMaxZoomLevel()); - } - - // Calculate the center point - PointF paddedNEPixel = new PointF(nePixel.x + padding.right / minScale, nePixel.y + padding.top / minScale); - PointF paddedSWPixel = new PointF(swPixel.x - padding.left / minScale, swPixel.y - padding.bottom / minScale); - PointF centerPixel = new PointF((paddedNEPixel.x + paddedSWPixel.x) / 2, (paddedNEPixel.y + paddedSWPixel.y) / 2); - centerPixel.y = viewportHeight - centerPixel.y; - LatLng center = projection.fromScreenLocation(centerPixel); - - return new CameraPosition.Builder() - .target(center) - .zoom(zoom) - .tilt(0) - .bearing(0) - .build(); + //// Get required objects + //Projection projection = mapboxMap.getProjection(); + //UiSettings uiSettings = mapboxMap.getUiSettings(); + // + //// calculate correct padding + //int[] mapPadding = mapboxMap.getPadding(); + //RectF latLngPadding = getPadding(); + //RectF padding = new RectF(latLngPadding.left + mapPadding[0], + //latLngPadding.top + mapPadding[1], + //latLngPadding.right + mapPadding[2], + //latLngPadding.bottom + mapPadding[3]); + // + //// Calculate the bounds of the possibly rotated shape with respect to the viewport + //PointF nePixel = new PointF(-Float.MAX_VALUE, -Float.MAX_VALUE); + //PointF swPixel = new PointF(Float.MAX_VALUE, Float.MAX_VALUE); + //float viewportHeight = uiSettings.getHeight(); + //for (LatLng latLng : getBounds().toLatLngs()) { + // PointF pixel = projection.toScreenLocation(latLng); + // swPixel.x = Math.min(swPixel.x, pixel.x); + // nePixel.x = Math.max(nePixel.x, pixel.x); + // swPixel.y = Math.min(swPixel.y, viewportHeight - pixel.y); + // nePixel.y = Math.max(nePixel.y, viewportHeight - pixel.y); + //} + // + //// Calculate width/height + //float width = nePixel.x - swPixel.x; + //float height = nePixel.y - swPixel.y; + // + //double zoom = 0; + //float minScale = 1; + //// Calculate the zoom level + //if (padding != null) { + // float scaleX = (uiSettings.getWidth() - padding.left - padding.right) / width; + // float scaleY = (uiSettings.getHeight() - padding.top - padding.bottom) / height; + // minScale = scaleX < scaleY ? scaleX : scaleY; + // zoom = calculateZoom(mapboxMap, minScale); + // zoom = MathUtils.clamp(zoom, mapboxMap.getMinZoomLevel(), mapboxMap.getMaxZoomLevel()); + //} + // + //// Calculate the center point + //PointF paddedNEPixel = new PointF(nePixel.x + padding.right / minScale, nePixel.y + padding.top / minScale); + //PointF paddedSWPixel = new PointF(swPixel.x - padding.left / minScale, swPixel.y - padding.bottom / minScale); + //PointF centerPixel = new PointF((paddedNEPixel.x + paddedSWPixel.x) / 2, (paddedNEPixel.y + paddedSWPixel.y) + // / 2); + //centerPixel.y = viewportHeight - centerPixel.y; + //LatLng center = projection.fromScreenLocation(centerPixel); + // + //return new CameraPosition.Builder() + // .target(center) + // .zoom(zoom) + // .tilt(0) + // .bearing(0) + // .build(); + throw new RuntimeException(); } /** @@ -301,24 +299,25 @@ public final class CameraUpdateFactory { @Override public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) { - UiSettings uiSettings = mapboxMap.getUiSettings(); - Projection projection = mapboxMap.getProjection(); - - // Calculate the new center point - float viewPortWidth = uiSettings.getWidth(); - float viewPortHeight = uiSettings.getHeight(); - PointF targetPoint = new PointF(viewPortWidth / 2 + x, viewPortHeight / 2 + y); - - // Convert point to LatLng - LatLng latLng = projection.fromScreenLocation(targetPoint); - - CameraPosition previousPosition = mapboxMap.getCameraPosition(); - return new CameraPosition.Builder() - .target(latLng != null ? latLng : previousPosition.target) - .zoom(previousPosition.zoom) - .tilt(previousPosition.tilt) - .bearing(previousPosition.bearing) - .build(); + // UiSettings uiSettings = mapboxMap.getUiSettings(); + // Projection projection = mapboxMap.getProjection(); + // + // // Calculate the new center point + // float viewPortWidth = uiSettings.getWidth(); + // float viewPortHeight = uiSettings.getHeight(); + // PointF targetPoint = new PointF(viewPortWidth / 2 + x, viewPortHeight / 2 + y); + // + // // Convert point to LatLng + // LatLng latLng = projection.fromScreenLocation(targetPoint); + // + // CameraPosition previousPosition = mapboxMap.getCameraPosition(); + // return new CameraPosition.Builder() + // .target(latLng != null ? latLng : previousPosition.target) + // .zoom(previousPosition.zoom) + // .tilt(previousPosition.tilt) + // .bearing(previousPosition.bearing) + // .build(); + throw new RuntimeException(); } } @@ -401,17 +400,18 @@ public final class CameraUpdateFactory { @Override public CameraPosition getCameraPosition(@NonNull MapboxMap mapboxMap) { - CameraPosition cameraPosition = mapboxMap.getCameraPosition(); - if (getType() != CameraUpdateFactory.ZoomUpdate.ZOOM_TO_POINT) { - return new CameraPosition.Builder(cameraPosition) - .zoom(transformZoom(cameraPosition.zoom)) - .build(); - } else { - return new CameraPosition.Builder(cameraPosition) - .zoom(transformZoom(cameraPosition.zoom)) - .target(mapboxMap.getProjection().fromScreenLocation(new PointF(getX(), getY()))) - .build(); - } + throw new RuntimeException(); + // CameraPosition cameraPosition = mapboxMap.getCameraPosition(); + // if (getType() != CameraUpdateFactory.ZoomUpdate.ZOOM_TO_POINT) { + // return new CameraPosition.Builder(cameraPosition) + // .zoom(transformZoom(cameraPosition.zoom)) + // .build(); + // } else { + // return new CameraPosition.Builder(cameraPosition) + // .zoom(transformZoom(cameraPosition.zoom)) + // .target(mapboxMap.getProjection().fromScreenLocation(new PointF(getX(), getY()))) + // .build(); + // } } } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java index d53216b811..587dd20426 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/constants/MapboxConstants.java @@ -105,6 +105,12 @@ public class MapboxConstants { // Save instance state keys public static final String STATE_HAS_SAVED_STATE = "savedState"; public static final String STATE_CAMERA_POSITION = "cameraPosition"; + public static final String STATE_CAMERA_LAT = "cameraPositionLat"; + public static final String STATE_CAMERA_LNG = "cameraPositionLng"; + public static final String STATE_CAMERA_BEARING = "cameraPositionBearing"; + public static final String STATE_CAMERA_TILT = "cameraPositionTilt"; + public static final String STATE_CAMERA_ZOOM = "cameraPositionZoom"; + public static final String STATE_ZOOM_ENABLED = "zoomEnabled"; public static final String STATE_ZOOM_ENABLED_CHANGE = "zoomEnabledChange"; public static final String STATE_SCROLL_ENABLED = "scrollEnabled"; @@ -118,6 +124,7 @@ public class MapboxConstants { public static final String STATE_DOUBLE_TAP_ENABLED_CHANGE = "doubleTapEnabledChange"; public static final String STATE_DEBUG_ACTIVE = "debugActive"; public static final String STATE_STYLE_URL = "styleUrl"; + public static final String STATE_API_BASE_URL = "apiBaseUrl"; public static final String STATE_MY_LOCATION_ENABLED = "myLocationEnabled"; public static final String STATE_MY_LOCATION_TRACKING_MODE = "myLocationTracking"; public static final String STATE_MY_BEARING_TRACKING_MODE = "myBearingTracking"; @@ -150,4 +157,6 @@ public class MapboxConstants { public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_URL = "mapboxTelemetryStagingUrl"; public static final String MAPBOX_SHARED_PREFERENCE_KEY_TELEMETRY_STAGING_ACCESS_TOKEN = "mapboxTelemetryStagingAccessToken"; + public static final String STATE_TRANSITION_DELAY = "transitionDelay"; + public static final String STATE_TRANSITION_DURATION = "transitionDuration"; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java index 0c77723354..81044a2afa 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AnnotationManager.java @@ -4,6 +4,8 @@ import android.graphics.PointF; import android.graphics.RectF; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.UiThread; +import android.support.annotation.WorkerThread; import android.support.v4.util.LongSparseArray; import com.mapbox.mapboxsdk.annotations.Annotation; @@ -17,6 +19,7 @@ import com.mapbox.mapboxsdk.annotations.Polygon; import com.mapbox.mapboxsdk.annotations.PolygonOptions; import com.mapbox.mapboxsdk.annotations.Polyline; import com.mapbox.mapboxsdk.annotations.PolylineOptions; +import com.mapbox.mapboxsdk.geometry.LatLng; import java.util.ArrayList; import java.util.Collections; @@ -33,27 +36,29 @@ import java.util.List; * com.mapbox.mapboxsdk.annotations. * </p> */ -class AnnotationManager { +class AnnotationManager extends MapThreadExecutor { - private final NativeMapView nativeMapView; private final MapView mapView; private final IconManager iconManager; private final InfoWindowManager infoWindowManager = new InfoWindowManager(); private final MarkerViewManager markerViewManager; + + // FIXME: 08/02/2017 threadsafe collection private final LongSparseArray<Annotation> annotations = new LongSparseArray<>(); private final List<Marker> selectedMarkers = new ArrayList<>(); private MapboxMap mapboxMap; private MapboxMap.OnMarkerClickListener onMarkerClickListener; - AnnotationManager(NativeMapView view, MapView mapView, MarkerViewManager markerViewManager) { - this.nativeMapView = view; + AnnotationManager(NativeMapView view, ThreadExecutor threadExecutor, MapView mapView, + MarkerViewManager markerViewManager) { + super(view, threadExecutor); this.mapView = mapView; - this.iconManager = new IconManager(nativeMapView); + this.iconManager = new IconManager(getNativeMapView()); this.markerViewManager = markerViewManager; if (view != null) { // null checking needed for unit tests - nativeMapView.addOnMapChangedListener(markerViewManager); + getNativeMapView().addOnMapChangedListener(markerViewManager); } } @@ -74,6 +79,7 @@ class AnnotationManager { // Annotations // + @UiThread Annotation getAnnotation(long id) { return annotations.get(id); } @@ -86,6 +92,7 @@ class AnnotationManager { return annotations; } + @UiThread void removeAnnotation(@NonNull Annotation annotation) { if (annotation instanceof Marker) { Marker marker = (Marker) annotation; @@ -94,23 +101,25 @@ class AnnotationManager { markerViewManager.removeMarkerView((MarkerView) marker); } } - long id = annotation.getId(); - if (nativeMapView != null) { - nativeMapView.removeAnnotation(id); - } + final long id = annotation.getId(); + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.removeAnnotation(id); + } + }); annotations.remove(id); } + @UiThread void removeAnnotation(long id) { - if (nativeMapView != null) { - nativeMapView.removeAnnotation(id); - } - annotations.remove(id); + removeAnnotation(annotations.get(id)); } + @UiThread void removeAnnotations(@NonNull List<? extends Annotation> annotationList) { int count = annotationList.size(); - long[] ids = new long[count]; + final long[] ids = new long[count]; for (int i = 0; i < count; i++) { Annotation annotation = annotationList.get(i); if (annotation instanceof Marker) { @@ -123,9 +132,12 @@ class AnnotationManager { ids[i] = annotationList.get(i).getId(); } - if (nativeMapView != null) { - nativeMapView.removeAnnotations(ids); - } + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.removeAnnotations(ids); + } + }); for (long id : ids) { annotations.remove(id); @@ -135,7 +147,7 @@ class AnnotationManager { void removeAnnotations() { Annotation annotation; int count = annotations.size(); - long[] ids = new long[count]; + final long[] ids = new long[count]; for (int i = 0; i < count; i++) { ids[i] = annotations.keyAt(i); annotation = annotations.get(ids[i]); @@ -148,9 +160,12 @@ class AnnotationManager { } } - if (nativeMapView != null) { - nativeMapView.removeAnnotations(ids); - } + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.removeAnnotations(ids); + } + }); annotations.clear(); } @@ -159,53 +174,78 @@ class AnnotationManager { // Markers // - Marker addMarker(@NonNull BaseMarkerOptions markerOptions, @NonNull MapboxMap mapboxMap) { - Marker marker = prepareMarker(markerOptions); - long id = nativeMapView != null ? nativeMapView.addMarker(marker) : 0; - marker.setMapboxMap(mapboxMap); - marker.setId(id); - annotations.put(id, marker); - return marker; - } - - List<Marker> addMarkers(@NonNull List<? extends BaseMarkerOptions> markerOptionsList, @NonNull MapboxMap mapboxMap) { - int count = markerOptionsList.size(); - List<Marker> markers = new ArrayList<>(count); - if (count > 0) { - BaseMarkerOptions markerOptions; - Marker marker; - for (int i = 0; i < count; i++) { - markerOptions = markerOptionsList.get(i); - marker = prepareMarker(markerOptions); - markers.add(marker); + void addMarker(@NonNull final BaseMarkerOptions markerOptions, @NonNull final MapboxMap mapboxMap, + final Callback<Marker> onMarkerResult) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final Marker marker = prepareMarker(markerOptions); + long id = nativeMapView != null ? nativeMapView.addMarker(marker) : 0; + marker.setMapboxMap(mapboxMap); + marker.setId(id); + annotations.put(id, marker); + + queueUiEvent(new Runnable() { + @Override + public void run() { + if (onMarkerResult != null) { + onMarkerResult.onResult(marker); + } + } + }); } + }); + } + + void addMarkers(@NonNull final List<? extends BaseMarkerOptions> markerOptionsList, + @NonNull final MapboxMap mapboxMap, final Callback<List<Marker>> onMarkersAddedResult) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + int count = markerOptionsList.size(); + final List<Marker> markers = new ArrayList<>(count); + if (count > 0) { + BaseMarkerOptions markerOptions; + Marker marker; + for (int i = 0; i < count; i++) { + markerOptions = markerOptionsList.get(i); + marker = prepareMarker(markerOptions); + markers.add(marker); + } - if (markers.size() > 0) { - long[] ids = null; - if (nativeMapView != null) { - ids = nativeMapView.addMarkers(markers); - } + if (markers.size() > 0) { + long[] ids = null; + if (nativeMapView != null) { + ids = nativeMapView.addMarkers(markers); + } - long id = 0; - Marker m; - for (int i = 0; i < markers.size(); i++) { - m = markers.get(i); - m.setMapboxMap(mapboxMap); - if (ids != null) { - id = ids[i]; - } else { - // unit test - id++; + long id = 0; + Marker m; + for (int i = 0; i < markers.size(); i++) { + m = markers.get(i); + m.setMapboxMap(mapboxMap); + if (ids != null) { + id = ids[i]; + } else { + // unit test + id++; + } + m.setId(id); + annotations.put(id, m); + } } - m.setId(id); - annotations.put(id, m); } - + queueUiEvent(new Runnable() { + @Override + public void run() { + onMarkersAddedResult.onResult(markers); + } + }); } - } - return markers; + }); } + @WorkerThread private Marker prepareMarker(BaseMarkerOptions markerOptions) { Marker marker = markerOptions.getMarker(); Icon icon = iconManager.loadIconForMarker(marker); @@ -213,54 +253,75 @@ class AnnotationManager { return marker; } - MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions, @NonNull MapboxMap mapboxMap, - @Nullable MarkerViewManager.OnMarkerViewAddedListener onMarkerViewAddedListener) { - final MarkerView marker = prepareViewMarker(markerOptions); - - // add marker to map - marker.setMapboxMap(mapboxMap); - long id = nativeMapView.addMarker(marker); - marker.setId(id); - annotations.put(id, marker); - - if (onMarkerViewAddedListener != null) { - markerViewManager.addOnMarkerViewAddedListener(marker, onMarkerViewAddedListener); - } - markerViewManager.setEnabled(true); - markerViewManager.setWaitingForRenderInvoke(true); - return marker; - } - + @UiThread + void addMarker(@NonNull final BaseMarkerViewOptions markerOptions, @NonNull final MapboxMap mapboxMap, + final Callback<MarkerView> callback) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final MarkerView marker = prepareViewMarker(markerOptions); + + // add marker to map + marker.setMapboxMap(mapboxMap); + long id = nativeMapView.addMarker(marker); + marker.setId(id); + annotations.put(id, marker); + + queueUiEvent(new Runnable() { + @Override + public void run() { + if (callback != null) { + markerViewManager.addOnMarkerViewAddedListener(marker, callback); + } + markerViewManager.setEnabled(true); + markerViewManager.setWaitingForRenderInvoke(true); + } + }); + } + }); + } + + + @UiThread + void addMarkerViews(@NonNull final List<? extends BaseMarkerViewOptions> markerViewOptions, + @NonNull final MapboxMap mapboxMap, final Callback<List<MarkerView>> callback) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + List<MarkerView> markers = new ArrayList<>(); + for (BaseMarkerViewOptions markerViewOption : markerViewOptions) { + // if last marker + if (markerViewOptions.indexOf(markerViewOption) == markerViewOptions.size() - 1) { + // get notified when render occurs to invalidate and draw MarkerViews + markerViewManager.setWaitingForRenderInvoke(true); + } + // add marker to map + MarkerView marker = prepareViewMarker(markerViewOption); + marker.setMapboxMap(mapboxMap); + long id = nativeMapView.addMarker(marker); + marker.setId(id); + annotations.put(id, marker); + markers.add(marker); + } + markerViewManager.setEnabled(true); + markerViewManager.update(); - List<MarkerView> addMarkerViews(@NonNull List<? extends BaseMarkerViewOptions> markerViewOptions, - @NonNull MapboxMap mapboxMap) { - List<MarkerView> markers = new ArrayList<>(); - for (BaseMarkerViewOptions markerViewOption : markerViewOptions) { - // if last marker - if (markerViewOptions.indexOf(markerViewOption) == markerViewOptions.size() - 1) { - // get notified when render occurs to invalidate and draw MarkerViews - markerViewManager.setWaitingForRenderInvoke(true); + if (callback != null) { + callback.onResult(markers); + } } - // add marker to map - MarkerView marker = prepareViewMarker(markerViewOption); - marker.setMapboxMap(mapboxMap); - long id = nativeMapView.addMarker(marker); - marker.setId(id); - annotations.put(id, marker); - markers.add(marker); - } - markerViewManager.setEnabled(true); - markerViewManager.update(); - return markers; + }); } + @WorkerThread private MarkerView prepareViewMarker(BaseMarkerViewOptions markerViewOptions) { MarkerView marker = markerViewOptions.getMarker(); iconManager.loadIconForMarkerView(marker); return marker; } - void updateMarker(@NonNull Marker updatedMarker, @NonNull MapboxMap mapboxMap) { + @UiThread + void updateMarker(@NonNull final Marker updatedMarker, @NonNull final MapboxMap mapboxMap) { if (updatedMarker == null) { return; } @@ -269,16 +330,21 @@ class AnnotationManager { return; } - if (!(updatedMarker instanceof MarkerView)) { - iconManager.ensureIconLoaded(updatedMarker, mapboxMap); - } + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + if (!(updatedMarker instanceof MarkerView)) { + iconManager.ensureIconLoaded(updatedMarker, mapboxMap); + } - nativeMapView.updateMarker(updatedMarker); + nativeMapView.updateMarker(updatedMarker); - int index = annotations.indexOfKey(updatedMarker.getId()); - if (index > -1) { - annotations.setValueAt(index, updatedMarker); - } + int index = annotations.indexOfKey(updatedMarker.getId()); + if (index > -1) { + annotations.setValueAt(index, updatedMarker); + } + } + }); } List<Marker> getMarkers() { @@ -293,10 +359,12 @@ class AnnotationManager { return markers; } + @UiThread void setOnMarkerClickListener(@Nullable MapboxMap.OnMarkerClickListener listener) { onMarkerClickListener = listener; } + @UiThread void selectMarker(@NonNull Marker marker) { if (selectedMarkers.contains(marker)) { return; @@ -320,6 +388,7 @@ class AnnotationManager { selectedMarkers.add(marker); } + @UiThread void deselectMarkers() { if (selectedMarkers.isEmpty()) { return; @@ -339,6 +408,7 @@ class AnnotationManager { selectedMarkers.clear(); } + @UiThread void deselectMarker(@NonNull Marker marker) { if (!selectedMarkers.contains(marker)) { return; @@ -359,113 +429,161 @@ class AnnotationManager { return selectedMarkers; } - @NonNull - List<Marker> getMarkersInRect(@NonNull RectF rectangle) { - // convert Rectangle to be density depedent - float pixelRatio = nativeMapView.getPixelRatio(); - RectF rect = new RectF(rectangle.left / pixelRatio, - rectangle.top / pixelRatio, - rectangle.right / pixelRatio, - rectangle.bottom / pixelRatio); + void getMarkersInRect(@NonNull final RectF rectangle, final Callback<List<Marker>> callback) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + // convert Rectangle to be density depedent + float pixelRatio = nativeMapView.getPixelRatio(); + RectF rect = new RectF(rectangle.left / pixelRatio, + rectangle.top / pixelRatio, + rectangle.right / pixelRatio, + rectangle.bottom / pixelRatio); - long[] ids = nativeMapView.queryPointAnnotations(rect); + long[] ids = nativeMapView.queryPointAnnotations(rect); - List<Long> idsList = new ArrayList<>(ids.length); - for (long id : ids) { - idsList.add(id); - } + List<Long> idsList = new ArrayList<>(ids.length); + for (long id : ids) { + idsList.add(id); + } - List<Marker> annotations = new ArrayList<>(ids.length); - List<Annotation> annotationList = getAnnotations(); - int count = annotationList.size(); - for (int i = 0; i < count; i++) { - Annotation annotation = annotationList.get(i); - if (annotation instanceof com.mapbox.mapboxsdk.annotations.Marker && idsList.contains(annotation.getId())) { - annotations.add((com.mapbox.mapboxsdk.annotations.Marker) annotation); - } - } + final List<Marker> annotations = new ArrayList<>(ids.length); + List<Annotation> annotationList = getAnnotations(); + int count = annotationList.size(); + for (int i = 0; i < count; i++) { + Annotation annotation = annotationList.get(i); + if (annotation instanceof Marker && idsList.contains(annotation.getId())) { + annotations.add((Marker) annotation); + } + } - return new ArrayList<>(annotations); + queueUiEvent(new Runnable() { + @Override + public void run() { + if (callback != null) { + callback.onResult(new ArrayList<>(annotations)); + } + } + }); + } + }); } - List<MarkerView> getMarkerViewsInRect(@NonNull RectF rectangle) { - float pixelRatio = nativeMapView.getPixelRatio(); - RectF rect = new RectF(rectangle.left / pixelRatio, - rectangle.top / pixelRatio, - rectangle.right / pixelRatio, - rectangle.bottom / pixelRatio); + void getMarkerViewsInRect(@NonNull final RectF rectangle, final Callback<List<MarkerView>> callback) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + float pixelRatio = nativeMapView.getPixelRatio(); + RectF rect = new RectF(rectangle.left / pixelRatio, + rectangle.top / pixelRatio, + rectangle.right / pixelRatio, + rectangle.bottom / pixelRatio); - long[] ids = nativeMapView.queryPointAnnotations(rect); + long[] ids = nativeMapView.queryPointAnnotations(rect); - List<Long> idsList = new ArrayList<>(ids.length); - for (long id : ids) { - idsList.add(id); - } + List<Long> idsList = new ArrayList<>(ids.length); + for (long id : ids) { + idsList.add(id); + } - List<MarkerView> annotations = new ArrayList<>(ids.length); - List<Annotation> annotationList = getAnnotations(); - int count = annotationList.size(); - for (int i = 0; i < count; i++) { - Annotation annotation = annotationList.get(i); - if (annotation instanceof MarkerView && idsList.contains(annotation.getId())) { - annotations.add((MarkerView) annotation); - } - } + final List<MarkerView> annotations = new ArrayList<>(ids.length); + List<Annotation> annotationList = getAnnotations(); + int count = annotationList.size(); + for (int i = 0; i < count; i++) { + Annotation annotation = annotationList.get(i); + if (annotation instanceof MarkerView && idsList.contains(annotation.getId())) { + annotations.add((MarkerView) annotation); + } + } - return new ArrayList<>(annotations); + if (callback != null) { + queueUiEvent(new Runnable() { + @Override + public void run() { + callback.onResult(annotations); + } + }); + } + } + }); } // // Polygons // - Polygon addPolygon(@NonNull PolygonOptions polygonOptions, @NonNull MapboxMap mapboxMap) { - Polygon polygon = polygonOptions.getPolygon(); - if (!polygon.getPoints().isEmpty()) { - long id = nativeMapView != null ? nativeMapView.addPolygon(polygon) : 0; - polygon.setId(id); - polygon.setMapboxMap(mapboxMap); - annotations.put(id, polygon); - } - return polygon; - } - - List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList, @NonNull MapboxMap mapboxMap) { - int count = polygonOptionsList.size(); - - Polygon polygon; - List<Polygon> polygons = new ArrayList<>(count); - if (count > 0) { - for (PolygonOptions polygonOptions : polygonOptionsList) { - polygon = polygonOptions.getPolygon(); + void addPolygon(@NonNull final PolygonOptions polygonOptions, @NonNull final MapboxMap mapboxMap, + final Callback<Polygon> listener) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final Polygon polygon = polygonOptions.getPolygon(); if (!polygon.getPoints().isEmpty()) { - polygons.add(polygon); + long id = nativeMapView.addPolygon(polygon); + polygon.setId(id); + polygon.setMapboxMap(mapboxMap); + annotations.put(id, polygon); + queueUiEvent(new Runnable() { + @Override + public void run() { + listener.onResult(polygon); + } + }); } } + }); + } + + void addPolygons(@NonNull final List<PolygonOptions> polygonOptionsList, @NonNull final MapboxMap mapboxMap, + final Callback<List<Polygon>> listCallback) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + int count = polygonOptionsList.size(); + + Polygon polygon; + final List<Polygon> polygons = new ArrayList<>(count); + if (count > 0) { + for (PolygonOptions polygonOptions : polygonOptionsList) { + polygon = polygonOptions.getPolygon(); + if (!polygon.getPoints().isEmpty()) { + polygons.add(polygon); + } + } - long[] ids = null; - if (nativeMapView != null) { - ids = nativeMapView.addPolygons(polygons); - } + long[] ids = null; + if (nativeMapView != null) { + ids = nativeMapView.addPolygons(polygons); + } - long id = 0; - for (int i = 0; i < polygons.size(); i++) { - polygon = polygons.get(i); - polygon.setMapboxMap(mapboxMap); - if (ids != null) { - id = ids[i]; - } else { - // unit test - id++; + long id = 0; + for (int i = 0; i < polygons.size(); i++) { + polygon = polygons.get(i); + polygon.setMapboxMap(mapboxMap); + if (ids != null) { + id = ids[i]; + } else { + // unit test + id++; + } + polygon.setId(id); + annotations.put(id, polygon); + } } - polygon.setId(id); - annotations.put(id, polygon); + + queueUiEvent(new Runnable() { + @Override + public void run() { + if (listCallback != null) { + listCallback.onResult(polygons); + } + } + }); } - } - return polygons; + }); } - void updatePolygon(Polygon polygon) { + void updatePolygon(final Polygon polygon) { if (polygon == null) { return; } @@ -474,12 +592,16 @@ class AnnotationManager { return; } - nativeMapView.updatePolygon(polygon); - - int index = annotations.indexOfKey(polygon.getId()); - if (index > -1) { - annotations.setValueAt(index, polygon); - } + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.updatePolygon(polygon); + int index = annotations.indexOfKey(polygon.getId()); + if (index > -1) { + annotations.setValueAt(index, polygon); + } + } + }); } List<Polygon> getPolygons() { @@ -498,55 +620,75 @@ class AnnotationManager { // Polylines // - Polyline addPolyline(@NonNull PolylineOptions polylineOptions, @NonNull MapboxMap mapboxMap) { - Polyline polyline = polylineOptions.getPolyline(); - if (!polyline.getPoints().isEmpty()) { - long id = nativeMapView != null ? nativeMapView.addPolyline(polyline) : 0; - polyline.setMapboxMap(mapboxMap); - polyline.setId(id); - annotations.put(id, polyline); - } - return polyline; - } - - List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList, @NonNull MapboxMap mapboxMap) { - int count = polylineOptionsList.size(); - Polyline polyline; - List<Polyline> polylines = new ArrayList<>(count); - - if (count > 0) { - for (PolylineOptions options : polylineOptionsList) { - polyline = options.getPolyline(); + void addPolyline(@NonNull final PolylineOptions polylineOptions, @NonNull final MapboxMap mapboxMap, + final Callback<Polyline> listener) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final Polyline polyline = polylineOptions.getPolyline(); if (!polyline.getPoints().isEmpty()) { - polylines.add(polyline); + long id = nativeMapView != null ? nativeMapView.addPolyline(polyline) : 0; + polyline.setMapboxMap(mapboxMap); + polyline.setId(id); + annotations.put(id, polyline); + queueUiEvent(new Runnable() { + @Override + public void run() { + if (listener != null) { + listener.onResult(polyline); + } + } + }); } } + }); + } + + void addPolylines(@NonNull final List<PolylineOptions> polylineOptionsList, @NonNull final MapboxMap mapboxMap, + final Callback<List<Polyline>> listener) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + int count = polylineOptionsList.size(); + Polyline polyline; + final List<Polyline> polylines = new ArrayList<>(count); + + if (count > 0) { + for (PolylineOptions options : polylineOptionsList) { + polyline = options.getPolyline(); + if (!polyline.getPoints().isEmpty()) { + polylines.add(polyline); + } + } - long[] ids = null; - if (nativeMapView != null) { - ids = nativeMapView.addPolylines(polylines); - } + long[] ids = nativeMapView.addPolylines(polylines); + long id = 0; + Polyline p; - long id = 0; - Polyline p; - - for (int i = 0; i < polylines.size(); i++) { - p = polylines.get(i); - p.setMapboxMap(mapboxMap); - if (ids != null) { - id = ids[i]; - } else { - // unit test - id++; + for (int i = 0; i < polylines.size(); i++) { + p = polylines.get(i); + p.setMapboxMap(mapboxMap); + if (ids != null) { + id = ids[i]; + } else { + // unit test + id++; + } + p.setId(id); + annotations.put(id, p); + } } - p.setId(id); - annotations.put(id, p); + queueUiEvent(new Runnable() { + @Override + public void run() { + listener.onResult(polylines); + } + }); } - } - return polylines; + }); } - void updatePolyline(Polyline polyline) { + void updatePolyline(final Polyline polyline) { if (polyline == null) { return; } @@ -555,12 +697,17 @@ class AnnotationManager { return; } - nativeMapView.updatePolyline(polyline); + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.updatePolyline(polyline); - int index = annotations.indexOfKey(polyline.getId()); - if (index > -1) { - annotations.setValueAt(index, polyline); - } + int index = annotations.indexOfKey(polyline.getId()); + if (index > -1) { + annotations.setValueAt(index, polyline); + } + } + }); } List<Polyline> getPolylines() { @@ -604,101 +751,130 @@ class AnnotationManager { void reloadMarkers() { iconManager.reloadIcons(); - int count = annotations.size(); - for (int i = 0; i < count; i++) { - Annotation annotation = annotations.get(i); - if (annotation instanceof Marker) { - Marker marker = (Marker) annotation; - nativeMapView.removeAnnotation(annotation.getId()); - long newId = nativeMapView.addMarker(marker); - marker.setId(newId); + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + int count = annotations.size(); + for (int i = 0; i < count; i++) { + Annotation annotation = annotations.get(i); + if (annotation instanceof Marker) { + Marker marker = (Marker) annotation; + nativeMapView.removeAnnotation(annotation.getId()); + long newId = nativeMapView.addMarker(marker); + marker.setId(newId); + } + } } - } + }); } // // Click event // - boolean onTap(PointF tapPoint, float screenDensity) { + // FIXME: 09/02/2017 cleanup + void onTap(final PointF tapPoint, final UiSettings uiSettings, final Projection projection, + final MapboxMap.OnMapClickListener onMapClickListener) { + float screenDensity = uiSettings.getPixelRatio(); float toleranceSides = 4 * screenDensity; float toleranceTopBottom = 10 * screenDensity; - boolean handledDefaultClick = false; RectF tapRect = new RectF(tapPoint.x - iconManager.getAverageIconWidth() / 2 - toleranceSides, tapPoint.y - iconManager.getAverageIconHeight() / 2 - toleranceTopBottom, tapPoint.x + iconManager.getAverageIconWidth() / 2 + toleranceSides, tapPoint.y + iconManager.getAverageIconHeight() / 2 + toleranceTopBottom); - List<Marker> nearbyMarkers = getMarkersInRect(tapRect); - long newSelectedMarkerId = -1; - - // find a Marker that isn't selected yet - if (nearbyMarkers.size() > 0) { - Collections.sort(nearbyMarkers); - for (Marker nearbyMarker : nearbyMarkers) { - boolean found = false; - for (Marker selectedMarker : selectedMarkers) { - if (selectedMarker.equals(nearbyMarker)) { - found = true; + getMarkersInRect(tapRect, new Callback<List<Marker>>() { + @Override + public void onResult(List<Marker> nearbyMarkers) { + boolean tapHandled = false; + + long newSelectedMarkerId = -1; + boolean handledDefaultClick = false; + + // find a Marker that isn't selected yet + if (nearbyMarkers.size() > 0) { + Collections.sort(nearbyMarkers); + for (Marker nearbyMarker : nearbyMarkers) { + boolean found = false; + for (Marker selectedMarker : selectedMarkers) { + if (selectedMarker.equals(nearbyMarker)) { + found = true; + } + } + if (!found) { + newSelectedMarkerId = nearbyMarker.getId(); + break; + } } } - if (!found) { - newSelectedMarkerId = nearbyMarker.getId(); - break; - } - } - } - // if unselected marker found - if (newSelectedMarkerId >= 0) { - List<Annotation> annotations = getAnnotations(); - int count = annotations.size(); - for (int i = 0; i < count; i++) { - Annotation annotation = annotations.get(i); - if (annotation instanceof Marker) { - if (annotation.getId() == newSelectedMarkerId) { - Marker marker = (Marker) annotation; - - if (marker instanceof MarkerView) { - handledDefaultClick = markerViewManager.onClickMarkerView((MarkerView) marker); - } else { - if (onMarkerClickListener != null) { - // end developer has provided a custom click listener - handledDefaultClick = onMarkerClickListener.onMarkerClick(marker); + // if unselected marker found + if (newSelectedMarkerId >= 0) { + List<Annotation> annotations = getAnnotations(); + int count = annotations.size(); + for (int i = 0; i < count; i++) { + Annotation annotation = annotations.get(i); + if (annotation instanceof Marker) { + if (annotation.getId() == newSelectedMarkerId) { + Marker marker = (Marker) annotation; + + if (marker instanceof MarkerView) { + handledDefaultClick = markerViewManager.onClickMarkerView((MarkerView) marker); + } else { + if (onMarkerClickListener != null) { + // end developer has provided a custom click listener + handledDefaultClick = onMarkerClickListener.onMarkerClick(marker); + } + } + + if (annotation instanceof MarkerView) { + markerViewManager.onClickMarkerView((MarkerView) annotation); + } else { + if (!handledDefaultClick) { + // only select marker if user didn't handle the click event themselves + selectMarker(marker); + } + } + tapHandled = true; } } - - if (annotation instanceof MarkerView) { - markerViewManager.onClickMarkerView((MarkerView) annotation); - } else { - if (!handledDefaultClick) { - // only select marker if user didn't handle the click event themselves - selectMarker(marker); + } + } else if (nearbyMarkers.size() > 0) { + // we didn't find an unselected marker, check if we can close an already open markers + for (Marker nearbyMarker : nearbyMarkers) { + for (Marker selectedMarker : selectedMarkers) { + if (nearbyMarker.equals(selectedMarker)) { + if (onMarkerClickListener != null) { + // end developer has provided a custom click listener + handledDefaultClick = onMarkerClickListener.onMarkerClick(nearbyMarker); + if (!handledDefaultClick) { + deselectMarker(nearbyMarker); + } + } + tapHandled = true; } } - - return true; } } - } - } else if (nearbyMarkers.size() > 0) { - // we didn't find an unselected marker, check if we can close an already open markers - for (Marker nearbyMarker : nearbyMarkers) { - for (Marker selectedMarker : selectedMarkers) { - if (nearbyMarker.equals(selectedMarker)) { - if (onMarkerClickListener != null) { - // end developer has provided a custom click listener - handledDefaultClick = onMarkerClickListener.onMarkerClick(nearbyMarker); - if (!handledDefaultClick) { - deselectMarker(nearbyMarker); + + if (!tapHandled) { + if (uiSettings.isDeselectMarkersOnTap()) { + // deselect any selected marker + deselectMarkers(); + } + + // notify app of map click + if (onMapClickListener != null) { + projection.fromScreenLocation(tapPoint, new Callback<LatLng>() { + @Override + public void onResult(LatLng latLng) { + onMapClickListener.onMapClick(latLng); } - } - return true; + }); } } } - } - return false; + }); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Callback.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Callback.java new file mode 100644 index 0000000000..2b0fd58d78 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Callback.java @@ -0,0 +1,18 @@ +package com.mapbox.mapboxsdk.maps; + +import com.mapbox.mapboxsdk.style.layers.Layer; +import com.mapbox.mapboxsdk.style.sources.Source; + +public interface Callback<T> { + + void onResult(T t); + + interface SourceCallback<U extends Source> { + void onResult(U u); + } + + interface LayerCallback<V extends Layer> { + void onResult(V v); + } + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java index c9d81a88bc..ca3a4496aa 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/IconManager.java @@ -1,6 +1,7 @@ package com.mapbox.mapboxsdk.maps; import android.graphics.Bitmap; +import android.support.annotation.WorkerThread; import android.util.DisplayMetrics; import com.mapbox.mapboxsdk.annotations.Icon; @@ -92,10 +93,12 @@ class IconManager { return icon; } + @WorkerThread int getTopOffsetPixelsForIcon(Icon icon) { return (int) (nativeMapView.getTopOffsetPixelsForAnnotationSymbol(icon.getId()) * nativeMapView.getPixelRatio()); } + @WorkerThread void loadIcon(Icon icon) { Bitmap bitmap = icon.getBitmap(); String id = icon.getId(); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java index 0f4d3197cc..be337b2bb0 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapGestureDetector.java @@ -100,9 +100,13 @@ final class MapGestureDetector { * @param y coordinate * @return location */ - private Location getLocationFromGesture(float x, float y) { - LatLng latLng = projection.fromScreenLocation(new PointF(x, y)); - return TelemetryUtils.buildLocation(latLng.getLongitude(), latLng.getLatitude()); + private void getLocationFromGesture(float x, float y, final Callback<Location> locationCallback) { + projection.fromScreenLocation(new PointF(x, y), new Callback<LatLng>() { + @Override + public void onResult(LatLng latLng) { + locationCallback.onResult(TelemetryUtils.buildLocation(latLng.getLongitude(), latLng.getLatitude())); + } + }); } /** @@ -139,9 +143,13 @@ final class MapGestureDetector { && uiSettings.isZoomGesturesEnabled(); if (twoTap) { // Confirmed 2nd Finger Down - MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( - getLocationFromGesture(event.getX(), event.getY()), - MapboxEvent.GESTURE_TWO_FINGER_SINGLETAP, transform.getZoom())); + getLocationFromGesture(event.getX(), event.getY(), new Callback<Location>() { + @Override + public void onResult(Location location) { + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + location, MapboxEvent.GESTURE_TWO_FINGER_SINGLETAP, transform.getZoom())); + } + }); } break; @@ -170,8 +178,13 @@ final class MapGestureDetector { // Scroll / Pan Has Stopped if (scrollInProgress) { - MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapDragEndEvent( - getLocationFromGesture(event.getX(), event.getY()), transform.getZoom())); + getLocationFromGesture(event.getX(), event.getY(), new Callback<Location>() { + @Override + public void onResult(Location location) { + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapDragEndEvent( + location, transform.getZoom())); + } + }); scrollInProgress = false; } @@ -242,12 +255,12 @@ final class MapGestureDetector { } @Override - public boolean onDoubleTapEvent(MotionEvent e) { + public boolean onDoubleTapEvent(MotionEvent event) { if (!uiSettings.isZoomGesturesEnabled() || !uiSettings.isDoubleTapGesturesEnabled()) { return false; } - switch (e.getAction()) { + switch (event.getAction()) { case MotionEvent.ACTION_DOWN: break; case MotionEvent.ACTION_MOVE: @@ -265,14 +278,18 @@ final class MapGestureDetector { transform.zoom(true, focalPoint.x, focalPoint.y); } else { // Zoom in on gesture - transform.zoom(true, e.getX(), e.getY()); + transform.zoom(true, event.getX(), event.getY()); } break; } - MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( - getLocationFromGesture(e.getX(), e.getY()), - MapboxEvent.GESTURE_DOUBLETAP, transform.getZoom())); + getLocationFromGesture(event.getX(), event.getY(), new Callback<Location>() { + @Override + public void onResult(Location location) { + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + location, MapboxEvent.GESTURE_DOUBLETAP, transform.getZoom())); + } + }); return true; } @@ -287,32 +304,28 @@ final class MapGestureDetector { @Override public boolean onSingleTapConfirmed(MotionEvent motionEvent) { PointF tapPoint = new PointF(motionEvent.getX(), motionEvent.getY()); - boolean tapHandled = annotationManager.onTap(tapPoint, uiSettings.getPixelRatio()); - - if (!tapHandled) { - if (uiSettings.isDeselectMarkersOnTap()) { - // deselect any selected marker - annotationManager.deselectMarkers(); - } - - // notify app of map click - if (onMapClickListener != null) { - onMapClickListener.onMapClick(projection.fromScreenLocation(tapPoint)); + annotationManager.onTap(tapPoint, uiSettings, projection, onMapClickListener); + getLocationFromGesture(motionEvent.getX(), motionEvent.getY(), new Callback<Location>() { + @Override + public void onResult(Location location) { + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + location, MapboxEvent.GESTURE_SINGLETAP, transform.getZoom())); } - } - - MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( - getLocationFromGesture(motionEvent.getX(), motionEvent.getY()), - MapboxEvent.GESTURE_SINGLETAP, transform.getZoom())); - + }); return true; } @Override public void onLongPress(MotionEvent motionEvent) { if (onMapLongClickListener != null && !quickZoom) { - onMapLongClickListener.onMapLongClick( - projection.fromScreenLocation(new PointF(motionEvent.getX(), motionEvent.getY()))); + projection.fromScreenLocation(new PointF(motionEvent.getX(), motionEvent.getY()), new Callback<LatLng>() { + @Override + public void onResult(LatLng latLng) { + if (onMapLongClickListener != null) { + onMapLongClickListener.onMapLongClick(latLng); + } + } + }); } } @@ -363,9 +376,13 @@ final class MapGestureDetector { public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (!scrollInProgress) { scrollInProgress = true; - MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( - getLocationFromGesture(e1.getX(), e1.getY()), - MapboxEvent.GESTURE_PAN_START, transform.getZoom())); + getLocationFromGesture(e1.getX(), e1.getY(), new Callback<Location>() { + @Override + public void onResult(Location location) { + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + location, MapboxEvent.GESTURE_PAN_START, transform.getZoom())); + } + }); } if (!trackingSettings.isScrollGestureCurrentlyEnabled()) { return false; @@ -407,9 +424,13 @@ final class MapGestureDetector { scaleGestureOccurred = true; beginTime = detector.getEventTime(); - MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( - getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), - MapboxEvent.GESTURE_PINCH_START, transform.getZoom())); + getLocationFromGesture(detector.getFocusX(), detector.getFocusY(), new Callback<Location>() { + @Override + public void onResult(Location location) { + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + location, MapboxEvent.GESTURE_PINCH_START, transform.getZoom())); + } + }); return true; } @@ -499,9 +520,13 @@ final class MapGestureDetector { } beginTime = detector.getEventTime(); - MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( - getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), - MapboxEvent.GESTURE_ROTATION_START, transform.getZoom())); + getLocationFromGesture(detector.getFocusX(), detector.getFocusY(), new Callback<Location>() { + @Override + public void onResult(Location location) { + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + location, MapboxEvent.GESTURE_ROTATION_START, transform.getZoom())); + } + }); return true; } @@ -549,7 +574,7 @@ final class MapGestureDetector { trackingSettings.resetTrackingModesIfRequired(true, true); // Get rotate value - double bearing = transform.getRawBearing(); + double bearing = transform.getBearing(); bearing += detector.getRotationDegreesDelta(); // Rotate the map @@ -580,9 +605,14 @@ final class MapGestureDetector { } beginTime = detector.getEventTime(); - MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( - getLocationFromGesture(detector.getFocusX(), detector.getFocusY()), - MapboxEvent.GESTURE_PITCH_START, transform.getZoom())); + getLocationFromGesture(detector.getFocusX(), detector.getFocusY(), new Callback<Location>() { + @Override + public void onResult(Location location) { + MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapClickEvent( + location, MapboxEvent.GESTURE_PITCH_START, transform.getZoom())); + } + }); + return true; } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapRunnable.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapRunnable.java new file mode 100644 index 0000000000..0268e2cf95 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapRunnable.java @@ -0,0 +1,9 @@ +package com.mapbox.mapboxsdk.maps; + +import android.support.annotation.NonNull; +import android.support.annotation.WorkerThread; + +interface MapRunnable { + @WorkerThread + void execute(@NonNull NativeMapView nativeMapView); +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapState.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapState.java new file mode 100644 index 0000000000..90764b709b --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapState.java @@ -0,0 +1,139 @@ +package com.mapbox.mapboxsdk.maps; + +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.annotation.UiThread; +import android.text.TextUtils; + +import com.mapbox.mapboxsdk.constants.MapboxConstants; + +class MapState extends MapThreadExecutor implements State { + + private String apiBaseUrl; + private String styleUrl; + private boolean debug; + private long transitionDuration; + private long transitionDelay; + + MapState(@NonNull NativeMapView nativeMapView, @NonNull ThreadExecutor invocation) { + super(nativeMapView, invocation); + } + + @UiThread + void setApiBaseUrl(@NonNull final String apiBaseUrl) { + this.apiBaseUrl = apiBaseUrl; + queueRenderEvent(new MapRunnable() { + @Override + public void execute(NativeMapView nativeMapView) { + nativeMapView.setApiBaseUrl(apiBaseUrl); + } + }); + } + + @UiThread + String getStyleUrl() { + return styleUrl; + } + + @UiThread + void setStyleUrl(final String styleUrl) { + this.styleUrl = styleUrl; + queueRenderEvent(new MapRunnable() { + @Override + public void execute(NativeMapView nativeMapView) { + nativeMapView.setStyleUrl(styleUrl); + } + }); + } + + @UiThread + boolean getDebug() { + return debug; + } + + @UiThread + void setDebug(final boolean debug) { + this.debug = debug; + queueRenderEvent(new MapRunnable() { + @Override + public void execute(NativeMapView nativeMapView) { + nativeMapView.setDebug(debug); + } + }); + } + + @UiThread + void cycleDebugOptions() { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.cycleDebugOptions(); + } + }); + } + + long getTransitionDuration() { + return transitionDuration; + } + + void setTransitionDuration(final long transitionDuration) { + this.transitionDuration = transitionDuration; + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.setTransitionDuration(transitionDuration); + } + }); + } + + long getTransitionDelay() { + return transitionDelay; + } + + void setTransitionDelay(final long transitionDelay) { + this.transitionDelay = transitionDelay; + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.setTransitionDuration(transitionDelay); + } + }); + } + + @UiThread + public void onSaveInstanceState(Bundle outState) { + outState.putBoolean(MapboxConstants.STATE_DEBUG_ACTIVE, debug); + outState.putString(MapboxConstants.STATE_STYLE_URL, styleUrl); + outState.putString(MapboxConstants.STATE_API_BASE_URL, apiBaseUrl); + outState.putLong(MapboxConstants.STATE_TRANSITION_DELAY, transitionDelay); + outState.putLong(MapboxConstants.STATE_TRANSITION_DURATION, transitionDuration); + } + + @UiThread + public void onRestoreInstanceState(Bundle savedInstanceState) { + boolean debug = savedInstanceState.getBoolean(MapboxConstants.STATE_DEBUG_ACTIVE); + if (debug) { + setDebug(debug); + } + + String styleUrl = savedInstanceState.getString(MapboxConstants.STATE_STYLE_URL); + if (!TextUtils.isEmpty(styleUrl)) { + setStyleUrl(styleUrl); + } + + String apiBaseUrl = savedInstanceState.getString(MapboxConstants.STATE_API_BASE_URL); + if (!TextUtils.isEmpty(apiBaseUrl)) { + setApiBaseUrl(apiBaseUrl); + } + + long transitionDuration = savedInstanceState.getLong(MapboxConstants.STATE_TRANSITION_DURATION); + if (transitionDuration != 0) { + setTransitionDuration(transitionDuration); + } + + long transitionDelay = savedInstanceState.getLong(MapboxConstants.STATE_TRANSITION_DELAY); + if (transitionDelay != 0) { + setTransitionDelay(transitionDelay); + } + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapThreadExecutor.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapThreadExecutor.java new file mode 100644 index 0000000000..24fc29224f --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapThreadExecutor.java @@ -0,0 +1,32 @@ +package com.mapbox.mapboxsdk.maps; + +import android.support.annotation.MainThread; +import android.support.annotation.NonNull; +import android.support.annotation.WorkerThread; + +abstract class MapThreadExecutor implements ThreadExecutor { + + private final NativeMapView nativeMapView; + private final ThreadExecutor threadExecutor; + + MapThreadExecutor(@NonNull NativeMapView nativeMapView, @NonNull ThreadExecutor threadExecutor) { + this.nativeMapView = nativeMapView; + this.threadExecutor = threadExecutor; + } + + @MainThread + public void queueRenderEvent(final MapRunnable mapRunnable) { + threadExecutor.queueRenderEvent(mapRunnable); + } + + @WorkerThread + public void queueUiEvent(Runnable runnable) { + threadExecutor.queueUiEvent(runnable); + } + + @NonNull + NativeMapView getNativeMapView() { + return nativeMapView; + } + +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index c124531fa5..e6c08ef021 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -8,7 +8,6 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; -import android.graphics.Canvas; import android.graphics.PointF; import android.net.ConnectivityManager; import android.net.NetworkInfo; @@ -21,7 +20,6 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; import android.support.v7.app.AlertDialog; -import android.text.TextUtils; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -74,6 +72,7 @@ import static android.opengl.GLSurfaceView.RENDERMODE_WHEN_DIRTY; public class MapView extends FrameLayout { private NativeMapView nativeMapView; + private MapState mapState; private boolean destroyed; private GLSurfaceView glSurfaceView; @@ -141,6 +140,7 @@ public class MapView extends FrameLayout { glSurfaceView = (GLSurfaceView) findViewById(R.id.surfaceView); glSurfaceView.setEGLConfigChooser(8, 8, 8, 0 /** TODO: What alpha value do we need here?? */, 16, 8); glSurfaceView.setEGLContextClientVersion(2); + glSurfaceView.setRenderer(new GLSurfaceView.Renderer() { @Override public void onSurfaceCreated(final GL10 gl, EGLConfig eglConfig) { @@ -149,9 +149,8 @@ public class MapView extends FrameLayout { // Create native Map object nativeMapView = new NativeMapView(MapView.this); - if (TextUtils.isEmpty(nativeMapView.getAccessToken())) { - nativeMapView.setAccessToken(Mapbox.getAccessToken()); - } + nativeMapView.setAccessToken(Mapbox.getAccessToken()); + nativeMapView.setReachability(isConnected()); //Continue configuring the map view on the main thread MapView.this.post(new Runnable() { @@ -191,6 +190,25 @@ public class MapView extends FrameLayout { } protected void onNativeMapViewReady() { + ThreadExecutor threadExecutor = new ThreadExecutor() { + @Override + public void queueRenderEvent(final MapRunnable runnable) { + glSurfaceView.queueEvent(new Runnable() { + @Override + public void run() { + runnable.execute(nativeMapView); + } + }); + } + + @Override + public void queueUiEvent(Runnable runnable) { + glSurfaceView.post(runnable); + } + }; + + + mapState = new MapState(nativeMapView, threadExecutor); // callback for focal point invalidation FocalPointInvalidator focalPoint = new FocalPointInvalidator(compassView); @@ -202,19 +220,19 @@ public class MapView extends FrameLayout { CameraZoomInvalidator zoomInvalidator = new CameraZoomInvalidator(); // setup components for MapboxMap creation - Projection proj = new Projection(nativeMapView); + Projection proj = new Projection(mapState, getWidth(), getHeight()); UiSettings uiSettings = new UiSettings(proj, focalPoint, compassView, attrView, logoView); - TrackingSettings trackingSettings = new TrackingSettings(myLocationView, uiSettings, focalPoint, zoomInvalidator); + TrackingSettings tracking = new TrackingSettings(myLocationView, uiSettings, focalPoint, zoomInvalidator); MyLocationViewSettings myLocationViewSettings = new MyLocationViewSettings(myLocationView, proj, focalPoint); MarkerViewManager markerViewManager = new MarkerViewManager((ViewGroup) findViewById(R.id.markerViewContainer)); - AnnotationManager annotations = new AnnotationManager(nativeMapView, this, markerViewManager); - Transform transform = new Transform(nativeMapView, annotations.getMarkerViewManager(), trackingSettings); - mapboxMap = new MapboxMap(nativeMapView, transform, uiSettings, trackingSettings, myLocationViewSettings, proj, + AnnotationManager annotations = new AnnotationManager(nativeMapView, threadExecutor, this, markerViewManager); + Transform transform = new Transform(nativeMapView, threadExecutor, annotations.getMarkerViewManager(), tracking); + mapboxMap = new MapboxMap(mapState, transform, uiSettings, tracking, myLocationViewSettings, proj, registerTouchListener, annotations); // user input - mapGestureDetector = new MapGestureDetector(getContext(), transform, proj, uiSettings, trackingSettings, annotations); - mapKeyListener = new MapKeyListener(transform, trackingSettings, uiSettings); + mapGestureDetector = new MapGestureDetector(getContext(), transform, proj, uiSettings, tracking, annotations); + mapKeyListener = new MapKeyListener(transform, tracking, uiSettings); mapZoomButtonController = new MapZoomButtonController(this, uiSettings, transform); // inject widgets with MapboxMap @@ -222,9 +240,6 @@ public class MapView extends FrameLayout { myLocationView.setMapboxMap(mapboxMap); attrView.setOnClickListener(new AttributionOnClickListener(getContext(), transform)); - // notify Map object about current connectivity state - nativeMapView.setReachability(isConnected()); - // initialise MapboxMap mapboxMap.initialise(getContext(), mapboxMapOptions); @@ -249,14 +264,12 @@ public class MapView extends FrameLayout { */ @UiThread public void onCreate(@Nullable Bundle savedInstanceState) { - //nativeMapView.setAccessToken(Mapbox.getAccessToken()); - if (savedInstanceState == null) { MapboxTelemetry.getInstance().pushEvent(MapboxEvent.buildMapLoadEvent()); } else if (savedInstanceState.getBoolean(MapboxConstants.STATE_HAS_SAVED_STATE)) { + mapState.onRestoreInstanceState(savedInstanceState); mapboxMap.onRestoreInstanceState(savedInstanceState); } - } /** @@ -269,6 +282,7 @@ public class MapView extends FrameLayout { @UiThread public void onSaveInstanceState(@NonNull Bundle outState) { outState.putBoolean(MapboxConstants.STATE_HAS_SAVED_STATE, true); + mapState.onSaveInstanceState(outState); mapboxMap.onSaveInstanceState(outState); } @@ -403,7 +417,12 @@ public class MapView extends FrameLayout { */ @UiThread public void onLowMemory() { - nativeMapView.onLowMemory(); + glSurfaceView.queueEvent(new Runnable() { + @Override + public void run() { + nativeMapView.onLowMemory(); + } + }); } // Called when debug mode is enabled to update a FPS counter @@ -449,17 +468,12 @@ public class MapView extends FrameLayout { * @param url The URL of the map style * @see Style */ - public void setStyleUrl(@NonNull String url) { + public void setStyleUrl(@NonNull final String url) { if (destroyed) { return; } - // stopgap for https://github.com/mapbox/mapbox-gl-native/issues/6242 - if (TextUtils.isEmpty(nativeMapView.getAccessToken())) { - nativeMapView.setAccessToken(Mapbox.getAccessToken()); - } - - nativeMapView.setStyleUrl(url); + mapState.setStyleUrl(url); } // @@ -485,28 +499,6 @@ public class MapView extends FrameLayout { } } - @Override - public void onDraw(Canvas canvas) { - Timber.i("onDraw"); - super.onDraw(canvas); - if (isInEditMode()) { - return; - } - } - - @Override - protected void onSizeChanged(int width, int height, int oldw, int oldh) { - if (destroyed) { - return; - } - - if (!isInEditMode()) { - if (nativeMapView != null) { - //XXX This should happen through GLSurfaceView#Renderer callbacks nativeMapView.resizeView(width, height); - } - } - } - // // View events // @@ -1005,14 +997,4 @@ public class MapView extends FrameLayout { onMapReadyCallbackList.add(callback); } } - - private class RenderRunnable implements Runnable { - @Override - public void run() { - if (destroyed) { - return; - } - nativeMapView.render(); - } - } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java index 69a95457b8..2ea9f422b9 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapboxMap.java @@ -6,7 +6,6 @@ import android.graphics.PointF; import android.graphics.RectF; import android.location.Location; import android.os.Bundle; -import android.os.Handler; import android.support.annotation.FloatRange; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -16,7 +15,6 @@ import android.text.TextUtils; import android.view.View; import android.view.ViewGroup; -import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.annotations.Annotation; import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions; import com.mapbox.mapboxsdk.annotations.BaseMarkerViewOptions; @@ -59,8 +57,7 @@ import timber.log.Timber; */ public final class MapboxMap { - private final NativeMapView nativeMapView; - + private final MapState mapState; private final UiSettings uiSettings; private final TrackingSettings trackingSettings; private final Projection projection; @@ -69,13 +66,12 @@ public final class MapboxMap { private final MyLocationViewSettings myLocationViewSettings; private final OnRegisterTouchListener onRegisterTouchListener; - private MapboxMap.OnFpsChangedListener onFpsChangedListener; - MapboxMap(NativeMapView map, Transform transform, UiSettings ui, TrackingSettings tracking, + MapboxMap(MapState mapState, Transform transform, UiSettings ui, TrackingSettings tracking, MyLocationViewSettings myLocationView, Projection projection, OnRegisterTouchListener listener, AnnotationManager annotations) { - this.nativeMapView = map; + this.mapState = mapState; this.uiSettings = ui; this.trackingSettings = tracking; this.projection = projection; @@ -94,16 +90,23 @@ public final class MapboxMap { // Map configuration setDebugActive(options.getDebugActive()); setApiBaseUrl(options); - setStyleUrl(options); + //setStyleUrl(options); } void onStart() { - nativeMapView.update(); - trackingSettings.onStart(); - if (TextUtils.isEmpty(nativeMapView.getStyleUrl())) { - // if user hasn't loaded a Style yet - nativeMapView.setStyleUrl(Style.MAPBOX_STREETS); + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.update(); + } + }); + + if (TextUtils.isEmpty(mapState.getStyleUrl())) { + Timber.e("Loading default style!!!!"); + mapState.setStyleUrl(Style.MAPBOX_STREETS); } + + trackingSettings.onStart(); } void onStop() { @@ -111,9 +114,7 @@ public final class MapboxMap { } void onSaveInstanceState(Bundle outState) { - outState.putParcelable(MapboxConstants.STATE_CAMERA_POSITION, transform.getCameraPosition()); - outState.putBoolean(MapboxConstants.STATE_DEBUG_ACTIVE, nativeMapView.getDebug()); - outState.putString(MapboxConstants.STATE_STYLE_URL, nativeMapView.getStyleUrl()); + transform.onSaveInstanceState(outState); trackingSettings.onSaveInstanceState(outState); uiSettings.onSaveInstanceState(outState); } @@ -126,12 +127,6 @@ public final class MapboxMap { uiSettings.onRestoreInstanceState(savedInstanceState); trackingSettings.onRestoreInstanceState(savedInstanceState); - nativeMapView.setDebug(savedInstanceState.getBoolean(MapboxConstants.STATE_DEBUG_ACTIVE)); - - final String styleUrl = savedInstanceState.getString(MapboxConstants.STATE_STYLE_URL); - if (!TextUtils.isEmpty(styleUrl)) { - nativeMapView.setStyleUrl(savedInstanceState.getString(MapboxConstants.STATE_STYLE_URL)); - } } /** @@ -157,11 +152,13 @@ public final class MapboxMap { * Called when the user */ void onUpdate() { - CameraPosition cameraPosition = transform.invalidateCameraPosition(); - uiSettings.update(cameraPosition); - // FIXME introduce update method with camera position - trackingSettings.update(); - annotationManager.update(); + CameraPosition cameraPosition = transform.getCameraPosition(); + if (cameraPosition != null) { + uiSettings.update(cameraPosition); + // FIXME introduce update method with camera position + trackingSettings.update(); + annotationManager.update(); + } } // Style @@ -176,7 +173,7 @@ public final class MapboxMap { */ @UiThread public long getTransitionDuration() { - return nativeMapView.getTransitionDuration(); + return mapState.getTransitionDuration(); } /** @@ -186,7 +183,7 @@ public final class MapboxMap { */ @UiThread public void setTransitionDuration(long duration) { - nativeMapView.setTransitionDuration(duration); + mapState.setTransitionDuration(duration); } /** @@ -199,7 +196,7 @@ public final class MapboxMap { */ @UiThread public long getTransitionDelay() { - return nativeMapView.getTransitionDelay(); + return mapState.getTransitionDelay(); } /** @@ -209,13 +206,26 @@ public final class MapboxMap { */ @UiThread public void setTransitionDelay(long delay) { - nativeMapView.setTransitionDelay(delay); + mapState.setTransitionDelay(delay); } - @Nullable + // FIXME: 10/02/2017 javadoc @UiThread - public Layer getLayer(@NonNull String layerId) { - return nativeMapView.getLayer(layerId); + public void getLayer(@NonNull final String layerId, final Callback<Layer> listener) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final Layer layer = nativeMapView.getLayer(layerId); + mapState.queueUiEvent(new Runnable() { + @Override + public void run() { + if (listener != null) { + listener.onResult(layer); + } + } + }); + } + }); } /** @@ -225,16 +235,29 @@ public final class MapboxMap { * @param <T> the generic attribute of a Layer * @return the casted Layer, null if another type */ - @Nullable @UiThread - public <T extends Layer> T getLayerAs(@NonNull String layerId) { - try { - // noinspection unchecked - return (T) nativeMapView.getLayer(layerId); - } catch (ClassCastException exception) { - Timber.e(String.format("Layer: %s is a different type: %s", layerId, exception)); - return null; - } + public void getLayerAs(@NonNull final String layerId, final Callback.LayerCallback listener) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final Layer layer = nativeMapView.getLayer(layerId); + mapState.queueUiEvent(new Runnable() { + @Override + public void run() { + if (listener != null) { + try { + // noinspection unchecked + listener.onResult(layer); + } catch (ClassCastException exception) { + Timber.e(String.format("Layer: %s is a different type: %s", layerId, exception)); + // noinspection unchecked + listener.onResult(null); + } + } + } + }); + } + }); } /** @@ -254,10 +277,16 @@ public final class MapboxMap { * @param before the layer id to add this layer before */ @UiThread - public void addLayer(@NonNull Layer layer, String before) { - nativeMapView.addLayer(layer, before); + public void addLayer(@NonNull final Layer layer, final String before) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.addLayer(layer, before); + } + }); } + /** * Removes the layer. Any references to the layer become invalid and should not be used anymore * @@ -265,8 +294,17 @@ public final class MapboxMap { * @throws NoSuchLayerException the exception thrown when layer with layerId doesn't exist */ @UiThread - public void removeLayer(@NonNull String layerId) throws NoSuchLayerException { - nativeMapView.removeLayer(layerId); + public void removeLayer(@NonNull final String layerId) throws NoSuchLayerException { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + try { + nativeMapView.removeLayer(layerId); + } catch (NoSuchLayerException exception) { + // FIXME handle exception + } + } + }); } /** @@ -276,14 +314,33 @@ public final class MapboxMap { * @throws NoSuchLayerException the exeption thrown when the layer doesn't exist */ @UiThread - public void removeLayer(@NonNull Layer layer) throws NoSuchLayerException { - nativeMapView.removeLayer(layer); + public void removeLayer(@NonNull final Layer layer) throws NoSuchLayerException { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + try { + nativeMapView.removeLayer(layer); + } catch (NoSuchLayerException exception) { + // FIXME handle exception + } + } + }); } - @Nullable @UiThread - public Source getSource(@NonNull String sourceId) { - return nativeMapView.getSource(sourceId); + public void getSource(@NonNull final String sourceId, final Callback<Source> listener) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final Source source = nativeMapView.getSource(sourceId); + mapState.queueUiEvent(new Runnable() { + @Override + public void run() { + listener.onResult(source); + } + }); + } + }); } /** @@ -293,16 +350,26 @@ public final class MapboxMap { * @param <T> the generic type of a Source * @return the casted Source, null if another type */ - @Nullable @UiThread - public <T extends Source> T getSourceAs(@NonNull String sourceId) { - try { - // noinspection unchecked - return (T) nativeMapView.getSource(sourceId); - } catch (ClassCastException exception) { - Timber.e(String.format("Source: %s is a different type: %s", sourceId, exception)); - return null; - } + public void getSourceAs(@NonNull final String sourceId, final Callback.SourceCallback listener) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final Source source = nativeMapView.getSource(sourceId); + mapState.queueUiEvent(new Runnable() { + @Override + public void run() { + try { + // noinspection unchecked + listener.onResult(source); + } catch (ClassCastException exception) { + Timber.e(String.format("Source: %s is a different type: %s", sourceId, exception)); + listener.onResult(null); + } + } + }); + } + }); } /** @@ -311,8 +378,13 @@ public final class MapboxMap { * @param source the source to add */ @UiThread - public void addSource(@NonNull Source source) { - nativeMapView.addSource(source); + public void addSource(@NonNull final Source source) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.addSource(source); + } + }); } /** @@ -322,8 +394,17 @@ public final class MapboxMap { * @throws NoSuchSourceException the exception thrown when the source with sourceId doesn't exist */ @UiThread - public void removeSource(@NonNull String sourceId) throws NoSuchSourceException { - nativeMapView.removeSource(sourceId); + public void removeSource(@NonNull final String sourceId) throws NoSuchSourceException { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + try { + nativeMapView.removeSource(sourceId); + } catch (NoSuchSourceException exception) { + // FIXME: 10/02/2017 handle exception + } + } + }); } /** @@ -333,8 +414,17 @@ public final class MapboxMap { * @throws NoSuchSourceException the exception thrown when the source with sourceId doesn't exist */ @UiThread - public void removeSource(@NonNull Source source) throws NoSuchSourceException { - nativeMapView.removeSource(source); + public void removeSource(@NonNull final Source source) throws NoSuchSourceException { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + try { + nativeMapView.removeSource(source); + } catch (NoSuchSourceException exception) { + // FIXME: 10/02/2017 handle exception + } + } + }); } /** @@ -344,8 +434,13 @@ public final class MapboxMap { * @param image the pre-multiplied Bitmap */ @UiThread - public void addImage(@NonNull String name, @NonNull Bitmap image) { - nativeMapView.addImage(name, image); + public void addImage(@NonNull final String name, @NonNull final Bitmap image) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.addImage(name, image); + } + }); } /** @@ -354,8 +449,13 @@ public final class MapboxMap { * @param name the name of the image to remove */ @UiThread - public void removeImage(String name) { - nativeMapView.removeImage(name); + public void removeImage(final String name) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.removeImage(name); + } + }); } // @@ -465,6 +565,7 @@ public final class MapboxMap { * * @return the Projection associated with this map */ + @UiThread public Projection getProjection() { return projection; } @@ -479,6 +580,7 @@ public final class MapboxMap { * This invokes the {@link CancelableCallback} for ongoing camera updates. * </p> */ + @UiThread public void cancelTransitions() { transform.cancelTransitions(); } @@ -490,6 +592,7 @@ public final class MapboxMap { * * @return The current position of the Camera. */ + @UiThread public final CameraPosition getCameraPosition() { return transform.getCameraPosition(); } @@ -501,6 +604,7 @@ public final class MapboxMap { * * @param cameraPosition the camera position to set */ + @UiThread public void setCameraPosition(@NonNull CameraPosition cameraPosition) { moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition), null); } @@ -527,15 +631,10 @@ public final class MapboxMap { */ @UiThread public final void moveCamera(final CameraUpdate update, final MapboxMap.CancelableCallback callback) { - new Handler().post(new Runnable() { - @Override - public void run() { - transform.moveCamera(MapboxMap.this, update, callback); - // MapChange.REGION_DID_CHANGE_ANIMATED is not called for `jumpTo` - // invalidate camera position to provide OnCameraChange event. - invalidateCameraPosition(); - } - }); + transform.moveCamera(MapboxMap.this, update, callback); + // MapChange.REGION_DID_CHANGE_ANIMATED is not called for `jumpTo` + // invalidate camera position to provide OnCameraChange event. + invalidateCameraPosition(); } /** @@ -633,12 +732,7 @@ public final class MapboxMap { @UiThread public final void easeCamera(final CameraUpdate update, final int durationMs, final boolean easingInterpolator, final MapboxMap.CancelableCallback callback) { - new Handler().post(new Runnable() { - @Override - public void run() { - transform.easeCamera(MapboxMap.this, update, durationMs, easingInterpolator, callback); - } - }); + transform.easeCamera(MapboxMap.this, update, durationMs, easingInterpolator, callback); } /** @@ -709,19 +803,14 @@ public final class MapboxMap { @UiThread public final void animateCamera(final CameraUpdate update, final int durationMs, final MapboxMap.CancelableCallback callback) { - new Handler().post(new Runnable() { - @Override - public void run() { - transform.animateCamera(MapboxMap.this, update, durationMs, callback); - } - }); + transform.animateCamera(MapboxMap.this, update, durationMs, callback); } /** * Invalidates the current camera position by reconstructing it from mbgl */ void invalidateCameraPosition() { - CameraPosition cameraPosition = transform.invalidateCameraPosition(); + CameraPosition cameraPosition = transform.getCameraPosition(); if (cameraPosition != null) { transform.updateCameraPosition(cameraPosition); } @@ -738,19 +827,12 @@ public final class MapboxMap { transform.resetNorth(); } - /** - * Set focal bearing. - */ - public void setFocalBearing(double bearing, float focalX, float focalY, long duration) { - transform.setBearing(bearing, focalX, focalY, duration); - } - public float getHeight() { - return nativeMapView.getHeight(); + return projection.getHeight(); } public float getWidth() { - return nativeMapView.getWidth(); + return projection.getWidth(); } // @@ -764,7 +846,7 @@ public final class MapboxMap { */ @UiThread public boolean isDebugActive() { - return nativeMapView.getDebug(); + return mapState.getDebug(); } /** @@ -777,7 +859,7 @@ public final class MapboxMap { */ @UiThread public void setDebugActive(boolean debugActive) { - nativeMapView.setDebug(debugActive); + mapState.setDebug(debugActive); } /** @@ -791,7 +873,7 @@ public final class MapboxMap { */ @UiThread public void cycleDebugOptions() { - nativeMapView.cycleDebugOptions(); + mapState.cycleDebugOptions(); } // @@ -801,7 +883,7 @@ public final class MapboxMap { private void setApiBaseUrl(@NonNull MapboxMapOptions options) { String apiBaseUrl = options.getApiBaseUrl(); if (!TextUtils.isEmpty(apiBaseUrl)) { - nativeMapView.setApiBaseUrl(apiBaseUrl); + mapState.setApiBaseUrl(apiBaseUrl); } } @@ -840,7 +922,7 @@ public final class MapboxMap { */ @UiThread public void setStyleUrl(@NonNull String url) { - nativeMapView.setStyleUrl(url); + mapState.setStyleUrl(url); } /** @@ -869,13 +951,10 @@ public final class MapboxMap { * * @param options the object containing the style url */ + @UiThread private void setStyleUrl(@NonNull MapboxMapOptions options) { String style = options.getStyle(); if (!TextUtils.isEmpty(style)) { - // stopgap for https://github.com/mapbox/mapbox-gl-native/issues/6242 - if (TextUtils.isEmpty(nativeMapView.getAccessToken())) { - nativeMapView.setAccessToken(Mapbox.getAccessToken()); - } setStyleUrl(style); } } @@ -891,7 +970,7 @@ public final class MapboxMap { @UiThread @NonNull public String getStyleUrl() { - return nativeMapView.getStyleUrl(); + return mapState.getStyleUrl(); } // @@ -909,9 +988,8 @@ public final class MapboxMap { * @return The {@code Marker} that was added to the map. */ @UiThread - @NonNull - public Marker addMarker(@NonNull MarkerOptions markerOptions) { - return annotationManager.addMarker(markerOptions, this); + public void addMarker(@NonNull MarkerOptions markerOptions) { + annotationManager.addMarker(markerOptions, this, null); } /** @@ -925,9 +1003,37 @@ public final class MapboxMap { * @return The {@code Marker} that was added to the map. */ @UiThread - @NonNull - public Marker addMarker(@NonNull BaseMarkerOptions markerOptions) { - return annotationManager.addMarker(markerOptions, this); + public void addMarker(@NonNull MarkerOptions markerOptions, @Nullable Callback<Marker> markerCallback) { + annotationManager.addMarker(markerOptions, this, markerCallback); + } + + + /** + * <p> + * Adds a marker to this map. + * </p> + * The marker's icon is rendered on the map at the location {@code Marker.position}. + * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet. + * + * @param markerOptions A marker options object that defines how to render the marker. + */ + @UiThread + public void addMarker(@NonNull BaseMarkerOptions markerOptions) { + annotationManager.addMarker(markerOptions, this, null); + } + + /** + * <p> + * Adds a marker to this map. + * </p> + * The marker's icon is rendered on the map at the location {@code Marker.position}. + * If {@code Marker.title} is defined, the map shows an info box with the marker's title and snippet. + * + * @param markerOptions A marker options object that defines how to render the marker. + */ + @UiThread + public void addMarker(@NonNull BaseMarkerOptions markerOptions, @Nullable Callback<Marker> markerCallback) { + annotationManager.addMarker(markerOptions, this, markerCallback); } /** @@ -942,8 +1048,8 @@ public final class MapboxMap { */ @UiThread @NonNull - public MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions) { - return annotationManager.addMarker(markerOptions, this, null); + public void addMarker(@NonNull BaseMarkerViewOptions markerOptions) { + annotationManager.addMarker(markerOptions, this, null); } @@ -959,29 +1065,34 @@ public final class MapboxMap { * @return The {@code Marker} that was added to the map. */ @UiThread - @NonNull - public MarkerView addMarker(@NonNull BaseMarkerViewOptions markerOptions, - final MarkerViewManager.OnMarkerViewAddedListener onMarkerViewAddedListener) { - return annotationManager.addMarker(markerOptions, this, onMarkerViewAddedListener); + public void addMarker(@NonNull BaseMarkerViewOptions markerOptions, + Callback<MarkerView> listener) { + annotationManager.addMarker(markerOptions, this, listener); } /** * FIXME javadoc */ @UiThread - @NonNull - public List<MarkerView> addMarkerViews(@NonNull List<? extends - BaseMarkerViewOptions> markerViewOptions) { - return annotationManager.addMarkerViews(markerViewOptions, this); + public void addMarkerViews(@NonNull List<? extends BaseMarkerViewOptions> markerViewOptions) { + annotationManager.addMarkerViews(markerViewOptions, this, null); } /** * FIXME javadoc */ @UiThread - @NonNull - public List<MarkerView> getMarkerViewsInRect(@NonNull RectF rect) { - return annotationManager.getMarkerViewsInRect(rect); + public void addMarkerViews(@NonNull List<? extends BaseMarkerViewOptions> markerViewOptions, + Callback<List<MarkerView>> callback) { + annotationManager.addMarkerViews(markerViewOptions, this, callback); + } + + /** + * FIXME javadoc + */ + @UiThread + public void getMarkerViewsInRect(@NonNull RectF rect, Callback<List<MarkerView>> listener) { + annotationManager.getMarkerViewsInRect(rect, listener); } /** @@ -995,10 +1106,9 @@ public final class MapboxMap { * @return A list of the {@code Marker}s that were added to the map. */ @UiThread - @NonNull - public List<Marker> addMarkers(@NonNull List<? extends - BaseMarkerOptions> markerOptionsList) { - return annotationManager.addMarkers(markerOptionsList, this); + public void addMarkers(@NonNull List<? extends + BaseMarkerOptions> markerOptionsList, Callback<List<Marker>> listCallback) { + annotationManager.addMarkers(markerOptionsList, this, listCallback); } /** @@ -1020,9 +1130,8 @@ public final class MapboxMap { * @return The {@code Polyine} that was added to the map. */ @UiThread - @NonNull - public Polyline addPolyline(@NonNull PolylineOptions polylineOptions) { - return annotationManager.addPolyline(polylineOptions, this); + public void addPolyline(@NonNull PolylineOptions polylineOptions, Callback<Polyline> listener) { + annotationManager.addPolyline(polylineOptions, this, listener); } /** @@ -1032,9 +1141,8 @@ public final class MapboxMap { * @return A list of the {@code Polyline}s that were added to the map. */ @UiThread - @NonNull - public List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList) { - return annotationManager.addPolylines(polylineOptionsList, this); + public void addPolylines(@NonNull List<PolylineOptions> polylineOptionsList, Callback<List<Polyline>> listener) { + annotationManager.addPolylines(polylineOptionsList, this, listener); } /** @@ -1054,9 +1162,8 @@ public final class MapboxMap { * @return The {@code Polygon} that was added to the map. */ @UiThread - @NonNull - public Polygon addPolygon(@NonNull PolygonOptions polygonOptions) { - return annotationManager.addPolygon(polygonOptions, this); + public void addPolygon(@NonNull PolygonOptions polygonOptions, Callback<Polygon> listener) { + annotationManager.addPolygon(polygonOptions, this, listener); } /** @@ -1066,9 +1173,8 @@ public final class MapboxMap { * @return A list of the {@code Polygon}s that were added to the map. */ @UiThread - @NonNull - public List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList) { - return annotationManager.addPolygons(polygonOptionsList, this); + public void addPolygons(@NonNull List<PolygonOptions> polygonOptionsList, Callback<List<Polygon>> listener) { + annotationManager.addPolygons(polygonOptionsList, this, listener); } @@ -1591,11 +1697,15 @@ public final class MapboxMap { * Takes a snapshot of the map. * * @param callback Callback method invoked when the snapshot is taken. - * @param bitmap A pre-allocated bitmap. */ @UiThread - public void snapshot(@NonNull SnapshotReadyCallback callback) { - nativeMapView.addSnapshotCallback(callback); + public void snapshot(@NonNull final SnapshotReadyCallback callback) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.addSnapshotCallback(callback); + } + }); } /** @@ -1606,10 +1716,20 @@ public final class MapboxMap { * @return the list of feature */ @UiThread - @NonNull - public List<Feature> queryRenderedFeatures(@NonNull PointF coordinates, @Nullable String... - layerIds) { - return nativeMapView.queryRenderedFeatures(coordinates, layerIds); + public void queryRenderedFeatures(@NonNull final PointF coordinates, @NonNull final Callback<List<Feature>> callback, + @Nullable final String... layerIds) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final List<Feature> features = nativeMapView.queryRenderedFeatures(coordinates, layerIds); + mapState.queueUiEvent(new Runnable() { + @Override + public void run() { + callback.onResult(features); + } + }); + } + }); } /** @@ -1620,10 +1740,20 @@ public final class MapboxMap { * @return the list of feature */ @UiThread - @NonNull - public List<Feature> queryRenderedFeatures(@NonNull RectF coordinates, @Nullable String... - layerIds) { - return nativeMapView.queryRenderedFeatures(coordinates, layerIds); + public void queryRenderedFeatures(@NonNull final RectF coordinates, @NonNull final Callback<List<Feature>> callback, + @Nullable final String... layerIds) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final List<Feature> features = nativeMapView.queryRenderedFeatures(coordinates, layerIds); + mapState.queueUiEvent(new Runnable() { + @Override + public void run() { + callback.onResult(features); + } + }); + } + }); } // @@ -2012,4 +2142,4 @@ public final class MapboxMap { Transform getTransform() { return transform; } -} +}
\ No newline at end of file diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java index f5fd886662..c1f6afbda1 100755 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/NativeMapView.java @@ -578,10 +578,15 @@ final class NativeMapView { * * @param bitmap the snapshot as a bitmap */ - protected void onSnapshotReady(Bitmap bitmap) { - if (snapshotReadyCallback != null && bitmap != null) { - snapshotReadyCallback.onSnapshotReady(bitmap); - } + protected void onSnapshotReady(final Bitmap bitmap) { + mapView.post(new Runnable() { + @Override + public void run() { + if (snapshotReadyCallback != null && bitmap != null) { + snapshotReadyCallback.onSnapshotReady(bitmap); + } + } + }); } native void setReachability(boolean status); diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java index b7f93cc913..b52184912c 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Projection.java @@ -15,25 +15,34 @@ import com.mapbox.mapboxsdk.geometry.VisibleRegion; */ public class Projection { - private final NativeMapView nativeMapView; - private int[] contentPadding; + private final MapState mapState; + private final float height; + private final float width; - Projection(@NonNull NativeMapView nativeMapView) { - this.nativeMapView = nativeMapView; - this.contentPadding = new int[] {0, 0, 0, 0}; + private int[] contentPadding = new int[] {0, 0, 0, 0}; + + Projection(@NonNull MapState mapState, float width, float height) { + this.mapState = mapState; + this.width = width; + this.height = height; } void setContentPadding(int[] contentPadding, int[] userLocationViewPadding) { this.contentPadding = contentPadding; - int[] padding = new int[] { + final int[] padding = new int[] { contentPadding[0] + userLocationViewPadding[0], contentPadding[1] + userLocationViewPadding[1], contentPadding[2] + userLocationViewPadding[2], contentPadding[3] + userLocationViewPadding[3] }; - nativeMapView.setContentPadding(padding); + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.setContentPadding(padding); + } + }); } int[] getContentPadding() { @@ -54,8 +63,20 @@ public class Projection { * @param latitude The latitude for which to return the value. * @return The distance measured in meters. */ - public double getMetersPerPixelAtLatitude(@FloatRange(from = -90, to = 90) double latitude) { - return nativeMapView.getMetersPerPixelAtLatitude(latitude); + public void getMetersPerPixelAtLatitude(@FloatRange(from = -90, to = 90) final double latitude, + final Callback<Double> listener) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final double metersPerPixel = nativeMapView.getMetersPerPixelAtLatitude(latitude); + mapState.queueUiEvent(new Runnable() { + @Override + public void run() { + listener.onResult(metersPerPixel); + } + }); + } + }); } /** @@ -67,8 +88,19 @@ public class Projection { * @return The LatLng corresponding to the point on the screen, or null if the ray through * the given screen point does not intersect the ground plane. */ - public LatLng fromScreenLocation(PointF point) { - return nativeMapView.latLngForPixel(point); + public void fromScreenLocation(final PointF point, final Callback<LatLng> listener) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final LatLng latLng = nativeMapView.latLngForPixel(point); + mapState.queueUiEvent(new Runnable() { + @Override + public void run() { + listener.onResult(latLng); + } + }); + } + }); } /** @@ -77,25 +109,37 @@ public class Projection { * * @return The projection of the viewing frustum in its current state. */ - public VisibleRegion getVisibleRegion() { - LatLngBounds.Builder builder = new LatLngBounds.Builder(); - - float left = contentPadding[0]; - float right = nativeMapView.getWidth() - contentPadding[2]; - float top = contentPadding[1]; - float bottom = nativeMapView.getHeight() - contentPadding[3]; - - LatLng topLeft = fromScreenLocation(new PointF(left, top)); - LatLng topRight = fromScreenLocation(new PointF(right, top)); - LatLng bottomRight = fromScreenLocation(new PointF(right, bottom)); - LatLng bottomLeft = fromScreenLocation(new PointF(left, bottom)); - - builder.include(topLeft) - .include(topRight) - .include(bottomRight) - .include(bottomLeft); - - return new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight, builder.build()); + public void getVisibleRegion(final Callback<VisibleRegion> listener) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + LatLngBounds.Builder builder = new LatLngBounds.Builder(); + + final float left = contentPadding[0]; + float right = nativeMapView.getWidth() - contentPadding[2]; + float top = contentPadding[1]; + float bottom = nativeMapView.getHeight() - contentPadding[3]; + + LatLng topLeft = nativeMapView.latLngForPixel(new PointF(left, top)); + LatLng topRight = nativeMapView.latLngForPixel(new PointF(right, top)); + LatLng bottomRight = nativeMapView.latLngForPixel(new PointF(right, bottom)); + LatLng bottomLeft = nativeMapView.latLngForPixel(new PointF(left, bottom)); + + LatLngBounds bounds = builder.include(topLeft) + .include(topRight) + .include(bottomRight) + .include(bottomLeft) + .build(); + + final VisibleRegion visibleRegion = new VisibleRegion(topLeft, topRight, bottomLeft, bottomRight, bounds); + mapState.queueUiEvent(new Runnable() { + @Override + public void run() { + listener.onResult(visibleRegion); + } + }); + } + }); } /** @@ -106,15 +150,26 @@ public class Projection { * @param location A LatLng on the map to convert to a screen location. * @return A Point representing the screen location in screen pixels. */ - public PointF toScreenLocation(LatLng location) { - return nativeMapView.pixelForLatLng(location); + public void toScreenLocation(final LatLng location, final Callback<PointF> listener) { + mapState.queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final PointF pointF = nativeMapView.pixelForLatLng(location); + mapState.queueUiEvent(new Runnable() { + @Override + public void run() { + listener.onResult(pointF); + } + }); + } + }); } float getHeight() { - return nativeMapView.getHeight(); + return height; } float getWidth() { - return nativeMapView.getWidth(); + return width; } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/State.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/State.java new file mode 100644 index 0000000000..5835312371 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/State.java @@ -0,0 +1,13 @@ +package com.mapbox.mapboxsdk.maps; + +import android.os.Bundle; +import android.support.annotation.UiThread; + +interface State { + + @UiThread + void onSaveInstanceState(Bundle outState); + + @UiThread + void onRestoreInstanceState(Bundle savedInstanceState); +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ThreadExecutor.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ThreadExecutor.java new file mode 100644 index 0000000000..1533ca5733 --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/ThreadExecutor.java @@ -0,0 +1,12 @@ +package com.mapbox.mapboxsdk.maps; + +import android.support.annotation.UiThread; +import android.support.annotation.WorkerThread; + +interface ThreadExecutor { + @UiThread + void queueRenderEvent(MapRunnable runnable); + + @WorkerThread + void queueUiEvent(Runnable runnable); +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java index 97170ca3d4..f2edac63a8 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/Transform.java @@ -1,8 +1,10 @@ package com.mapbox.mapboxsdk.maps; +import android.os.Bundle; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; +import android.support.annotation.WorkerThread; import com.mapbox.mapboxsdk.annotations.MarkerViewManager; import com.mapbox.mapboxsdk.camera.CameraPosition; @@ -16,8 +18,6 @@ import java.util.concurrent.TimeUnit; import timber.log.Timber; -import static com.mapbox.mapboxsdk.maps.MapView.REGION_DID_CHANGE_ANIMATED; - /** * Resembles the current Map transformation. * <p> @@ -25,19 +25,24 @@ import static com.mapbox.mapboxsdk.maps.MapView.REGION_DID_CHANGE_ANIMATED; * {@link com.mapbox.mapboxsdk.maps.MapboxMap.OnCameraChangeListener}. * </p> */ -final class Transform implements MapView.OnMapChangedListener { +// FIXME use MapState instead of exending MapThreadExecutor +final class Transform extends MapThreadExecutor implements State { - private final NativeMapView mapView; private final MarkerViewManager markerViewManager; private final TrackingSettings trackingSettings; private final MyLocationView myLocationView; - private CameraPosition cameraPosition; private MapboxMap.CancelableCallback cameraCancelableCallback; private MapboxMap.OnCameraChangeListener onCameraChangeListener; - Transform(NativeMapView mapView, MarkerViewManager markerViewManager, TrackingSettings trackingSettings) { - this.mapView = mapView; + private LatLng centerLatLng; + private double bearing; + private double tilt; + private double zoom; + + Transform(NativeMapView mapView, ThreadExecutor threadExecutor, MarkerViewManager markerViewManager, + TrackingSettings trackingSettings) { + super(mapView, threadExecutor); this.markerViewManager = markerViewManager; this.trackingSettings = trackingSettings; this.myLocationView = trackingSettings.getMyLocationView(); @@ -51,15 +56,43 @@ final class Transform implements MapView.OnMapChangedListener { } // + // State + // + + @Override + public void onSaveInstanceState(Bundle outState) { + outState.putDouble(MapboxConstants.STATE_CAMERA_LAT, centerLatLng.getLatitude()); + outState.putDouble(MapboxConstants.STATE_CAMERA_LNG, centerLatLng.getLongitude()); + outState.putDouble(MapboxConstants.STATE_CAMERA_BEARING, bearing); + outState.putDouble(MapboxConstants.STATE_CAMERA_TILT, tilt); + outState.putDouble(MapboxConstants.STATE_CAMERA_ZOOM, zoom); + } + + @Override + public void onRestoreInstanceState(Bundle savedInstanceState) { + double latitude = savedInstanceState.getDouble(MapboxConstants.STATE_CAMERA_LAT, 0); + double longitude = savedInstanceState.getDouble(MapboxConstants.STATE_CAMERA_LNG, 0); + centerLatLng = new LatLng(latitude, longitude); + bearing = savedInstanceState.getDouble(MapboxConstants.STATE_CAMERA_BEARING, 0); + tilt = savedInstanceState.getDouble(MapboxConstants.STATE_CAMERA_TILT, 0); + zoom = savedInstanceState.getDouble(MapboxConstants.STATE_CAMERA_ZOOM, 0); + // FIXME: 10/02/2017 ACTUALLY RESTORE STATE + } + + // // Camera API // @UiThread public final CameraPosition getCameraPosition() { - if (cameraPosition == null) { - cameraPosition = invalidateCameraPosition(); - } - return cameraPosition; + return new CameraPosition.Builder(centerLatLng, zoom, tilt, bearing).build(); + } + + void setCameraPosition(CameraPosition cameraPostion) { + centerLatLng = cameraPostion.target; + tilt = cameraPostion.tilt; + bearing = cameraPostion.bearing; + zoom = cameraPostion.zoom; } @UiThread @@ -70,87 +103,123 @@ final class Transform implements MapView.OnMapChangedListener { markerViewManager.setTilt((float) position.tilt); } - @Override - public void onMapChanged(@MapView.MapChange int change) { - if (change == REGION_DID_CHANGE_ANIMATED && cameraCancelableCallback != null) { - updateCameraPosition(invalidateCameraPosition()); - if (cameraCancelableCallback != null) { - cameraCancelableCallback.onFinish(); - cameraCancelableCallback = null; + @UiThread + final void moveCamera(final MapboxMap mapboxMap, final CameraUpdate update, + final MapboxMap.CancelableCallback callback) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + CameraPosition cameraPosition = update.getCameraPosition(mapboxMap); + setCameraPosition(cameraPosition); + cancelTransitions(nativeMapView); + nativeMapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom); + trackingSettings.resetTrackingModesIfRequired(cameraPosition); + if (callback != null) { + callback.onFinish(); + } } - mapView.removeOnMapChangedListener(this); - } - } + }); - @UiThread - final void moveCamera(MapboxMap mapboxMap, CameraUpdate update, MapboxMap.CancelableCallback callback) { - cameraPosition = update.getCameraPosition(mapboxMap); - trackingSettings.resetTrackingModesIfRequired(cameraPosition); - cancelTransitions(); - mapView.jumpTo(cameraPosition.bearing, cameraPosition.target, cameraPosition.tilt, cameraPosition.zoom); - if (callback != null) { - callback.onFinish(); - } } @UiThread - final void easeCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, boolean easingInterpolator, - final MapboxMap.CancelableCallback callback) { - cameraPosition = update.getCameraPosition(mapboxMap); - trackingSettings.resetTrackingModesIfRequired(cameraPosition); - - cancelTransitions(); - if (callback != null) { - cameraCancelableCallback = callback; - mapView.addOnMapChangedListener(this); - } - - mapView.easeTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt, - cameraPosition.zoom, easingInterpolator); + final void easeCamera(final MapboxMap mapboxMap, final CameraUpdate update, final int durationMs, + final boolean easingInterpolator, final MapboxMap.CancelableCallback callback) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + CameraPosition position = update.getCameraPosition(mapboxMap); + trackingSettings.resetTrackingModesIfRequired(position); + + cancelTransitions(nativeMapView); + if (callback != null) { + cameraCancelableCallback = callback; + // nativeMapView.addOnMapChangedListener(Transform.this); + } + + nativeMapView.easeTo(position.bearing, position.target, getDurationNano(durationMs), position.tilt, + position.zoom, easingInterpolator); + } + }); } @UiThread - final void animateCamera(MapboxMap mapboxMap, CameraUpdate update, int durationMs, + final void animateCamera(final MapboxMap mapboxMap, final CameraUpdate update, final int durationMs, final MapboxMap.CancelableCallback callback) { - cameraPosition = update.getCameraPosition(mapboxMap); - trackingSettings.resetTrackingModesIfRequired(cameraPosition); - - cancelTransitions(); - if (callback != null) { - cameraCancelableCallback = callback; - mapView.addOnMapChangedListener(this); - } - - mapView.flyTo(cameraPosition.bearing, cameraPosition.target, getDurationNano(durationMs), cameraPosition.tilt, - cameraPosition.zoom); + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + CameraPosition position = update.getCameraPosition(mapboxMap); + trackingSettings.resetTrackingModesIfRequired(position); + + cancelTransitions(nativeMapView); + if (callback != null) { + cameraCancelableCallback = callback; + // nativeMapView.addOnMapChangedListener(Transform.this); + } + + nativeMapView.flyTo(position.bearing, position.target, getDurationNano(durationMs), position.tilt, + position.zoom); + } + }); } @UiThread - @Nullable - CameraPosition invalidateCameraPosition() { - if (mapView != null) { - cameraPosition = new CameraPosition.Builder(mapView.getCameraValues()).build(); - if (onCameraChangeListener != null) { - onCameraChangeListener.onCameraChange(this.cameraPosition); + void invalidateCameraPosition() { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + final CameraPosition cameraPosition = new CameraPosition.Builder(nativeMapView.getCameraValues()).build(); + queueUiEvent(new Runnable() { + @Override + public void run() { + updateCameraPosition(cameraPosition); + if (onCameraChangeListener != null) { + // post camera change event on ui Thread + onCameraChangeListener.onCameraChange(cameraPosition); + } + } + }); } - } - return cameraPosition; + }); } + @UiThread void cancelTransitions() { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + cancelTransitions(nativeMapView); + } + }); + } + + @WorkerThread + void cancelTransitions(NativeMapView nativeMapView) { if (cameraCancelableCallback != null) { - cameraCancelableCallback.onCancel(); - cameraCancelableCallback = null; + queueUiEvent(new Runnable() { + @Override + public void run() { + cameraCancelableCallback.onCancel(); + cameraCancelableCallback = null; + } + }); } - mapView.cancelTransitions(); + nativeMapView.cancelTransitions(); } @UiThread void resetNorth() { - cancelTransitions(); - mapView.resetNorth(); + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + cancelTransitions(nativeMapView); + nativeMapView.resetNorth(); + } + }); } + @UiThread void setOnCameraChangeListener(@Nullable MapboxMap.OnCameraChangeListener listener) { this.onCameraChangeListener = listener; } @@ -159,151 +228,175 @@ final class Transform implements MapView.OnMapChangedListener { return durationMs > 0 ? TimeUnit.NANOSECONDS.convert(durationMs, TimeUnit.MILLISECONDS) : 0; } - // - // non Camera API - // - - // Zoom in or out - + @UiThread double getZoom() { - return cameraPosition.zoom; + return zoom; } + @UiThread void zoom(boolean zoomIn) { + zoom = zoomIn ? zoom + 1 : zoom - 1; zoom(zoomIn, -1.0f, -1.0f); } - void zoom(boolean zoomIn, float x, float y) { - // Cancel any animation - cancelTransitions(); + @UiThread + void zoom(final boolean zoomIn, final float x, final float y) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + cancelTransitions(nativeMapView); + + if (zoomIn) { + nativeMapView.scaleBy(2.0, x, y, MapboxConstants.ANIMATION_DURATION); + } else { + nativeMapView.scaleBy(0.5, x, y, MapboxConstants.ANIMATION_DURATION); + } + } + }); - if (zoomIn) { - mapView.scaleBy(2.0, x, y, MapboxConstants.ANIMATION_DURATION); - } else { - mapView.scaleBy(0.5, x, y, MapboxConstants.ANIMATION_DURATION); - } } - void setZoom(double zoom) { - mapView.setZoom(zoom); + @UiThread + void setZoom(final double zoom) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.setZoom(zoom); + } + }); } - // Direction + @UiThread double getBearing() { - double direction = -mapView.getBearing(); - - while (direction > 360) { - direction -= 360; - } - while (direction < 0) { - direction += 360; - } - - return direction; + return bearing; } - double getRawBearing() { - return mapView.getBearing(); - } - - void setBearing(double bearing) { - if (myLocationView != null) { - myLocationView.setBearing(bearing); - } - mapView.setBearing(bearing); - } - - void setBearing(double bearing, float focalX, float focalY) { + @UiThread + void setBearing(final double bearing) { if (myLocationView != null) { myLocationView.setBearing(bearing); } - mapView.setBearing(bearing, focalX, focalY); + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.setBearing(bearing); + } + }); } - void setBearing(double bearing, float focalX, float focalY, long duration) { + @UiThread + void setBearing(final double bearing, final float focalX, final float focalY) { + this.bearing = bearing; if (myLocationView != null) { myLocationView.setBearing(bearing); } - mapView.setBearing(bearing, focalX, focalY, duration); - } - - - // - // LatLng / CenterCoordinate - // - - LatLng getLatLng() { - return mapView.getLatLng(); + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.setBearing(bearing, focalX, focalY); + } + }); } // // Pitch / Tilt // + @UiThread double getTilt() { - return mapView.getPitch(); + return tilt; } - void setTilt(Double pitch) { + @UiThread + void setTilt(final Double pitch) { + tilt = pitch; if (myLocationView != null) { myLocationView.setTilt(pitch); } markerViewManager.setTilt(pitch.floatValue()); - mapView.setPitch(pitch, 0); + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.setPitch(pitch, 0); + } + }); } // // Center coordinate // - LatLng getCenterCoordinate() { - return mapView.getLatLng(); - } - - void setCenterCoordinate(LatLng centerCoordinate) { - mapView.setLatLng(centerCoordinate); - } - - void setGestureInProgress(boolean gestureInProgress) { - mapView.setGestureInProgress(gestureInProgress); + void setGestureInProgress(final boolean gestureInProgress) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.setGestureInProgress(gestureInProgress); + } + }); if (!gestureInProgress) { invalidateCameraPosition(); } } - void zoomBy(double pow, float x, float y) { - mapView.scaleBy(pow, x, y); + void zoomBy(final double pow, final float x, final float y) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.scaleBy(pow, x, y); + } + }); } - void moveBy(double offsetX, double offsetY, long duration) { - mapView.moveBy(offsetX, offsetY, duration); + void moveBy(final double offsetX, final double offsetY, final long duration) { + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.moveBy(offsetX, offsetY, duration); + } + }); } // // Min & Max ZoomLevel // - void setMinZoom(double minZoom) { + private double minZoom; + private double maxZoom; + + void setMinZoom(final double minZoom) { if ((minZoom < MapboxConstants.MINIMUM_ZOOM) || (minZoom > MapboxConstants.MAXIMUM_ZOOM)) { Timber.e("Not setting minZoomPreference, value is in unsupported range: " + minZoom); return; } - mapView.setMinZoom(minZoom); + this.minZoom = minZoom; + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.setMinZoom(minZoom); + } + }); } double getMinZoom() { - return mapView.getMinZoom(); + return minZoom; } - void setMaxZoom(double maxZoom) { + void setMaxZoom(final double maxZoom) { if ((maxZoom < MapboxConstants.MINIMUM_ZOOM) || (maxZoom > MapboxConstants.MAXIMUM_ZOOM)) { Timber.e("Not setting maxZoomPreference, value is in unsupported range: " + maxZoom); return; } - mapView.setMaxZoom(maxZoom); + + this.maxZoom = maxZoom; + queueRenderEvent(new MapRunnable() { + @Override + public void execute(@NonNull NativeMapView nativeMapView) { + nativeMapView.setMaxZoom(maxZoom); + } + }); } double getMaxZoom() { - return mapView.getMaxZoom(); + return maxZoom; } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java index ed6ef5199a..b3a7fd787f 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/CompassView.java @@ -172,12 +172,14 @@ public final class CompassView extends AppCompatImageView implements Runnable, F final MapboxMap mapboxMap = this.mapboxMap.get(); final CompassView compassView = this.compassView.get(); if (mapboxMap != null && compassView != null) { - PointF focalPoint = compassView.getFocalPoint(); - if (focalPoint != null) { - mapboxMap.setFocalBearing(0, focalPoint.x, focalPoint.y, TIME_MAP_NORTH_ANIMATION); - } else { - mapboxMap.setFocalBearing(0, mapboxMap.getWidth() / 2, mapboxMap.getHeight() / 2, TIME_MAP_NORTH_ANIMATION); - } + //PointF focalPoint = compassView.getFocalPoint(); + //if (focalPoint != null) { + //mapboxMap.setFocalBearing(0, focalPoint.x, focalPoint.y, TIME_MAP_NORTH_ANIMATION); + //} else { + //mapboxMap.setFocalBearing(0, mapboxMap.getWidth() / 2, mapboxMap.getHeight() / 2, TIME_MAP_NORTH_ANIMATION); + //} + // FIXME: 10/02/2017 with animation and focal point + mapboxMap.resetNorth(); compassView.postDelayed(compassView, TIME_WAIT_IDLE + TIME_MAP_NORTH_ANIMATION); } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java index c9888c36d2..fdc9f2dcb0 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationView.java @@ -32,6 +32,7 @@ import com.mapbox.mapboxsdk.constants.MyBearingTracking; import com.mapbox.mapboxsdk.constants.MyLocationTracking; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.location.LocationSource; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.Projection; import com.mapbox.services.android.telemetry.location.LocationEngine; @@ -60,6 +61,7 @@ public class MyLocationView extends View { private Location location; private long locationUpdateTimestamp; private float previousDirection; + private float metersPerPixel; private float accuracy; private Paint accuracyPaint; @@ -256,7 +258,6 @@ public class MyLocationView extends View { } final PointF pointF = screenLocation; - float metersPerPixel = (float) projection.getMetersPerPixelAtLatitude(location.getLatitude()); float accuracyPixels = (Float) accuracyAnimator.getAnimatedValue() / metersPerPixel / 2; float maxRadius = getWidth() / 2; accuracyPixels = accuracyPixels <= maxRadius ? accuracyPixels : maxRadius; @@ -333,6 +334,15 @@ public class MyLocationView extends View { setBearing(position.bearing); setTilt(position.tilt); } + + if (location != null) { + projection.getMetersPerPixelAtLatitude(location.getLatitude(), new Callback<Double>() { + @Override + public void onResult(Double aDouble) { + metersPerPixel = (float) aDouble.doubleValue(); + } + }); + } } public void onStart() { @@ -837,9 +847,14 @@ public class MyLocationView extends View { @Override void invalidate() { if (latLng != null) { - screenLocation = projection.toScreenLocation(latLng); + projection.toScreenLocation(latLng, new Callback<PointF>() { + @Override + public void onResult(PointF pointF) { + screenLocation = pointF; + MyLocationView.this.invalidate(); + } + }); } - MyLocationView.this.invalidate(); } } } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java index e9d823ebda..81ae044777 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/widgets/MyLocationViewSettings.java @@ -21,7 +21,7 @@ public class MyLocationViewSettings { private FocalPointChangeListener focalPointChangeListener; // - // State + // MapThreadExecutor // private boolean enabled; diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AddRemoveMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AddRemoveMarkerActivity.java index c9c0c105fd..1e41d0ae4c 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AddRemoveMarkerActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AddRemoveMarkerActivity.java @@ -13,6 +13,7 @@ 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.Callback; import com.mapbox.mapboxsdk.testapp.R; import com.mapbox.mapboxsdk.testapp.utils.IconUtils; @@ -99,8 +100,13 @@ public class AddRemoveMarkerActivity extends AppCompatActivity { Timber.e("active marker is null"); } - activeMarker = mapboxMap.addMarker(lowThresholdMarker); - Timber.d("showLowThresholdMarker() " + activeMarker.getId()); + mapboxMap.addMarker(lowThresholdMarker, new Callback<Marker>() { + @Override + public void onResult(Marker marker) { + activeMarker = marker; + Timber.d("showLowThresholdMarker() " + activeMarker.getId()); + } + }); } private void showHighThresholdMarker() { @@ -118,8 +124,13 @@ public class AddRemoveMarkerActivity extends AppCompatActivity { Timber.e("active marker is null"); } - activeMarker = mapboxMap.addMarker(highThresholdMarker); - Timber.d("showHighThresholdMarker() " + activeMarker.getId()); + mapboxMap.addMarker(highThresholdMarker, new Callback<Marker>() { + @Override + public void onResult(Marker marker) { + activeMarker = marker; + Timber.d("showHighThresholdMarker() " + activeMarker.getId()); + } + }); } @Override diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java index 5501a8324d..3780271f9f 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/AnimatedMarkerActivity.java @@ -8,30 +8,26 @@ import android.animation.ValueAnimator; import android.os.Bundle; import android.support.annotation.DrawableRes; import android.support.annotation.NonNull; -import android.support.v4.content.res.ResourcesCompat; import android.support.v7.app.AppCompatActivity; -import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import com.mapbox.mapboxsdk.annotations.Icon; import com.mapbox.mapboxsdk.annotations.IconFactory; import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.MarkerView; -import com.mapbox.mapboxsdk.annotations.MarkerViewManager; import com.mapbox.mapboxsdk.annotations.MarkerViewOptions; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; +import com.mapbox.mapboxsdk.geometry.VisibleRegion; +import com.mapbox.mapboxsdk.maps.Callback; 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.utils.IconUtils; -import com.mapbox.services.commons.models.Position; import com.mapbox.services.api.utils.turf.TurfMeasurement; +import com.mapbox.services.commons.models.Position; -import java.util.ArrayList; -import java.util.List; import java.util.Random; public class AnimatedMarkerActivity extends AppCompatActivity { @@ -46,9 +42,6 @@ public class AnimatedMarkerActivity extends AppCompatActivity { private Runnable animationRunnable; - private List<MarkerView> markerViews = new ArrayList<>(); - private boolean stopped; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -87,51 +80,49 @@ public class AnimatedMarkerActivity extends AppCompatActivity { } private void addPassenger() { - if (isActivityStopped()) { - return; - } - - LatLng randomLatLng = getLatLngInBounds(); - - if (passengerMarker == null) { - Icon icon = IconUtils.drawableToIcon(this, R.drawable.ic_directions_run_black, - ResourcesCompat.getColor(getResources(), R.color.blueAccent, getTheme())); - passengerMarker = mapboxMap.addMarker(new MarkerViewOptions() - .position(randomLatLng) - .icon(icon)); - } else { - passengerMarker.setPosition(randomLatLng); - } + getLatLngInBounds(new Callback<LatLng>() { + @Override + public void onResult(LatLng randomLatLng) { + if (passengerMarker == null) { + Icon icon = IconFactory.getInstance(AnimatedMarkerActivity.this) + .fromResource(R.drawable.ic_directions_run_black); + mapboxMap.addMarker(new MarkerViewOptions() + .position(randomLatLng) + .icon(icon), + new Callback<MarkerView>() { + @Override + public void onResult(MarkerView markerView) { + passengerMarker = markerView; + } + }); + } else { + passengerMarker.setPosition(randomLatLng); + } + } + }); } private void addMainCar() { - if (isActivityStopped()) { - return; - } - - LatLng randomLatLng = getLatLngInBounds(); - - if (carMarker == null) { - carMarker = createCarMarker(randomLatLng, R.drawable.ic_taxi_top, - new MarkerViewManager.OnMarkerViewAddedListener() { - @Override - public void onViewAdded(@NonNull MarkerView markerView) { - // Make sure the car marker is selected so that it's always brought to the front (#5285) - mapboxMap.selectMarker(carMarker); - animateMoveToPassenger(carMarker); - } - }); - markerViews.add(carMarker); - } else { - carMarker.setPosition(randomLatLng); - } + getLatLngInBounds(new Callback<LatLng>() { + @Override + public void onResult(LatLng randomLatLng) { + if (carMarker == null) { + createCarMarker(randomLatLng, R.drawable.ic_taxi_top, new Callback<MarkerView>() { + @Override + public void onResult(MarkerView markerView) { + carMarker = markerView; + mapboxMap.selectMarker(carMarker); + animateMoveToPassenger(carMarker); + } + }); + } else { + carMarker.setPosition(randomLatLng); + } + } + }); } private void animateMoveToPassenger(final MarkerView car) { - if (isActivityStopped()) { - return; - } - ValueAnimator animator = animateMoveMarker(car, passengerMarker.getPosition()); animator.addListener(new AnimatorListenerAdapter() { @Override @@ -143,27 +134,31 @@ public class AnimatedMarkerActivity extends AppCompatActivity { } protected void addRandomCar() { - markerViews.add(createCarMarker(getLatLngInBounds(), R.drawable.ic_car_top, - new MarkerViewManager.OnMarkerViewAddedListener() { - @Override - public void onViewAdded(@NonNull MarkerView markerView) { - randomlyMoveMarker(markerView); - } - })); + getLatLngInBounds(new Callback<LatLng>() { + @Override + public void onResult(LatLng latLng) { + createCarMarker(latLng, R.drawable.ic_car_top, new Callback<MarkerView>() { + @Override + public void onResult(MarkerView markerView) { + randomlyMoveMarker(markerView); + } + }); + } + }); } private void randomlyMoveMarker(final MarkerView marker) { - if (isActivityStopped()) { - return; - } - - ValueAnimator animator = animateMoveMarker(marker, getLatLngInBounds()); - - // Add listener to restart animation on end - animator.addListener(new AnimatorListenerAdapter() { + getLatLngInBounds(new Callback<LatLng>() { @Override - public void onAnimationEnd(Animator animation) { - randomlyMoveMarker(marker); + public void onResult(LatLng latLng) { + ValueAnimator animator = animateMoveMarker(marker, latLng); + // Add listener to restart animation on end + animator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + randomlyMoveMarker(marker); + } + }); } }); } @@ -182,31 +177,35 @@ public class AnimatedMarkerActivity extends AppCompatActivity { return markerAnimator; } - private MarkerView createCarMarker(LatLng start, @DrawableRes int carResource, - MarkerViewManager.OnMarkerViewAddedListener listener) { + private void createCarMarker(LatLng start, @DrawableRes int carResource, + Callback<MarkerView> listener) { Icon icon = IconFactory.getInstance(AnimatedMarkerActivity.this) .fromResource(carResource); // View Markers - return mapboxMap.addMarker(new MarkerViewOptions() + mapboxMap.addMarker(new MarkerViewOptions() .position(start) .icon(icon), listener); // GL Markers -// return mapboxMap.addMarker(new MarkerOptions() -// .position(start) -// .icon(icon)); - + //return mapboxMap.addMarker(new MarkerOptions() + // .position(start) + // .icon(icon)); } - private LatLng getLatLngInBounds() { - LatLngBounds bounds = mapboxMap.getProjection().getVisibleRegion().latLngBounds; - Random generator = new Random(); - double randomLat = bounds.getLatSouth() + generator.nextDouble() - * (bounds.getLatNorth() - bounds.getLatSouth()); - double randomLon = bounds.getLonWest() + generator.nextDouble() - * (bounds.getLonEast() - bounds.getLonWest()); - return new LatLng(randomLat, randomLon); + private void getLatLngInBounds(final Callback<LatLng> listener) { + mapboxMap.getProjection().getVisibleRegion(new Callback<VisibleRegion>() { + @Override + public void onResult(VisibleRegion visibleRegion) { + LatLngBounds bounds = visibleRegion.latLngBounds; + Random generator = new Random(); + double randomLat = bounds.getLatSouth() + generator.nextDouble() + * (bounds.getLatNorth() - bounds.getLatSouth()); + double randomLon = bounds.getLonWest() + generator.nextDouble() + * (bounds.getLonEast() - bounds.getLonWest()); + listener.onResult(new LatLng(randomLat, randomLon)); + } + }); } @Override @@ -230,19 +229,6 @@ public class AnimatedMarkerActivity extends AppCompatActivity { @Override protected void onStop() { super.onStop(); - - stopped = true; - - // Stop ongoing animations, prevent memory lekas - MarkerViewManager markerViewManager = mapboxMap.getMarkerViewManager(); - for (MarkerView markerView : markerViews) { - View view = markerViewManager.getView(markerView); - if (view != null) { - view.animate().cancel(); - } - } - - // onStop mapView.onStop(); mapView.removeCallbacks(animationRunnable); } @@ -288,8 +274,4 @@ public class AnimatedMarkerActivity extends AppCompatActivity { Position.fromCoordinates(to.getLongitude(), to.getLatitude()) ); } - - private boolean isActivityStopped() { - return stopped; - } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java index e1e49de95b..209574e96a 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/BulkMarkerActivity.java @@ -26,6 +26,7 @@ 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.Callback; import com.mapbox.mapboxsdk.testapp.R; import com.mapbox.mapboxsdk.testapp.utils.GeoParseUtil; import com.mapbox.mapboxsdk.testapp.utils.IconUtils; @@ -147,7 +148,12 @@ public class BulkMarkerActivity extends AppCompatActivity implements AdapterView .snippet(formatter.format(latLng.getLatitude()) + ", " + formatter.format(latLng.getLongitude()))); } - mapboxMap.addMarkers(markerOptionsList); + mapboxMap.addMarkers(markerOptionsList, new Callback<List<Marker>>() { + @Override + public void onResult(List<Marker> markers) { + Timber.i("Markers added!"); + } + }); } @Override diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java index 85e7aeedef..9135544622 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/DynamicMarkerChangeActivity.java @@ -14,6 +14,7 @@ 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.Callback; import com.mapbox.mapboxsdk.testapp.R; import com.mapbox.mapboxsdk.testapp.utils.IconUtils; @@ -45,7 +46,12 @@ public class DynamicMarkerChangeActivity extends AppCompatActivity { ResourcesCompat.getColor(getResources(), R.color.blueAccent, getTheme()))) .title(getString(R.string.dynamic_marker_chelsea_title)) .snippet(getString(R.string.dynamic_marker_chelsea_snippet)); - marker = mapboxMap.addMarker(markerOptions); + mapboxMap.addMarker(markerOptions, new Callback<Marker>() { + @Override + public void onResult(Marker marker) { + DynamicMarkerChangeActivity.this.marker = marker; + } + }); } }); @@ -54,7 +60,7 @@ public class DynamicMarkerChangeActivity extends AppCompatActivity { fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - if (mapboxMap != null) { + if (mapboxMap != null && marker != null) { updateMarker(); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java index c5ed1d1740..171e99fb7e 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java @@ -3,9 +3,7 @@ package com.mapbox.mapboxsdk.testapp.activity.annotation; import android.animation.Animator; import android.animation.AnimatorInflater; import android.animation.AnimatorListenerAdapter; -import android.animation.FloatEvaluator; import android.animation.ObjectAnimator; -import android.animation.ValueAnimator; import android.content.Context; import android.os.Bundle; import android.os.Handler; @@ -27,6 +25,7 @@ import com.mapbox.mapboxsdk.annotations.MarkerView; import com.mapbox.mapboxsdk.annotations.MarkerViewManager; import com.mapbox.mapboxsdk.annotations.MarkerViewOptions; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -38,6 +37,8 @@ import com.mapbox.mapboxsdk.testapp.model.annotations.TextMarkerViewOptions; import java.util.Random; +import timber.log.Timber; + public class MarkerViewActivity extends AppCompatActivity { private static final LatLng[] LAT_LNGS = new LatLng[] { @@ -75,7 +76,7 @@ public class MarkerViewActivity extends AppCompatActivity { mapView.onCreate(savedInstanceState); mapView.getMapAsync(new OnMapReadyCallback() { @Override - public void onMapReady(@NonNull MapboxMap mapboxMap) { + public void onMapReady(@NonNull final MapboxMap mapboxMap) { MarkerViewActivity.this.mapboxMap = mapboxMap; final MarkerViewManager markerViewManager = mapboxMap.getMarkerViewManager(); @@ -100,25 +101,30 @@ public class MarkerViewActivity extends AppCompatActivity { options.title("Hello"); options.position(new LatLng(38.899774, -77.023237)); options.flat(true); - MarkerView markerView = mapboxMap.addMarker(options); - - // Use object animator to rotate MarkerView - ValueAnimator markerAnimator = ObjectAnimator.ofObject(markerView, "rotation", new FloatEvaluator(), -90, 90); - markerAnimator.setDuration(5000); - markerAnimator.start(); + mapboxMap.addMarker(options); MarkerViewActivity.this.mapboxMap.addMarker(new MarkerOptions() - .title("United States") - .position(new LatLng(38.902580, -77.050102)) - ); - - rotateMarker = MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions() - .text("A") - .rotation(rotation = 270) - .position(new LatLng(38.889876, -77.008849)) + .title("United States") + .position(new LatLng(38.902580, -77.050102)), + new Callback<Marker>() { + @Override + public void onResult(Marker marker) { + Timber.i("United states marker added"); + } + } ); - loopMarkerRotate(); + MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions() + .text("A") + .rotation(rotation = 270) + .position(new LatLng(38.889876, -77.008849)), + new Callback<MarkerView>() { + @Override + public void onResult(MarkerView markerView) { + rotateMarker = markerView; + loopMarkerRotate(); + } + }); MarkerViewActivity.this.mapboxMap.addMarker(new TextMarkerViewOptions() .text("B") @@ -160,35 +166,55 @@ public class MarkerViewActivity extends AppCompatActivity { } }); - movingMarkerOne = MarkerViewActivity.this.mapboxMap.addMarker(new MarkerViewOptions() - .position(CarLocation.CAR_0_LNGS[0]) - .icon(IconFactory.getInstance(mapView.getContext()) - .fromResource(R.drawable.ic_android)) + MarkerViewActivity.this.mapboxMap.addMarker(new MarkerViewOptions() + .position(CarLocation.CAR_0_LNGS[0]) + .icon(IconFactory.getInstance(mapView.getContext()) + .fromResource(R.drawable.ic_android)), + new Callback<MarkerView>() { + @Override + public void onResult(MarkerView markerView) { + movingMarkerOne = markerView; + } + } ); - movingMarkerTwo = mapboxMap.addMarker(new MarkerViewOptions() - .position(CarLocation.CAR_1_LNGS[0]) - .icon(IconFactory.getInstance(mapView.getContext()) - .fromResource(R.drawable.ic_android_2)) + mapboxMap.addMarker(new MarkerViewOptions() + .position(CarLocation.CAR_1_LNGS[0]) + .icon(IconFactory.getInstance(mapView.getContext()) + .fromResource(R.drawable.ic_android_2)), + new Callback<MarkerView>() { + @Override + public void onResult(MarkerView markerView) { + movingMarkerTwo = markerView; + } + } ); // allow more open infowindows at the same time mapboxMap.setAllowConcurrentMultipleOpenInfoWindows(true); // add offscreen markers - Marker markerRightOffScreen = mapboxMap.addMarker(new MarkerOptions() - .setPosition(new LatLng(38.892846, -76.909399)) - .title("InfoWindow") - .snippet("Offscreen, to the right of the Map.")); - - Marker markerRightBottomOffScreen = mapboxMap.addMarker(new MarkerOptions() - .setPosition(new LatLng(38.791645, -77.039006)) - .title("InfoWindow") - .snippet("Offscreen, to the bottom of the Map")); - - // open infowindow offscreen markers - mapboxMap.selectMarker(markerRightOffScreen); - mapboxMap.selectMarker(markerRightBottomOffScreen); + mapboxMap.addMarker(new MarkerOptions() + .setPosition(new LatLng(38.892846, -76.909399)) + .title("InfoWindow") + .snippet("Offscreen, to the right of the Map."), + new Callback<Marker>() { + @Override + public void onResult(Marker marker) { + mapboxMap.selectMarker(marker); + } + }); + + mapboxMap.addMarker(new MarkerOptions() + .setPosition(new LatLng(38.791645, -77.039006)) + .title("InfoWindow") + .snippet("Offscreen, to the bottom of the Map"), + new Callback<Marker>() { + @Override + public void onResult(Marker marker) { + mapboxMap.selectMarker(marker); + } + }); } }); } @@ -222,11 +248,13 @@ public class MarkerViewActivity extends AppCompatActivity { private class MoveMarkerRunnable implements Runnable { @Override public void run() { - int randomInteger = randomAnimator.nextInt(9); - if (randomAnimator.nextInt() % 2 == 0) { - movingMarkerOne.setPosition(CarLocation.CAR_0_LNGS[randomInteger]); - } else { - movingMarkerTwo.setPosition(CarLocation.CAR_1_LNGS[randomInteger]); + if (movingMarkerTwo != null && movingMarkerOne != null) { + int randomInteger = randomAnimator.nextInt(9); + if (randomAnimator.nextInt() % 2 == 0) { + movingMarkerOne.setPosition(CarLocation.CAR_0_LNGS[randomInteger]); + } else { + movingMarkerTwo.setPosition(CarLocation.CAR_1_LNGS[randomInteger]); + } } loopMarkerMove(); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewsInRectangleActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewsInRectangleActivity.java index 266db3fdd1..43c38ef715 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewsInRectangleActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewsInRectangleActivity.java @@ -13,6 +13,7 @@ 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.Callback; import com.mapbox.mapboxsdk.testapp.R; import java.util.List; @@ -54,13 +55,16 @@ public class MarkerViewsInRectangleActivity extends AppCompatActivity implements int left = selectionBox.getLeft() - mapView.getLeft(); RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight()); Timber.i(String.format("Querying box %s", box)); - List<MarkerView> markers = mapboxMap.getMarkerViewsInRect(box); - - // Show count - Toast.makeText( - MarkerViewsInRectangleActivity.this, - String.format("%s markers inside box", markers.size()), - Toast.LENGTH_SHORT).show(); + mapboxMap.getMarkerViewsInRect(box, new Callback<List<MarkerView>>() { + @Override + public void onResult(List<MarkerView> markers) { + // Show count + Toast.makeText( + MarkerViewsInRectangleActivity.this, + String.format("%s markers inside box", markers.size()), + Toast.LENGTH_SHORT).show(); + } + }); } @Override diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java index a88d98161f..4d4b7d739d 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolygonActivity.java @@ -11,6 +11,7 @@ import com.mapbox.mapboxsdk.annotations.PolygonOptions; import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.MapboxMapOptions; @@ -72,9 +73,15 @@ public class PolygonActivity extends AppCompatActivity implements OnMapReadyCall @Override public void onMapReady(MapboxMap map) { mapboxMap = map; - polygon = mapboxMap.addPolygon(new PolygonOptions() - .addAll(STAR_SHAPE_POINTS) - .fillColor(BLUE_COLOR)); + mapboxMap.addPolygon(new PolygonOptions() + .addAll(STAR_SHAPE_POINTS) + .fillColor(BLUE_COLOR), + new Callback<Polygon>() { + @Override + public void onResult(Polygon polygon) { + PolygonActivity.this.polygon = polygon; + } + }); } @Override diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolylineActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolylineActivity.java index 76e38018ca..674ceb0c66 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolylineActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PolylineActivity.java @@ -15,6 +15,7 @@ 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.Callback; import com.mapbox.mapboxsdk.testapp.R; import java.util.ArrayList; @@ -63,7 +64,12 @@ public class PolylineActivity extends AppCompatActivity { @Override public void onMapReady(@NonNull MapboxMap mapboxMap) { PolylineActivity.this.mapboxMap = mapboxMap; - polylines = mapboxMap.addPolylines(polylineOptions); + mapboxMap.addPolylines(polylineOptions, new Callback<List<Polyline>>() { + @Override + public void onResult(List<Polyline> polylines) { + PolylineActivity.this.polylines = polylines; + } + }); } }); @@ -84,8 +90,12 @@ public class PolylineActivity extends AppCompatActivity { } polylineOptions.clear(); polylineOptions.addAll(getRandomLine()); - polylines = mapboxMap.addPolylines(polylineOptions); - + mapboxMap.addPolylines(polylineOptions, new Callback<List<Polyline>>() { + @Override + public void onResult(List<Polyline> polylines) { + PolylineActivity.this.polylines = polylines; + } + }); } } }); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java index f79e4c6704..bf9b88a09e 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/PressForMarkerActivity.java @@ -8,15 +8,20 @@ import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuItem; +import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.MarkerOptions; 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.Callback; import com.mapbox.mapboxsdk.testapp.R; import java.text.DecimalFormat; import java.util.ArrayList; +import java.util.List; + +import timber.log.Timber; public class PressForMarkerActivity extends AppCompatActivity { @@ -43,26 +48,39 @@ public class PressForMarkerActivity extends AppCompatActivity { mapboxMap.setOnMapLongClickListener(new MapboxMap.OnMapLongClickListener() { @Override - public void onMapLongClick(@NonNull LatLng point) { - final PointF pixel = mapboxMap.getProjection().toScreenLocation(point); - - String title = LAT_LON_FORMATTER.format(point.getLatitude()) + ", " - + LAT_LON_FORMATTER.format(point.getLongitude()); - String snippet = "X = " + (int) pixel.x + ", Y = " + (int) pixel.y; - - MarkerOptions marker = new MarkerOptions() - .position(point) - .title(title) - .snippet(snippet); - - markerList.add(marker); - mapboxMap.addMarker(marker); + public void onMapLongClick(@NonNull final LatLng point) { + mapboxMap.getProjection().toScreenLocation(point, new Callback<PointF>() { + @Override + public void onResult(PointF pixel) { + String title = LAT_LON_FORMATTER.format(point.getLatitude()) + ", " + + LAT_LON_FORMATTER.format(point.getLongitude()); + String snippet = "X = " + (int) pixel.x + ", Y = " + (int) pixel.y; + + MarkerOptions marker = new MarkerOptions() + .position(point) + .title(title) + .snippet(snippet); + + markerList.add(marker); + mapboxMap.addMarker(marker, new Callback<Marker>() { + @Override + public void onResult(Marker marker) { + Timber.i("Marker added"); + } + }); + } + }); } }); if (savedInstanceState != null) { markerList = savedInstanceState.getParcelableArrayList(STATE_MARKER_LIST); - mapboxMap.addMarkers(markerList); + mapboxMap.addMarkers(markerList, new Callback<List<Marker>>() { + @Override + public void onResult(List<Marker> markers) { + Timber.i("Markers added with size %d", markers.size()); + } + }); } } }); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java index d6db2aeeb0..48d3553ad4 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/camera/LatLngBoundsActivity.java @@ -3,11 +3,14 @@ package com.mapbox.mapboxsdk.testapp.activity.camera; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; +import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.MarkerOptions; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.geometry.LatLngBounds; +import com.mapbox.mapboxsdk.geometry.VisibleRegion; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -45,14 +48,26 @@ public class LatLngBoundsActivity extends AppCompatActivity implements OnMapRead uiSettings.setAllGesturesEnabled(false); mapboxMap.addMarker(new MarkerOptions() - .title("Los Angeles") - .snippet("City Hall") - .position(LOS_ANGELES)); + .title("Los Angeles") + .snippet("City Hall") + .position(LOS_ANGELES), + new Callback<Marker>() { + @Override + public void onResult(Marker marker) { + Timber.i("Marker added", marker); + } + }); mapboxMap.addMarker(new MarkerOptions() - .title("New York") - .snippet("City Hall") - .position(NEW_YORK)); + .title("New York") + .snippet("City Hall") + .position(NEW_YORK), + new Callback<Marker>() { + @Override + public void onResult(Marker marker) { + Timber.i("Marker added", marker); + } + }); List<LatLng> points = new ArrayList<>(); points.add(NEW_YORK); @@ -73,7 +88,12 @@ public class LatLngBoundsActivity extends AppCompatActivity implements OnMapRead // Log data Timber.e("Move to bounds: " + bounds.toString()); - Timber.e("Resulting bounds:" + mapboxMap.getProjection().getVisibleRegion().latLngBounds.toString()); + mapboxMap.getProjection().getVisibleRegion(new Callback<VisibleRegion>() { + @Override + public void onResult(VisibleRegion visibleRegion) { + Timber.e("Resulting bounds:" + visibleRegion.latLngBounds.toString()); + } + }); } @Override diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxCountActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxCountActivity.java index c5b4c92bd5..28ec5d3b9b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxCountActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxCountActivity.java @@ -7,6 +7,7 @@ import android.view.View; import android.widget.Toast; import com.google.gson.JsonElement; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -49,16 +50,19 @@ public class QueryRenderedFeaturesBoxCountActivity extends AppCompatActivity { int left = selectionBox.getLeft() - mapView.getLeft(); RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight()); Timber.i(String.format("Querying box %s", box)); - List<Feature> features = mapboxMap.queryRenderedFeatures(box); - - // Show count - Toast.makeText( - QueryRenderedFeaturesBoxCountActivity.this, - String.format("%s features in box", features.size()), - Toast.LENGTH_SHORT).show(); - - // Debug output - debugOutput(features); + mapboxMap.queryRenderedFeatures(box, new Callback<List<Feature>>() { + @Override + public void onResult(List<Feature> features) { + // Show count + Toast.makeText( + QueryRenderedFeaturesBoxCountActivity.this, + String.format("%s features in box", features.size()), + Toast.LENGTH_SHORT).show(); + + // Debug output + debugOutput(features); + } + }); } }); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxHighlightActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxHighlightActivity.java index 07b677a788..b7d49f2f8c 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxHighlightActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxHighlightActivity.java @@ -7,6 +7,7 @@ import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Toast; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -53,29 +54,33 @@ public class QueryRenderedFeaturesBoxHighlightActivity extends AppCompatActivity int left = selectionBox.getLeft() - mapView.getLeft(); RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight()); Timber.i(String.format("Querying box %s for buildings", box)); - List<Feature> features = mapboxMap.queryRenderedFeatures(box, "building"); - - // Show count - Toast.makeText( - QueryRenderedFeaturesBoxHighlightActivity.this, - String.format("%s features in box", features.size()), - Toast.LENGTH_SHORT).show(); - - // remove layer / source if already added - try { - mapboxMap.removeSource("highlighted-shapes-source"); - mapboxMap.removeLayer("highlighted-shapes-layer"); - } catch (Exception exception) { - // that's ok - } - - // Add layer / source - mapboxMap.addSource( - new GeoJsonSource("highlighted-shapes-source", - FeatureCollection.fromFeatures(features)) - ); - mapboxMap.addLayer(new FillLayer("highlighted-shapes-layer", "highlighted-shapes-source") - .withProperties(fillColor(Color.RED))); + mapboxMap.queryRenderedFeatures(box, new Callback<List<Feature>>() { + @Override + public void onResult(List<Feature> features) { + + // Show count + Toast.makeText( + QueryRenderedFeaturesBoxHighlightActivity.this, + String.format("%s features in box", features.size()), + Toast.LENGTH_SHORT).show(); + + // remove layer / source if already added + try { + mapboxMap.removeSource("highlighted-shapes-source"); + mapboxMap.removeLayer("highlighted-shapes-layer"); + } catch (Exception exception) { + // that's ok + } + + // Add layer / source + mapboxMap.addSource( + new GeoJsonSource("highlighted-shapes-source", + FeatureCollection.fromFeatures(features)) + ); + mapboxMap.addLayer(new FillLayer("highlighted-shapes-layer", "highlighted-shapes-source") + .withProperties(fillColor(Color.RED))); + } + }, "building"); } }); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxSymbolCountActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxSymbolCountActivity.java index 7a4c36f30d..e09c773d79 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxSymbolCountActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesBoxSymbolCountActivity.java @@ -8,6 +8,7 @@ import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Toast; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -77,17 +78,20 @@ public class QueryRenderedFeaturesBoxSymbolCountActivity extends AppCompatActivi int left = selectionBox.getLeft() - mapView.getLeft(); RectF box = new RectF(left, top, left + selectionBox.getWidth(), top + selectionBox.getHeight()); Timber.i(String.format("Querying box %s", box)); - List<Feature> features = mapboxMap.queryRenderedFeatures(box, "symbols-layer"); - - // Show count - if (toast != null) { - toast.cancel(); - } - toast = Toast.makeText( - QueryRenderedFeaturesBoxSymbolCountActivity.this, - String.format("%s features in box", features.size()), - Toast.LENGTH_SHORT); - toast.show(); + mapboxMap.queryRenderedFeatures(box, new Callback<List<Feature>>() { + @Override + public void onResult(List<Feature> features) { + // Show count + if (toast != null) { + toast.cancel(); + } + toast = Toast.makeText( + QueryRenderedFeaturesBoxSymbolCountActivity.this, + String.format("%s features in box", features.size()), + Toast.LENGTH_SHORT); + toast.show(); + } + }, "symbols-layer"); } }); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesPropertiesActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesPropertiesActivity.java index f6cf09828d..165090d21e 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesPropertiesActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/feature/QueryRenderedFeaturesPropertiesActivity.java @@ -15,6 +15,7 @@ import com.google.gson.JsonElement; import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions; import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -56,26 +57,38 @@ public class QueryRenderedFeaturesPropertiesActivity extends AppCompatActivity { // Add a click listener mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() { @Override - public void onMapClick(@NonNull LatLng point) { - // Query - final PointF pixel = mapboxMap.getProjection().toScreenLocation(point); - Timber.i(String.format( - "Requesting features for %sx%s (%sx%s adjusted for density)", - pixel.x, pixel.y, pixel.x / density, pixel.y / density) - ); - List<Feature> features = mapboxMap.queryRenderedFeatures(pixel); - - // Debug output - debugOutput(features); - - // Remove any previous markers - if (marker != null) { - mapboxMap.removeMarker(marker); - } - - // Add a marker on the clicked point - marker = mapboxMap.addMarker(new CustomMarkerOptions().position(point).features(features)); - mapboxMap.selectMarker(marker); + public void onMapClick(@NonNull final LatLng point) { + mapboxMap.getProjection().toScreenLocation(point, new Callback<PointF>() { + @Override + public void onResult(final PointF pixel) { + Timber.i(String.format( + "Requesting features for %sx%s (%sx%s adjusted for density)", + pixel.x, pixel.y, pixel.x / density, pixel.y / density) + ); + mapboxMap.queryRenderedFeatures(pixel, new Callback<List<Feature>>() { + @Override + public void onResult(List<Feature> features) { + // Debug output + debugOutput(features); + + // Remove any previous markers + if (marker != null) { + mapboxMap.removeMarker(marker); + } + + // Add a marker on the clicked point + mapboxMap.addMarker(new CustomMarkerOptions().position(point).features(features), + new Callback<Marker>() { + @Override + public void onResult(Marker marker) { + QueryRenderedFeaturesPropertiesActivity.this.marker = marker; + mapboxMap.selectMarker(marker); + } + }); + } + }); + } + }); } }); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.java index c1fa768f83..b1655c921b 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/imagegenerator/SnapshotActivity.java @@ -9,7 +9,6 @@ import android.view.View; import android.widget.ImageView; import android.widget.Toast; -import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -33,7 +32,6 @@ public class SnapshotActivity extends AppCompatActivity implements OnMapReadyCal @Override public void onMapReady(MapboxMap map) { mapboxMap = map; - mapboxMap.setStyleUrl(Style.OUTDOORS); FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); if (fab != null) { fab.setColorFilter(ContextCompat.getColor(SnapshotActivity.this, R.color.primary)); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/DynamicInfoWindowAdapterActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/DynamicInfoWindowAdapterActivity.java index df6d24900b..313361e974 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/DynamicInfoWindowAdapterActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/DynamicInfoWindowAdapterActivity.java @@ -15,6 +15,7 @@ import com.mapbox.mapboxsdk.annotations.MarkerView; import com.mapbox.mapboxsdk.annotations.MarkerViewOptions; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -53,27 +54,32 @@ public class DynamicInfoWindowAdapterActivity extends AppCompatActivity implemen mapboxMap.getUiSettings().setDeselectMarkersOnTap(false); // Add a marker - final MarkerView marker = addMarker(mapboxMap); - mapboxMap.selectMarker(marker); - - // On map click, change the info window contents - mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() { + addMarker(mapboxMap, new Callback<MarkerView>() { @Override - public void onMapClick(@NonNull LatLng point) { - // Distance from click to marker - double distanceKm = marker.getPosition().distanceTo(point) / 1000; - - // Get the info window - InfoWindow infoWindow = marker.getInfoWindow(); - - // Get the view from the info window - if (infoWindow != null && infoWindow.getView() != null) { - // Set the new text on the text view in the info window - ((TextView) infoWindow.getView()).setText(String.format("%.2fkm", distanceKm)); - - // Update the info window position (as the text length changes) - infoWindow.update(); - } + public void onResult(final MarkerView marker) { + mapboxMap.selectMarker(marker); + // On map click, change the info window contents + mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() { + @Override + public void onMapClick(@NonNull LatLng point) { + if (marker != null) { + // Distance from click to marker + double distanceKm = marker.getPosition().distanceTo(point) / 1000; + + // Get the info window + InfoWindow infoWindow = marker.getInfoWindow(); + + // Get the view from the info window + if (infoWindow != null && infoWindow.getView() != null) { + // Set the new text on the text view in the info window + ((TextView) infoWindow.getView()).setText(String.format("%.2fkm", distanceKm)); + + // Update the info window position (as the text length changes) + infoWindow.update(); + } + } + } + }); } }); @@ -81,13 +87,12 @@ public class DynamicInfoWindowAdapterActivity extends AppCompatActivity implemen mapboxMap.animateCamera(CameraUpdateFactory.newLatLng(paris)); } - private MarkerView addMarker(MapboxMap mapboxMap) { - return mapboxMap.addMarker( + private void addMarker(MapboxMap mapboxMap, Callback<MarkerView> listener) { + mapboxMap.addMarker( new MarkerViewOptions() .position(paris) .icon(IconUtils.drawableToIcon(this, R.drawable.ic_location_city, - ResourcesCompat.getColor(getResources(),R.color.mapbox_blue, getTheme())) - )); + ResourcesCompat.getColor(getResources(), R.color.mapbox_blue, getTheme()))), listener); } private void addCustomInfoWindowAdapter(final MapboxMap mapboxMap) { diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowActivity.java index 45ccfcec72..bc624b59b9 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/infowindow/InfoWindowActivity.java @@ -10,6 +10,7 @@ import android.widget.Toast; import com.mapbox.mapboxsdk.annotations.Marker; import com.mapbox.mapboxsdk.annotations.MarkerOptions; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -58,15 +59,18 @@ public class InfoWindowActivity extends AppCompatActivity mapboxMap.addMarker(new MarkerOptions().snippet("Lafayette Square").position(new LatLng(38.89949, -77.03656))); - Marker marker = mapboxMap.addMarker(new MarkerOptions() - .title("White House") - .snippet("The official residence and principal workplace of the President of the United States, " - + "located at 1600 Pennsylvania Avenue NW in Washington, D.C. It has been the residence of every" - + "U.S. president since John Adams in 1800.") - .position(new LatLng(38.897705003219784, -77.03655168667463))); - - // open InfoWindow at startup - mapboxMap.selectMarker(marker); + mapboxMap.addMarker(new MarkerOptions() + .title("White House") + .snippet("The official residence and principal workplace of the President of the United States, " + + "located at 1600 Pennsylvania Avenue NW in Washington, D.C. It has been the residence of every" + + "U.S. president since John Adams in 1800.") + .position(new LatLng(38.897705003219784, -77.03655168667463)), + new Callback<Marker>() { + @Override + public void onResult(Marker marker) { + mapboxMap.selectMarker(marker); + } + }); } private void addInfoWindowListeners() { @@ -111,11 +115,17 @@ public class InfoWindowActivity extends AppCompatActivity } // Add marker on long click location with default marker image - customMarker = mapboxMap.addMarker(new MarkerOptions() - .title("Custom Marker") - .snippet(new DecimalFormat("#.#####").format(point.getLatitude()) + ", " - + new DecimalFormat("#.#####").format(point.getLongitude())) - .position(point)); + mapboxMap.addMarker(new MarkerOptions() + .title("Custom Marker") + .snippet(new DecimalFormat("#.#####").format(point.getLatitude()) + ", " + + new DecimalFormat("#.#####").format(point.getLongitude())) + .position(point), + new Callback<Marker>() { + @Override + public void onResult(Marker marker) { + customMarker = marker; + } + }); } @Override diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java index c2b0cb0769..27a2460332 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/offline/OfflineActivity.java @@ -16,9 +16,11 @@ 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.geometry.VisibleRegion; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.offline.OfflineManager; import com.mapbox.mapboxsdk.offline.OfflineRegion; import com.mapbox.mapboxsdk.offline.OfflineRegionError; @@ -221,30 +223,36 @@ public class OfflineActivity extends AppCompatActivity startProgress(); // Definition - LatLngBounds bounds = mapboxMap.getProjection().getVisibleRegion().latLngBounds; - double minZoom = mapboxMap.getCameraPosition().zoom; - double maxZoom = mapboxMap.getMaxZoomLevel(); - float pixelRatio = this.getResources().getDisplayMetrics().density; - OfflineTilePyramidRegionDefinition definition = new OfflineTilePyramidRegionDefinition( - STYLE_URL, bounds, minZoom, maxZoom, pixelRatio); - - // Sample way of encoding metadata from a JSONObject - byte[] metadata = OfflineUtils.convertRegionName(regionName); - - // Create region - offlineManager.createOfflineRegion(definition, metadata, new OfflineManager.CreateOfflineRegionCallback() { + mapboxMap.getProjection().getVisibleRegion(new Callback<VisibleRegion>() { @Override - public void onCreate(OfflineRegion offlineRegion) { - Timber.d("Offline region created: " + regionName); - OfflineActivity.this.offlineRegion = offlineRegion; - launchDownload(); - } - - @Override - public void onError(String error) { - Timber.e("Error: " + error); + public void onResult(VisibleRegion visibleRegion) { + LatLngBounds bounds = visibleRegion.latLngBounds; + double minZoom = mapboxMap.getCameraPosition().zoom; + double maxZoom = mapboxMap.getMaxZoomLevel(); + float pixelRatio = OfflineActivity.this.getResources().getDisplayMetrics().density; + OfflineTilePyramidRegionDefinition definition = new OfflineTilePyramidRegionDefinition( + STYLE_URL, bounds, minZoom, maxZoom, pixelRatio); + + // Sample way of encoding metadata from a JSONObject + byte[] metadata = OfflineUtils.convertRegionName(regionName); + + // Create region + offlineManager.createOfflineRegion(definition, metadata, new OfflineManager.CreateOfflineRegionCallback() { + @Override + public void onCreate(OfflineRegion offlineRegion) { + Timber.d("Offline region created: " + regionName); + OfflineActivity.this.offlineRegion = offlineRegion; + launchDownload(); + } + + @Override + public void onError(String error) { + Timber.e("Error: " + error); + } + }); } }); + } private void launchDownload() { diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/DataDrivenStyleActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/DataDrivenStyleActivity.java index a44b03fc03..c57c5c0afd 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/DataDrivenStyleActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/DataDrivenStyleActivity.java @@ -10,6 +10,7 @@ import android.widget.Toast; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -161,194 +162,231 @@ public class DataDrivenStyleActivity extends AppCompatActivity { private void addExponentialZoomFunction() { Timber.i("Add exponential zoom function"); - FillLayer layer = mapboxMap.getLayerAs("water"); - assert layer != null; - layer.setProperties( - fillColor( - zoom( - exponential( - stop(1, fillColor(Color.RED)), - stop(5, fillColor(Color.BLUE)), - stop(10, fillColor(Color.GREEN)) - ).withBase(0.5f) - ) - ) - ); + mapboxMap.getLayerAs("water", new Callback.LayerCallback<FillLayer>() { + @Override + public void onResult(FillLayer layer) { + assert layer != null; + layer.setProperties( + fillColor( + zoom( + exponential( + stop(1, fillColor(Color.RED)), + stop(5, fillColor(Color.BLUE)), + stop(10, fillColor(Color.GREEN)) + ).withBase(0.5f) + ) + ) + ); - Timber.i("Fill color: %s", layer.getFillColor()); + Timber.i("Fill color: %s", layer.getFillColor()); + } + }); } private void addIntervalZoomFunction() { Timber.i("Add interval zoom function"); - FillLayer layer = mapboxMap.getLayerAs("water"); - assert layer != null; - layer.setProperties( - fillColor( - zoom( - interval( - stop(1, fillColor(Color.RED)), - stop(5, fillColor(Color.BLUE)), - stop(10, fillColor(Color.GREEN)) + mapboxMap.getLayerAs("water", new Callback.LayerCallback<FillLayer>() { + @Override + public void onResult(FillLayer layer) { + assert layer != null; + layer.setProperties( + fillColor( + zoom( + interval( + stop(1, fillColor(Color.RED)), + stop(5, fillColor(Color.BLUE)), + stop(10, fillColor(Color.GREEN)) + ) + ) ) - ) - ) - ); + ); - Timber.i("Fill color: %s", layer.getFillColor()); + Timber.i("Fill color: %s", layer.getFillColor()); + } + }); } private void addExponentialSourceFunction() { Timber.i("Add exponential source function"); - FillLayer layer = mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER); - assert layer != null; - layer.setProperties( - fillColor( - property( - "stroke-width", - exponential( - stop(1f, fillColor(Color.RED)), - stop(5f, fillColor(Color.BLUE)), - stop(10f, fillColor(Color.GREEN)) - ).withBase(0.5f) - ) - ) - ); + mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER, new Callback.LayerCallback<FillLayer>() { + @Override + public void onResult(FillLayer layer) { + assert layer != null; + layer.setProperties( + fillColor( + property( + "stroke-width", + exponential( + stop(1f, fillColor(Color.RED)), + stop(5f, fillColor(Color.BLUE)), + stop(10f, fillColor(Color.GREEN)) + ).withBase(0.5f) + ) + ) + ); - Timber.i("Fill color: %s", layer.getFillColor()); + Timber.i("Fill color: %s", layer.getFillColor()); + } + }); } private void addCategoricalSourceFunction() { Timber.i("Add categorical source function"); - FillLayer layer = mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER); - assert layer != null; - layer.setProperties( - fillColor( - property( - "name", - categorical( - stop("Westerpark", fillColor(Color.RED)), - stop("Jordaan", fillColor(Color.BLUE)), - stop("Prinseneiland", fillColor(Color.GREEN)) - )) - ) - ); + mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER, new Callback.LayerCallback<FillLayer>() { + @Override + public void onResult(FillLayer layer) { + assert layer != null; + layer.setProperties( + fillColor( + property( + "name", + categorical( + stop("Westerpark", fillColor(Color.RED)), + stop("Jordaan", fillColor(Color.BLUE)), + stop("Prinseneiland", fillColor(Color.GREEN)) + )) + ) + ); - Timber.i("Fill color: %s", layer.getFillColor()); + Timber.i("Fill color: %s", layer.getFillColor()); + } + }); } private void addIdentitySourceFunction() { Timber.i("Add identity source function"); - FillLayer layer = mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER); - assert layer != null; - layer.setProperties( - fillOpacity( - property( - "fill-opacity", - Stops.<Float>identity()) - ) - ); + mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER, new Callback.LayerCallback<FillLayer>() { + @Override + public void onResult(FillLayer layer) { + assert layer != null; + layer.setProperties( + + fillOpacity( + property( + "fill-opacity", + Stops.<Float>identity()) + ) + ); - Timber.i("Fill opacity: %s", layer.getFillOpacity()); + Timber.i("Fill opacity: %s", layer.getFillOpacity()); + } + }); } private void addIntervalSourceFunction() { Timber.i("Add interval source function"); - FillLayer layer = mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER); - assert layer != null; - layer.setProperties( - fillColor( - property( - "stroke-width", - interval( - stop(1f, fillColor(Color.RED)), - stop(5f, fillColor(Color.BLUE)), - stop(10f, fillColor(Color.GREEN)) - )) - ) - ); + mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER, new Callback.LayerCallback<FillLayer>() { + @Override + public void onResult(FillLayer layer) { + assert layer != null; + layer.setProperties( + fillColor( + property( + "stroke-width", + interval( + stop(1f, fillColor(Color.RED)), + stop(5f, fillColor(Color.BLUE)), + stop(10f, fillColor(Color.GREEN)) + )) + ) + ); - Timber.i("Fill color: %s", layer.getFillColor()); + Timber.i("Fill color: %s", layer.getFillColor()); + } + }); } private void addCompositeExponentialFunction() { Timber.i("Add composite exponential function"); - FillLayer layer = mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER); - assert layer != null; - layer.setProperties( - fillColor( - composite( - "stroke-width", - exponential( - stop(1, 1, fillColor(Color.RED)), - stop(10, 2, fillColor(Color.BLUE)), - stop(22, 3, fillColor(Color.GREEN)), - stop(1, 1, fillColor(Color.CYAN)), - stop(10, 2, fillColor(Color.GRAY)), - stop(22, 3, fillColor(Color.YELLOW)) - ).withBase(1f) - ) - ) - ); + mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER, new Callback.LayerCallback<FillLayer>() { + @Override + public void onResult(FillLayer layer) { + assert layer != null; + layer.setProperties( + fillColor( + composite( + "stroke-width", + exponential( + stop(1, 1, fillColor(Color.RED)), + stop(10, 2, fillColor(Color.BLUE)), + stop(22, 3, fillColor(Color.GREEN)), + stop(1, 1, fillColor(Color.CYAN)), + stop(10, 2, fillColor(Color.GRAY)), + stop(22, 3, fillColor(Color.YELLOW)) + ).withBase(1f) + ) + ) + ); - Timber.i("Fill color: %s", layer.getFillColor()); + Timber.i("Fill color: %s", layer.getFillColor()); + } + }); } private void addCompositeIntervalFunction() { Timber.i("Add composite exponential function"); - FillLayer layer = mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER); - assert layer != null; - layer.setProperties( - fillColor( - composite( - "stroke-width", - interval( - stop(1, 1, fillColor(Color.RED)), - stop(10, 2, fillColor(Color.BLUE)), - stop(22, 3, fillColor(Color.GREEN)), - stop(1, 1, fillColor(Color.CYAN)), - stop(10, 2, fillColor(Color.GRAY)), - stop(22, 3, fillColor(Color.YELLOW)) - )) - ) - ); + mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER, new Callback.LayerCallback<FillLayer>() { + @Override + public void onResult(FillLayer layer) { + assert layer != null; + layer.setProperties( + fillColor( + composite( + "stroke-width", + interval( + stop(1, 1, fillColor(Color.RED)), + stop(10, 2, fillColor(Color.BLUE)), + stop(22, 3, fillColor(Color.GREEN)), + stop(1, 1, fillColor(Color.CYAN)), + stop(10, 2, fillColor(Color.GRAY)), + stop(22, 3, fillColor(Color.YELLOW)) + )) + ) + ); - Timber.i("Fill color: %s", layer.getFillColor()); + Timber.i("Fill color: %s", layer.getFillColor()); + } + }); } private void addCompositeCategoricalFunction() { Timber.i("Add composite categorical function"); - FillLayer layer = mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER); - assert layer != null; - layer.setProperties( - fillColor( - composite( - "name", - categorical( - stop(7f, "Westerpark", fillColor(Color.RED)), - stop(8f, "Westerpark", fillColor(Color.BLUE)), - stop(9f, "Westerpark", fillColor(Color.RED)), - stop(10f, "Westerpark", fillColor(Color.BLUE)), - stop(11f, "Westerpark", fillColor(Color.RED)), - stop(12f, "Westerpark", fillColor(Color.BLUE)), - stop(13f, "Westerpark", fillColor(Color.RED)), - stop(14f, "Westerpark", fillColor(Color.BLUE)), - stop(15f, "Westerpark", fillColor(Color.RED)), - stop(16f, "Westerpark", fillColor(Color.BLUE)), - stop(17f, "Westerpark", fillColor(Color.RED)), - stop(18f, "Westerpark", fillColor(Color.BLUE)), - stop(19f, "Westerpark", fillColor(Color.RED)), - stop(20f, "Westerpark", fillColor(Color.BLUE)), - stop(21f, "Westerpark", fillColor(Color.RED)), - stop(22f, "Westerpark", fillColor(Color.BLUE)), - stop(14f, "Jordaan", fillColor(Color.GREEN)), - stop(18f, "Jordaan", fillColor(Color.CYAN)), - stop(14f, "Prinseneiland", fillColor(Color.WHITE)), - stop(18f, "Prinseneiland", fillColor(Color.BLACK)) - )) - ) - ); + mapboxMap.getLayerAs(AMSTERDAM_PARKS_LAYER, new Callback.LayerCallback<FillLayer>() { + @Override + public void onResult(FillLayer layer) { + assert layer != null; + layer.setProperties( + fillColor( + composite( + "name", + categorical( + stop(7f, "Westerpark", fillColor(Color.RED)), + stop(8f, "Westerpark", fillColor(Color.BLUE)), + stop(9f, "Westerpark", fillColor(Color.RED)), + stop(10f, "Westerpark", fillColor(Color.BLUE)), + stop(11f, "Westerpark", fillColor(Color.RED)), + stop(12f, "Westerpark", fillColor(Color.BLUE)), + stop(13f, "Westerpark", fillColor(Color.RED)), + stop(14f, "Westerpark", fillColor(Color.BLUE)), + stop(15f, "Westerpark", fillColor(Color.RED)), + stop(16f, "Westerpark", fillColor(Color.BLUE)), + stop(17f, "Westerpark", fillColor(Color.RED)), + stop(18f, "Westerpark", fillColor(Color.BLUE)), + stop(19f, "Westerpark", fillColor(Color.RED)), + stop(20f, "Westerpark", fillColor(Color.BLUE)), + stop(21f, "Westerpark", fillColor(Color.RED)), + stop(22f, "Westerpark", fillColor(Color.BLUE)), + stop(14f, "Jordaan", fillColor(Color.GREEN)), + stop(18f, "Jordaan", fillColor(Color.CYAN)), + stop(14f, "Prinseneiland", fillColor(Color.WHITE)), + stop(18f, "Prinseneiland", fillColor(Color.BLACK)) + )) + ) + ); - Timber.i("Fill color: %s", layer.getFillColor()); + Timber.i("Fill color: %s", layer.getFillColor()); + } + }); } private void addParksLayer() { diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RealTimeGeoJsonActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RealTimeGeoJsonActivity.java index aea5f7c25d..8900ec470c 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RealTimeGeoJsonActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RealTimeGeoJsonActivity.java @@ -8,8 +8,10 @@ import android.support.v7.app.AppCompatActivity; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.style.layers.SymbolLayer; import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; +import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.mapboxsdk.testapp.R; import java.net.MalformedURLException; @@ -118,7 +120,15 @@ public class RealTimeGeoJsonActivity extends AppCompatActivity implements OnMapR @Override public void run() { - ((GeoJsonSource) mapboxMap.getSource(ID_GEOJSON_SOURCE)).setUrl(URL_GEOJSON_SOURCE); + mapboxMap.getSource(ID_GEOJSON_SOURCE, new Callback<Source>() { + + + + @Override + public void onResult(Source source) { + ((GeoJsonSource) source).setUrl(URL_GEOJSON_SOURCE); + } + }); handler.postDelayed(this, 2000); } } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleActivity.java index e6650e8300..5c72a6dec9 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/RuntimeStyleActivity.java @@ -11,6 +11,7 @@ import android.widget.Toast; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -24,6 +25,7 @@ import com.mapbox.mapboxsdk.style.layers.NoSuchLayerException; import com.mapbox.mapboxsdk.style.layers.Property; import com.mapbox.mapboxsdk.style.layers.PropertyValue; import com.mapbox.mapboxsdk.style.layers.RasterLayer; +import com.mapbox.mapboxsdk.style.sources.CannotAddSourceException; import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; import com.mapbox.mapboxsdk.style.sources.RasterSource; import com.mapbox.mapboxsdk.style.sources.Source; @@ -201,10 +203,14 @@ public class RuntimeStyleActivity extends AppCompatActivity { private void setLayerInvisible() { String[] roadLayers = new String[] {"water"}; for (String roadLayer : roadLayers) { - Layer layer = mapboxMap.getLayer(roadLayer); - if (layer != null) { - layer.setProperties(visibility(NONE)); - } + mapboxMap.getLayer(roadLayer, new Callback<Layer>() { + @Override + public void onResult(Layer layer) { + if (layer != null) { + layer.setProperties(visibility(NONE)); + } + } + }); } } @@ -215,34 +221,46 @@ public class RuntimeStyleActivity extends AppCompatActivity { public void onFinish() { String[] roadLayers = new String[] {"road-label-small", "road-label-medium", "road-label-large"}; for (String roadLayer : roadLayers) { - Layer layer = mapboxMap.getLayer(roadLayer); - if (layer != null) { - layer.setProperties(symbolPlacement(SYMBOL_PLACEMENT_POINT)); - } + mapboxMap.getLayer(roadLayer, new Callback<Layer>() { + @Override + public void onResult(Layer layer) { + if (layer != null) { + layer.setProperties(symbolPlacement(SYMBOL_PLACEMENT_POINT)); + } + } + }); } } }); } private void setBackgroundOpacity() { - Layer background = mapboxMap.getLayer("background"); - if (background != null) { - background.setProperties(backgroundOpacity(0.2f)); - } + mapboxMap.getLayer("background", new Callback<Layer>() { + @Override + public void onResult(Layer layer) { + if (layer != null) { + layer.setProperties(backgroundOpacity(0.2f)); + } + } + }); } private void setWaterColor() { - Layer water = mapboxMap.getLayer("water"); - if (water != null) { - mapboxMap.setTransitionDuration(5); - mapboxMap.setTransitionDelay(1); - water.setProperties( - visibility(VISIBLE), - fillColor(Color.RED) - ); - } else { - Toast.makeText(RuntimeStyleActivity.this, "No water layer in this style", Toast.LENGTH_SHORT).show(); - } + mapboxMap.getLayer("water", new Callback<Layer>() { + @Override + public void onResult(Layer water) { + if (water != null) { + mapboxMap.setTransitionDuration(5); + mapboxMap.setTransitionDelay(1); + water.setProperties( + visibility(VISIBLE), + fillColor(Color.RED) + ); + } else { + Toast.makeText(RuntimeStyleActivity.this, "No water layer in this style", Toast.LENGTH_SHORT).show(); + } + } + }); } private void removeBuildings() { @@ -284,18 +302,27 @@ public class RuntimeStyleActivity extends AppCompatActivity { // layer.setPaintProperty(fillColor(Color.RED)); // XXX But not after the object is attached // Or get the object later and set it. It's all good. - mapboxMap.getLayer("parksLayer").setProperties(fillColor(Color.RED)); + mapboxMap.getLayer("parksLayer", new Callback<Layer>() { + @Override + public void onResult(Layer layer) { + layer.setProperties(fillColor(Color.RED)); + } + }); // You can get a typed layer, if you're sure it's of that type. Use with care - layer = mapboxMap.getLayerAs("parksLayer"); - // And get some properties - PropertyValue<Boolean> fillAntialias = layer.getFillAntialias(); - Timber.d("Fill anti alias: " + fillAntialias.getValue()); - layer.setProperties(fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP)); - PropertyValue<String> fillTranslateAnchor = layer.getFillTranslateAnchor(); - Timber.d("Fill translate anchor: " + fillTranslateAnchor.getValue()); - PropertyValue<String> visibility = layer.getVisibility(); - Timber.d("Visibility: " + visibility.getValue()); + mapboxMap.getLayerAs("parksLayer", new Callback.LayerCallback<FillLayer>() { + @Override + public void onResult(FillLayer layer) { + // And get some properties + PropertyValue<Boolean> fillAntialias = layer.getFillAntialias(); + Timber.d("Fill anti alias: " + fillAntialias.getValue()); + layer.setProperties(fillTranslateAnchor(FILL_TRANSLATE_ANCHOR_MAP)); + PropertyValue<String> fillTranslateAnchor = layer.getFillTranslateAnchor(); + Timber.d("Fill translate anchor: " + fillTranslateAnchor.getValue()); + PropertyValue<String> visibility = layer.getVisibility(); + Timber.d("Visibility: " + visibility.getValue()); + } + }); // Get a good look at it all mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(12)); @@ -350,22 +377,26 @@ public class RuntimeStyleActivity extends AppCompatActivity { Timber.d("Updating parks source"); // change the source - int park = counter < parks.getFeatures().size() - 1 ? counter : 0; - - GeoJsonSource source = mapboxMap.getSourceAs("dynamic-park-source"); - - if (source == null) { - Timber.e("Source not found"); - Toast.makeText(RuntimeStyleActivity.this, "Source not found", Toast.LENGTH_SHORT).show(); - return; - } - - List<Feature> features = new ArrayList<>(); - features.add(parks.getFeatures().get(park)); - source.setGeoJson(FeatureCollection.fromFeatures(features)); + mapboxMap.getSourceAs("dynamic-park-source", new Callback.SourceCallback<GeoJsonSource>() { + @Override + public void onResult(GeoJsonSource source) { + int park = counter < parks.getFeatures().size() - 1 ? counter : 0; + + if (source == null) { + Timber.e("Source not found"); + Toast.makeText(RuntimeStyleActivity.this, "Source not found", Toast.LENGTH_SHORT).show(); + return; + } + + List<Feature> features = new ArrayList<>(); + features.add(parks.getFeatures().get(park)); + source.setGeoJson(FeatureCollection.fromFeatures(features)); + + // Re-post + animateParksSource(parks, park + 1); + } + }); - // Re-post - animateParksSource(parks, park + 1); } }, counter == 0 ? 100 : 1000); } @@ -373,29 +404,41 @@ public class RuntimeStyleActivity extends AppCompatActivity { private void addTerrainLayer() { // Add a source Source source = new VectorSource("my-terrain-source", "mapbox://mapbox.mapbox-terrain-v2"); - mapboxMap.addSource(source); - - LineLayer layer = new LineLayer("terrainLayer", "my-terrain-source"); - layer.setSourceLayer("contour"); - layer.setProperties( - lineJoin(Property.LINE_JOIN_ROUND), - lineCap(Property.LINE_CAP_ROUND), - lineColor(Color.RED), - lineWidth(20f) - ); - - mapboxMap.addLayer(layer); - - // Need to get a fresh handle - layer = mapboxMap.getLayerAs("terrainLayer"); - - // Make sure it's also applied after the fact - layer.setMinZoom(10); - layer.setMaxZoom(15); + try { + mapboxMap.addSource(source); + LineLayer layer = new LineLayer("terrainLayer", "my-terrain-source"); + layer.setSourceLayer("contour"); + layer.setProperties( + lineJoin(Property.LINE_JOIN_ROUND), + lineCap(Property.LINE_CAP_ROUND), + lineColor(Color.RED), + lineWidth(20f) + ); - layer = (LineLayer) mapboxMap.getLayer("terrainLayer"); - Toast.makeText(this, String.format( - "Set min/max zoom to %s - %s", layer.getMinZoom(), layer.getMaxZoom()), Toast.LENGTH_SHORT).show(); + mapboxMap.addLayer(layer); + + // Need to get a fresh handle + mapboxMap.getLayerAs("terrainLayer", new Callback.LayerCallback<LineLayer>() { + @Override + public void onResult(LineLayer layer) { + // Make sure it's also applied after the fact + layer.setMinZoom(10); + layer.setMaxZoom(15); + + mapboxMap.getLayer("terrainLayer", new Callback<Layer>() { + @Override + public void onResult(Layer layer) { + LineLayer lineLayer = (LineLayer) layer; + Toast.makeText(RuntimeStyleActivity.this, String.format( + "Set min/max zoom to %s - %s", lineLayer.getMinZoom(), lineLayer.getMaxZoom()), + Toast.LENGTH_SHORT).show(); + } + }); + } + }); + } catch (CannotAddSourceException exception) { + Timber.e("Can't add terain layer", exception); + } } private void addSatelliteLayer() { @@ -408,38 +451,42 @@ public class RuntimeStyleActivity extends AppCompatActivity { } private void updateWaterColorOnZoom() { - FillLayer layer = mapboxMap.getLayerAs("water"); - if (layer == null) { - return; - } + mapboxMap.getLayerAs("water", new Callback.LayerCallback<FillLayer>() { + @Override + public void onResult(FillLayer layer) { + if (layer == null) { + return; + } - // Set a zoom function to update the color of the water - layer.setProperties(fillColor( - zoom( - exponential( - stop(1, fillColor(Color.GREEN)), - stop(4, fillColor(Color.BLUE)), - stop(12, fillColor(Color.RED)), - stop(20, fillColor(Color.BLACK)) - ).withBase(0.8f) - ) - )); - - // do some animations to show it off properly - mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(1), 1500); - - PropertyValue<String> fillColor = layer.getFillColor(); - Function<Float, String> function = (Function<Float, String>) fillColor.getFunction(); - if (function != null) { - ExponentialStops<Float, String> stops = (ExponentialStops) function.getStops(); - Timber.d("Fill color base: " + stops.getBase()); - Timber.d("Fill color #stops: " + stops.size()); - if (function.getStops() != null) { - for (Stop<Float, String> stop : stops) { - Timber.d("Fill color #stops: " + stop); + // Set a zoom function to update the color of the water + layer.setProperties(fillColor( + zoom( + exponential( + stop(1, fillColor(Color.GREEN)), + stop(4, fillColor(Color.BLUE)), + stop(12, fillColor(Color.RED)), + stop(20, fillColor(Color.BLACK)) + ).withBase(0.8f) + ) + )); + + // do some animations to show it off properly + mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(1), 1500); + + PropertyValue<String> fillColor = layer.getFillColor(); + Function<Float, String> function = (Function<Float, String>) fillColor.getFunction(); + if (function != null) { + ExponentialStops<Float, String> stops = (ExponentialStops) function.getStops(); + Timber.d("Fill color base: " + stops.getBase()); + Timber.d("Fill color #stops: " + stops.size()); + if (function.getStops() != null) { + for (Stop<Float, String> stop : stops) { + Timber.d("Fill color #stops: " + stop); + } + } } } - } + }); } private String readRawResource(@RawRes int rawResource) throws IOException { @@ -461,7 +508,8 @@ public class RuntimeStyleActivity extends AppCompatActivity { private void addCustomTileSource() { // Add a source - Source source = new VectorSource("custom-tile-source", new TileSet("2.1.0", "https://vector.mapzen.com/osm/all/{z}/{x}/{y}.mvt?api_key=vector-tiles-LM25tq4")); + Source source = new VectorSource("custom-tile-source", new TileSet("2.1.0", + "https://vector.mapzen.com/osm/all/{z}/{x}/{y}.mvt?api_key=vector-tiles-LM25tq4")); mapboxMap.addSource(source); // Add a layer @@ -485,18 +533,22 @@ public class RuntimeStyleActivity extends AppCompatActivity { Timber.d("Styling filtered fill layer"); - FillLayer states = (FillLayer) mapboxMap.getLayer("states"); - - if (states != null) { - states.setFilter(eq("name", "Texas")); - - states.setProperties( - fillColor(Color.RED), - fillOpacity(0.25f) - ); - } else { - Toast.makeText(RuntimeStyleActivity.this, "No states layer in this style", Toast.LENGTH_SHORT).show(); - } + mapboxMap.getLayer("states", new Callback<Layer>() { + @Override + public void onResult(Layer layer) { + FillLayer states = (FillLayer) layer; + if (states != null) { + states.setFilter(eq("name", "Texas")); + + states.setProperties( + fillColor(Color.RED), + fillOpacity(0.25f) + ); + } else { + Toast.makeText(RuntimeStyleActivity.this, "No states layer in this style", Toast.LENGTH_SHORT).show(); + } + } + }); } }, 2000); } @@ -514,20 +566,23 @@ public class RuntimeStyleActivity extends AppCompatActivity { } Timber.d("Styling filtered line layer"); - - LineLayer counties = (LineLayer) mapboxMap.getLayer("counties"); - - if (counties != null) { - counties.setFilter(eq("NAME10", "Washington")); - - counties.setProperties( - lineColor(Color.RED), - lineOpacity(0.75f), - lineWidth(5f) - ); - } else { - Toast.makeText(RuntimeStyleActivity.this, "No counties layer in this style", Toast.LENGTH_SHORT).show(); - } + mapboxMap.getLayer("counties", new Callback<Layer>() { + @Override + public void onResult(Layer layer) { + LineLayer counties = (LineLayer) layer; + if (counties != null) { + counties.setFilter(eq("NAME10", "Washington")); + + counties.setProperties( + lineColor(Color.RED), + lineOpacity(0.75f), + lineWidth(5f) + ); + } else { + Toast.makeText(RuntimeStyleActivity.this, "No counties layer in this style", Toast.LENGTH_SHORT).show(); + } + } + }); } }, 2000); } @@ -546,18 +601,22 @@ public class RuntimeStyleActivity extends AppCompatActivity { Timber.d("Styling numeric fill layer"); - FillLayer regions = (FillLayer) mapboxMap.getLayer("regions"); - - if (regions != null) { - regions.setFilter(all(gte("HRRNUM", 200), lt("HRRNUM", 300))); - - regions.setProperties( - fillColor(Color.BLUE), - fillOpacity(0.5f) - ); - } else { - Toast.makeText(RuntimeStyleActivity.this, "No regions layer in this style", Toast.LENGTH_SHORT).show(); - } + mapboxMap.getLayer("regions", new Callback<Layer>() { + @Override + public void onResult(Layer layer) { + FillLayer regions = (FillLayer) layer; + if (regions != null) { + regions.setFilter(all(gte("HRRNUM", 200), lt("HRRNUM", 300))); + + regions.setProperties( + fillColor(Color.BLUE), + fillOpacity(0.5f) + ); + } else { + Toast.makeText(RuntimeStyleActivity.this, "No regions layer in this style", Toast.LENGTH_SHORT).show(); + } + } + }); } }, 2000); } diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java index 4b7ec2a5bf..8b997b16db 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/style/SymbolLayerActivity.java @@ -13,6 +13,7 @@ import com.google.gson.JsonObject; import com.google.gson.JsonPrimitive; import com.mapbox.mapboxsdk.camera.CameraUpdateFactory; import com.mapbox.mapboxsdk.geometry.LatLng; +import com.mapbox.mapboxsdk.maps.Callback; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -94,37 +95,59 @@ public class SymbolLayerActivity extends AppCompatActivity implements MapboxMap. @Override public void onMapClick(@NonNull LatLng point) { // Query which features are clicked - PointF screenLoc = mapboxMap.getProjection().toScreenLocation(point); - List<Feature> features = mapboxMap.queryRenderedFeatures(screenLoc, MARKER_LAYER); - - SymbolLayer layer = mapboxMap.getLayerAs(MARKER_LAYER); - if (features.size() == 0) { - // Reset - layer.setProperties(iconSize(1f)); - } else { - layer.setProperties(iconSize(3f)); - } + mapboxMap.getProjection().toScreenLocation(point, new Callback<PointF>() { + @Override + public void onResult(PointF pointF) { + mapboxMap.queryRenderedFeatures(pointF, new Callback<List<Feature>>() { + @Override + public void onResult(final List<Feature> features) { + mapboxMap.getLayerAs(MARKER_LAYER, new LayerCallback<SymbolLayer>() { + @Override + public void onResult(SymbolLayer layer) { + if (features.size() == 0) { + // Reset + layer.setProperties(iconSize(1f)); + } else { + layer.setProperties(iconSize(3f)); + } + } + }); + } + }, MARKER_LAYER); + } + }); } private void toggleTextSize() { - SymbolLayer layer = mapboxMap.getLayerAs(MARKER_LAYER); - layer.setProperties(layer.getTextSize().getValue() > 10 ? textSize(10f) : textSize(20f)); + mapboxMap.getLayerAs(MARKER_LAYER, new Callback.LayerCallback<SymbolLayer>() { + @Override + public void onResult(SymbolLayer layer) { + layer.setProperties(layer.getTextSize().getValue() > 10 ? textSize(10f) : textSize(20f)); + } + }); } private void toggleTextField() { - SymbolLayer layer = mapboxMap.getLayerAs(MARKER_LAYER); - layer.setProperties("{title}".equals(layer.getTextField().getValue()) ? textField("āA") : textField("{title}")); + mapboxMap.getLayerAs(MARKER_LAYER, new Callback.LayerCallback<SymbolLayer>() { + @Override + public void onResult(SymbolLayer layer) { + layer.setProperties("{title}".equals(layer.getTextField().getValue()) ? textField("āA") : textField("{title}")); + } + }); } private void toggleTextFont() { - SymbolLayer layer = mapboxMap.getLayerAs(MARKER_LAYER); - - String[] fonts = layer.getTextFont().getValue(); - if (fonts == null || fonts.length == 0 || Arrays.asList(fonts).contains("Arial Unicode MS Regular")) { - layer.setProperties(textFont(new String[] {"DIN Offc Pro Bold", "Arial Unicode MS Bold"})); - } else { - layer.setProperties(textFont(new String[] {"DIN Offc Pro Medium", "Arial Unicode MS Regular"})); - } + mapboxMap.getLayerAs(MARKER_LAYER, new Callback.LayerCallback<SymbolLayer>() { + @Override + public void onResult(SymbolLayer layer) { + String[] fonts = layer.getTextFont().getValue(); + if (fonts == null || fonts.length == 0 || Arrays.asList(fonts).contains("Arial Unicode MS Regular")) { + layer.setProperties(textFont(new String[] {"DIN Offc Pro Bold", "Arial Unicode MS Bold"})); + } else { + layer.setProperties(textFont(new String[] {"DIN Offc Pro Medium", "Arial Unicode MS Regular"})); + } + } + }); } private JsonObject featureProperties(String title) { diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java index fbe00b4dce..f140f7c8b0 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/test/java/com/mapbox/mapboxsdk/maps/UiSettingsTest.java @@ -184,7 +184,7 @@ public class UiSettingsTest { public void testRotateGestureChange() { assertEquals("Default state should be true", true, uiSettings.isRotateGestureChangeAllowed()); uiSettings.setRotateGestureChangeAllowed(false); - assertEquals("State should have been changed", false, uiSettings.isRotateGestureChangeAllowed()); + assertEquals("MapThreadExecutor should have been changed", false, uiSettings.isRotateGestureChangeAllowed()); } @Test @@ -219,7 +219,7 @@ public class UiSettingsTest { public void testTiltGestureChange() { assertEquals("Default state should be true", true, uiSettings.isTiltGestureChangeAllowed()); uiSettings.setTiltGestureChangeAllowed(false); - assertEquals("State should have been changed", false, uiSettings.isTiltGestureChangeAllowed()); + assertEquals("MapThreadExecutor should have been changed", false, uiSettings.isTiltGestureChangeAllowed()); } @Test @@ -254,7 +254,7 @@ public class UiSettingsTest { public void testZoomGestureChange() { assertEquals("Default state should be true", true, uiSettings.isZoomGestureChangeAllowed()); uiSettings.setZoomGestureChangeAllowed(false); - assertEquals("State should have been changed", false, uiSettings.isZoomGestureChangeAllowed()); + assertEquals("MapThreadExecutor should have been changed", false, uiSettings.isZoomGestureChangeAllowed()); } @Test @@ -336,7 +336,7 @@ public class UiSettingsTest { public void testScrollGestureChange() { assertEquals("Default state should be true", true, uiSettings.isScrollGestureChangeAllowed()); uiSettings.setScrollGestureChangeAllowed(false); - assertEquals("State should have been changed", false, uiSettings.isScrollGestureChangeAllowed()); + assertEquals("MapThreadExecutor should have been changed", false, uiSettings.isScrollGestureChangeAllowed()); } @Test diff --git a/platform/android/checkstyle.xml b/platform/android/checkstyle.xml index 3449036e99..56d7ba7903 100644 --- a/platform/android/checkstyle.xml +++ b/platform/android/checkstyle.xml @@ -20,7 +20,7 @@ <property name="lineSeparator" value="lf" /> </module> --> <module name="FileLength"> - <property name="max" value="2042"/> + <property name="max" value="3064"/> </module> <module name="FileTabCharacter"/> |