Skip to content

Commit 65795f7

Browse files
authored
Add map overlays (#373)
* transit overlay global * add overlay spinner to example * persist transit overlay on rotation, add restore map state tests * add bike overlay and update example * add path overlay and update example * add batch overlay update method * checkstyle * default path overlay to enabled
1 parent 5b54aaf commit 65795f7

File tree

16 files changed

+568
-46
lines changed

16 files changed

+568
-46
lines changed

core/src/main/java/com/mapzen/android/graphics/MapInitializer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ private void loadMap(final MapView mapView, MapStyle mapStyle, boolean styleExpl
8787

8888
private void loadMap(final MapView mapView, String sceneFile, final OnMapReadyCallback callback) {
8989
final String apiKey = MapzenManager.instance(context).getApiKey();
90-
final List<SceneUpdate> sceneUpdates = sceneUpdateManager.getUpdatesFor(apiKey, locale);
90+
final List<SceneUpdate> sceneUpdates = sceneUpdateManager.getUpdatesFor(apiKey, locale,
91+
mapStateManager.isTransitOverlayEnabled(), mapStateManager.isBikeOverlayEnabled(),
92+
mapStateManager.isPathOverlayEnabled());
9193
getTangramView(mapView).getMapAsync(new com.mapzen.tangram.MapView.OnMapReadyCallback() {
9294
@Override public void onMapReady(MapController mapController) {
9395
mapController.setHttpHandler(tileHttpHandler);

core/src/main/java/com/mapzen/android/graphics/MapStateManager.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ class MapStateManager {
1818
private float rotation = 0;
1919
private float tilt = 0;
2020
private CameraType cameraType = CameraType.ISOMETRIC;
21+
private boolean transitOverlayEnabled = false;
22+
private boolean bikeOverlayEnabled = false;
23+
private boolean pathOverlayEnabled = true;
2124

2225
public void setPersistMapState(boolean persistMapState) {
2326
this.persistMapState = persistMapState;
@@ -74,4 +77,28 @@ public void setCameraType(CameraType cameraType) {
7477
public CameraType getCameraType() {
7578
return this.cameraType;
7679
}
80+
81+
public void setTransitOverlayEnabled(boolean transitOverlayEnabled) {
82+
this.transitOverlayEnabled = transitOverlayEnabled;
83+
}
84+
85+
public boolean isTransitOverlayEnabled() {
86+
return this.transitOverlayEnabled;
87+
}
88+
89+
public void setBikeOverlayEnabled(boolean bikeOverlayEnabled) {
90+
this.bikeOverlayEnabled = bikeOverlayEnabled;
91+
}
92+
93+
public boolean isBikeOverlayEnabled() {
94+
return this.bikeOverlayEnabled;
95+
}
96+
97+
public void setPathOverlayEnabled(boolean pathOverlayEnabled) {
98+
this.pathOverlayEnabled = pathOverlayEnabled;
99+
}
100+
101+
public boolean isPathOverlayEnabled() {
102+
return this.pathOverlayEnabled;
103+
}
77104
}

core/src/main/java/com/mapzen/android/graphics/MapzenMap.java

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import android.support.annotation.Nullable;
2525
import android.view.View;
2626

27+
import java.util.ArrayList;
2728
import java.util.HashMap;
2829
import java.util.List;
2930
import java.util.Locale;
@@ -183,7 +184,9 @@ public OverlayManager getOverlayManager() {
183184
public void setStyle(MapStyle mapStyle) {
184185
mapStateManager.setMapStyle(mapStyle);
185186
String apiKey = mapzenManager.getApiKey();
186-
List<SceneUpdate> globalSceneUpdates = sceneUpdateManager.getUpdatesFor(apiKey, locale);
187+
List<SceneUpdate> globalSceneUpdates = sceneUpdateManager.getUpdatesFor(apiKey, locale,
188+
mapStateManager.isTransitOverlayEnabled(), mapStateManager.isBikeOverlayEnabled(),
189+
mapStateManager.isPathOverlayEnabled());
187190
mapController.loadSceneFile(mapStyle.getSceneFile(), globalSceneUpdates);
188191
}
189192

@@ -864,6 +867,60 @@ public void setPersistMapState(boolean persistStateOnRecreation) {
864867
mapStateManager.setPersistMapState(persistStateOnRecreation);
865868
}
866869

870+
/**
871+
* All Mapzen basemap styles support a transit overlay. This method toggles its visibility.
872+
* @param transitOverlayEnabled whether or not the transit overlay should be enabled.
873+
*/
874+
public void setTransitOverlayEnabled(boolean transitOverlayEnabled) {
875+
mapStateManager.setTransitOverlayEnabled(transitOverlayEnabled);
876+
mapController.queueSceneUpdate(sceneUpdateManager.getTransitOverlayUpdate(
877+
transitOverlayEnabled));
878+
mapController.applySceneUpdates();
879+
}
880+
881+
/**
882+
* The {@link com.mapzen.android.graphics.model.WalkaboutStyle} supports a bike overlay. This
883+
* method toggles its visibility.
884+
* @param bikeOverlayEnabled whether or not the bike overlay should be enabled.
885+
*/
886+
public void setBikeOverlayEnabled(boolean bikeOverlayEnabled) {
887+
mapStateManager.setBikeOverlayEnabled(bikeOverlayEnabled);
888+
mapController.queueSceneUpdate(sceneUpdateManager.getBikeOverlayUpdate(
889+
bikeOverlayEnabled));
890+
mapController.applySceneUpdates();
891+
}
892+
893+
/**
894+
* The {@link com.mapzen.android.graphics.model.WalkaboutStyle} supports a path overlay. This
895+
* method toggles its visibility.
896+
* @param pathOverlayEnabled whether or not the path overlay should be enabled.
897+
*/
898+
public void setPathOverlayEnabled(boolean pathOverlayEnabled) {
899+
mapStateManager.setPathOverlayEnabled(pathOverlayEnabled);
900+
mapController.queueSceneUpdate(sceneUpdateManager.getPathOverlayUpdate(
901+
pathOverlayEnabled));
902+
mapController.applySceneUpdates();
903+
}
904+
905+
/**
906+
* Method to facilitate enabling/disabling multiple overlays at once.
907+
* @param transitOverlayEnabled whether or not the transit overlay should be enabled.
908+
* @param bikeOverlayEnabled whether or not the bike overlay should be enabled.
909+
* @param pathOverlayEnabled whether or not the path overlay should be enabled.
910+
*/
911+
public void setOverlaysEnabled(boolean transitOverlayEnabled, boolean bikeOverlayEnabled,
912+
boolean pathOverlayEnabled) {
913+
mapStateManager.setTransitOverlayEnabled(transitOverlayEnabled);
914+
mapStateManager.setBikeOverlayEnabled(bikeOverlayEnabled);
915+
mapStateManager.setPathOverlayEnabled(pathOverlayEnabled);
916+
List<SceneUpdate> updates = new ArrayList<>();
917+
updates.add(sceneUpdateManager.getTransitOverlayUpdate(transitOverlayEnabled));
918+
updates.add(sceneUpdateManager.getBikeOverlayUpdate(bikeOverlayEnabled));
919+
updates.add(sceneUpdateManager.getPathOverlayUpdate(pathOverlayEnabled));
920+
mapController.queueSceneUpdate(updates);
921+
mapController.applySceneUpdates();
922+
}
923+
867924
/**
868925
* Restores all aspects of the map EXCEPT the style, this is restored in the
869926
* {@link MapInitializer}.
@@ -877,6 +934,8 @@ private void restoreMapState() {
877934
setRotation(mapStateManager.getRotation());
878935
setTilt(mapStateManager.getTilt());
879936
setCameraType(mapStateManager.getCameraType());
937+
setOverlaysEnabled(mapStateManager.isTransitOverlayEnabled(),
938+
mapStateManager.isBikeOverlayEnabled(), mapStateManager.isPathOverlayEnabled());
880939
}
881940

882941
/**

core/src/main/java/com/mapzen/android/graphics/SceneUpdateManager.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,54 @@ class SceneUpdateManager {
1313

1414
static final String STYLE_GLOBAL_VAR_API_KEY = "global.sdk_mapzen_api_key";
1515
static final String STYLE_GLOBAL_VAR_LANGUAGE = "global.ux_language";
16+
static final String STYLE_GLOBAL_VAR_TRANSIT_OVERLAY = "global.sdk_transit_overlay";
17+
static final String STYLE_GLOBAL_VAR_BIKE_OVERLAY = "global.sdk_bike_overlay";
18+
static final String STYLE_GLOBAL_VAR_PATH_OVERLAY = "global.sdk_path_overlay";
1619

1720
/**
1821
* Creates {@link SceneUpdate}s given an api key and locale.
1922
* @param apiKey user's api key.
2023
* @param locale user's preferred map locale.
2124
* @return scene updates for api key and locale.
2225
*/
23-
List<SceneUpdate> getUpdatesFor(String apiKey, Locale locale) {
26+
List<SceneUpdate> getUpdatesFor(String apiKey, Locale locale, boolean transitOverlayEnabled,
27+
boolean bikeOverlayEnabled, boolean pathOverlayEnabled) {
2428
final ArrayList<SceneUpdate> sceneUpdates = new ArrayList<>(2);
2529
sceneUpdates.add(new SceneUpdate(STYLE_GLOBAL_VAR_API_KEY, apiKey));
2630
sceneUpdates.add(new SceneUpdate(STYLE_GLOBAL_VAR_LANGUAGE, locale.getLanguage()));
31+
sceneUpdates.add(getTransitOverlayUpdate(transitOverlayEnabled));
32+
sceneUpdates.add(getBikeOverlayUpdate(bikeOverlayEnabled));
33+
sceneUpdates.add(getPathOverlayUpdate(pathOverlayEnabled));
2734
return sceneUpdates;
2835
}
36+
37+
/**
38+
* Creates a {@link SceneUpdate} for enabling/disabling the transit overlay.
39+
* @param transitOverlayEnabled
40+
* @return
41+
*/
42+
SceneUpdate getTransitOverlayUpdate(boolean transitOverlayEnabled) {
43+
return new SceneUpdate(STYLE_GLOBAL_VAR_TRANSIT_OVERLAY, String.valueOf(
44+
transitOverlayEnabled));
45+
}
46+
47+
/**
48+
* Creates a {@link SceneUpdate} for enabling/disabling the bike overlay.
49+
* @param bikeOverlayEnabled
50+
* @return
51+
*/
52+
SceneUpdate getBikeOverlayUpdate(boolean bikeOverlayEnabled) {
53+
return new SceneUpdate(STYLE_GLOBAL_VAR_BIKE_OVERLAY, String.valueOf(
54+
bikeOverlayEnabled));
55+
}
56+
57+
/**
58+
* Creates a {@link SceneUpdate} for enabling/disabling the path overlay.
59+
* @param pathOverlayEnabled
60+
* @return
61+
*/
62+
SceneUpdate getPathOverlayUpdate(boolean pathOverlayEnabled) {
63+
return new SceneUpdate(STYLE_GLOBAL_VAR_PATH_OVERLAY, String.valueOf(
64+
pathOverlayEnabled));
65+
}
2966
}

core/src/test/java/com/mapzen/android/graphics/MapInitializerTest.java

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,21 @@
88
import org.junit.Before;
99
import org.junit.Test;
1010
import org.junit.runner.RunWith;
11-
import org.mockito.ArgumentMatcher;
1211
import org.powermock.core.classloader.annotations.PowerMockIgnore;
1312
import org.powermock.core.classloader.annotations.SuppressStaticInitializationFor;
1413
import org.powermock.modules.junit4.PowerMockRunner;
1514

1615
import android.content.Context;
1716

1817
import java.util.ArrayList;
19-
import java.util.List;
2018
import java.util.Locale;
2119

2220
import static com.mapzen.TestHelper.getMockContext;
2321
import static com.mapzen.android.graphics.SceneUpdateManager.STYLE_GLOBAL_VAR_API_KEY;
22+
import static com.mapzen.android.graphics.SceneUpdateManager.STYLE_GLOBAL_VAR_BIKE_OVERLAY;
2423
import static com.mapzen.android.graphics.SceneUpdateManager.STYLE_GLOBAL_VAR_LANGUAGE;
24+
import static com.mapzen.android.graphics.SceneUpdateManager.STYLE_GLOBAL_VAR_PATH_OVERLAY;
25+
import static com.mapzen.android.graphics.SceneUpdateManager.STYLE_GLOBAL_VAR_TRANSIT_OVERLAY;
2526
import static org.assertj.core.api.Assertions.assertThat;
2627
import static org.mockito.Matchers.any;
2728
import static org.mockito.Matchers.anyString;
@@ -73,8 +74,11 @@ public class MapInitializerTest {
7374
ArrayList<SceneUpdate> expected = new ArrayList<>();
7475
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_API_KEY, "fake-mapzen-api-key"));
7576
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_LANGUAGE, Locale.getDefault().getLanguage()));
77+
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_TRANSIT_OVERLAY, "false"));
78+
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_BIKE_OVERLAY, "false"));
79+
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_PATH_OVERLAY, "true"));
7680
verify(tangramMapView).getMapAsync(any(com.mapzen.tangram.MapView.OnMapReadyCallback.class),
77-
anyString(), argThat(new SceneUpdateMatcher(expected)));
81+
anyString(), argThat(new SceneUpdatesMatcher(expected)));
7882
}
7983

