[android] #5610 - Initial Runtime Style Bindings
[android] #5610 - Adjusted public api after discussion [android] #5610 - added jni binding for NativeMapView#getLayer [android] #5610 - Added initial test Activity [android] #5610 - Started on NativePeer implementation for Layer [android] #5610 - replaced low-level jni code with high-level for native getLayer [android] 5610 - completed basic layer peer class - constructible from java and c++ [android] #5610 - removed reference that was redundant and causing the finalizer exception [android] #5610 - Added a property peer [android] #5610 - added value type to do type conversions - wip [android] #5610 - simplified property conversion approach - wrapped value with jenv [android] #5610 - added some more value conversions [android] #5610 - Finished conversion for basic types [android] #5610 - allow color's to be set as either an android color int or a String to support all formats in the spec [android] #5610 - encode color ints as rgba to retain alpha channel [android] #5610 - recalculate classes after paint property [android] #5610 - more examples [android] #5610 - fixed the example [android] #5610 - cleaned up example code before continueing [android] #5610 - added layout property example [android] #5610 - set visibility on layer [android] #5610 - added removeLayer and example [android] #5610 - added more type conversions [android] #5610 - Started on peer classes for layer implementations - WIP [android] #5610 - First complete layer subclass peer implementation [android] #5610 - added a little bit of structure before adding the other layer types [android] #5610 - generate the c++ headers from the style spec [android] #5610 - make sure the visibility is set as a string [android] #5610 - Generate c++ layer peer class implementations from the style spec [android] #5610 - generate java layer peer classes [android] #5610 - cleanup comments [android] #5610 - register all c++ peer classes with jni [android] #5610 - addLayer [android] #5610 - comment out broken case [android] #5610 - Sources api - very much WIP [android] 5610 - GeoJson source implementation and geojson conversion [android] #5610 - cleanup add source/layer example a bit [android] #5610 - initial filter api [android] #5610 - Added filter api on the relevant Layer classes [android] #5610 - raster layer is not filterable [android] #5610 - actually make it compile [android] #5610 - completed filter implementation [android] #5610 - Vector and Raster Source + examples [android] #5610 - removed superfluous interface, moved filters to the correct package [android] #5610 - fixed comments [android] #5610 - moved tests to the right package [android] #5610 - hide difference between paint and layout properties in public api, make more performant set method for proeprties [android] #5610 - fix rebase issue
This commit is contained in:
@@ -301,6 +301,14 @@
|
||||
android:value="@string/category_fragment" />
|
||||
</activity>
|
||||
|
||||
<activity android:name=".activity.style.RuntimeStyleActivity"
|
||||
android:description="@string/description_runtime_style"
|
||||
android:label="@string/activity_runtime_style">
|
||||
<meta-data
|
||||
android:name="@string/category"
|
||||
android:value="@string/category_style" />
|
||||
</activity>
|
||||
|
||||
<!-- Configuration Settings -->
|
||||
<meta-data
|
||||
android:name="com.mapbox.TestEventsServer"
|
||||
|
||||
@@ -0,0 +1,299 @@
|
||||
package com.mapbox.mapboxsdk.testapp.activity.style;
|
||||
|
||||
import android.graphics.Color;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.RawRes;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.mapbox.mapboxsdk.camera.CameraUpdateFactory;
|
||||
import com.mapbox.mapboxsdk.geometry.LatLng;
|
||||
import com.mapbox.mapboxsdk.maps.MapView;
|
||||
import com.mapbox.mapboxsdk.maps.MapboxMap;
|
||||
import com.mapbox.mapboxsdk.maps.OnMapReadyCallback;
|
||||
import com.mapbox.mapboxsdk.style.layers.FillLayer;
|
||||
import com.mapbox.mapboxsdk.style.layers.Layer;
|
||||
import com.mapbox.mapboxsdk.style.layers.LineLayer;
|
||||
import com.mapbox.mapboxsdk.style.layers.NoSuchLayerException;
|
||||
import com.mapbox.mapboxsdk.style.layers.Property;
|
||||
import com.mapbox.mapboxsdk.style.layers.RasterLayer;
|
||||
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource;
|
||||
import com.mapbox.mapboxsdk.style.sources.RasterSource;
|
||||
import com.mapbox.mapboxsdk.style.sources.Source;
|
||||
import com.mapbox.mapboxsdk.style.sources.VectorSource;
|
||||
import com.mapbox.mapboxsdk.testapp.R;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
|
||||
import static com.mapbox.mapboxsdk.style.layers.Filter.*;
|
||||
import static com.mapbox.mapboxsdk.style.layers.Property.*;
|
||||
import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.*;
|
||||
|
||||
/**
|
||||
* Sample Activity to show a typical location picker use case
|
||||
*/
|
||||
public class RuntimeStyleActivity extends AppCompatActivity {
|
||||
private static final String TAG = RuntimeStyleActivity.class.getSimpleName();
|
||||
|
||||
private MapView mapView;
|
||||
private MapboxMap mapboxMap;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_runtime_style);
|
||||
|
||||
setupActionBar();
|
||||
|
||||
//Initialize map as normal
|
||||
mapView = (MapView) findViewById(R.id.mapView);
|
||||
mapView.onCreate(savedInstanceState);
|
||||
|
||||
|
||||
mapView.getMapAsync(new OnMapReadyCallback() {
|
||||
@Override
|
||||
public void onMapReady(MapboxMap map) {
|
||||
//Store for later
|
||||
mapboxMap = map;
|
||||
|
||||
//Center and Zoom (Amsterdam, zoomed to streets)
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(52.379189, 4.899431), 14));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_runtime_style, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mapView.onResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
mapView.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
onBackPressed();
|
||||
return true;
|
||||
case R.id.action_water_color:
|
||||
setWaterColor();
|
||||
return true;
|
||||
case R.id.action_background_opacity:
|
||||
setBackgroundOpacity();
|
||||
return true;
|
||||
case R.id.action_road_avoid_edges:
|
||||
setRoadSymbolPlacement();
|
||||
return true;
|
||||
case R.id.action_layer_visibility:
|
||||
setLayerInvisible();
|
||||
return true;
|
||||
case R.id.action_remove_layer:
|
||||
removeBuildings();
|
||||
return true;
|
||||
case R.id.action_add_parks_layer:
|
||||
addParksLayer();
|
||||
return true;
|
||||
case R.id.action_add_terrain_layer:
|
||||
addTerrainLayer();
|
||||
return true;
|
||||
case R.id.action_add_satellite_layer:
|
||||
addSatelliteLayer();
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void setLayerInvisible() {
|
||||
String[] roadLayers = new String[]{"water"};
|
||||
for (String roadLayer : roadLayers) {
|
||||
Layer layer = mapboxMap.getLayer(roadLayer);
|
||||
if (layer != null) {
|
||||
layer.set(visibility(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setRoadSymbolPlacement() {
|
||||
//Zoom so that the labels are visible first
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(14), new DefaultCallback() {
|
||||
@Override
|
||||
public void onFinish() {
|
||||
String[] roadLayers = new String[]{"road-label-small", "road-label-medium", "road-label-large"};
|
||||
for (String roadLayer : roadLayers) {
|
||||
Layer layer = mapboxMap.getLayer(roadLayer);
|
||||
if (layer != null) {
|
||||
layer.set(symbolPlacement(SYMBOL_PLACEMENT_POINT));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setBackgroundOpacity() {
|
||||
Layer background = mapboxMap.getLayer("background");
|
||||
if (background != null) {
|
||||
background.set(backgroundOpacity(0.2f));
|
||||
}
|
||||
}
|
||||
|
||||
private void setWaterColor() {
|
||||
Layer water = mapboxMap.getLayer("water");
|
||||
if (water != null) {
|
||||
water.set(
|
||||
visibility(true),
|
||||
fillColor(Color.RED)
|
||||
);
|
||||
} else {
|
||||
Toast.makeText(RuntimeStyleActivity.this, "No water layer in this style", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void removeBuildings() {
|
||||
//Zoom to see buildings first
|
||||
try {
|
||||
mapboxMap.removeLayer("building");
|
||||
} catch (NoSuchLayerException e) {
|
||||
Toast.makeText(RuntimeStyleActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private void addParksLayer() {
|
||||
//Add a source
|
||||
Source source;
|
||||
try {
|
||||
source = new GeoJsonSource("amsterdam-spots", readRawResource(R.raw.amsterdam));
|
||||
} catch (IOException e) {
|
||||
Toast.makeText(RuntimeStyleActivity.this, "Couldn't add source: " + e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
mapboxMap.addSource(source);
|
||||
|
||||
FillLayer layer = new FillLayer("parksLayer", "amsterdam-spots");
|
||||
layer.set(
|
||||
fillColor(Color.RED),
|
||||
fillOutlineColor(Color.BLUE),
|
||||
fillOpacity(0.3f),
|
||||
fillAntialias(true)
|
||||
);
|
||||
|
||||
//Only show me parks
|
||||
layer.setFilter(eq("type", "park"));
|
||||
|
||||
mapboxMap.addLayer(layer, "building");
|
||||
//layer.setPaintProperty(fillColor(Color.RED)); //XXX But not after the object is attached
|
||||
|
||||
//Or get the object later and set it. It's all good.
|
||||
mapboxMap.getLayer("parksLayer").set(fillColor(Color.RED));
|
||||
|
||||
//Get a good look at it all
|
||||
mapboxMap.animateCamera(CameraUpdateFactory.zoomTo(12));
|
||||
}
|
||||
|
||||
private void addTerrainLayer() {
|
||||
//Add a source
|
||||
Source source = new VectorSource("my-terrain-source", "mapbox://mapbox.mapbox-terrain-v2");
|
||||
mapboxMap.addSource(source);
|
||||
|
||||
LineLayer layer = new LineLayer("terrainLayer", "my-terrain-source");
|
||||
layer.setSourceLayer("contour");
|
||||
layer.set(
|
||||
lineJoin(Property.LINE_JOIN_ROUND),
|
||||
lineCap(Property.LINE_CAP_ROUND),
|
||||
lineColor(Color.RED),
|
||||
lineWidth(20f)
|
||||
);
|
||||
|
||||
mapboxMap.addLayer(layer);
|
||||
}
|
||||
|
||||
private void addSatelliteLayer() {
|
||||
//Add a source
|
||||
Source source = new RasterSource("my-raster-source", "mapbox://mapbox.satellite");
|
||||
mapboxMap.addSource(source);
|
||||
|
||||
//Add a layer
|
||||
mapboxMap.addLayer(new RasterLayer("satellite-layer", "my-raster-source"));
|
||||
}
|
||||
|
||||
private String readRawResource(@RawRes int rawResource) throws IOException {
|
||||
InputStream is = getResources().openRawResource(rawResource);
|
||||
Writer writer = new StringWriter();
|
||||
char[] buffer = new char[1024];
|
||||
try {
|
||||
Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
|
||||
int n;
|
||||
while ((n = reader.read(buffer)) != -1) {
|
||||
writer.write(buffer, 0, n);
|
||||
}
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
private void setupActionBar() {
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setDisplayShowHomeEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DefaultCallback implements MapboxMap.CancelableCallback {
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
//noop
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
//noop
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="@color/primary"
|
||||
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
|
||||
|
||||
<com.mapbox.mapboxsdk.maps.MapView
|
||||
android:id="@+id/mapView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/toolbar"/>
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:mapbox="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_water_color"
|
||||
android:title="Color the water"
|
||||
mapbox:showAsAction="never"/>
|
||||
<item
|
||||
android:id="@+id/action_background_opacity"
|
||||
android:title="Set background opacity"
|
||||
mapbox:showAsAction="never"/>
|
||||
<item
|
||||
android:id="@+id/action_road_avoid_edges"
|
||||
android:title="Set road symbol placement to Point"
|
||||
mapbox:showAsAction="never"/>
|
||||
<item
|
||||
android:id="@+id/action_layer_visibility"
|
||||
android:title="Set layer visibility to false"
|
||||
mapbox:showAsAction="never"/>
|
||||
<item
|
||||
android:id="@+id/action_add_parks_layer"
|
||||
android:title="Add a parks layer"
|
||||
mapbox:showAsAction="never"/>
|
||||
<item
|
||||
android:id="@+id/action_remove_layer"
|
||||
android:title="Remove buildings layer"
|
||||
mapbox:showAsAction="never"/>
|
||||
<item
|
||||
android:id="@+id/action_add_terrain_layer"
|
||||
android:title="Add a terrain layer"
|
||||
mapbox:showAsAction="never"/>
|
||||
<item
|
||||
android:id="@+id/action_add_satellite_layer"
|
||||
android:title="Add a satellite layer"
|
||||
mapbox:showAsAction="never"/>
|
||||
</menu>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -54,6 +54,7 @@
|
||||
<string name="activity_minmax_zoom">Min/Max Zoom</string>
|
||||
<string name="activity_viewpager">ViewPager</string>
|
||||
<string name="title_activity_navigation_drawer">Navigation Drawer</string>
|
||||
<string name="activity_runtime_style">Runtime Style</string>
|
||||
|
||||
<!-- Description -->
|
||||
<string name="description_user_location_tracking">Tracks the location of the user</string>
|
||||
@@ -92,6 +93,7 @@
|
||||
<string name="description_location_picker">Use a fixed Marker to select your location</string>
|
||||
<string name="description_viewpager">Use SupportMapFragments in a ViewPager</string>
|
||||
<string name="description_navigation_drawer">Test for Navigation Drawer support</string>
|
||||
<string name="description_runtime_style">Adopt the map style on the fly</string>
|
||||
|
||||
<string name="menuitem_title_concurrent_infowindow">Concurrent Open InfoWindows</string>
|
||||
<string name="menuitem_title_deselect_markers_on_tap">Deselect Markers On Tap</string>
|
||||
@@ -112,6 +114,7 @@
|
||||
<string name="category_offline">Offline</string>
|
||||
<string name="category_userlocation">User Location</string>
|
||||
<string name="category_navigation">Navigation</string>
|
||||
<string name="category_style">Styling</string>
|
||||
|
||||
<string name="action_visible_bounds_explanation">Center map around 2 markers</string>
|
||||
<string name="action_remove_polylines">Remove polylines</string>
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.mapbox.mapboxsdk.style.layers;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static com.mapbox.mapboxsdk.style.layers.Filter.*;
|
||||
|
||||
/**
|
||||
* Tests for Filter
|
||||
*/
|
||||
public class FilterTest {
|
||||
|
||||
@Test
|
||||
public void testAll() {
|
||||
assertArrayEquals(all().toArray(), new Object[]{"all"});
|
||||
assertArrayEquals(
|
||||
all(eq("key", 2), neq("key", 3)).toArray(),
|
||||
new Object[]{"all", new Object[]{"==", "key", 2}, new Object[]{"!=", "key", 3}}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAny() {
|
||||
assertArrayEquals(any().toArray(), new Object[]{"any"});
|
||||
assertArrayEquals(
|
||||
any(eq("key", 2), neq("key", 3)).toArray(),
|
||||
new Object[]{"any", new Object[]{"==", "key", 2}, new Object[]{"!=", "key", 3}}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNone() {
|
||||
assertArrayEquals(none().toArray(), new Object[]{"none"});
|
||||
assertArrayEquals(
|
||||
none(eq("key", 2), neq("key", 3)).toArray(),
|
||||
new Object[]{"none", new Object[]{"==", "key", 2}, new Object[]{"!=", "key", 3}}
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHas() {
|
||||
assertArrayEquals(has("key").toArray(), new Object[]{"has", "key"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHasNot() {
|
||||
assertArrayEquals(notHas("key").toArray(), new Object[]{"!has", "key"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEq() {
|
||||
assertArrayEquals(eq("key", 1).toArray(), new Object[]{"==", "key", 1});
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNeq() {
|
||||
assertArrayEquals(neq("key", 1).toArray(), new Object[]{"!=", "key", 1});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGt() {
|
||||
assertArrayEquals(gt("key", 1).toArray(), new Object[]{">", "key", 1});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGte() {
|
||||
assertArrayEquals(gte("key", 1).toArray(), new Object[]{">=", "key", 1});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLt() {
|
||||
assertArrayEquals(lt("key", 1).toArray(), new Object[]{"<", "key", 1});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLte() {
|
||||
assertArrayEquals(lte("key", 1).toArray(), new Object[]{"<=", "key", 1});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIn() {
|
||||
assertArrayEquals(in("key", 1, 2, "Aap").toArray(), new Object[]{"in", "key", 1, 2, "Aap"});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNotIn() {
|
||||
assertArrayEquals(notIn("key", 1, 2, "Noot").toArray(), new Object[]{"!in", "key", 1, 2, "Noot"});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user