[android] #3756 - unit test annotations integration in MapboxMap

[android] #3756 - unit tests fixes

[android] #3756 - allow using inheritance Marker, added example to WindowAdapterActivity
This commit is contained in:
Tobrun
2016-02-05 09:05:35 +01:00
parent ef865f04f6
commit fb9021f929
14 changed files with 714 additions and 335 deletions

View File

@@ -0,0 +1,38 @@
package com.mapbox.mapboxsdk.annotations;
import android.os.Parcelable;
import com.mapbox.mapboxsdk.geometry.LatLng;
public abstract class BaseMarkerOptions<U extends Marker, T extends BaseMarkerOptions<U, T>> implements Parcelable {
protected LatLng position;
protected String snippet;
protected String title;
protected Icon icon;
public T position(LatLng position) {
this.position = position;
return getThis();
}
public T snippet(String snippet) {
this.snippet = snippet;
return getThis();
}
public T title(String title) {
this.title = title;
return getThis();
}
public T icon(Icon icon) {
this.icon = icon;
return getThis();
}
public abstract T getThis();
public abstract U getMarker();
}

View File

@@ -150,4 +150,8 @@ public final class IconFactory {
}
return fromInputStream(is);
}
public static Icon recreate(@NonNull String iconId, @NonNull Bitmap bitmap) {
return new Icon(iconId, bitmap);
}
}

View File