8084
@Test public void init_shouldSetGivenMapLocale() throws Exception {
@@ -91,32 +95,31 @@ public class MapInitializerTest {
9195
ArrayList<SceneUpdate> expected = new ArrayList<>();
9296
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_API_KEY, "fake-mapzen-api-key"));
9397
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_LANGUAGE, Locale.FRENCH.getLanguage()));
98+
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_TRANSIT_OVERLAY, "false"));
99+
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_BIKE_OVERLAY, "false"));
100+
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_PATH_OVERLAY, "true"));
94101
verify(tangramMapView).getMapAsync(any(com.mapzen.tangram.MapView.OnMapReadyCallback.class),
95-
anyString(), argThat(new SceneUpdateMatcher(expected)));
102+
anyString(), argThat(new SceneUpdatesMatcher(expected)));
96103
}
97104

98-
/**
99-
* Custom Mockito matcher for a list of SceneUpdates. Verifies paths and values are all equal.
100-
*/
101-
private class SceneUpdateMatcher extends ArgumentMatcher<List<SceneUpdate>> {
102-
List<SceneUpdate> thisObject;
103-
104-
public SceneUpdateMatcher(List<SceneUpdate> thisObject) {
105-
this.thisObject = thisObject;
106-
}
107-
108-
@Override public boolean matches(Object argument) {
109-
List<SceneUpdate> otherObject = (List<SceneUpdate>) argument;
110-
for (int i = 0; i < thisObject.size(); i++) {
111-
if (!thisObject.get(i).getPath().equals(otherObject.get(i).getPath())) {
112-
return false;
113-
}
114-
if (!thisObject.get(i).getValue().equals(otherObject.get(i).getValue())) {
115-
return false;
116-
}
117-
}
118-
119-
return true;
120-
}
105+
@Test public void init_shouldDefaultToOverlaysDisabledExceptPath() throws Exception {
106+
// Arrange
107+
MapView mapView = mock(MapView.class);
108+
TangramMapView tangramMapView = mock(TangramMapView.class);
109+
when(mapView.getTangramMapView()).thenReturn(tangramMapView);
110+
MapzenManager.instance(getMockContext()).setApiKey("fake-mapzen-api-key");
111+
112+
// Act
113+
mapInitializer.init(mapView, new BubbleWrapStyle(), null);
114+
115+
// Assert
116+
ArrayList<SceneUpdate> expected = new ArrayList<>();
117+
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_API_KEY, "fake-mapzen-api-key"));
118+
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_LANGUAGE, Locale.getDefault().getLanguage()));
119+
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_TRANSIT_OVERLAY, "false"));
120+
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_BIKE_OVERLAY, "false"));
121+
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_PATH_OVERLAY, "true"));
122+
verify(tangramMapView).getMapAsync(any(com.mapzen.tangram.MapView.OnMapReadyCallback.class),
123+
anyString(), argThat(new SceneUpdatesMatcher(expected)));
121124
}
122125
}

