Skip to content

Commit

Permalink
Add theme methods to MapzenMap
Browse files Browse the repository at this point in the history
  • Loading branch information
sarahsnow1 committed Sep 7, 2017
1 parent 36ab9ff commit 5f47829
Show file tree
Hide file tree
Showing 6 changed files with 589 additions and 9 deletions.
15 changes: 12 additions & 3 deletions core/src/main/java/com/mapzen/android/graphics/MapInitializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.mapzen.android.graphics.model.BubbleWrapStyle;
import com.mapzen.android.graphics.model.MapStyle;
import com.mapzen.android.graphics.model.BitmapMarkerManager;
import com.mapzen.android.graphics.model.ThemedMapStyle;
import com.mapzen.tangram.MapController;
import com.mapzen.tangram.SceneError;
import com.mapzen.tangram.SceneUpdate;
Expand Down Expand Up @@ -89,10 +90,11 @@ private void loadMap(final MapView mapView, MapStyle mapStyle, boolean styleExpl
mapStyle = restoredMapStyle;
}
mapStateManager.setMapStyle(mapStyle);
loadMap(mapView, mapStyle.getSceneFile(), callback);
loadMap(mapView, mapStyle, callback);
}

private void loadMap(final MapView mapView, String sceneFile, final OnMapReadyCallback callback) {
private void loadMap(final MapView mapView, MapStyle mapStyle,
final OnMapReadyCallback callback) {
final String apiKey = MapzenManager.instance(context).getApiKey();
final List<SceneUpdate> sceneUpdates = sceneUpdateManager.getUpdatesFor(apiKey, locale,
mapStateManager.isTransitOverlayEnabled(), mapStateManager.isBikeOverlayEnabled(),
Expand All @@ -104,6 +106,13 @@ private void loadMap(final MapView mapView, String sceneFile, final OnMapReadyCa
mapStateManager, sceneUpdateManager, locale, bitmapMarkerManager, yamlGenerator);
}
});
controller.loadSceneFileAsync(sceneFile, sceneUpdates);
if (mapStyle instanceof ThemedMapStyle) {
ThemedMapStyle themedMapStyle = (ThemedMapStyle) mapStyle;
String yaml = yamlGenerator.getImportYaml(themedMapStyle, mapStateManager.getLabelLevel(),
mapStateManager.getDetailLevel(), mapStateManager.getThemeColor());
controller.loadSceneYamlAsync(yaml, themedMapStyle.getStyleRootPath(), sceneUpdates);
} else {
controller.loadSceneFileAsync(mapStyle.getSceneFile(), sceneUpdates);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.mapzen.android.graphics.model.BubbleWrapStyle;
import com.mapzen.android.graphics.model.CameraType;
import com.mapzen.android.graphics.model.MapStyle;
import com.mapzen.android.graphics.model.ThemeColor;
import com.mapzen.tangram.LngLat;

/**
Expand All @@ -14,6 +15,9 @@ class MapStateManager {
private boolean persistMapState = true;
private LngLat position = new LngLat(0, 0);
private MapStyle mapStyle = new BubbleWrapStyle();
private int labelLevel = 0;
private int detailLevel = 0;
private ThemeColor themeColor = null;
private float zoom = 0;
private float rotation = 0;
private float tilt = 0;
Expand Down Expand Up @@ -46,6 +50,30 @@ public MapStyle getMapStyle() {
return this.mapStyle;
}

public void setLabelLevel(int labelLevel) {
this.labelLevel = labelLevel;
}

public int getLabelLevel() {
return this.labelLevel;
}

public void setDetailLevel(int detailLevel) {
this.detailLevel = detailLevel;
}

public int getDetailLevel() {
return this.detailLevel;
}

public void setThemeColor(ThemeColor color) {
this.themeColor = color;
}

public ThemeColor getThemeColor() {
return this.themeColor;
}

public void setZoom(float zoom) {
this.zoom = zoom;
}
Expand Down
222 changes: 217 additions & 5 deletions core/src/main/java/com/mapzen/android/graphics/MapzenMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import com.mapzen.android.graphics.model.MarkerOptions;
import com.mapzen.android.graphics.model.Polygon;
import com.mapzen.android.graphics.model.Polyline;
import com.mapzen.android.graphics.model.ThemeColor;
import com.mapzen.android.graphics.model.ThemedMapStyle;
import com.mapzen.tangram.LngLat;
import com.mapzen.tangram.MapController;
import com.mapzen.tangram.MapData;
Expand Down Expand Up @@ -192,11 +194,138 @@ public OverlayManager getOverlayManager() {
*/
public void setStyle(MapStyle mapStyle) {
mapStateManager.setMapStyle(mapStyle);
String apiKey = mapzenManager.getApiKey();
List<SceneUpdate> globalSceneUpdates = sceneUpdateManager.getUpdatesFor(apiKey, locale,
mapStateManager.isTransitOverlayEnabled(), mapStateManager.isBikeOverlayEnabled(),
mapStateManager.isPathOverlayEnabled());
mapController.loadSceneFile(mapStyle.getSceneFile(), globalSceneUpdates);
if (currentMapStyleIsThemed()) {
mapStateManager.setLabelLevel(getThemedMapStyle().getDefaultLabelLevel());
mapStateManager.setDetailLevel(getThemedMapStyle().getDefaultDetailLevel());
mapStateManager.setThemeColor(getThemedMapStyle().getDefaultColor());
loadSceneYaml();
} else {
loadSceneFile();
}
}

/**
* Sets the map style with given label level and default detail and theme color values. If the
* label level is not supported by this theme then this method throws an
* {@link IllegalArgumentException}.
* @param themedMapStyle
* @param labelLevel
*/
public void setStyleAndLabelLevel(ThemedMapStyle themedMapStyle, int labelLevel) {
setStyleLabelDetailLevelThemeColor(themedMapStyle, labelLevel,
themedMapStyle.getDefaultDetailLevel(), themedMapStyle.getDefaultColor());
}

/**
* Sets the map style with given detail level and default label and theme color values. If the
* detail level is not supported by this theme then this method throws an
* {@link IllegalArgumentException}.
* @param themedMapStyle
* @param detailLevel
*/
public void setStyleAndDetailLevel(ThemedMapStyle themedMapStyle, int detailLevel) {
setStyleLabelDetailLevelThemeColor(themedMapStyle, themedMapStyle.getDefaultLabelLevel(),
detailLevel, themedMapStyle.getDefaultColor());
}

/**
* Sets the map style with given theme color and default label and detail levels.
* @param themedMapStyle
* @param color
*/
public void setStyleAndThemeColor(ThemedMapStyle themedMapStyle, ThemeColor color) {
setStyleLabelDetailLevelThemeColor(themedMapStyle, themedMapStyle.getDefaultLabelLevel(),
themedMapStyle.getDefaultDetailLevel(), color);
}

/**
* Sets the map style with given label level, detail level, and theme color. If either the label
* or detail level are not supported, this method will throw an {@link IllegalArgumentException}.
* @param themedMapStyle
* @param labelLevel
* @param detailLevel
* @param color
*/
public void setStyleLabelDetailLevelThemeColor(ThemedMapStyle themedMapStyle, int labelLevel,
int detailLevel, ThemeColor color) {
mapStateManager.setMapStyle(themedMapStyle);
setLabelDetailLevelThemeColor(labelLevel, detailLevel, color);
}

/**
* Sets the label level when the current style is of type {@link ThemedMapStyle}. If the label
* level is not supported by the current style, this method will throw an
* {@link IllegalArgumentException}. If the current map style is not {@link ThemedMapStyle} then
* this method does nothing.
* @param labelLevel
*/
public void setLabelLevel(int labelLevel) {
if (!currentMapStyleIsThemed()) {
return;
}
setLabelDetailLevelThemeColor(labelLevel, getThemedMapStyle().getDefaultDetailLevel(),
getThemedMapStyle().getDefaultColor());
}

/**
* Sets the detail level when the current style is of type {@link ThemedMapStyle}. If the detail
* level is not supported by the current style, this method will throw an
* {@link IllegalArgumentException}. If the current map style is not {@link ThemedMapStyle} then
* this method does nothing.
* @param detailLevel
*/
public void setDetailLevel(int detailLevel) {
if (!currentMapStyleIsThemed()) {
return;
}
setLabelDetailLevelThemeColor(getThemedMapStyle().getDefaultLabelLevel(), detailLevel,
getThemedMapStyle().getDefaultColor());
}

/**
* Sets the theme color when the current style is of type {@link ThemedMapStyle}. If the theme
* color is not supported by the current style, this method will throw an
* {@link IllegalArgumentException}. If the current map style is not {@link ThemedMapStyle} then
* this method does nothing.
* @param color
*/
public void setThemeColor(ThemeColor color) {
if (!currentMapStyleIsThemed()) {
return;
}
setLabelDetailLevelThemeColor(getThemedMapStyle().getDefaultLabelLevel(),
getThemedMapStyle().getDefaultDetailLevel(), color);
}

/**
* Sets the label level, detail level, and theme color when the current style is of type
* {@link ThemedMapStyle}. If the label level, detail level, or theme color are not supported by
* the current style, this method will throw an {@link IllegalArgumentException}. If the current
* map style is not {@link ThemedMapStyle} then this method does nothing.
* @param labelLevel
* @param detailLevel
* @param color
*/
public void setLabelDetailLevelThemeColor(int labelLevel, int detailLevel, ThemeColor color) {
if (!currentMapStyleIsThemed()) {
return;
}
if (!isValidLabelLevel(labelLevel)) {
throw new IllegalArgumentException("Invalid label level for " +
getThemedMapStyle().getClass().getSimpleName());
}
if (!isValidDetailLevel(detailLevel)) {
throw new IllegalArgumentException("Invalid detail level for " +
getThemedMapStyle().getClass().getSimpleName());
}
if (!isValidColor(color)) {
throw new IllegalArgumentException("Invalid theme color for " +
getThemedMapStyle().getClass().getSimpleName());
}
mapStateManager.setLabelLevel(labelLevel);
mapStateManager.setDetailLevel(detailLevel);
mapStateManager.setThemeColor(color);
loadSceneYaml();
}

/**
Expand Down Expand Up @@ -980,4 +1109,87 @@ private void restoreMapState() {
mapStateManager.isBikeOverlayEnabled(), mapStateManager.isPathOverlayEnabled());
}

/**
* Returns all {@link SceneUpdate}s that should be applied when a new map style is set.
* @return
*/
private List<SceneUpdate> getGlobalSceneUpdates() {
String apiKey = mapzenManager.getApiKey();
return sceneUpdateManager.getUpdatesFor(apiKey, locale,
mapStateManager.isTransitOverlayEnabled(), mapStateManager.isBikeOverlayEnabled(),
mapStateManager.isPathOverlayEnabled());
}

/**
* Internal convenience method for loading scene file when the current style is a
* {@link MapStyle}.
* Applies all global scene updates.
*/
private void loadSceneFile() {
mapController.loadSceneFile(mapStateManager.getMapStyle().getSceneFile(),
getGlobalSceneUpdates());
}

/**
* Internal convenience method for loading scene yaml when the current style is a
* {@link ThemedMapStyle}. Applies all global scene updates.
* applied.
*/
private void loadSceneYaml() {
String yaml = yamlGenerator.getImportYaml(getThemedMapStyle(), mapStateManager.getLabelLevel(),
mapStateManager.getDetailLevel(), mapStateManager.getThemeColor());
String resourceRoot = getThemedMapStyle().getStyleRootPath();
mapController.loadSceneYaml(yaml, resourceRoot, getGlobalSceneUpdates());
}

/**
* Queries the {@link MapStateManager} to determine if the current style supports themes. Use to
* determine if scene yaml or simply scene file should be loaded.
* @return
*/
private boolean currentMapStyleIsThemed() {
return mapStateManager.getMapStyle() instanceof ThemedMapStyle;
}

/**
* Internal convenience method. Returns the current style downcasted to {@link ThemedMapStyle}.
* Users of this method should first check that the style is a {@link ThemedMapStyle}.
* @return
*/
private ThemedMapStyle getThemedMapStyle() {
return (ThemedMapStyle) mapStateManager.getMapStyle();
}

/**
* Checks the given label level against the current map style to determine if the level is
* supported by the theme. Users of this method should first check that the style is a
* {@link ThemedMapStyle}.
* @param labelLevel
* @return
*/
private boolean isValidLabelLevel(int labelLevel) {
return labelLevel >= 0 && labelLevel < getThemedMapStyle().getLabelCount();
}

/**
* Checks the given detail level against the current map style to determine if the level is
* supported by the theme. Users of this method should first check that the style is a
* {@link ThemedMapStyle}.
* @param detailLevel
* @return
*/
private boolean isValidDetailLevel(int detailLevel) {
return detailLevel >= 0 && detailLevel < getThemedMapStyle().getDetailCount();
}

/**
* Checks the given theme color against the current map style to determine if the color is
* supported by the theme. Users of this method should first check that the style is a
* {@link ThemedMapStyle}.
* @param color
* @return
*/
private boolean isValidColor(ThemeColor color) {
return getThemedMapStyle().getColors().contains(color);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import com.mapzen.android.core.MapzenManager;
import com.mapzen.android.graphics.model.BubbleWrapStyle;
import com.mapzen.android.graphics.model.BitmapMarkerManager;
import com.mapzen.android.graphics.model.RefillStyle;
import com.mapzen.android.graphics.model.ThemeColor;
import com.mapzen.tangram.MapController;
import com.mapzen.tangram.SceneUpdate;

Expand All @@ -29,6 +31,7 @@
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.argThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
Expand All @@ -39,11 +42,13 @@
public class MapInitializerTest {

private MapInitializer mapInitializer;
private MapStateManager mapStateManager;

@Before public void setUp() throws Exception {
CoreDI.init(getMockContext());
mapStateManager = new MapStateManager();
mapInitializer = new MapInitializer(mock(Context.class), mock(MapzenMapHttpHandler.class),
new MapDataManager(), new MapStateManager(), new SceneUpdateManager(),
new MapDataManager(), mapStateManager, new SceneUpdateManager(),
new BitmapMarkerManager(null, null), new ImportYamlGenerator());
}

Expand Down Expand Up @@ -142,4 +147,37 @@ public class MapInitializerTest {
verify(mapController).loadSceneFileAsync(anyString(), argThat(
new SceneUpdatesMatcher(expected)));
}

@Test public void init_shouldCallLoadSceneYamlAsync() throws Exception {
// Arrange
TestCallback callback = mock(TestCallback.class);
TestMapView mapView = mock(TestMapView.class);
TestTangramMapView tangramMapView = mock(TestTangramMapView.class);
MapController mapController = mock(MapController.class);
when(tangramMapView.getMap(any(MapController.SceneLoadListener.class))).thenReturn(
mapController);
tangramMapView.mapView = mapView;
tangramMapView.callback = callback;
when(mapView.getTangramMapView()).thenReturn(tangramMapView);
MapzenManager.instance(getMockContext()).setApiKey("fake-mapzen-api-key");
mapStateManager.setThemeColor(ThemeColor.BLACK);
mapStateManager.setLabelLevel(10);
mapStateManager.setDetailLevel(10);

// Act
RefillStyle refillStyle = new RefillStyle();
mapInitializer.init(mapView, refillStyle, null);

// Assert
ArrayList<SceneUpdate> expected = new ArrayList<>();
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_API_KEY, "fake-mapzen-api-key"));
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_LANGUAGE, Locale.getDefault().getLanguage()));
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_TRANSIT_OVERLAY, "false"));
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_BIKE_OVERLAY, "false"));
expected.add(new SceneUpdate(STYLE_GLOBAL_VAR_PATH_OVERLAY, "true"));
String yaml = "{ import: [ refill-style.yaml, themes/label-10.yaml, "
+ "themes/detail-10.yaml, themes/color-black.yaml ] }";
verify(mapController).loadSceneYamlAsync(eq(yaml), eq(refillStyle.getStyleRootPath()), argThat(
new SceneUpdatesMatcher(expected)));
}
}

0 comments on commit 5f47829

Please sign in to comment.