@@ -15,7 +15,7 @@ import com.mapbox.mapboxsdk.maps.MapView;
* An {@link InfoWindow} can be shown when a Marker is pressed
* <p/>
*/
public final class Marker extends Annotation {
public class Marker extends Annotation {
private LatLng position;
private String snippet;
@@ -32,6 +32,13 @@ public final class Marker extends Annotation {
super();
}
public Marker(BaseMarkerOptions baseMarkerOptions) {
position = baseMarkerOptions.position;
snippet = baseMarkerOptions.snippet;
icon = baseMarkerOptions.icon;
title = baseMarkerOptions.title;
}
public LatLng getPosition() {
return position;
}

View File

@@ -22,7 +22,7 @@ import com.mapbox.mapboxsdk.geometry.LatLng;
* .position(new LatLng(38.9002073, -77.03364419)));
* </pre>
*/
public final class MarkerOptions implements Parcelable {
public final class MarkerOptions extends BaseMarkerOptions<Marker, MarkerOptions> implements Parcelable {
public static final Parcelable.Creator<MarkerOptions> CREATOR
= new Parcelable.Creator<MarkerOptions>() {
@@ -46,6 +46,11 @@ public final class MarkerOptions implements Parcelable {
title(in.readString());
}
@Override
public MarkerOptions getThis() {
return this;
}
@Override
public int describeContents() {
return 0;

View File

@@ -64,14 +64,12 @@ import com.almeros.android.multitouch.gesturedetectors.TwoFingerGestureDetector;
import com.mapbox.mapboxsdk.R;
import com.mapbox.mapboxsdk.annotations.Annotation;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.InfoWindow;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
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.annotations.IconFactory;
import com.mapbox.mapboxsdk.camera.CameraPosition;
import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
@@ -124,7 +122,6 @@ public class MapView extends FrameLayout {
private static final float DIMENSION_SEVENTYSIX_DP = 76f;
private MapboxMap mMapboxMap;
private LongSparseArray<Annotation> mAnnotations;
private List<Icon> mIcons;
private NativeMapView mNativeMapView;
@@ -173,9 +170,7 @@ public class MapView extends FrameLayout {
private void initialize(@NonNull Context context, @Nullable AttributeSet attrs) {
mOnMapChangedListener = new CopyOnWriteArrayList<>();
mMapboxMap = new MapboxMap(this);
mAnnotations = new LongSparseArray<>();
mIcons = new ArrayList<>();
View view = LayoutInflater.from(context).inflate(R.layout.mapview_internal, this);
if (!isInEditMode()) {
@@ -974,7 +969,25 @@ public class MapView extends FrameLayout {
// Annotations
//
private void loadIcon(Icon icon) {
Icon loadIconForMarker(Marker marker) {
Icon icon = marker.getIcon();
if (icon == null) {
icon = IconFactory.getInstance(getContext()).defaultMarker();
marker.setIcon(icon);
}
if (!mIcons.contains(icon)) {
mIcons.add(icon);
loadIcon(icon);
} else {
Icon oldIcon = mIcons.get(mIcons.indexOf(icon));
if (!oldIcon.getBitmap().sameAs(icon.getBitmap())) {
throw new IconBitmapChangedException();
}
}
return icon;
}
void loadIcon(Icon icon) {
Bitmap bitmap = icon.getBitmap();
String id = icon.getId();
if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) {
@@ -996,7 +1009,7 @@ public class MapView extends FrameLayout {
scale, buffer.array());
}
private void reloadIcons() {
void reloadIcons() {
int count = mIcons.size();
for (int i = 0; i < count; i++) {
Icon icon = mIcons.get(i);
@@ -1004,6 +1017,28 @@ public class MapView extends FrameLayout {
}
}
/**
* <p>
* Updates a marker on this map. Does nothing if the marker is already added.
* </p>
*
* @param updatedMarker An updated marker object.
*/
@UiThread
void updateMarker(@NonNull Marker updatedMarker) {
if (updatedMarker == null) {
Log.w(TAG, "marker was null, doing nothing");
return;
}
if (updatedMarker.getId() == -1) {
Log.w(TAG, "marker has an id of -1, possibly was not added yet, doing nothing");
}
ensureIconLoaded(updatedMarker);
mNativeMapView.updateMarker(updatedMarker);
}
private Marker prepareMarker(MarkerOptions markerOptions) {
Marker marker = markerOptions.getMarker();
ensureIconLoaded(marker);
@@ -1027,308 +1062,48 @@ public class MapView extends FrameLayout {
}
// this seems to be a costly operation according to the profiler so I'm trying to save some calls
Marker previousMarker = marker.getId() != -1 ? (Marker) mAnnotations.get(marker.getId()) : null;
Marker previousMarker = marker.getId() != -1 ? (Marker) mMapboxMap.getAnnotation(marker.getId()) : null;
if (previousMarker == null || previousMarker.getIcon() == null || previousMarker.getIcon() != marker.getIcon()) {
marker.setTopOffsetPixels(getTopOffsetPixelsForIcon(icon));
}
}
/**
* <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.
* @return The {@code Marker} that was added to the map.
*/
@UiThread
@NonNull
Marker addMarker(@NonNull MarkerOptions markerOptions) {
if (markerOptions == null) {
Log.w(TAG, "markerOptions was null, so just returning null");
return null;
}
Marker marker = prepareMarker(markerOptions);
long id = mNativeMapView.addMarker(marker);
marker.setId(id); // the annotation needs to know its id
marker.setMapboxMap(mMapboxMap); // the annotation needs to know which map view it is in
mAnnotations.put(id, marker);
return marker;
long addMarker(@NonNull Marker marker) {
if (mNativeMapView == null) {
return 0l;
}
return mNativeMapView.addMarker(marker);
}
/**
* <p>
* Updates a marker on this map. Does nothing if the marker is already added.
* </p>
*
* @param updatedMarker An updated marker object.
*/
@UiThread
void updateMarker(@NonNull Marker updatedMarker) {
if (updatedMarker == null) {
Log.w(TAG, "marker was null, doing nothing");
return;
}
if (updatedMarker.getId() == -1) {
Log.w(TAG, "marker has an id of -1, possibly was not added yet, doing nothing");
}
ensureIconLoaded(updatedMarker);
mNativeMapView.updateMarker(updatedMarker);
int index = mAnnotations.indexOfKey(updatedMarker.getId());
if (index > -1) {
mAnnotations.setValueAt(index, updatedMarker);
}
long[] addMarkers(@NonNull List<Marker> markerList) {
return mNativeMapView.addMarkers(markerList);
}
/**
* <p>
* Adds multiple markers 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 markerOptionsList A list of marker options objects that defines how to render the markers.
* @return A list of the {@code Marker}s that were added to the map.
*/
@UiThread
@NonNull
List<Marker> addMarkers(@NonNull List<MarkerOptions> markerOptionsList) {
if (markerOptionsList == null) {
Log.w(TAG, "markerOptionsList was null, so just returning null");
return null;
}
int count = markerOptionsList.size();
List<Marker> markers = new ArrayList<>(count);
for (int i = 0; i < count; i++) {
MarkerOptions markerOptions = markerOptionsList.get(i);
Marker marker = prepareMarker(markerOptions);
markers.add(marker);
}
long[] ids = mNativeMapView.addMarkers(markers);
Marker m;
for (int i = 0; i < count; i++) {
m = markers.get(i);
m.setId(ids[i]);
m.setMapboxMap(mMapboxMap);
mAnnotations.put(ids[i], m);
}
return new ArrayList<>(markers);
long addPolyline(@NonNull Polyline polyline) {
return mNativeMapView.addPolyline(polyline);
}
/**
* Adds a polyline to this map.
*
* @param polylineOptions A polyline options object that defines how to render the polyline.
* @return The {@code Polyine} that was added to the map.
*/
@UiThread
@NonNull
Polyline addPolyline(@NonNull PolylineOptions polylineOptions) {
if (polylineOptions == null) {
Log.w(TAG, "polylineOptions was null, so just returning null");
return null;
}
Polyline polyline = polylineOptions.getPolyline();
long id = mNativeMapView.addPolyline(polyline);
polyline.setId(id);
polyline.setMapboxMap(mMapboxMap);
mAnnotations.put(id, polyline);
return polyline;
long[] addPolylines(@NonNull List<Polyline> polylines) {
return mNativeMapView.addPolylines(polylines);
}
/**
* Adds multiple polylines to this map.
*
* @param polylineOptionsList A list of polyline options objects that defines how to render the polylines.
* @return A list of the {@code Polyline}s that were added to the map.
*/
@UiThread
@NonNull
List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList) {
if (polylineOptionsList == null) {
Log.w(TAG, "polylineOptionsList was null, so just returning null");
return null;
}
int count = polylineOptionsList.size();
List<Polyline> polylines = new ArrayList<>(count);
for (PolylineOptions options : polylineOptionsList) {
polylines.add(options.getPolyline());
}
long[] ids = mNativeMapView.addPolylines(polylines);
Polyline p;
for (int i = 0; i < count; i++) {
p = polylines.get(i);
p.setId(ids[i]);
p.setMapboxMap(mMapboxMap);
mAnnotations.put(ids[i], p);
}
return new ArrayList<>(polylines);
long addPolygon(@NonNull Polygon polygon) {
return mNativeMapView.addPolygon(polygon);
}
/**
* Adds a polygon to this map.
*
* @param polygonOptions A polygon options object that defines how to render the polygon.
* @return The {@code Polygon} that was added to the map.
*/
@UiThread
@NonNull
Polygon addPolygon(@NonNull PolygonOptions polygonOptions) {
if (polygonOptions == null) {
Log.w(TAG, "polygonOptions was null, so just returning null");
return null;
}
Polygon polygon = polygonOptions.getPolygon();
long id = mNativeMapView.addPolygon(polygon);
polygon.setId(id);
polygon.setMapboxMap(mMapboxMap);
mAnnotations.put(id, polygon);
return polygon;
long[] addPolygons(@NonNull List<Polygon> polygons) {
return mNativeMapView.addPolygons(polygons);
}
/**
* Adds multiple polygons to this map.
*
* @param polygonOptionsList A list of polygon options objects that defines how to render the polygons.
* @return A list of the {@code Polygon}s that were added to the map.
*/
@UiThread
@NonNull
List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList) {
if (polygonOptionsList == null) {
Log.w(TAG, "polygonOptionsList was null, so just returning null");
return null;
}
int count = polygonOptionsList.size();
List<Polygon> polygons = new ArrayList<>(count);
for (PolygonOptions polygonOptions : polygonOptionsList) {
polygons.add(polygonOptions.getPolygon());
}
long[] ids = mNativeMapView.addPolygons(polygons);
Polygon p;
for (int i = 0; i < count; i++) {
p = polygons.get(i);
p.setId(ids[i]);
p.setMapboxMap(mMapboxMap);
mAnnotations.put(ids[i], p);
}
return new ArrayList<>(polygons);
}
/**
* <p>
* Convenience method for removing a Marker from the map.
* </p>
* Calls removeAnnotation() internally
*
* @param marker Marker to remove
*/
@UiThread
void removeMarker(@NonNull Marker marker) {
removeAnnotation(marker);
}
/**
* Removes an annotation from the map.
*
* @param annotation The annotation object to remove.
*/
@UiThread
void removeAnnotation(@NonNull Annotation annotation) {
if (annotation == null) {
Log.w(TAG, "annotation was null, so just returning");
return;
}
if (annotation instanceof Marker) {
((Marker) annotation).hideInfoWindow();
}
long id = annotation.getId();
void removeAnnotation(long id) {
mNativeMapView.removeAnnotation(id);
mAnnotations.delete(id);
}
/**
* Removes multiple annotations from the map.
*
* @param annotationList A list of annotation objects to remove.
*/
@UiThread
void removeAnnotations(@NonNull List<? extends Annotation> annotationList) {
if (annotationList == null) {
Log.w(TAG, "annotationList was null, so just returning");
return;
}
int count = annotationList.size();
long[] ids = new long[count];
for (int i = 0; i < count; i++) {
ids[i] = annotationList.get(i).getId();
}
void removeAnnotations(@NonNull long[] ids) {
mNativeMapView.removeAnnotations(ids);
}
/**
* Removes all annotations from the map.
*/
@UiThread
void removeAllAnnotations() {
int count = mAnnotations.size();
long[] ids = new long[count];
for (int i = 0; i < count; i++) {
Annotation annotation = mAnnotations.valueAt(i);
long id = annotation.getId();
ids[i] = id;
if (annotation instanceof Marker) {
((Marker) annotation).hideInfoWindow();
}
}
mNativeMapView.removeAnnotations(ids);
mAnnotations.clear();
}
/**
* Returns a list of all the annotations on the map.
*
* @return A list of all the annotation objects. The returned object is a copy so modifying this
* list will not update the map.
*/
@NonNull
public List<Annotation> getAllAnnotations() {
List<Annotation> copyOfAnnotations = new ArrayList<>(mAnnotations.size());
for (int i = 0; i < mAnnotations.size(); i++) {
copyOfAnnotations.add(mAnnotations.valueAt(i));
}
return copyOfAnnotations;
}
private List<Marker> getMarkersInBounds(@NonNull LatLngBounds bbox) {
if (bbox == null) {
Log.w(TAG, "bbox was null, so just returning null");
@@ -1344,9 +1119,10 @@ public class MapView extends FrameLayout {
}
List<Marker> annotations = new ArrayList<>(ids.length);
int count = mAnnotations.size();
List<Annotation> annotationList = mMapboxMap.getAnnotations();
int count = annotationList.size();
for (int i = 0; i < count; i++) {
Annotation annotation = mAnnotations.valueAt(i);
Annotation annotation = annotationList.get(i);
if (annotation instanceof Marker && idsList.contains(annotation.getId())) {
annotations.add((Marker) annotation);
}
@@ -1355,7 +1131,7 @@ public class MapView extends FrameLayout {
return new ArrayList<>(annotations);
}
private int getTopOffsetPixelsForIcon(Icon icon) {
int getTopOffsetPixelsForIcon(Icon icon) {
// This method will dead lock if map paused. Causes a freeze if you add a marker in an
// activity's onCreate()
if (mNativeMapView.isPaused()) {
@@ -1504,9 +1280,10 @@ public class MapView extends FrameLayout {
}
private void adjustTopOffsetPixels() {
int count = mAnnotations.size();
List<Annotation> annotations = mMapboxMap.getAnnotations();
int count = annotations.size();
for (int i = 0; i < count; i++) {
Annotation annotation = mAnnotations.valueAt(i);
Annotation annotation = annotations.get(i);
if (annotation instanceof Marker) {
Marker marker = (Marker) annotation;
marker.setTopOffsetPixels(
@@ -1523,9 +1300,10 @@ public class MapView extends FrameLayout {
}
private void reloadMarkers() {
int count = mAnnotations.size();
List<Annotation> annotations = mMapboxMap.getAnnotations();
int count = annotations.size();
for (int i = 0; i < count; i++) {
Annotation annotation = mAnnotations.valueAt(i);
Annotation annotation = annotations.get(i);
if (annotation instanceof Marker) {
Marker marker = (Marker) annotation;
mNativeMapView.removeAnnotation(annotation.getId());
@@ -1830,9 +1608,10 @@ public class MapView extends FrameLayout {
}
if (newSelectedMarkerId >= 0) {
int count = mAnnotations.size();
List<Annotation> annotations = mMapboxMap.getAnnotations();
int count = annotations.size();
for (int i = 0; i < count; i++) {
Annotation annotation = mAnnotations.valueAt(i);
Annotation annotation = annotations.get(i);
if (annotation instanceof Marker) {
if (annotation.getId() == newSelectedMarkerId) {
if (selectedMarkers.isEmpty() || !selectedMarkers.contains(annotation)) {

View File

@@ -11,11 +11,15 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresPermission;
import android.support.annotation.UiThread;
import android.support.v4.util.LongSparseArray;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import com.mapbox.mapboxsdk.annotations.Annotation;
import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.annotations.InfoWindow;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
@@ -28,11 +32,13 @@ import com.mapbox.mapboxsdk.constants.MapboxConstants;
import com.mapbox.mapboxsdk.constants.MyBearingTracking;
import com.mapbox.mapboxsdk.constants.MyLocationTracking;
import com.mapbox.mapboxsdk.constants.Style;
import com.mapbox.mapboxsdk.exceptions.IconBitmapChangedException;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.layers.CustomLayer;
import com.mapbox.mapboxsdk.utils.ApiAccess;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.TimeUnit;
@@ -45,6 +51,7 @@ public class MapboxMap {
private CameraPosition mCameraPosition;
private boolean mInvalidCameraPosition;
private String mStyleUrl;
private LongSparseArray<Annotation> mAnnotations;
private List<Marker> mSelectedMarkers;
private List<InfoWindow> mInfoWindows;
private MapboxMap.InfoWindowAdapter mInfoWindowAdapter;
@@ -71,6 +78,7 @@ public class MapboxMap {
mUiSettings = new UiSettings(mapView);
mTrackingSettings = new TrackingSettings(mMapView, mUiSettings);
mProjection = new Projection(mapView);
mAnnotations = new LongSparseArray<>();
mSelectedMarkers = new ArrayList<>();
mInfoWindows = new ArrayList<>();
}
@@ -97,7 +105,7 @@ public class MapboxMap {
*
* @return
*/
public TrackingSettings getTrackingSettings(){
public TrackingSettings getTrackingSettings() {
return mTrackingSettings;
}
@@ -532,7 +540,17 @@ public class MapboxMap {
@UiThread
@NonNull
public Marker addMarker(@NonNull MarkerOptions markerOptions) {
return mMapView.addMarker(markerOptions);
return addMarker((BaseMarkerOptions)markerOptions);
}
@UiThread
@NonNull
public Marker addMarker(@NonNull BaseMarkerOptions markerOptions) {
Marker marker = prepareMarker(markerOptions);
long id = mMapView.addMarker(marker);
marker.setId(id);
mAnnotations.put(id, marker);
return marker;
}
/**
@@ -548,7 +566,33 @@ public class MapboxMap {
@UiThread
@NonNull
public List<Marker> addMarkers(@NonNull List<MarkerOptions> markerOptionsList) {
return mMapView.addMarkers(markerOptionsList);
int count = markerOptionsList.size();
List<Marker> markers = new ArrayList<>(count);
MarkerOptions markerOptions;
Marker marker;
for (int i = 0; i < count; i++) {
markerOptions = markerOptionsList.get(i);
marker = prepareMarker(markerOptions);
markers.add(marker);
}
long[] ids = mMapView.addMarkers(markers);
long id = 0;
Marker m;
for (int i = 0; i < markers.size(); i++) {
m = markers.get(i);
m.setMapboxMap(this);
if (ids != null) {
id = ids[i];
} else {
//unit test
id++;
}
m.setId(id);
mAnnotations.put(id, m);
}
return markers;
}
/**
@@ -561,6 +605,11 @@ public class MapboxMap {
@UiThread
public void updateMarker(@NonNull Marker updatedMarker) {
mMapView.updateMarker(updatedMarker);
int index = mAnnotations.indexOfKey(updatedMarker.getId());
if (index > -1) {
mAnnotations.setValueAt(index, updatedMarker);
}
}
/**
@@ -572,7 +621,12 @@ public class MapboxMap {
@UiThread
@NonNull
public Polyline addPolyline(@NonNull PolylineOptions polylineOptions) {
return mMapView.addPolyline(polylineOptions);
Polyline polyline = polylineOptions.getPolyline();
long id = mMapView.addPolyline(polyline);
polyline.setMapboxMap(this);
polyline.setId(id);
mAnnotations.put(id, polyline);
return polyline;
}
/**
@@ -584,7 +638,29 @@ public class MapboxMap {
@UiThread
@NonNull
public List<Polyline> addPolylines(@NonNull List<PolylineOptions> polylineOptionsList) {
return mMapView.addPolylines(polylineOptionsList);
int count = polylineOptionsList.size();
List<Polyline> polylines = new ArrayList<>(count);
for (PolylineOptions options : polylineOptionsList) {
polylines.add(options.getPolyline());
}
long[] ids = mMapView.addPolylines(polylines);
long id = 0;
Polyline p;
for (int i = 0; i < polylines.size(); i++) {
p = polylines.get(i);
p.setMapboxMap(this);
if (ids != null) {
id = ids[i];
} else {
// unit test
id++;
}
p.setId(id);
mAnnotations.put(id, p);
}
return polylines;
}
/**
@@ -596,7 +672,12 @@ public class MapboxMap {
@UiThread
@NonNull
public Polygon addPolygon(@NonNull PolygonOptions polygonOptions) {
return mMapView.addPolygon(polygonOptions);
Polygon polygon = polygonOptions.getPolygon();
long id = mMapView.addPolygon(polygon);
polygon.setId(id);
polygon.setMapboxMap(this);
mAnnotations.put(id, polygon);
return polygon;
}
/**
@@ -608,7 +689,29 @@ public class MapboxMap {
@UiThread
@NonNull
public List<Polygon> addPolygons(@NonNull List<PolygonOptions> polygonOptionsList) {
return mMapView.addPolygons(polygonOptionsList);
int count = polygonOptionsList.size();
List<Polygon> polygons = new ArrayList<>(count);
for (PolygonOptions polygonOptions : polygonOptionsList) {
polygons.add(polygonOptions.getPolygon());
}
long[] ids = mMapView.addPolygons(polygons);
long id = 0;
Polygon polygon;
for (int i = 0; i < polygons.size(); i++) {
polygon = polygons.get(i);
polygon.setMapboxMap(this);
if(ids!=null){
id = ids[i];
}else{
// unit test
id++;
}
polygon.setId(id);
mAnnotations.put(id, polygon);
}
return polygons;
}
/**
@@ -624,6 +727,32 @@ public class MapboxMap {
removeAnnotation(marker);
}
/**
* <p>
* Convenience method for removing a Polyline from the map.
* </p>
* Calls removeAnnotation() internally
*
* @param polyline Polyline to remove
*/
@UiThread
public void removePolyline(@NonNull Polyline polyline) {
removeAnnotation(polyline);
}
/**
* <p>
* Convenience method for removing a Polygon from the map.
* </p>
* Calls removeAnnotation() internally
*
* @param polygon Polygon to remove
*/
@UiThread
public void removePolygon(@NonNull Polygon polygon) {
removeAnnotation(polygon);
}
/**
* Removes an annotation from the map.
*
@@ -631,7 +760,23 @@ public class MapboxMap {
*/
@UiThread
public void removeAnnotation(@NonNull Annotation annotation) {
mMapView.removeAnnotation(annotation);
if (annotation instanceof Marker) {
((Marker) annotation).hideInfoWindow();
}
long id = annotation.getId();
mMapView.removeAnnotation(id);
mAnnotations.remove(id);
}
/**
* Removes an annotation from the map
*
* @param id The identifier associated to the annotation to be removed
*/
@UiThread
public void removeAnnotation(long id) {
mMapView.removeAnnotation(id);
mAnnotations.remove(id);
}
/**
@@ -641,15 +786,38 @@ public class MapboxMap {
*/
@UiThread
public void removeAnnotations(@NonNull List<? extends Annotation> annotationList) {
mMapView.removeAnnotations(annotationList);
int count = annotationList.size();
long[] ids = new long[count];
for (int i = 0; i < count; i++) {
Annotation annotation = annotationList.get(i);
if (annotation instanceof Marker) {
((Marker) annotation).hideInfoWindow();
}
ids[i] = annotationList.get(i).getId();
}
mMapView.removeAnnotations(ids);
for (long id : ids) {
mAnnotations.remove(id);
}
}
/**
* Removes all annotations from the map.
*/
@UiThread
public void removeAllAnnotations() {
mMapView.removeAllAnnotations();
public void removeAnnotations() {
mAnnotations.clear();
}
/**
* Return a annotation based on its id.
*
* @return An annotation with a matched id, null is returned if no match was found.
*/
@UiThread
@Nullable
public Annotation getAnnotation(long id) {
return mAnnotations.get(id);
}
/**
@@ -659,8 +827,69 @@ public class MapboxMap {
* list will not update the map.
*/
@NonNull
public List<Annotation> getAllAnnotations() {
return mMapView.getAllAnnotations();
public List<Annotation> getAnnotations() {
List<Annotation> annotations = new ArrayList<>();
for (int i = 0; i < mAnnotations.size(); i++) {
annotations.add(mAnnotations.get(mAnnotations.keyAt(i)));
}
return annotations;
}
/**
* Returns a list of all the markers on the map.
*
* @return A list of all the markers objects. The returned object is a copy so modifying this
* list will not update the map.
*/
@NonNull
public List<Marker> getMarkers() {
List<Marker> markers = new ArrayList<>();
Annotation annotation;
for (int i = 0; i < mAnnotations.size(); i++) {
annotation = mAnnotations.get(mAnnotations.keyAt(i));
if (annotation instanceof Marker) {
markers.add((Marker) annotation);
}
}
return markers;
}
/**
* Returns a list of all the polygons on the map.
*
* @return A list of all the polygon objects. The returned object is a copy so modifying this
* list will not update the map.
*/
@NonNull
public List<Polygon> getPolygons() {
List<Polygon> polygons = new ArrayList<>();
Annotation annotation;
for (int i = 0; i < mAnnotations.size(); i++) {
annotation = mAnnotations.get(mAnnotations.keyAt(i));
if (annotation instanceof Polygon) {
polygons.add((Polygon) annotation);
}
}
return polygons;
}
/**
* Returns a list of all the polylines on the map.
*
* @return A list of all the polylines objects. The returned object is a copy so modifying this
* list will not update the map.
*/
@NonNull
public List<Polyline> getPolylines() {
List<Polyline> polylines = new ArrayList<>();
Annotation annotation;
for (int i = 0; i < mAnnotations.size(); i++) {
annotation = mAnnotations.get(mAnnotations.keyAt(i));
if (annotation instanceof Polyline) {
polylines.add((Polyline) annotation);
}
}
return polylines;
}
/**
@@ -746,11 +975,17 @@ public class MapboxMap {
* @return The currently selected marker.
*/
@UiThread
@Nullable
public List<Marker> getSelectedMarkers() {
return mSelectedMarkers;
}
private Marker prepareMarker(BaseMarkerOptions markerOptions) {
Marker marker = markerOptions.getMarker();
Icon icon = mMapView.loadIconForMarker(marker);
marker.setTopOffsetPixels(mMapView.getTopOffsetPixelsForIcon(icon));
return marker;
}
//
// InfoWindow
//
@@ -1107,9 +1342,9 @@ public class MapboxMap {
return mMapView;
}
//
// Interfaces
//
//
// Interfaces
//
/**
* Interface definition for a callback to be invoked when the map is flinged.
@@ -1287,7 +1522,7 @@ public class MapboxMap {
/**
* Interface definition for a callback to be invoked when the the My Location tracking mode changes.
*
* @see MapboxMap#setMyLocationTrackingMode(int)
* @see MapView#setMyLocationTrackingMode(int)
*/
public interface OnMyLocationTrackingModeChangeListener {
@@ -1302,7 +1537,7 @@ public class MapboxMap {
/**
* Interface definition for a callback to be invoked when the the My Location tracking mode changes.
*
* @see MapboxMap#setMyLocationTrackingMode(int)
* @see MapView#setMyLocationTrackingMode(int)
*/
public interface OnMyBearingTrackingModeChangeListener {

View File

@@ -150,7 +150,7 @@ public class BulkMarkerActivity extends AppCompatActivity implements AdapterView
public LoadBulkMarkerTask(Context context, MapboxMap mapboxMap, int amount) {
mMapboxMap = mapboxMap;
mapboxMap.removeAllAnnotations();
mapboxMap.removeAnnotations();
mProgressDialog = ProgressDialog.show(context, "Loading", "Fetching markers", false);
mAppContext = context.getApplicationContext();
mAmount = amount;

View File

@@ -78,7 +78,7 @@ public class GeocoderActivity extends AppCompatActivity {
@Override
public void onMapClick(@NonNull LatLng point) {
setMessage("Geocoding...");
mapboxMap.removeAllAnnotations();
mapboxMap.removeAnnotations();
mapboxMap.addMarker(new MarkerOptions()
.position(point)
.title("Your finger is here"));

View File

@@ -16,10 +16,11 @@ import android.widget.TextView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
import com.mapbox.mapboxsdk.testapp.annotations.CityStateMarker;
import com.mapbox.mapboxsdk.testapp.annotations.CityStateMarkerOptions;
import com.mapbox.mapboxsdk.utils.ApiAccess;
import com.mapbox.mapboxsdk.maps.MapView;
@@ -54,12 +55,12 @@ public class InfoWindowAdapterActivity extends AppCompatActivity {
@Override
public void onMapReady(@NonNull MapboxMap mapboxMap) {
// add markers
mapboxMap.addMarker(generateMarker("Andorra", 42.505777, 1.52529, "#F44336"));
mapboxMap.addMarker(generateMarker("Luxembourg", 49.815273, 6.129583, "#3F51B5"));
mapboxMap.addMarker(generateMarker("Monaco", 43.738418, 7.424616, "#673AB7"));
mapboxMap.addMarker(generateMarker("Vatican City", 41.902916, 12.453389, "#009688"));
mapboxMap.addMarker(generateMarker("San Marino", 43.942360, 12.457777, "#795548"));
mapboxMap.addMarker(generateMarker("Liechtenstein", 47.166000, 9.555373, "#FF5722"));
mapboxMap.addMarker(generateCityStateMarker("Andorra", 42.505777, 1.52529, "#F44336"));
mapboxMap.addMarker(generateCityStateMarker("Luxembourg", 49.815273, 6.129583, "#3F51B5"));
mapboxMap.addMarker(generateCityStateMarker("Monaco", 43.738418, 7.424616, "#673AB7"));
mapboxMap.addMarker(generateCityStateMarker("Vatican City", 41.902916, 12.453389, "#009688"));
mapboxMap.addMarker(generateCityStateMarker("San Marino", 43.942360, 12.457777, "#795548"));
mapboxMap.addMarker(generateCityStateMarker("Liechtenstein", 47.166000, 9.555373, "#FF5722"));
// add custom window adapter
mapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() {
@@ -71,7 +72,12 @@ public class InfoWindowAdapterActivity extends AppCompatActivity {
TextView textView = new TextView(InfoWindowAdapterActivity.this);
textView.setText(marker.getTitle());
textView.setTextColor(Color.WHITE);
textView.setBackgroundColor(Color.parseColor(marker.getSnippet()));
if(marker instanceof CityStateMarker){
CityStateMarker cityStateMarker = (CityStateMarker)marker;
textView.setBackgroundColor(Color.parseColor(cityStateMarker.getInfoWindowBackgroundColor()));
}
textView.setPadding(tenDp, tenDp, tenDp, tenDp);
return textView;
}
@@ -80,13 +86,13 @@ public class InfoWindowAdapterActivity extends AppCompatActivity {
});
}
private MarkerOptions generateMarker(String title, double lat, double lng, String color) {
MarkerOptions marker = new MarkerOptions();
private CityStateMarkerOptions generateCityStateMarker(String title, double lat, double lng, String color) {
CityStateMarkerOptions marker = new CityStateMarkerOptions();
marker.title(title);
marker.snippet(color);
marker.position(new LatLng(lat, lng));
marker.infoWindowBackground(color);
mIconDrawable.setColorFilter(Color.parseColor(marker.getSnippet()), PorterDuff.Mode.SRC_IN);
mIconDrawable.setColorFilter(Color.parseColor(color), PorterDuff.Mode.SRC_IN);
Icon icon = mIconFactory.fromDrawable(mIconDrawable);
marker.icon(icon);
return marker;
@@ -144,4 +150,5 @@ public class InfoWindowAdapterActivity extends AppCompatActivity {
return super.onOptionsItemSelected(item);
}
}
}

View File

@@ -655,7 +655,7 @@ public class MainActivity extends AppCompatActivity {
private void removeAnnotations() {
mMarkerList.clear();
mMapboxMap.removeAllAnnotations();
mMapboxMap.removeAnnotations();
}
private void addCustomLayer() {

View File

@@ -169,7 +169,7 @@ public class PolylineActivity extends AppCompatActivity {
case R.id.action_id_remove:
// test to remove all annotations
mPolylineOptions.clear();
mMapboxMap.removeAllAnnotations();
mMapboxMap.removeAnnotations();
return true;
case android.R.id.home:

View File

@@ -0,0 +1,18 @@
package com.mapbox.mapboxsdk.testapp.annotations;
import com.mapbox.mapboxsdk.annotations.Marker;
public class CityStateMarker extends Marker {
private String mInfoWindowBackgroundColor;
public CityStateMarker(CityStateMarkerOptions cityStateOptions, String color) {
super(cityStateOptions);
mInfoWindowBackgroundColor = color;
}
public String getInfoWindowBackgroundColor() {
return mInfoWindowBackgroundColor;
}
}

View File

@@ -0,0 +1,68 @@
package com.mapbox.mapboxsdk.testapp.annotations;
import android.graphics.Bitmap;
import android.os.Parcel;
import android.os.Parcelable;
import com.mapbox.mapboxsdk.annotations.BaseMarkerOptions;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.IconFactory;
import com.mapbox.mapboxsdk.geometry.LatLng;
public class CityStateMarkerOptions extends BaseMarkerOptions<CityStateMarker, CityStateMarkerOptions> {
private String mInfoWindowBackgroundColor;
public CityStateMarkerOptions infoWindowBackground(String color) {
mInfoWindowBackgroundColor = color;
return getThis();
}
public CityStateMarkerOptions() {
}
private CityStateMarkerOptions(Parcel in) {
position((LatLng) in.readParcelable(LatLng.class.getClassLoader()));
snippet(in.readString());
String iconId = in.readString();
Bitmap iconBitmap = in.readParcelable(Bitmap.class.getClassLoader());
Icon icon = IconFactory.recreate(iconId, iconBitmap);
icon(icon);
title(in.readString());
}
@Override
public CityStateMarkerOptions getThis() {
return this;
}
@Override
public CityStateMarker getMarker() {
return new CityStateMarker(this, mInfoWindowBackgroundColor);
}
public static final Parcelable.Creator<CityStateMarkerOptions> CREATOR
= new Parcelable.Creator<CityStateMarkerOptions>() {
public CityStateMarkerOptions createFromParcel(Parcel in) {
return new CityStateMarkerOptions(in);
}
public CityStateMarkerOptions[] newArray(int size) {
return new CityStateMarkerOptions[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeParcelable(position, flags);
out.writeString(snippet);
out.writeString(icon.getId());
out.writeParcelable(icon.getBitmap(), flags);
out.writeString(title);
}
}

View File

@@ -1,9 +1,14 @@
package com.mapbox.mapboxsdk.maps;
import android.graphics.Color;
import android.graphics.Point;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
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.camera.CameraPosition;
import com.mapbox.mapboxsdk.constants.Style;
@@ -15,9 +20,13 @@ import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.matches;
import static org.mockito.Mockito.mock;
import static org.junit.Assert.assertNotNull;
@@ -46,6 +55,16 @@ public class MapboxMapTest {
assertNotNull("mMapboxMap should not be null", mMapboxMap);
}
@Test
public void testMock() {
assertNotNull("mMapView should be mocked", mMapView);
}
@Test
public void testGetMapView(){
assertNotNull("MapView should be non null", mMapboxMap.getMapView());
}
//
// UiSettings
//
@@ -60,12 +79,11 @@ public class MapboxMapTest {
//
@Test
public void testProjection(){
assertNotNull("Projection should not be null",mMapboxMap.getProjection());
public void testProjection() {
assertNotNull("Projection should not be null", mMapboxMap.getProjection());
}
//
// InfoWindow
//
@@ -368,6 +386,206 @@ public class MapboxMapTest {
assertTrue("Zoomlevel should be same", 12 == mMapboxMap.getCameraPosition().zoom);
}
//
// Annotations
//
@Test
public void testAddMarker() {
MarkerOptions markerOptions = new MarkerOptions();
Marker marker = mMapboxMap.addMarker(markerOptions);
assertTrue("Marker should be contained", mMapboxMap.getMarkers().contains(marker));
}
@Test
public void testAddMarkers() {
List<MarkerOptions> markerList = new ArrayList<>();
MarkerOptions markerOptions1 = new MarkerOptions().title("a");
MarkerOptions markerOptions2 = new MarkerOptions().title("b");
markerList.add(markerOptions1);
markerList.add(markerOptions2);
mMapboxMap.addMarkers(markerList);
assertEquals("Markers size should be 2", 2, mMapboxMap.getMarkers().size());
assertTrue(mMapboxMap.getMarkers().contains(markerOptions1.getMarker()));
assertTrue(mMapboxMap.getMarkers().contains(markerOptions2.getMarker()));
}
@Test
public void testAddPolygon() {
PolygonOptions polygonOptions = new PolygonOptions();
Polygon polygon = mMapboxMap.addPolygon(polygonOptions);
assertTrue("Polygon should be contained", mMapboxMap.getPolygons().contains(polygon));
}
@Test
public void testAddPolygons() {
List<PolygonOptions> polygonList = new ArrayList<>();
PolygonOptions polygonOptions1 = new PolygonOptions().fillColor(Color.BLACK);
PolygonOptions polygonOptions2 = new PolygonOptions().fillColor(Color.WHITE);
polygonList.add(polygonOptions1);
polygonList.add(polygonOptions2);
mMapboxMap.addPolygons(polygonList);
assertEquals("Polygons size should be 2", 2, mMapboxMap.getPolygons().size());
assertTrue(mMapboxMap.getPolygons().contains(polygonOptions1.getPolygon()));
assertTrue(mMapboxMap.getPolygons().contains(polygonOptions2.getPolygon()));
}
@Test
public void testAddPolyline() {
PolylineOptions polylineOptions = new PolylineOptions();
Polyline polyline = mMapboxMap.addPolyline(polylineOptions);
assertTrue("Polyline should be contained", mMapboxMap.getPolylines().contains(polyline));
}
@Test
public void testAddPolylines() {
List<PolylineOptions> polylineList = new ArrayList<>();
PolylineOptions polygonOptions1 = new PolylineOptions().color(Color.BLACK);
PolylineOptions polygonOptions2 = new PolylineOptions().color(Color.WHITE);
polylineList.add(polygonOptions1);
polylineList.add(polygonOptions2);
mMapboxMap.addPolylines(polylineList);
assertEquals("Polygons size should be 2", 2, mMapboxMap.getPolylines().size());
assertTrue(mMapboxMap.getPolylines().contains(polygonOptions1.getPolyline()));
assertTrue(mMapboxMap.getPolylines().contains(polygonOptions2.getPolyline()));
}
@Test
public void testRemoveMarker() {
MarkerOptions markerOptions = new MarkerOptions();
Marker marker = mMapboxMap.addMarker(markerOptions);
mMapboxMap.removeMarker(marker);
assertTrue("Markers should be empty", mMapboxMap.getMarkers().isEmpty());
}
@Test
public void testRemovePolygon() {
PolygonOptions polygonOptions = new PolygonOptions();
Polygon polygon = mMapboxMap.addPolygon(polygonOptions);
mMapboxMap.removePolygon(polygon);
assertTrue("Polygons should be empty", mMapboxMap.getPolylines().isEmpty());
}
@Test
public void testRemovePolyline() {
PolylineOptions polylineOptions = new PolylineOptions();
Polyline polyline = mMapboxMap.addPolyline(polylineOptions);
mMapboxMap.removePolyline(polyline);
assertTrue("Polylines should be empty", mMapboxMap.getPolylines().isEmpty());
}
@Test
public void testRemoveAnnotation() {
MarkerOptions markerOptions = new MarkerOptions();
Marker marker = mMapboxMap.addMarker(markerOptions);
mMapboxMap.removeAnnotation(marker);
assertTrue("Annotations should be empty", mMapboxMap.getAnnotations().isEmpty());
}
@Test
public void testRemoveAnnotationById() {
MarkerOptions markerOptions = new MarkerOptions();
mMapboxMap.addMarker(markerOptions);
// id will always be 0 in unit tests
mMapboxMap.removeAnnotation(0);
assertTrue("Annotations should be empty", mMapboxMap.getAnnotations().isEmpty());
}
@Test
public void testRemoveAnnotations() {
List<MarkerOptions> markerList = new ArrayList<>();
MarkerOptions markerOptions1 = new MarkerOptions().title("a");
MarkerOptions markerOptions2 = new MarkerOptions().title("b");
markerList.add(markerOptions1);
markerList.add(markerOptions2);
mMapboxMap.addMarkers(markerList);
mMapboxMap.removeAnnotations();
assertTrue("Annotations should be empty", mMapboxMap.getAnnotations().isEmpty());
}
@Test
public void testRemoveAnnotationsByList() {
List<MarkerOptions> markerList = new ArrayList<>();
MarkerOptions markerOptions1 = new MarkerOptions().title("a");
MarkerOptions markerOptions2 = new MarkerOptions().title("b");
markerList.add(markerOptions1);
markerList.add(markerOptions2);
List<Marker> markers = mMapboxMap.addMarkers(markerList);
Marker marker = mMapboxMap.addMarker(new MarkerOptions().title("c"));
mMapboxMap.removeAnnotations(markers);
assertTrue("Annotations should not be empty", mMapboxMap.getAnnotations().size() == 1);
assertTrue("Marker should be contained", mMapboxMap.getAnnotations().contains(marker));
}
@Test
public void testGetAnnotationById() {
MarkerOptions markerOptions = new MarkerOptions();
Marker initialMarker = mMapboxMap.addMarker(markerOptions);
Marker retrievedMarker = (Marker) mMapboxMap.getAnnotation(0);
assertEquals("Markers should match", initialMarker, retrievedMarker);
}
@Test
public void testGetAnnotations() {
assertNotNull("Annotations should be non null", mMapboxMap.getAnnotations());
}
@Test
public void testGetMarkers() {
assertNotNull("Markers should be non null", mMapboxMap.getMarkers());
}
@Test
public void testGetPolygons() {
assertNotNull("Polygons should be non null", mMapboxMap.getPolygons());
}
@Test
public void testGetPolylines() {
assertNotNull("Polylines should be non null", mMapboxMap.getPolylines());
}
@Test
public void testGetSelectedMarkers() {
assertNotNull("Selected markers should be non null", mMapboxMap.getSelectedMarkers());
}
@Test
public void testSelectMarker() {
mMapboxMap.setOnMarkerClickListener(mOnMarkerClickListener);
MarkerOptions markerOptions = new MarkerOptions();
Marker marker = mMapboxMap.addMarker(markerOptions);
when(mOnMarkerClickListener.onMarkerClick(marker)).thenReturn(true);
mMapboxMap.selectMarker(marker);
assertTrue("Marker should be contained", mMapboxMap.getSelectedMarkers().contains(marker));
}
@Test
public void testDeselectMarker() {
mMapboxMap.setOnMarkerClickListener(mOnMarkerClickListener);
MarkerOptions markerOptions = new MarkerOptions();
Marker marker = mMapboxMap.addMarker(markerOptions);
when(mOnMarkerClickListener.onMarkerClick(marker)).thenReturn(true);
mMapboxMap.selectMarker(marker);
mMapboxMap.deselectMarker(marker);
assertTrue("Selected markers should be empty", mMapboxMap.getSelectedMarkers().isEmpty());
}
@Test
public void testDeselectMarkers() {
mMapboxMap.setOnMarkerClickListener(mOnMarkerClickListener);
MarkerOptions markerOptions = new MarkerOptions();
Marker marker1 = mMapboxMap.addMarker(markerOptions);
Marker marker2 = mMapboxMap.addMarker(markerOptions);
when(mOnMarkerClickListener.onMarkerClick(marker1)).thenReturn(true);
when(mOnMarkerClickListener.onMarkerClick(marker2)).thenReturn(true);
mMapboxMap.selectMarker(marker1);
mMapboxMap.selectMarker(marker2);
mMapboxMap.deselectMarkers();
assertTrue("Selected markers should be empty", mMapboxMap.getSelectedMarkers().isEmpty());
}
//
// OnMarkerClick interface
//