core/src/test/java/com/mapzen/android/graphics/MapStateManagerTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,31 @@ public class MapStateManagerTest {
7777
stateManager.setCameraType(CameraType.PERSPECTIVE);
7878
assertThat(stateManager.getCameraType()).isEqualTo(CameraType.PERSPECTIVE);
7979
}
80+
81+
@Test public void isTransitOverlayEnabled_shouldDefaultToFalse() {
82+
assertThat(stateManager.isTransitOverlayEnabled()).isEqualTo(false);
83+
}
84+
85+
@Test public void setTransitOverlayEnabled_shouldUpdateTransitOverlayEnabled() {
86+
stateManager.setTransitOverlayEnabled(true);
87+
assertThat(stateManager.isTransitOverlayEnabled()).isEqualTo(true);
88+
}
89+
90+
@Test public void isBikeOverlayEnabled_shouldDefaultToFalse() {
91+
assertThat(stateManager.isBikeOverlayEnabled()).isEqualTo(false);
92+
}
93+
94+
@Test public void setBikeOverlayEnabled_shouldUpdateBikeOverlayEnabled() {
95+
stateManager.setBikeOverlayEnabled(true);
96+
assertThat(stateManager.isBikeOverlayEnabled()).isEqualTo(true);
97+
}
98+
99+
@Test public void isPathOverlayEnabled_shouldDefaultToTrue() {
100+
assertThat(stateManager.isPathOverlayEnabled()).isEqualTo(true);
101+
}
102+
103+
@Test public void setPathOverlayEnabled_shouldUpdatePathOverlayEnabled() {
104+
stateManager.setPathOverlayEnabled(true);
105+
assertThat(stateManager.isPathOverlayEnabled()).isEqualTo(true);
106+
}
80107
}

0 commit comments

Comments
 (0)