diff --git a/config/checkstyle/checkstyle-suppressions.xml b/config/checkstyle/checkstyle-suppressions.xml index 6141b18b..226c90e1 100644 --- a/config/checkstyle/checkstyle-suppressions.xml +++ b/config/checkstyle/checkstyle-suppressions.xml @@ -19,4 +19,7 @@ + + + diff --git a/core/src/main/java/com/mapzen/android/graphics/GraphicsModule.java b/core/src/main/java/com/mapzen/android/graphics/GraphicsModule.java index ab759dbe..00c2eaa2 100644 --- a/core/src/main/java/com/mapzen/android/graphics/GraphicsModule.java +++ b/core/src/main/java/com/mapzen/android/graphics/GraphicsModule.java @@ -1,5 +1,9 @@ package com.mapzen.android.graphics; +import com.mapzen.android.graphics.internal.StyleStringGenerator; +import com.mapzen.android.graphics.model.BitmapMarkerFactory; +import com.mapzen.android.graphics.model.BitmapMarkerManager; + import javax.inject.Singleton; import dagger.Module; @@ -34,4 +38,29 @@ @Provides @Singleton public SceneUpdateManager providesSceneUpdateManager() { return new SceneUpdateManager(); } + + /** + * Returns the object used create {@link com.mapzen.android.graphics.model.BitmapMarker}s. + * @return + */ + @Provides @Singleton public BitmapMarkerFactory providesBitmapMarkerFactory() { + return new BitmapMarkerFactory(); + } + + /** + * Returns the object used to generate a style string for a Tangram + * {@link com.mapzen.tangram.Marker}. + */ + @Provides @Singleton public StyleStringGenerator providesStyleStringGenerator() { + return new StyleStringGenerator(); + } + + /** + * Returns the object used to manager markers. + * {@link com.mapzen.tangram.Marker}. + */ + @Provides @Singleton public BitmapMarkerManager providesBitmapMarkerManager( + BitmapMarkerFactory bitmapMarkerFactory, StyleStringGenerator styleStringGenerator) { + return new BitmapMarkerManager(bitmapMarkerFactory, styleStringGenerator); + } } diff --git a/core/src/main/java/com/mapzen/android/graphics/MapInitializer.java b/core/src/main/java/com/mapzen/android/graphics/MapInitializer.java index d5d0caa6..900e9ce3 100644 --- a/core/src/main/java/com/mapzen/android/graphics/MapInitializer.java +++ b/core/src/main/java/com/mapzen/android/graphics/MapInitializer.java @@ -3,6 +3,7 @@ import com.mapzen.android.core.MapzenManager; import com.mapzen.android.graphics.model.BubbleWrapStyle; import com.mapzen.android.graphics.model.MapStyle; +import com.mapzen.android.graphics.model.BitmapMarkerManager; import com.mapzen.tangram.MapController; import com.mapzen.tangram.SceneError; import com.mapzen.tangram.SceneUpdate; @@ -33,18 +34,21 @@ public class MapInitializer { MapReadyInitializer mapReadyInitializer; + private BitmapMarkerManager bitmapMarkerManager; + /** * Creates a new instance. */ @Inject MapInitializer(Context context, MapzenMapHttpHandler mapzenMapHttpHandler, MapDataManager mapDataManager, MapStateManager mapStateManager, - SceneUpdateManager sceneUpdateManager) { + SceneUpdateManager sceneUpdateManager, BitmapMarkerManager bitmapMarkerManager) { this.context = context; this.mapzenMapHttpHandler = mapzenMapHttpHandler; this.mapDataManager = mapDataManager; this.mapStateManager = mapStateManager; this.sceneUpdateManager = sceneUpdateManager; mapReadyInitializer = new MapReadyInitializer(); + this.bitmapMarkerManager = bitmapMarkerManager; } /** @@ -93,7 +97,7 @@ private void loadMap(final MapView mapView, String sceneFile, final OnMapReadyCa new MapController.SceneLoadListener() { @Override public void onSceneReady(int sceneId, SceneError sceneError) { mapReadyInitializer.onMapReady(mapView, mapzenMapHttpHandler, callback, mapDataManager, - mapStateManager, sceneUpdateManager, locale); + mapStateManager, sceneUpdateManager, locale, bitmapMarkerManager); } }); controller.loadSceneFileAsync(sceneFile, sceneUpdates); diff --git a/core/src/main/java/com/mapzen/android/graphics/MapReadyInitializer.java b/core/src/main/java/com/mapzen/android/graphics/MapReadyInitializer.java index 6b84b856..2123f196 100644 --- a/core/src/main/java/com/mapzen/android/graphics/MapReadyInitializer.java +++ b/core/src/main/java/com/mapzen/android/graphics/MapReadyInitializer.java @@ -1,7 +1,7 @@ package com.mapzen.android.graphics; import com.mapzen.android.core.MapzenManager; -import com.mapzen.android.graphics.model.MarkerManager; +import com.mapzen.android.graphics.model.BitmapMarkerManager; import com.mapzen.tangram.MapController; import java.util.Locale; @@ -24,14 +24,16 @@ class MapReadyInitializer { */ void onMapReady(MapView mapView, MapzenMapHttpHandler mapzenMapHttpHandler, OnMapReadyCallback callback, MapDataManager mapDataManager, MapStateManager mapStateManager, - SceneUpdateManager sceneUpdateManager, Locale locale) { + SceneUpdateManager sceneUpdateManager, Locale locale, + BitmapMarkerManager bitmapMarkerManager) { MapController mapController = mapView.getTangramMapView().getMap(null); mapController.setSceneLoadListener(null); mapController.setHttpHandler(mapzenMapHttpHandler.httpHandler()); MapzenManager mapzenManager = MapzenManager.instance(mapView.getContext()); + bitmapMarkerManager.setMapController(mapController); callback.onMapReady( new MapzenMap(mapView, mapController, new OverlayManager(mapView, mapController, mapDataManager, mapStateManager), mapStateManager, new LabelPickHandler(mapView), - new MarkerManager(mapController), sceneUpdateManager, locale, mapzenManager)); + bitmapMarkerManager, sceneUpdateManager, locale, mapzenManager)); } } diff --git a/core/src/main/java/com/mapzen/android/graphics/MapzenMap.java b/core/src/main/java/com/mapzen/android/graphics/MapzenMap.java index 38a4013f..9929243b 100644 --- a/core/src/main/java/com/mapzen/android/graphics/MapzenMap.java +++ b/core/src/main/java/com/mapzen/android/graphics/MapzenMap.java @@ -3,11 +3,12 @@ import com.mapzen.android.core.MapzenManager; import com.mapzen.android.graphics.internal.StyleStringGenerator; import com.mapzen.android.graphics.model.BitmapMarker; +import com.mapzen.android.graphics.model.BitmapMarkerManager; +import com.mapzen.android.graphics.model.BitmapMarkerOptions; import com.mapzen.android.graphics.model.CameraType; import com.mapzen.android.graphics.model.EaseType; import com.mapzen.android.graphics.model.MapStyle; import com.mapzen.android.graphics.model.Marker; -import com.mapzen.android.graphics.model.MarkerManager; import com.mapzen.android.graphics.model.MarkerOptions; import com.mapzen.android.graphics.model.Polygon; import com.mapzen.android.graphics.model.Polyline; @@ -15,6 +16,7 @@ import com.mapzen.tangram.MapController; import com.mapzen.tangram.MapData; import com.mapzen.tangram.MarkerPickResult; +import com.mapzen.tangram.SceneError; import com.mapzen.tangram.SceneUpdate; import com.mapzen.tangram.TouchInput; @@ -48,7 +50,7 @@ public class MapzenMap { private final OverlayManager overlayManager; private final MapStateManager mapStateManager; private final LabelPickHandler labelPickHandler; - private final MarkerManager markerManager; + private final BitmapMarkerManager bitmapMarkerManager; private final SceneUpdateManager sceneUpdateManager; private final MapzenManager mapzenManager; private Locale locale; @@ -138,19 +140,27 @@ public boolean onRotate(float x, float y, float rotation) { } }; + MapController.SceneLoadListener internalSceneLoadListener + = new MapController.SceneLoadListener() { + @Override public void onSceneReady(int sceneId, SceneError sceneError) { + bitmapMarkerManager.restoreMarkers(); + } + }; + /** * Creates a new map based on the given {@link MapView} and {@link MapController}. */ MapzenMap(MapView mapView, MapController mapController, OverlayManager overlayManager, MapStateManager mapStateManager, LabelPickHandler labelPickHandler, - MarkerManager markerManager, SceneUpdateManager sceneUpdateManager, Locale locale, + BitmapMarkerManager bitmapMarkerManager, SceneUpdateManager sceneUpdateManager, Locale locale, MapzenManager mapzenManager) { this.mapView = mapView; this.mapController = mapController; + this.mapController.setSceneLoadListener(internalSceneLoadListener); this.overlayManager = overlayManager; this.mapStateManager = mapStateManager; this.labelPickHandler = labelPickHandler; - this.markerManager = markerManager; + this.bitmapMarkerManager = bitmapMarkerManager; this.sceneUpdateManager = sceneUpdateManager; this.locale = locale; this.mapzenManager = mapzenManager; @@ -646,8 +656,8 @@ public void onMarkerPick(final MarkerPickResult markerPickResult, final float po mapView.post(new Runnable() { @Override public void run() { if (markerPickResult != null) { - listener.onMarkerPick(new BitmapMarker(markerManager, markerPickResult.getMarker(), - new StyleStringGenerator())); + listener.onMarkerPick(new BitmapMarker(bitmapMarkerManager, + markerPickResult.getMarker(), new StyleStringGenerator())); } } }); @@ -954,7 +964,18 @@ void onDestroy() { * @param markerOptions options used to define marker appearance. * @return a new bitmap marker instance. */ + @Deprecated public BitmapMarker addBitmapMarker(MarkerOptions markerOptions) { - return markerManager.addMarker(markerOptions); + return bitmapMarkerManager.addMarker(markerOptions); + } + + /** + * Adds a custom bitmap marker to the map. + * + * @param markerOptions options used to define marker appearance. + * @return a new bitmap marker instance. + */ + public BitmapMarker addBitmapMarker(BitmapMarkerOptions markerOptions) { + return bitmapMarkerManager.addMarker(markerOptions); } } diff --git a/core/src/main/java/com/mapzen/android/graphics/internal/StyleStringGenerator.java b/core/src/main/java/com/mapzen/android/graphics/internal/StyleStringGenerator.java index 36bb5d3d..ab705ca8 100644 --- a/core/src/main/java/com/mapzen/android/graphics/internal/StyleStringGenerator.java +++ b/core/src/main/java/com/mapzen/android/graphics/internal/StyleStringGenerator.java @@ -7,42 +7,11 @@ */ public class StyleStringGenerator { - private int width = 50; - private int height = 50; - private boolean interactive = true; - private String colorHex = "#FFFFFF"; - - /** - * Set the width and height in pixels. - * @param width - * @param height - */ - public void setSize(int width, int height) { - this.width = width; - this.height = height; - } - - /** - * Set whether or not the marker can be selected. - * @param interactive - */ - public void setInteractive(boolean interactive) { - this.interactive = interactive; - } - - /** - * Sets the hex value for color to be used. - * @param hex - */ - public void setColor(String hex) { - this.colorHex = hex; - } - /** * Return the style string given the current property configurations. * @return */ - public String getStyleString() { + public String getStyleString(int width, int height, boolean interactive, String colorHex) { return new StringBuilder() .append("{ style: 'points', color: '") .append(colorHex) diff --git a/core/src/main/java/com/mapzen/android/graphics/model/BitmapMarker.java b/core/src/main/java/com/mapzen/android/graphics/model/BitmapMarker.java index 3c0c2cd9..953a3065 100644 --- a/core/src/main/java/com/mapzen/android/graphics/model/BitmapMarker.java +++ b/core/src/main/java/com/mapzen/android/graphics/model/BitmapMarker.java @@ -12,18 +12,28 @@ */ public class BitmapMarker { - private final MarkerManager markerManager; - private final Marker tangramMarker; + private final BitmapMarkerManager bitmapMarkerManager; + private Marker tangramMarker; private final StyleStringGenerator styleStringGenerator; + private LngLat position; + private int resourceId; + private Drawable drawable; + private int width; + private int height; + private boolean isVisible; + private int drawOrder; + private int colorInt; + private String colorHex; + private boolean isInteractive; /** * Constructor that wraps a Tangram marker. * * @param tangramMarker the underlying Tangram marker object. */ - public BitmapMarker(MarkerManager markerManager, Marker tangramMarker, + public BitmapMarker(BitmapMarkerManager bitmapMarkerManager, Marker tangramMarker, StyleStringGenerator styleStringGenerator) { - this.markerManager = markerManager; + this.bitmapMarkerManager = bitmapMarkerManager; this.tangramMarker = tangramMarker; this.styleStringGenerator = styleStringGenerator; } @@ -33,7 +43,7 @@ public BitmapMarker(MarkerManager markerManager, Marker tangramMarker, * methods is undefined. */ public void remove() { - markerManager.removeMarker(tangramMarker); + bitmapMarkerManager.removeMarker(this); } /** @@ -41,6 +51,7 @@ public void remove() { * @param position */ public void setPosition(LngLat position) { + this.position = position; this.tangramMarker.setPoint(position); } @@ -51,52 +62,118 @@ public void setPosition(LngLat position) { * @param easeType */ public void setPosition(LngLat position, int duration, EaseType easeType) { + this.position = position; this.tangramMarker.setPointEased(position, duration, EaseTypeConverter.EASE_TYPE_TO_MAP_CONTROLLER_EASE_TYPE.get(easeType)); } /** - * Sets the drawable resource id displayed as the marker's icon. + * Returns the marker's coordinate position. + * @return + */ + public LngLat getPosition() { + return this.position; + } + + /** + * Sets the drawable resource id displayed as the marker's icon. Setting this value will override + * existing icon drawable values set via {@link BitmapMarker#setIcon(Drawable)}. * @param resourceId */ public void setIcon(int resourceId) { + this.resourceId = resourceId; + this.drawable = null; this.tangramMarker.setDrawable(resourceId); } /** - * Sets the drawable displayed as the marker's icon. + * Returns the marker's icon resource id. + * @return + */ + public int getIcon() { + return this.resourceId; + } + + /** + * Sets the drawable displayed as the marker's icon. Setting this value will override existing + * icon resource id values set via {@link BitmapMarker#setIcon(int)}. * @param drawable */ public void setIcon(Drawable drawable) { + this.resourceId = Integer.MIN_VALUE; + this.drawable = drawable; this.tangramMarker.setDrawable(drawable); } + /** + * Returns the marker's icon drawable. + * @return + */ + public Drawable getIconDrawable() { + return this.drawable; + } + /** * Sets the width and height in pixels for the marker's size. * @param width * @param height */ public void setSize(int width, int height) { - styleStringGenerator.setSize(width, height); + this.width = width; + this.height = height; updateStyleString(); } + /** + * Returns the marker's width in pixels. + * @return + */ + public int getWidth() { + return this.width; + } + + /** + * Returns the marker's height in pixels. + * @return + */ + public int getHeight() { + return this.height; + } + /** * Sets the marker's visibility. * @param visible */ public void setVisible(boolean visible) { + this.isVisible = visible; tangramMarker.setVisible(visible); } + /** + * Returns whether the marker is visible. + * @return + */ + public boolean isVisible() { + return isVisible; + } + /** * Sets marker z-axis draw order. * @param drawOrder */ public void setDrawOrder(int drawOrder) { + this.drawOrder = drawOrder; this.tangramMarker.setDrawOrder(drawOrder); } + /** + * Returns the marker's z-axis draw order. + * @return + */ + public int getDrawOrder() { + return this.drawOrder; + } + /** * Sets extra data to be associated with this marker. * @param userData @@ -114,35 +191,87 @@ public Object getUserData() { } /** - * Sets color of marker given a color int ie {@code android.graphics.Color.BLUE}. + * Sets color of marker given a color int ie {@code android.graphics.Color.BLUE}. Setting this + * value will override existing color hex values set via {@link BitmapMarker#setColor(String)}. * @param colorInt */ public void setColor(int colorInt) { - String hex = "#" + Integer.toHexString(colorInt); - styleStringGenerator.setColor(hex); + this.colorInt = colorInt; + this.colorHex = "#" + Integer.toHexString(colorInt); updateStyleString(); } /** - * Sets color of marker given a color hex string. + * Returns the marker's color int. + * @return + */ + public int getColor() { + return this.colorInt; + } + + /** + * Sets color of marker given a color hex string. Setting this value will override existing + * color int values set via {@link BitmapMarker#setColor(int)}. * @param hex */ public void setColor(String hex) { - styleStringGenerator.setColor(hex); + this.colorHex = hex; + this.colorInt = Integer.MIN_VALUE; updateStyleString(); } + /** + * Returns the marker's color hex. + * @return + */ + public String getColorHex() { + return this.colorHex; + } + /** * Sets whether or not marker can be selected. * @param interactive */ public void setInteractive(boolean interactive) { - styleStringGenerator.setInteractive(interactive); + this.isInteractive = interactive; updateStyleString(); } + /** + * Returns whether or not the marker responds to touches. + * @return + */ + public boolean isInteractive() { + return this.isInteractive; + } + + /** + * Allows setting the tangram marker, useful when restoring markers. + * @param tangramMarker + */ + void setTangramMarker(Marker tangramMarker) { + this.tangramMarker = tangramMarker; + } + + /** + * Returns the underlying Tangram {@link Marker}. + * @return + */ + Marker getTangramMarker() { + return tangramMarker; + } + + /** + * Returns the object used to generate style string. + * @return + */ + StyleStringGenerator getStyleStringGenerator() { + return styleStringGenerator; + } + private void updateStyleString() { - tangramMarker.setStylingFromString(styleStringGenerator.getStyleString()); + tangramMarker.setStylingFromString(styleStringGenerator.getStyleString(width, height, + isInteractive, colorHex)); } } diff --git a/core/src/main/java/com/mapzen/android/graphics/model/BitmapMarkerFactory.java b/core/src/main/java/com/mapzen/android/graphics/model/BitmapMarkerFactory.java new file mode 100644 index 00000000..53a0df33 --- /dev/null +++ b/core/src/main/java/com/mapzen/android/graphics/model/BitmapMarkerFactory.java @@ -0,0 +1,21 @@ +package com.mapzen.android.graphics.model; + +import com.mapzen.android.graphics.internal.StyleStringGenerator; + +/** + * Creates {@link BitmapMarker} objects. + */ +public class BitmapMarkerFactory { + + /** + * Creates new {@link BitmapMarker} with the given parameters. + * @param manager + * @param marker + * @param styleStringGenerator + * @return + */ + BitmapMarker createMarker(BitmapMarkerManager manager, com.mapzen.tangram.Marker marker, + StyleStringGenerator styleStringGenerator) { + return new BitmapMarker(manager, marker, styleStringGenerator); + } +} diff --git a/core/src/main/java/com/mapzen/android/graphics/model/BitmapMarkerManager.java b/core/src/main/java/com/mapzen/android/graphics/model/BitmapMarkerManager.java new file mode 100644 index 00000000..092b4343 --- /dev/null +++ b/core/src/main/java/com/mapzen/android/graphics/model/BitmapMarkerManager.java @@ -0,0 +1,141 @@ +package com.mapzen.android.graphics.model; + +import com.mapzen.android.graphics.internal.StyleStringGenerator; +import com.mapzen.tangram.LngLat; +import com.mapzen.tangram.MapController; +import com.mapzen.tangram.Marker; + +import android.graphics.drawable.Drawable; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Manages {@link BitmapMarker} instances on the map. + */ +public class BitmapMarkerManager { + private MapController mapController; + private final BitmapMarkerFactory bitmapMarkerFactory; + private final StyleStringGenerator styleStringGenerator; + private List restorableMarkers; + + /** + * Constructor. + */ + public BitmapMarkerManager(BitmapMarkerFactory bitmapMarkerFactory, + StyleStringGenerator styleStringGenerator) { + this.bitmapMarkerFactory = bitmapMarkerFactory; + this.styleStringGenerator = styleStringGenerator; + this.restorableMarkers = new ArrayList<>(); + } + + /** + * Sets the manager's tangram map. Reset upon orientation changes. + * @param mapController + */ + public void setMapController(MapController mapController) { + this.mapController = mapController; + } + + /** + * Adds a new marker to the map. + * + * Deprecated in favor of {@link BitmapMarkerManager#addMarker(BitmapMarkerOptions)}. + * + * @param markerOptions options that define the appearance of the marker. + * @return a new bitmap marker wrapper for the Tangram marker object. + */ + @Deprecated + public BitmapMarker addMarker(MarkerOptions markerOptions) { + final Marker marker = mapController.addMarker(); + BitmapMarker bitmapMarker = bitmapMarkerFactory.createMarker(this, marker, + styleStringGenerator); + configureMarker(bitmapMarker, markerOptions); + Collections.synchronizedList(restorableMarkers).add(bitmapMarker); + return bitmapMarker; + } + + /** + * Adds a new marker to the map. + * + * @param markerOptions options that define the appearance of the marker. + * @return a new bitmap marker wrapper for the Tangram marker object. + */ + public BitmapMarker addMarker(BitmapMarkerOptions markerOptions) { + final Marker marker = mapController.addMarker(); + BitmapMarker bitmapMarker = bitmapMarkerFactory.createMarker(this, marker, + styleStringGenerator); + configureMarker(bitmapMarker, markerOptions); + Collections.synchronizedList(restorableMarkers).add(bitmapMarker); + return bitmapMarker; + } + + /** + * Removes a marker from the map. + * + * @param marker Tangram marker to be removed. + */ + public void removeMarker(BitmapMarker marker) { + Collections.synchronizedList(restorableMarkers).remove(marker); + mapController.removeMarker(marker.getTangramMarker()); + } + + /** + * Restores underlying Tangram marker for all {@link BitmapMarker}s when scene updates occur. + */ + public void restoreMarkers() { + for (BitmapMarker restorableMarker : Collections.synchronizedList(restorableMarkers)) { + Marker tangramMarker = mapController.addMarker(); + restorableMarker.setTangramMarker(tangramMarker); + configureMarker(restorableMarker); + } + } + + private void configureMarker(BitmapMarker bitmapMarker) { + configureMarker(bitmapMarker, bitmapMarker.getPosition(), + bitmapMarker.getIconDrawable(), bitmapMarker.getIcon(), + bitmapMarker.getWidth(), bitmapMarker.getHeight(), + bitmapMarker.isInteractive(), bitmapMarker.getColorHex(), + bitmapMarker.getColor(), bitmapMarker.isVisible(), + bitmapMarker.getDrawOrder(), bitmapMarker.getUserData()); + } + + private void configureMarker(BitmapMarker bitmapMarker, BitmapMarkerOptions markerOptions) { + configureMarker(bitmapMarker, markerOptions.getPosition(), markerOptions.getIconDrawable(), + markerOptions.getIcon(), markerOptions.getWidth(), + markerOptions.getHeight(), markerOptions.isInteractive(), markerOptions.getColorHex(), + markerOptions.getColorInt(), markerOptions.isVisible(), markerOptions.getDrawOrder(), + markerOptions.getUserData()); + } + + @Deprecated + private void configureMarker(BitmapMarker bitmapMarker, MarkerOptions markerOptions) { + configureMarker(bitmapMarker, markerOptions.getPosition(), markerOptions.getIconDrawable(), + markerOptions.getIcon(), markerOptions.getWidth(), + markerOptions.getHeight(), markerOptions.isInteractive(), markerOptions.getColorHex(), + markerOptions.getColorInt(), markerOptions.isVisible(), markerOptions.getDrawOrder(), + markerOptions.getUserData()); + } + + private void configureMarker(BitmapMarker marker, LngLat position, Drawable drawable, + int drawableId, int width, int height, boolean interactive, String colorHex, int colorInt, + boolean visible, int drawOrder, Object userData) { + marker.setPosition(position); + if (drawable != null) { + marker.setIcon(drawable); + } else { + marker.setIcon(drawableId); + } + marker.setVisible(visible); + marker.setDrawOrder(drawOrder); + marker.setUserData(userData); + if (colorHex != null) { + marker.setColor(colorHex); + } else { + marker.setColor(colorInt); + } + marker.setSize(width, height); + marker.setInteractive(interactive); + } +} diff --git a/core/src/main/java/com/mapzen/android/graphics/model/BitmapMarkerOptions.java b/core/src/main/java/com/mapzen/android/graphics/model/BitmapMarkerOptions.java new file mode 100644 index 00000000..e9afb8a4 --- /dev/null +++ b/core/src/main/java/com/mapzen/android/graphics/model/BitmapMarkerOptions.java @@ -0,0 +1,189 @@ +package com.mapzen.android.graphics.model; + +import com.mapzen.R; +import com.mapzen.tangram.LngLat; + +import android.graphics.drawable.Drawable; + +/** + * Defines options for a {@link BitmapMarker}. + */ +public class BitmapMarkerOptions { + private static final LngLat DEFAULT_POSITION = new LngLat(-73.985428, 40.748817); + private static final int DEFAULT_DRAWABLE = R.drawable.mapzen; + private static final int DEFAULT_WIDTH = 50; + private static final int DEFAULT_HEIGHT = 50; + private static final int RES_NONE = Integer.MIN_VALUE; + + private LngLat position = DEFAULT_POSITION; + private int resId = DEFAULT_DRAWABLE; + private Drawable res = null; + private int width = DEFAULT_WIDTH; + private int height = DEFAULT_HEIGHT; + private boolean isVisible = true; + private int drawOrder = 1; + private Object userData; + private int colorInt = Integer.MIN_VALUE; + private String colorHex = "#fff"; + private boolean isInteractive = true; + + // Setters + + /** + * Set the marker position. + * + * @param position coordinate to display the marker. + * @return this marker options instance. + */ + public BitmapMarkerOptions position(LngLat position) { + this.position = position; + return this; + } + + /** + * Set the marker icon resource ID. Setting this property will override previously set resource + * ids set in the call to {@link BitmapMarkerOptions#icon(Drawable)}. + * + * @param resId drawable resource ID for the marker to display. + * @return this marker options instance. + */ + public BitmapMarkerOptions icon(int resId) { + this.resId = resId; + this.res = null; + return this; + } + + /** + * Set the marker icon resource. Setting this property will override previously set resource ids + * set in the call to {@link BitmapMarkerOptions#icon(int)}. + * + * @param res drawable resource for the marker to display. + * @return this marker options instance. + */ + public BitmapMarkerOptions icon(Drawable res) { + this.res = res; + this.resId = RES_NONE; + return this; + } + + /** + * Set the marker size. + * + * @param width in pixels + * @param height in pixels + * @return this marker options instance. + */ + public BitmapMarkerOptions size(int width, int height) { + this.width = width; + this.height = height; + return this; + } + + /** + * Sets the marker visibility. + * @param isVisible + * @return + */ + public BitmapMarkerOptions visible(boolean isVisible) { + this.isVisible = isVisible; + return this; + } + + /** + * Sets marker z-axis draw order. + */ + public BitmapMarkerOptions drawOrder(int drawOrder) { + this.drawOrder = drawOrder; + return this; + } + + /** + * Sets extra data to be associated with the marker. + * @param userData + * @return + */ + public BitmapMarkerOptions userData(Object userData) { + this.userData = userData; + return this; + } + + /** + * Sets color resource int. Setting the color in overrides previous set color hex values set via + * {@link BitmapMarkerOptions#colorHex(String)}. + * @param colorInt + * @return + */ + public BitmapMarkerOptions colorInt(int colorInt) { + this.colorInt = colorInt; + this.colorHex = null; + return this; + } + + /** + * Sets color hex value. Setting the color in overrides previous set color int values set via + * {@link BitmapMarkerOptions#colorInt(int)}. + * @param colorHex + * @return + */ + public BitmapMarkerOptions colorHex(String colorHex) { + this.colorHex = colorHex; + this.colorInt = Integer.MIN_VALUE; + return this; + } + + /** + * Sets whether or not the marker is interactive. + * @param isInteractive + * @return + */ + public BitmapMarkerOptions interactive(boolean isInteractive) { + this.isInteractive = isInteractive; + return this; + } + + // Getters + + public LngLat getPosition() { + return position; + } + + public int getIcon() { + return resId; + } + + public Drawable getIconDrawable() { + return res; + } + + public int getWidth() { + return width; + } + + public int getHeight() { + return height; + } + + public boolean isVisible() { + return isVisible; + } + + public int getDrawOrder() { + return drawOrder; + } + + public Object getUserData() { + return userData; + } + + public int getColorInt() { + return colorInt; + } + + public String getColorHex() { + return colorHex; + } + + public boolean isInteractive() { + return isInteractive; + } +} diff --git a/core/src/main/java/com/mapzen/android/graphics/model/MarkerManager.java b/core/src/main/java/com/mapzen/android/graphics/model/MarkerManager.java deleted file mode 100644 index 35843e5b..00000000 --- a/core/src/main/java/com/mapzen/android/graphics/model/MarkerManager.java +++ /dev/null @@ -1,50 +0,0 @@ -package com.mapzen.android.graphics.model; - -import com.mapzen.android.graphics.internal.StyleStringGenerator; -import com.mapzen.tangram.MapController; -import com.mapzen.tangram.Marker; - -/** - * Manages {@link BitmapMarker} instances on the map. - */ -public class MarkerManager { - private final MapController mapController; - - /** - * Constructor. - * - * @param mapController Tangram map controller used to generate markers. - */ - public MarkerManager(MapController mapController) { - this.mapController = mapController; - } - - /** - * Adds a new marker to the map. - * - * @param markerOptions options that define the appearance of the marker. - * @return a new bitmap marker wrapper for the Tangram marker object. - */ - public BitmapMarker addMarker(MarkerOptions markerOptions) { - final Marker marker = mapController.addMarker(); - marker.setPoint(markerOptions.getPosition()); - if (markerOptions.getIconDrawable() != null) { - marker.setDrawable(markerOptions.getIconDrawable()); - } else { - marker.setDrawable(markerOptions.getIcon()); - } - StyleStringGenerator styleStringGenerator = new StyleStringGenerator(); - styleStringGenerator.setSize(markerOptions.getWidth(), markerOptions.getHeight()); - marker.setStylingFromString(styleStringGenerator.getStyleString()); - return new BitmapMarker(this, marker, styleStringGenerator); - } - - /** - * Removes a marker from the map. - * - * @param marker Tangram marker to be removed. - */ - public void removeMarker(Marker marker) { - mapController.removeMarker(marker); - } -} diff --git a/core/src/main/java/com/mapzen/android/graphics/model/MarkerOptions.java b/core/src/main/java/com/mapzen/android/graphics/model/MarkerOptions.java index 7aca7a23..ec1f3fb0 100644 --- a/core/src/main/java/com/mapzen/android/graphics/model/MarkerOptions.java +++ b/core/src/main/java/com/mapzen/android/graphics/model/MarkerOptions.java @@ -5,9 +5,15 @@ import android.graphics.drawable.Drawable; + /** * Defines options for a {@link BitmapMarker}. + * + * This class has been deprecated in favor of + * {@link com.mapzen.android.graphics.model.BitmapMarkerOptions} which replaces this class' + * behavior exactly. */ +@Deprecated public class MarkerOptions { private static final LngLat DEFAULT_POSITION = new LngLat(-73.985428, 40.748817); private static final int DEFAULT_DRAWABLE = R.drawable.mapzen; @@ -20,6 +26,12 @@ public class MarkerOptions { private Drawable res = null; private int width = DEFAULT_WIDTH; private int height = DEFAULT_HEIGHT; + private boolean isVisible = true; + private int drawOrder = 1; + private Object userData; + private int colorInt = Integer.MIN_VALUE; + private String colorHex = "#fff"; + private boolean isInteractive = true; // Setters @@ -73,6 +85,68 @@ public MarkerOptions size(int width, int height) { return this; } + /** + * Sets the marker visibility. + * @param isVisible + * @return + */ + public MarkerOptions visible(boolean isVisible) { + this.isVisible = isVisible; + return this; + } + + /** + * Sets marker z-axis draw order. + */ + public MarkerOptions drawOrder(int drawOrder) { + this.drawOrder = drawOrder; + return this; + } + + /** + * Sets extra data to be associated with the marker. + * @param userData + * @return + */ + public MarkerOptions userData(Object userData) { + this.userData = userData; + return this; + } + + /** + * Sets color resource int. Setting the color in overrides previous set color hex values set via + * {@link MarkerOptions#colorHex(String)}. + * @param colorInt + * @return + */ + public MarkerOptions colorInt(int colorInt) { + this.colorInt = colorInt; + this.colorHex = null; + return this; + } + + /** + * Sets color hex value. Setting the color in overrides previous set color int values set via + * {@link MarkerOptions#colorInt(int)}. + * @param colorHex + * @return + */ + public MarkerOptions colorHex(String colorHex) { + this.colorHex = colorHex; + this.colorInt = Integer.MIN_VALUE; + return this; + } + + /** + * Sets whether or not the marker is interactive. + * @param isInteractive + * @return + */ + public MarkerOptions interactive(boolean isInteractive) { + this.isInteractive = isInteractive; + return this; + } + // Getters public LngLat getPosition() { @@ -94,4 +168,28 @@ public int getWidth() { public int getHeight() { return height; } + + public boolean isVisible() { + return isVisible; + } + + public int getDrawOrder() { + return drawOrder; + } + + public Object getUserData() { + return userData; + } + + public int getColorInt() { + return colorInt; + } + + public String getColorHex() { + return colorHex; + } + + public boolean isInteractive() { + return isInteractive; + } } diff --git a/core/src/test/java/com/mapzen/android/graphics/MapInitializerTest.java b/core/src/test/java/com/mapzen/android/graphics/MapInitializerTest.java index 4cbde527..1c35b7a6 100644 --- a/core/src/test/java/com/mapzen/android/graphics/MapInitializerTest.java +++ b/core/src/test/java/com/mapzen/android/graphics/MapInitializerTest.java @@ -3,6 +3,7 @@ import com.mapzen.android.core.CoreDI; import com.mapzen.android.core.MapzenManager; import com.mapzen.android.graphics.model.BubbleWrapStyle; +import com.mapzen.android.graphics.model.BitmapMarkerManager; import com.mapzen.tangram.MapController; import com.mapzen.tangram.SceneUpdate; @@ -42,7 +43,8 @@ public class MapInitializerTest { @Before public void setUp() throws Exception { CoreDI.init(getMockContext()); mapInitializer = new MapInitializer(mock(Context.class), mock(MapzenMapHttpHandler.class), - new MapDataManager(), new MapStateManager(), new SceneUpdateManager()); + new MapDataManager(), new MapStateManager(), new SceneUpdateManager(), + new BitmapMarkerManager(null, null)); } @Test public void shouldNotBeNull() throws Exception { diff --git a/core/src/test/java/com/mapzen/android/graphics/MapReadyInitializerTest.java b/core/src/test/java/com/mapzen/android/graphics/MapReadyInitializerTest.java index 0fd5b6e3..199a902d 100644 --- a/core/src/test/java/com/mapzen/android/graphics/MapReadyInitializerTest.java +++ b/core/src/test/java/com/mapzen/android/graphics/MapReadyInitializerTest.java @@ -1,5 +1,6 @@ package com.mapzen.android.graphics; +import com.mapzen.android.graphics.model.BitmapMarkerManager; import com.mapzen.tangram.HttpHandler; import com.mapzen.tangram.MapController; @@ -37,7 +38,7 @@ public class MapReadyInitializerTest { mapController); initializer.onMapReady(mapView, mock(MapzenMapHttpHandler.class), mock(OnMapReadyCallback.class), mock(MapDataManager.class), mock(MapStateManager.class), - mock(SceneUpdateManager.class), new Locale("en_us")); + mock(SceneUpdateManager.class), new Locale("en_us"), mock(BitmapMarkerManager.class)); verify(mapController).setSceneLoadListener(null); } @@ -56,7 +57,7 @@ public class MapReadyInitializerTest { when(mapzenHttpHandler.httpHandler()).thenReturn(httpHandler); initializer.onMapReady(mapView, mapzenHttpHandler, mock(OnMapReadyCallback.class), mock(MapDataManager.class), mock(MapStateManager.class), - mock(SceneUpdateManager.class), new Locale("en_us")); + mock(SceneUpdateManager.class), new Locale("en_us"), mock(BitmapMarkerManager.class)); verify(mapController).setHttpHandler(httpHandler); } @@ -73,7 +74,7 @@ public class MapReadyInitializerTest { OnMapReadyCallback callback = mock(OnMapReadyCallback.class); initializer.onMapReady(mapView, mock(MapzenMapHttpHandler.class), callback, mock(MapDataManager.class), mock(MapStateManager.class), - mock(SceneUpdateManager.class), new Locale("en_us")); + mock(SceneUpdateManager.class), new Locale("en_us"), mock(BitmapMarkerManager.class)); verify(callback).onMapReady(any(MapzenMap.class)); } } diff --git a/core/src/test/java/com/mapzen/android/graphics/MapzenMapTest.java b/core/src/test/java/com/mapzen/android/graphics/MapzenMapTest.java index f19697b3..98adec81 100644 --- a/core/src/test/java/com/mapzen/android/graphics/MapzenMapTest.java +++ b/core/src/test/java/com/mapzen/android/graphics/MapzenMapTest.java @@ -2,11 +2,11 @@ import com.mapzen.android.core.MapzenManager; import com.mapzen.android.graphics.model.BitmapMarker; +import com.mapzen.android.graphics.model.BitmapMarkerManager; import com.mapzen.android.graphics.model.BubbleWrapStyle; import com.mapzen.android.graphics.model.CameraType; import com.mapzen.android.graphics.model.EaseType; import com.mapzen.android.graphics.model.Marker; -import com.mapzen.android.graphics.model.MarkerManager; import com.mapzen.android.graphics.model.Polygon; import com.mapzen.android.graphics.model.Polyline; import com.mapzen.android.graphics.model.WalkaboutStyle; @@ -60,7 +60,7 @@ public class MapzenMapTest { private OverlayManager overlayManager; private LabelPickHandler labelPickHandler; private MapStateManager mapStateManager; - private MarkerManager markerManager; + private BitmapMarkerManager bitmapMarkerManager; private SceneUpdateManager sceneUpdateManager; private Locale locale; private MapzenManager mapzenManager; @@ -85,12 +85,12 @@ public class MapzenMapTest { overlayManager = mock(OverlayManager.class); mapStateManager = new MapStateManager(); labelPickHandler = new LabelPickHandler(mapView); - markerManager = new MarkerManager(mapController); + bitmapMarkerManager = mock(BitmapMarkerManager.class); sceneUpdateManager = new SceneUpdateManager(); locale = new Locale("en_us"); mapzenManager = mock(MapzenManager.class); map = new MapzenMap(mapView, mapController, overlayManager, mapStateManager, labelPickHandler, - markerManager, sceneUpdateManager, locale, mapzenManager); + bitmapMarkerManager, sceneUpdateManager, locale, mapzenManager); } @Test public void shouldNotBeNull() throws Exception { @@ -704,6 +704,11 @@ public void applySceneUpdates_shouldClearQueuedUpdates() throws Exception { verify(mapController).updateSceneAsync(argThat(new SceneUpdatesMatcher(sceneUpdates))); } + @Test public void onSceneReady_restoresMarkers() throws Exception { + map.internalSceneLoadListener.onSceneReady(1, null); + verify(bitmapMarkerManager).restoreMarkers(); + } + public class TestRotateResponder implements TouchInput.RotateResponder { boolean rotated = false; diff --git a/core/src/test/java/com/mapzen/android/graphics/TestMapView.java b/core/src/test/java/com/mapzen/android/graphics/TestMapView.java index 5b7af05e..10c4725a 100644 --- a/core/src/test/java/com/mapzen/android/graphics/TestMapView.java +++ b/core/src/test/java/com/mapzen/android/graphics/TestMapView.java @@ -2,7 +2,7 @@ import com.mapzen.android.core.MapzenManager; import com.mapzen.android.graphics.model.MapStyle; -import com.mapzen.android.graphics.model.MarkerManager; +import com.mapzen.android.graphics.model.BitmapMarkerManager; import com.mapzen.tangram.MapController; import android.content.Context; @@ -28,14 +28,14 @@ public class TestMapView extends MapView { @Override public void getMapAsync(@NonNull OnMapReadyCallback callback) { callback.onMapReady(new MapzenMap(mock(MapView.class), mock(MapController.class), mock(OverlayManager.class), mock(MapStateManager.class), mock(LabelPickHandler.class), - mock(MarkerManager.class), mock(SceneUpdateManager.class), new Locale("en_us"), mock( + mock(BitmapMarkerManager.class), mock(SceneUpdateManager.class), new Locale("en_us"), mock( MapzenManager.class))); } @Override public void getMapAsync(MapStyle mapStyle, @NonNull OnMapReadyCallback callback) { callback.onMapReady(new MapzenMap(mock(MapView.class), mock(MapController.class), mock(OverlayManager.class), mock(MapStateManager.class), mock(LabelPickHandler.class), - mock(MarkerManager.class), mock(SceneUpdateManager.class), new Locale("en_us"), mock( + mock(BitmapMarkerManager.class), mock(SceneUpdateManager.class), new Locale("en_us"), mock( MapzenManager.class))); } diff --git a/core/src/test/java/com/mapzen/android/graphics/internal/StyleStringGeneratorTest.java b/core/src/test/java/com/mapzen/android/graphics/internal/StyleStringGeneratorTest.java index b7218df6..98f6f2ce 100644 --- a/core/src/test/java/com/mapzen/android/graphics/internal/StyleStringGeneratorTest.java +++ b/core/src/test/java/com/mapzen/android/graphics/internal/StyleStringGeneratorTest.java @@ -9,25 +9,8 @@ public class StyleStringGeneratorTest { private StyleStringGenerator generator = new StyleStringGenerator(); @Test public void defaultStyleString() throws Exception { - assertThat(generator.getStyleString()).isEqualTo("{ style: 'points', color: '#FFFFFF', " - + "size: [50px, 50px], collide: false, interactive: true }"); + assertThat(generator.getStyleString(50, 50, true, "#FFFFFF")).isEqualTo("{ style: 'points', " + + "color: '#FFFFFF', size: [50px, 50px], collide: false, interactive: true }"); } - @Test public void setSize_updatesStyleString() throws Exception { - generator.setSize(10, 10); - assertThat(generator.getStyleString()).isEqualTo("{ style: 'points', color: '#FFFFFF', " - + "size: [10px, 10px], collide: false, interactive: true }"); - } - - @Test public void setInteractive_updatesStyleString() throws Exception { - generator.setInteractive(false); - assertThat(generator.getStyleString()).isEqualTo("{ style: 'points', color: '#FFFFFF', " - + "size: [50px, 50px], collide: false, interactive: false }"); - } - - @Test public void setBackgroundColor_updatesStyleString() throws Exception { - generator.setColor("#0000FF"); - assertThat(generator.getStyleString()).isEqualTo("{ style: 'points', color: '#0000FF', " - + "size: [50px, 50px], collide: false, interactive: true }"); - } } diff --git a/core/src/test/java/com/mapzen/android/graphics/model/BitmapMarkerManagerTest.java b/core/src/test/java/com/mapzen/android/graphics/model/BitmapMarkerManagerTest.java new file mode 100644 index 00000000..16af2786 --- /dev/null +++ b/core/src/test/java/com/mapzen/android/graphics/model/BitmapMarkerManagerTest.java @@ -0,0 +1,207 @@ +package com.mapzen.android.graphics.model; + +import com.mapzen.android.graphics.internal.StyleStringGenerator; +import com.mapzen.tangram.LngLat; +import com.mapzen.tangram.MapController; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; +import org.powermock.modules.junit4.PowerMockRunner; + +import android.graphics.Color; +import android.graphics.drawable.Drawable; + +import java.util.HashMap; +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@SuppressStaticInitializationFor("com.mapzen.tangram.MapController") +public class BitmapMarkerManagerTest { + private MapController mapController = mock(MapController.class); + private com.mapzen.tangram.Marker tangramMarker = mock(com.mapzen.tangram.Marker.class); + private BitmapMarkerFactory markerFactory = mock(BitmapMarkerFactory.class); + private BitmapMarkerManager bitmapMarkerManager = new BitmapMarkerManager(markerFactory, + new StyleStringGenerator()); + + @Before public void setUp() throws Exception { + bitmapMarkerManager.setMapController(mapController); + when(mapController.addMarker()).thenReturn(tangramMarker); + when(markerFactory.createMarker(any(BitmapMarkerManager.class), + any(com.mapzen.tangram.Marker.class), any(StyleStringGenerator.class))).thenReturn( + mock(BitmapMarker.class)); + } + + @Test public void shouldNotBeNull() throws Exception { + assertThat(bitmapMarkerManager).isNotNull(); + } + + @Test public void addMarker_shouldAddMarkerToMapController() throws Exception { + bitmapMarkerManager.addMarker(new MarkerOptions()); + verify(mapController).addMarker(); + } + + @Test public void addMarker_shouldSetPosition() throws Exception { + LngLat lngLat = new LngLat(); + MarkerOptions markerOptions = new MarkerOptions().position(lngLat); + BitmapMarker marker = bitmapMarkerManager.addMarker(markerOptions); + verify(marker).setPosition(lngLat); + } + + @Test public void addMarker_resId_shouldSetDrawable() throws Exception { + int resId = 123; + MarkerOptions markerOptions = new MarkerOptions().icon(resId); + BitmapMarker marker = bitmapMarkerManager.addMarker(markerOptions); + verify(marker).setIcon(resId); + verify(marker, never()).setIcon(any(Drawable.class)); + } + + @Test public void addMarker_res_shouldSetDrawable() throws Exception { + Drawable res = mock(Drawable.class); + MarkerOptions markerOptions = new MarkerOptions().icon(res); + BitmapMarker marker = bitmapMarkerManager.addMarker(markerOptions); + verify(marker).setIcon(res); + verify(marker, never()).setIcon(anyInt()); + } + + @Test public void addMarker_shouldSetSize() throws Exception { + MarkerOptions markerOptions = new MarkerOptions().size(100, 100); + BitmapMarker marker = bitmapMarkerManager.addMarker(markerOptions); + verify(marker).setSize(100, 100); + } + + @Test public void addMarker_shouldReturnBitmapMarker() throws Exception { + assertThat(bitmapMarkerManager.addMarker(new MarkerOptions())).isNotNull(); + } + + @Test public void addMarker_shouldSetVisibile() throws Exception { + MarkerOptions markerOptions = new MarkerOptions().visible(false); + BitmapMarker marker = bitmapMarkerManager.addMarker(markerOptions); + verify(marker).setVisible(false); + } + + @Test public void addMarker_shouldSetUserData() throws Exception { + Object data = mock(Object.class); + MarkerOptions markerOptions = new MarkerOptions().userData(data); + BitmapMarker marker = bitmapMarkerManager.addMarker(markerOptions); + verify(marker).setUserData(data); + } + + @Test public void addMarker_shouldSetDrawOrder() throws Exception { + MarkerOptions markerOptions = new MarkerOptions().drawOrder(8); + BitmapMarker marker = bitmapMarkerManager.addMarker(markerOptions); + verify(marker).setDrawOrder(8); + } + + @Test public void addMarker_shouldSetColorHex() throws Exception { + MarkerOptions markerOptions = new MarkerOptions().colorHex("#fff"); + BitmapMarker marker = bitmapMarkerManager.addMarker(markerOptions); + verify(marker).setColor("#fff"); + } + + @Test public void addMarker_shouldSetColorInt() throws Exception { + MarkerOptions markerOptions = new MarkerOptions().colorInt(Color.RED); + BitmapMarker marker = bitmapMarkerManager.addMarker(markerOptions); + verify(marker).setColor(Color.RED); + } + + @Test public void addMarker_shouldSetInteractive() throws Exception { + MarkerOptions markerOptions = new MarkerOptions().interactive(false); + BitmapMarker marker = bitmapMarkerManager.addMarker(markerOptions); + verify(marker).setInteractive(false); + } + + @Test public void restoreMarkers_shouldProperlyRestoreManagedMarkers() throws Exception { + Drawable drawable = mock(Drawable.class); + LngLat point = new LngLat(40, 70); + int width = 10; + int height = 20; + boolean isVisible = true; + int drawOrder = 20; + Map userData = mock(HashMap.class); + String colorHex = "#ff00ff"; + boolean isInteractive = true; + MarkerOptions options = new MarkerOptions() + .icon(drawable) + .position(point) + .size(width, height) + .colorHex(colorHex) + .drawOrder(drawOrder) + .visible(isVisible) + .userData(userData) + .interactive(isInteractive); + BitmapMarker marker = bitmapMarkerManager.addMarker(options); + bitmapMarkerManager.restoreMarkers(); + + verify(marker).setTangramMarker(tangramMarker); + verify(marker).setPosition(point); + verify(marker).setIcon(drawable); + verify(marker).setSize(width, height); + verify(marker).setColor(colorHex); + verify(marker).setInteractive(isInteractive); + verify(marker).setVisible(isVisible); + verify(marker).setDrawOrder(drawOrder); + verify(marker).setUserData(userData); + } + + @Test public void restoreMarkers_shouldProperlyRestoreAllManagedMarkers() throws Exception { + Drawable drawable = mock(Drawable.class); + LngLat point = new LngLat(40, 70); + int width = 10; + int height = 20; + boolean isVisible = true; + int drawOrder = 20; + Map userData = mock(HashMap.class); + int colorInt = Color.BLUE; + boolean isInteractive = true; + MarkerOptions options = new MarkerOptions() + .icon(drawable) + .position(point) + .size(width, height) + .visible(isVisible) + .drawOrder(drawOrder) + .userData(userData) + .colorInt(colorInt) + .interactive(isInteractive); + + BitmapMarker marker = mock(BitmapMarker.class); + when(markerFactory.createMarker(any(BitmapMarkerManager.class), + any(com.mapzen.tangram.Marker.class), any(StyleStringGenerator.class))).thenReturn(marker); + when(marker.getPosition()).thenReturn(point); + when(marker.getIconDrawable()).thenReturn(drawable); + when(marker.getWidth()).thenReturn(width); + when(marker.getHeight()).thenReturn(height); + when(marker.isInteractive()).thenReturn(isInteractive); + when(marker.getColor()).thenReturn(colorInt); + when(marker.isVisible()).thenReturn(isVisible); + when(marker.getDrawOrder()).thenReturn(drawOrder); + when(marker.getUserData()).thenReturn(userData); + + bitmapMarkerManager.addMarker(options); + bitmapMarkerManager.addMarker(options); + bitmapMarkerManager.restoreMarkers(); + + //times(2) 2 markers and 1x 1x when restoring + verify(marker, times(2)).setTangramMarker(tangramMarker); + //times(4) 2 markers and 1x for when adding each marker, 1x when restoring + verify(marker, times(4)).setPosition(point); + verify(marker, times(4)).setIcon(drawable); + verify(marker, times(4)).setSize(width, height); + verify(marker, times(4)).setColor(Color.BLUE); + verify(marker, times(4)).setInteractive(isInteractive); + verify(marker, times(4)).setVisible(isVisible); + verify(marker, times(4)).setDrawOrder(drawOrder); + verify(marker, times(4)).setUserData(userData); + } + +} diff --git a/core/src/test/java/com/mapzen/android/graphics/model/BitmapMarkerOptionsTest.java b/core/src/test/java/com/mapzen/android/graphics/model/BitmapMarkerOptionsTest.java new file mode 100644 index 00000000..dc16ee7d --- /dev/null +++ b/core/src/test/java/com/mapzen/android/graphics/model/BitmapMarkerOptionsTest.java @@ -0,0 +1,67 @@ +package com.mapzen.android.graphics.model; + +import com.mapzen.tangram.LngLat; + +import org.junit.Test; + +import android.graphics.drawable.Drawable; + +import java.util.Map; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + + +public class BitmapMarkerOptionsTest { + + private BitmapMarkerOptions markerOptions = new BitmapMarkerOptions(); + + @Test public void shouldNotBeNull() throws Exception { + assertThat(markerOptions).isNotNull(); + } + + @Test public void shouldSetPosition() throws Exception { + assertThat(markerOptions.position(new LngLat()).getPosition()).isEqualTo(new LngLat()); + } + + @Test public void shouldSetIconAndNullDrawable() throws Exception { + assertThat(markerOptions.icon(123).getIcon()).isEqualTo(123); + assertThat(markerOptions.getIconDrawable()).isNull(); + } + + @Test public void shouldSetIconDrawableAndNullIcon() throws Exception { + Drawable drawable = mock(Drawable.class); + assertThat(markerOptions.icon(drawable).getIconDrawable()).isEqualTo(drawable); + assertThat(markerOptions.getIcon()).isEqualTo(Integer.MIN_VALUE); + } + + @Test public void shouldSetDrawOrder() throws Exception { + assertThat(markerOptions.drawOrder(1).getDrawOrder()).isEqualTo(1); + } + + @Test public void shouldSetUserData() throws Exception { + Map userData = mock(Map.class); + assertThat(markerOptions.userData(userData).getUserData()).isEqualTo(userData); + } + + @Test public void shouldSetColorInt() throws Exception { + assertThat(markerOptions.colorInt(8).getColorInt()).isEqualTo(8); + } + + @Test public void shouldSetColorIntResetColorHex() throws Exception { + markerOptions.colorHex("test"); + markerOptions.colorInt(8); + assertThat(markerOptions.getColorHex()).isNull(); + } + + @Test public void shouldSetColorHex() throws Exception { + assertThat(markerOptions.colorHex("asdf").getColorHex()).isEqualTo("asdf"); + } + + @Test public void shouldSetColorHexResetColorInt() throws Exception { + markerOptions.colorInt(10); + markerOptions.colorHex("asdf"); + assertThat(markerOptions.getColorInt()).isEqualTo(Integer.MIN_VALUE); + } +} + diff --git a/core/src/test/java/com/mapzen/android/graphics/model/BitmapMarkerTest.java b/core/src/test/java/com/mapzen/android/graphics/model/BitmapMarkerTest.java index 6c2e4565..a30c0a55 100644 --- a/core/src/test/java/com/mapzen/android/graphics/model/BitmapMarkerTest.java +++ b/core/src/test/java/com/mapzen/android/graphics/model/BitmapMarkerTest.java @@ -5,6 +5,7 @@ import com.mapzen.tangram.MapController; import com.mapzen.tangram.Marker; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; @@ -16,6 +17,7 @@ import java.util.HashMap; import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -24,11 +26,16 @@ public class BitmapMarkerTest { private Marker tangramMarker = mock(Marker.class); private MapController mapController = mock(MapController.class); - private MarkerManager markerManager = new MarkerManager(mapController); + private BitmapMarkerManager bitmapMarkerManager = new BitmapMarkerManager( + new BitmapMarkerFactory(), new StyleStringGenerator()); private StyleStringGenerator styleStringGenerator = mock(StyleStringGenerator.class); - private BitmapMarker bitmapMarker = new BitmapMarker(markerManager, tangramMarker, + private BitmapMarker bitmapMarker = new BitmapMarker(bitmapMarkerManager, tangramMarker, styleStringGenerator); + @Before public void setup() throws Exception { + bitmapMarkerManager.setMapController(mapController); + } + @Test public void shouldNotBeNull() throws Exception { assertThat(bitmapMarker).isNotNull(); } @@ -44,30 +51,81 @@ public class BitmapMarkerTest { verify(tangramMarker).setPoint(pos); } + @Test public void setPosition_shouldSetPosition() throws Exception { + LngLat pos = new LngLat(40, 70); + bitmapMarker.setPosition(pos); + assertThat(bitmapMarker.getPosition()).isEqualTo(pos); + } + @Test public void setPosition_animated_shouldCallTangramMarker() throws Exception { LngLat pos = new LngLat(40, 70); bitmapMarker.setPosition(pos, 1, EaseType.CUBIC); verify(tangramMarker).setPointEased(pos, 1, MapController.EaseType.CUBIC); } + @Test public void setPosition_animated_shouldSetPosition() throws Exception { + LngLat pos = new LngLat(40, 70); + bitmapMarker.setPosition(pos, 1, EaseType.CUBIC); + assertThat(bitmapMarker.getPosition()).isEqualTo(pos); + } + @Test public void setIcon_shouldCallTangramMarker() throws Exception { int resId = 1; bitmapMarker.setIcon(resId); verify(tangramMarker).setDrawable(resId); } + @Test public void setIcon_shouldSetIcon() throws Exception { + int resId = 1; + bitmapMarker.setIcon(resId); + assertThat(bitmapMarker.getIcon()).isEqualTo(resId); + } + + @Test public void setIcon_shouldNullIconDrawable() throws Exception { + int resId = 1; + bitmapMarker.setIcon(mock(Drawable.class)); + bitmapMarker.setIcon(resId); + assertThat(bitmapMarker.getIconDrawable()).isNull(); + } + @Test public void setIcon_drawable_shouldCallTangramMarker() throws Exception { Drawable drawable = mock(Drawable.class); bitmapMarker.setIcon(drawable); verify(tangramMarker).setDrawable(drawable); } - @Test public void setSize_shouldCallTangramMarkerAndStyleStringGenerator() throws Exception { + @Test public void setIcon_drawable_shouldSetIcon() throws Exception { + Drawable drawable = mock(Drawable.class); + bitmapMarker.setIcon(drawable); + assertThat(bitmapMarker.getIconDrawable()).isEqualTo(drawable); + } + + @Test public void setIcon_drawable_shouldResetIconResId() throws Exception { + Drawable drawable = mock(Drawable.class); + bitmapMarker.setIcon(1); + bitmapMarker.setIcon(drawable); + assertThat(bitmapMarker.getIcon()).isEqualTo(Integer.MIN_VALUE); + } + + @Test public void setSize_shouldCallTangramMarker() throws Exception { + int width = 10; + int height = 5; + bitmapMarker.setSize(width, height); + verify(tangramMarker).setStylingFromString(anyString()); + } + + @Test public void setSize_shouldSetWidth() throws Exception { + int width = 10; + int height = 5; + bitmapMarker.setSize(width, height); + assertThat(bitmapMarker.getWidth()).isEqualTo(width); + } + + @Test public void setSize_shouldSetHeight() throws Exception { int width = 10; int height = 5; bitmapMarker.setSize(width, height); - verify(styleStringGenerator).setSize(width, height); - verify(tangramMarker).setStylingFromString(styleStringGenerator.getStyleString()); + assertThat(bitmapMarker.getHeight()).isEqualTo(height); } @Test public void setVisible_shouldCallTangramMarker() throws Exception { @@ -75,11 +133,23 @@ public class BitmapMarkerTest { verify(tangramMarker).setVisible(true); } + @Test public void setVisible_shouldSetVisibility() throws Exception { + bitmapMarker.setVisible(true); + assertThat(bitmapMarker.isVisible()).isTrue(); + bitmapMarker.setVisible(false); + assertThat(bitmapMarker.isVisible()).isFalse(); + } + @Test public void setDrawOrder_shouldCallTangramMarker() throws Exception { bitmapMarker.setDrawOrder(1); verify(tangramMarker).setDrawOrder(1); } + @Test public void setDrawOrder_shouldSetDrawOrder() throws Exception { + bitmapMarker.setDrawOrder(1); + assertThat(bitmapMarker.getDrawOrder()).isEqualTo(1); + } + @Test public void setUserData_shouldCallTangramMarker() throws Exception { HashMap obj = new HashMap(); bitmapMarker.setUserData(obj); @@ -93,19 +163,51 @@ public class BitmapMarkerTest { @Test public void setInteractive_shouldCallTangramMarker() throws Exception { bitmapMarker.setInteractive(true); - verify(styleStringGenerator).setInteractive(true); - verify(tangramMarker).setStylingFromString(styleStringGenerator.getStyleString()); + verify(tangramMarker).setStylingFromString(anyString()); } - @Test public void setBackgroundColor_colorInt_shouldCallTangramMarker() throws Exception { + @Test public void setInteractive_shouldSetInteractive() throws Exception { + bitmapMarker.setInteractive(true); + assertThat(bitmapMarker.isInteractive()).isTrue(); + bitmapMarker.setInteractive(false); + assertThat(bitmapMarker.isInteractive()).isFalse(); + } + + @Test public void setColor_colorInt_shouldCallTangramMarker() throws Exception { + bitmapMarker.setColor(Color.BLUE); + verify(tangramMarker).setStylingFromString(anyString()); + } + + @Test public void setColor_shouldSetColor() throws Exception { + bitmapMarker.setColor(Color.BLUE); + assertThat(bitmapMarker.getColor()).isEqualTo(Color.BLUE); + } + + @Test public void setColor_shouldUpdateColorHex() throws Exception { + bitmapMarker.setColor("test"); bitmapMarker.setColor(Color.BLUE); - verify(styleStringGenerator).setColor("#ff0000ff"); - verify(tangramMarker).setStylingFromString(styleStringGenerator.getStyleString()); + assertThat(bitmapMarker.getColorHex()).isEqualTo("#ff0000ff"); } - @Test public void setBackgroundColor_hex_shouldCallTangramMarker() throws Exception { + @Test public void setColor_hex_shouldCallTangramMarker() throws Exception { bitmapMarker.setColor("#222222"); - verify(styleStringGenerator).setColor("#222222"); - verify(tangramMarker).setStylingFromString(styleStringGenerator.getStyleString()); + verify(tangramMarker).setStylingFromString(anyString()); + } + + @Test public void setColor_hex_shouldSetColor() throws Exception { + bitmapMarker.setColor("hex"); + assertThat(bitmapMarker.getColorHex()).isEqualTo("hex"); + } + + @Test public void setIcon_hex_shouldResetColorInt() throws Exception { + bitmapMarker.setColor(Color.BLUE); + bitmapMarker.setColor("test"); + assertThat(bitmapMarker.getColor()).isEqualTo(Integer.MIN_VALUE); + } + + @Test public void getTangramMarker_shouldReturnMarker() throws Exception { + Marker marker = mock(Marker.class); + bitmapMarker.setTangramMarker(marker); + assertThat(bitmapMarker.getTangramMarker()).isEqualTo(marker); } } diff --git a/core/src/test/java/com/mapzen/android/graphics/model/MarkerManagerTest.java b/core/src/test/java/com/mapzen/android/graphics/model/MarkerManagerTest.java deleted file mode 100644 index 7f049ece..00000000 --- a/core/src/test/java/com/mapzen/android/graphics/model/MarkerManagerTest.java +++ /dev/null @@ -1,82 +0,0 @@ -package com.mapzen.android.graphics.model; - -import com.mapzen.tangram.LngLat; -import com.mapzen.tangram.MapController; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor; -import org.powermock.modules.junit4.PowerMockRunner; - -import android.graphics.drawable.Drawable; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyInt; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.verify; -import static org.powermock.api.mockito.PowerMockito.when; - -@RunWith(PowerMockRunner.class) -@SuppressStaticInitializationFor("com.mapzen.tangram.MapController") -public class MarkerManagerTest { - private MapController mapController = mock(MapController.class); - private com.mapzen.tangram.Marker tangramMarker = mock(com.mapzen.tangram.Marker.class); - private MarkerManager markerManager = new MarkerManager(mapController); - - @Before public void setUp() throws Exception { - when(mapController.addMarker()).thenReturn(tangramMarker); - } - - @Test public void shouldNotBeNull() throws Exception { - assertThat(markerManager).isNotNull(); - } - - @Test public void addMarker_shouldAddMarkerToMapController() throws Exception { - markerManager.addMarker(new MarkerOptions()); - verify(mapController).addMarker(); - } - - @Test public void addMarker_shouldSetPosition() throws Exception { - LngLat lngLat = new LngLat(); - MarkerOptions markerOptions = new MarkerOptions().position(lngLat); - markerManager.addMarker(markerOptions); - verify(tangramMarker).setPoint(lngLat); - } - - @Test public void addMarker_resId_shouldSetDrawable() throws Exception { - int resId = 123; - MarkerOptions markerOptions = new MarkerOptions().icon(resId); - markerManager.addMarker(markerOptions); - verify(tangramMarker).setDrawable(resId); - verify(tangramMarker, never()).setDrawable(any(Drawable.class)); - } - - @Test public void addMarker_res_shouldSetDrawable() throws Exception { - Drawable res = mock(Drawable.class); - MarkerOptions markerOptions = new MarkerOptions().icon(res); - markerManager.addMarker(markerOptions); - verify(tangramMarker).setDrawable(res); - verify(tangramMarker, never()).setDrawable(anyInt()); - } - - @Test public void addMarker_shouldSetStyling() throws Exception { - MarkerOptions markerOptions = new MarkerOptions(); - markerManager.addMarker(markerOptions); - verify(tangramMarker).setStylingFromString(anyString()); - } - - @Test public void addMarker_shouldSetSize() throws Exception { - MarkerOptions markerOptions = new MarkerOptions().size(100, 100); - markerManager.addMarker(markerOptions); - verify(tangramMarker).setStylingFromString("{ style: 'points', color: '#FFFFFF', " - + "size: [100px, 100px], collide: false, interactive: true }"); - } - - @Test public void addMarker_shouldReturnBitmapMarker() throws Exception { - assertThat(markerManager.addMarker(new MarkerOptions())).isNotNull(); - } -} diff --git a/core/src/test/java/com/mapzen/android/graphics/model/MarkerOptionsTest.java b/core/src/test/java/com/mapzen/android/graphics/model/MarkerOptionsTest.java index 76641a84..7f5265f3 100644 --- a/core/src/test/java/com/mapzen/android/graphics/model/MarkerOptionsTest.java +++ b/core/src/test/java/com/mapzen/android/graphics/model/MarkerOptionsTest.java @@ -6,6 +6,8 @@ import android.graphics.drawable.Drawable; +import java.util.Map; + import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; @@ -30,4 +32,33 @@ public class MarkerOptionsTest { assertThat(markerOptions.icon(drawable).getIconDrawable()).isEqualTo(drawable); assertThat(markerOptions.getIcon()).isEqualTo(Integer.MIN_VALUE); } + + @Test public void shouldSetDrawOrder() throws Exception { + assertThat(markerOptions.drawOrder(1).getDrawOrder()).isEqualTo(1); + } + + @Test public void shouldSetUserData() throws Exception { + Map userData = mock(Map.class); + assertThat(markerOptions.userData(userData).getUserData()).isEqualTo(userData); + } + + @Test public void shouldSetColorInt() throws Exception { + assertThat(markerOptions.colorInt(8).getColorInt()).isEqualTo(8); + } + + @Test public void shouldSetColorIntResetColorHex() throws Exception { + markerOptions.colorHex("test"); + markerOptions.colorInt(8); + assertThat(markerOptions.getColorHex()).isNull(); + } + + @Test public void shouldSetColorHex() throws Exception { + assertThat(markerOptions.colorHex("asdf").getColorHex()).isEqualTo("asdf"); + } + + @Test public void shouldSetColorHexResetColorInt() throws Exception { + markerOptions.colorInt(10); + markerOptions.colorHex("asdf"); + assertThat(markerOptions.getColorInt()).isEqualTo(Integer.MIN_VALUE); + } } diff --git a/samples/mapzen-android-sdk-sample/src/main/AndroidManifest.xml b/samples/mapzen-android-sdk-sample/src/main/AndroidManifest.xml index 19e289a5..8977c732 100644 --- a/samples/mapzen-android-sdk-sample/src/main/AndroidManifest.xml +++ b/samples/mapzen-android-sdk-sample/src/main/AndroidManifest.xml @@ -42,8 +42,7 @@ + android:theme="@style/AppTheme.NoActionBar"/> diff --git a/samples/mapzen-android-sdk-sample/src/main/java/com/mapzen/android/sdk/sample/CustomMarkerActivity.java b/samples/mapzen-android-sdk-sample/src/main/java/com/mapzen/android/sdk/sample/CustomMarkerActivity.java index 556f814c..8545a9bc 100644 --- a/samples/mapzen-android-sdk-sample/src/main/java/com/mapzen/android/sdk/sample/CustomMarkerActivity.java +++ b/samples/mapzen-android-sdk-sample/src/main/java/com/mapzen/android/sdk/sample/CustomMarkerActivity.java @@ -1,51 +1,40 @@ package com.mapzen.android.sdk.sample; -import com.mapzen.android.graphics.MapFragment; -import com.mapzen.android.graphics.MapzenMap; import com.mapzen.android.graphics.MarkerPickListener; -import com.mapzen.android.graphics.OnMapReadyCallback; import com.mapzen.android.graphics.model.BitmapMarker; import com.mapzen.android.graphics.model.MarkerOptions; import com.mapzen.tangram.LngLat; -import android.os.Bundle; import android.view.View; import android.widget.Toast; /** * Custom marker demo. */ -public class CustomMarkerActivity extends BaseDemoActivity implements MarkerPickListener { +public class CustomMarkerActivity extends SwitchStyleActivity implements MarkerPickListener { - private MapzenMap map; - private BitmapMarker bitmapMarker; + private static BitmapMarker bitmapMarker; - @Override protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_custom_marker); - final MapFragment mapFragment = - (MapFragment) getSupportFragmentManager().findFragmentById(R.id.fragment); - mapFragment.getMapAsync(new OnMapReadyCallback() { - @Override public void onMapReady(MapzenMap map) { - CustomMarkerActivity.this.map = map; - configureMap(); - } - }); + int getLayoutId() { + return R.layout.activity_custom_marker; } - private void configureMap() { - map.setCompassButtonEnabled(true); - map.setPersistMapState(true); - map.setPosition(new LngLat(-73.985428, 40.748817)); - map.setZoom(16); - map.setMarkerPickListener(this); + /** + * Configure map position and zoom. Also setup buttons to add/rm custom marker. + */ + void configureMap() { + mapzenMap.setCompassButtonEnabled(true); + mapzenMap.setPersistMapState(true); + mapzenMap.setPosition(new LngLat(-73.985428, 40.748817)); + mapzenMap.setZoom(16); + mapzenMap.setMarkerPickListener(this); findViewById(R.id.add_marker_btn).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final MarkerOptions markerOptions = new MarkerOptions() .position(new LngLat(-73.985428, 40.748817)) .icon(R.drawable.mapzen); - bitmapMarker = map.addBitmapMarker(markerOptions); + bitmapMarker = mapzenMap.addBitmapMarker(markerOptions); } }); diff --git a/samples/mapzen-android-sdk-sample/src/main/res/layout/activity_custom_marker.xml b/samples/mapzen-android-sdk-sample/src/main/res/layout/activity_custom_marker.xml index 9166d5aa..118ce90e 100644 --- a/samples/mapzen-android-sdk-sample/src/main/res/layout/activity_custom_marker.xml +++ b/samples/mapzen-android-sdk-sample/src/main/res/layout/activity_custom_marker.xml @@ -1,38 +1,66 @@ - + + + + + + + + + + + app:layout_behavior="@string/appbar_scrolling_view_behavior"> - -