From b9402a6ac3ba3ebe88545ecef93eeb6166fefe5b Mon Sep 17 00:00:00 2001 From: langsmith Date: Thu, 11 Apr 2019 17:02:40 -0700 Subject: [PATCH] initial changes refactoring the basic symbol and moving icon change example to new one --- .../mapboxandroiddemo/MainActivity.java | 9 + .../src/main/AndroidManifest.xml | 7 + .../styles/BasicSymbolLayerActivity.java | 158 ++++--------- .../styles/IconSizeChangeOnClickActivity.java | 218 ++++++++++++++++++ .../activity_style_basic_symbol_layer.xml | 18 ++ ...tyle_symbol_icon_size_change_on_click.xml} | 0 .../main/res/values/descriptions_strings.xml | 3 +- .../src/main/res/values/titles_strings.xml | 3 +- .../src/main/res/values/urls_strings.xml | 3 +- 9 files changed, 297 insertions(+), 122 deletions(-) create mode 100644 MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/styles/IconSizeChangeOnClickActivity.java create mode 100644 MapboxAndroidDemo/src/main/res/layout/activity_style_basic_symbol_layer.xml rename MapboxAndroidDemo/src/main/res/layout/{activity_basic_symbol_layer.xml => activity_style_symbol_icon_size_change_on_click.xml} (100%) diff --git a/MapboxAndroidDemo/src/global/java/com/mapbox/mapboxandroiddemo/MainActivity.java b/MapboxAndroidDemo/src/global/java/com/mapbox/mapboxandroiddemo/MainActivity.java index b73be3704..eac500b61 100644 --- a/MapboxAndroidDemo/src/global/java/com/mapbox/mapboxandroiddemo/MainActivity.java +++ b/MapboxAndroidDemo/src/global/java/com/mapbox/mapboxandroiddemo/MainActivity.java @@ -121,6 +121,7 @@ import com.mapbox.mapboxandroiddemo.examples.styles.DefaultStyleActivity; import com.mapbox.mapboxandroiddemo.examples.styles.GeojsonLayerInStackActivity; import com.mapbox.mapboxandroiddemo.examples.styles.HillShadeActivity; +import com.mapbox.mapboxandroiddemo.examples.styles.IconSizeChangeOnClickActivity; import com.mapbox.mapboxandroiddemo.examples.styles.ImageSourceActivity; import com.mapbox.mapboxandroiddemo.examples.styles.ImageSourceTimeLapseActivity; import com.mapbox.mapboxandroiddemo.examples.styles.LanguageSwitchActivity; @@ -467,6 +468,14 @@ private void initializeModels() { null, R.string.activity_styles_symbol_layer_url, false, BuildConfig.MIN_SDK_VERSION)); + exampleItemModels.add(new ExampleItemModel( + R.id.nav_styles, + R.string.activity_styles_symbol_icon_onclick_size_change_title, + R.string.activity_styles_symbol_icon_onclick_size_change_description, + new Intent(MainActivity.this, IconSizeChangeOnClickActivity.class), + null, + R.string.activity_styles_symbol_icon_onclick_size_change_url, false, BuildConfig.MIN_SDK_VERSION)); + exampleItemModels.add(new ExampleItemModel( R.id.nav_styles, R.string.activity_styles_line_layer_title, diff --git a/MapboxAndroidDemo/src/main/AndroidManifest.xml b/MapboxAndroidDemo/src/main/AndroidManifest.xml index 04e40a3e2..f07445894 100644 --- a/MapboxAndroidDemo/src/main/AndroidManifest.xml +++ b/MapboxAndroidDemo/src/main/AndroidManifest.xml @@ -487,6 +487,13 @@ android:name="android.support.PARENT_ACTIVITY" android:value="com.mapbox.mapboxandroiddemo.MainActivity" /> + + + diff --git a/MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/styles/BasicSymbolLayerActivity.java b/MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/styles/BasicSymbolLayerActivity.java index c4a13f1c5..bcf9c0b9a 100644 --- a/MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/styles/BasicSymbolLayerActivity.java +++ b/MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/styles/BasicSymbolLayerActivity.java @@ -1,8 +1,6 @@ package com.mapbox.mapboxandroiddemo.examples.styles; -import android.animation.ValueAnimator; import android.graphics.BitmapFactory; -import android.graphics.PointF; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v7.app.AppCompatActivity; @@ -12,7 +10,6 @@ import com.mapbox.geojson.Point; import com.mapbox.mapboxandroiddemo.R; import com.mapbox.mapboxsdk.Mapbox; -import com.mapbox.mapboxsdk.geometry.LatLng; import com.mapbox.mapboxsdk.maps.MapView; import com.mapbox.mapboxsdk.maps.MapboxMap; import com.mapbox.mapboxsdk.maps.OnMapReadyCallback; @@ -24,17 +21,19 @@ import java.util.ArrayList; import java.util.List; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap; import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconOffset; /** - * Display markers on the map by adding a symbol layer + * Display {@link SymbolLayer} icons on the map. */ public class BasicSymbolLayerActivity extends AppCompatActivity implements - OnMapReadyCallback, MapboxMap.OnMapClickListener { + OnMapReadyCallback { + private static final String SOURCE_ID = "SOURCE_ID"; + private static final String ICON_ID = "ICON_ID"; + private static final String LAYER_ID = "LAYER_ID"; private MapView mapView; - private MapboxMap mapboxMap; - private boolean markerSelected = false; @Override protected void onCreate(Bundle savedInstanceState) { @@ -45,7 +44,7 @@ protected void onCreate(Bundle savedInstanceState) { Mapbox.getInstance(this, getString(R.string.access_token)); // This contains the MapView in XML and needs to be called after the access token is configured. - setContentView(R.layout.activity_basic_symbol_layer); + setContentView(R.layout.activity_style_basic_symbol_layer); mapView = findViewById(R.id.mapView); mapView.onCreate(savedInstanceState); @@ -55,117 +54,41 @@ protected void onCreate(Bundle savedInstanceState) { @Override public void onMapReady(@NonNull final MapboxMap mapboxMap) { - this.mapboxMap = mapboxMap; - - mapboxMap.setStyle(Style.DARK, new Style.OnStyleLoaded() { - @Override - public void onStyleLoaded(@NonNull Style style) { - List markerCoordinates = new ArrayList<>(); - markerCoordinates.add(Feature.fromGeometry( - Point.fromLngLat(-71.065634, 42.354950))); // Boston Common Park - markerCoordinates.add(Feature.fromGeometry( - Point.fromLngLat(-71.097293, 42.346645))); // Fenway Park - markerCoordinates.add(Feature.fromGeometry( - Point.fromLngLat(-71.053694, 42.363725))); // The Paul Revere House - - style.addSource(new GeoJsonSource("marker-source", - FeatureCollection.fromFeatures(markerCoordinates))); - - // Add the marker image to map - style.addImage("my-marker-image", BitmapFactory.decodeResource( - BasicSymbolLayerActivity.this.getResources(), R.drawable.blue_marker_view)); - - // Adding an offset so that the bottom of the blue icon gets fixed to the coordinate, rather than the - // middle of the icon being fixed to the coordinate point. - style.addLayer(new SymbolLayer("marker-layer", "marker-source") - .withProperties(PropertyFactory.iconImage("my-marker-image"), - iconOffset(new Float[]{0f, -9f}))); - - // Add the selected marker source and layer - style.addSource(new GeoJsonSource("selected-marker")); - - // Adding an offset so that the bottom of the blue icon gets fixed to the coordinate, rather than the - // middle of the icon being fixed to the coordinate point. - style.addLayer(new SymbolLayer("selected-marker-layer", "selected-marker") - .withProperties(PropertyFactory.iconImage("my-marker-image"), - iconOffset(new Float[]{0f, -9f}))); - - mapboxMap.addOnMapClickListener(BasicSymbolLayerActivity.this); - } - }); - } + List symbolLayerIconFeatureList = new ArrayList<>(); + symbolLayerIconFeatureList.add(Feature.fromGeometry( + Point.fromLngLat(-57.225365, -33.213144))); + symbolLayerIconFeatureList.add(Feature.fromGeometry( + Point.fromLngLat(-54.14164, -33.981818))); + symbolLayerIconFeatureList.add(Feature.fromGeometry( + Point.fromLngLat(-56.990533, -30.583266))); - @Override - public boolean onMapClick(@NonNull LatLng point) { - Style style = mapboxMap.getStyle(); - if (style != null) { - final SymbolLayer selectedMarkerSymbolLayer = - (SymbolLayer) style.getLayer("selected-marker-layer"); - - final PointF pixel = mapboxMap.getProjection().toScreenLocation(point); - List features = mapboxMap.queryRenderedFeatures(pixel, "marker-layer"); - List selectedFeature = mapboxMap.queryRenderedFeatures( - pixel, "selected-marker-layer"); - - if (selectedFeature.size() > 0 && markerSelected) { - return false; - } - - if (features.isEmpty()) { - if (markerSelected) { - deselectMarker(selectedMarkerSymbolLayer); - } - return false; - } - - GeoJsonSource source = style.getSourceAs("selected-marker"); - if (source != null) { - source.setGeoJson(FeatureCollection.fromFeatures( - new Feature[]{Feature.fromGeometry(features.get(0).geometry())})); - } - - if (markerSelected) { - deselectMarker(selectedMarkerSymbolLayer); - } - if (features.size() > 0) { - selectMarker(selectedMarkerSymbolLayer); - } - } - return true; - } + mapboxMap.setStyle(new Style.Builder().fromUrl("mapbox://styles/mapbox/cjf4m44iw0uza2spb3q0a7s41") - private void selectMarker(final SymbolLayer iconLayer) { - ValueAnimator markerAnimator = new ValueAnimator(); - markerAnimator.setObjectValues(1f, 2f); - markerAnimator.setDuration(300); - markerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - - @Override - public void onAnimationUpdate(ValueAnimator animator) { - iconLayer.setProperties( - PropertyFactory.iconSize((float) animator.getAnimatedValue()) - ); - } - }); - markerAnimator.start(); - markerSelected = true; - } + // Add the SymbolLayer icon image to the map style + .withImage(ICON_ID, BitmapFactory.decodeResource( + BasicSymbolLayerActivity.this.getResources(), R.drawable.red_marker)) - private void deselectMarker(final SymbolLayer iconLayer) { - ValueAnimator markerAnimator = new ValueAnimator(); - markerAnimator.setObjectValues(2f, 1f); - markerAnimator.setDuration(300); - markerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - - @Override - public void onAnimationUpdate(ValueAnimator animator) { - iconLayer.setProperties( - PropertyFactory.iconSize((float) animator.getAnimatedValue()) - ); - } - }); - markerAnimator.start(); - markerSelected = false; + // Adding a GeoJson source for the SymbolLayer icons. + .withSource(new GeoJsonSource(SOURCE_ID, + FeatureCollection.fromFeatures(symbolLayerIconFeatureList))) + + // Adding the actual SymbolLayer to the map style. An offset is added that the bottom of the red + // marker icon gets fixed to the coordinate, rather than the middle of the icon being fixed to + // the coordinate point. This is offset is not always needed and is dependent on the image + // that you use for the SymbolLayer icon. + .withLayer(new SymbolLayer(LAYER_ID, SOURCE_ID) + .withProperties(PropertyFactory.iconImage(ICON_ID), + iconAllowOverlap(true), + iconOffset(new Float[] {0f, -9f})) + ), new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + + // Map is set up and the style has loaded. Now you can add additional data or make other map adjustments. + + + } + }); } @Override @@ -201,9 +124,6 @@ public void onLowMemory() { @Override protected void onDestroy() { super.onDestroy(); - if (mapboxMap != null) { - mapboxMap.removeOnMapClickListener(this); - } mapView.onDestroy(); } diff --git a/MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/styles/IconSizeChangeOnClickActivity.java b/MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/styles/IconSizeChangeOnClickActivity.java new file mode 100644 index 000000000..8738048b8 --- /dev/null +++ b/MapboxAndroidDemo/src/main/java/com/mapbox/mapboxandroiddemo/examples/styles/IconSizeChangeOnClickActivity.java @@ -0,0 +1,218 @@ +package com.mapbox.mapboxandroiddemo.examples.styles; + +import android.animation.ValueAnimator; +import android.graphics.BitmapFactory; +import android.graphics.PointF; +import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v7.app.AppCompatActivity; + +import com.mapbox.geojson.Feature; +import com.mapbox.geojson.FeatureCollection; +import com.mapbox.geojson.Point; +import com.mapbox.mapboxandroiddemo.R; +import com.mapbox.mapboxsdk.Mapbox; +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.maps.Style; +import com.mapbox.mapboxsdk.style.layers.PropertyFactory; +import com.mapbox.mapboxsdk.style.layers.SymbolLayer; +import com.mapbox.mapboxsdk.style.sources.GeoJsonSource; + +import java.util.ArrayList; +import java.util.List; + +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconAllowOverlap; +import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconOffset; + +/** + * Use a SymbolLayer to display icons and then change an icon's size when tapped on. + */ +public class IconSizeChangeOnClickActivity extends AppCompatActivity implements + OnMapReadyCallback, MapboxMap.OnMapClickListener { + + private MapView mapView; + private MapboxMap mapboxMap; + private boolean markerSelected = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Mapbox access token is configured here. This needs to be called either in your application + // object or in the same activity which contains the mapview. + Mapbox.getInstance(this, getString(R.string.access_token)); + + // This contains the MapView in XML and needs to be called after the access token is configured. + setContentView(R.layout.activity_style_symbol_icon_size_change_on_click); + + mapView = findViewById(R.id.mapView); + mapView.onCreate(savedInstanceState); + mapView.getMapAsync(this); + } + + @Override + public void onMapReady(@NonNull final MapboxMap mapboxMap) { + + this.mapboxMap = mapboxMap; + + mapboxMap.setStyle(Style.DARK, new Style.OnStyleLoaded() { + @Override + public void onStyleLoaded(@NonNull Style style) { + List markerCoordinates = new ArrayList<>(); + markerCoordinates.add(Feature.fromGeometry( + Point.fromLngLat(-71.065634, 42.354950))); // Boston Common Park + markerCoordinates.add(Feature.fromGeometry( + Point.fromLngLat(-71.097293, 42.346645))); // Fenway Park + markerCoordinates.add(Feature.fromGeometry( + Point.fromLngLat(-71.053694, 42.363725))); // The Paul Revere House + + style.addSource(new GeoJsonSource("marker-source", + FeatureCollection.fromFeatures(markerCoordinates))); + + // Add the marker image to map + style.addImage("my-marker-image", BitmapFactory.decodeResource( + IconSizeChangeOnClickActivity.this.getResources(), R.drawable.blue_marker_view)); + + // Adding an offset so that the bottom of the blue icon gets fixed to the coordinate, rather than the + // middle of the icon being fixed to the coordinate point. + style.addLayer(new SymbolLayer("marker-layer", "marker-source") + .withProperties(PropertyFactory.iconImage("my-marker-image"), + iconAllowOverlap(true), + iconOffset(new Float[]{0f, -9f}))); + + // Add the selected marker source and layer + style.addSource(new GeoJsonSource("selected-marker")); + + // Adding an offset so that the bottom of the blue icon gets fixed to the coordinate, rather than the + // middle of the icon being fixed to the coordinate point. + style.addLayer(new SymbolLayer("selected-marker-layer", "selected-marker") + .withProperties(PropertyFactory.iconImage("my-marker-image"), + iconAllowOverlap(true), + iconOffset(new Float[]{0f, -9f}))); + + mapboxMap.addOnMapClickListener(IconSizeChangeOnClickActivity.this); + } + }); + } + + @Override + public boolean onMapClick(@NonNull LatLng point) { + Style style = mapboxMap.getStyle(); + if (style != null) { + final SymbolLayer selectedMarkerSymbolLayer = + (SymbolLayer) style.getLayer("selected-marker-layer"); + + final PointF pixel = mapboxMap.getProjection().toScreenLocation(point); + List features = mapboxMap.queryRenderedFeatures(pixel, "marker-layer"); + List selectedFeature = mapboxMap.queryRenderedFeatures( + pixel, "selected-marker-layer"); + + if (selectedFeature.size() > 0 && markerSelected) { + return false; + } + + if (features.isEmpty()) { + if (markerSelected) { + deselectMarker(selectedMarkerSymbolLayer); + } + return false; + } + + GeoJsonSource source = style.getSourceAs("selected-marker"); + if (source != null) { + source.setGeoJson(FeatureCollection.fromFeatures( + new Feature[]{Feature.fromGeometry(features.get(0).geometry())})); + } + + if (markerSelected) { + deselectMarker(selectedMarkerSymbolLayer); + } + if (features.size() > 0) { + selectMarker(selectedMarkerSymbolLayer); + } + } + return true; + } + + private void selectMarker(final SymbolLayer iconLayer) { + ValueAnimator markerAnimator = new ValueAnimator(); + markerAnimator.setObjectValues(1f, 2f); + markerAnimator.setDuration(300); + markerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + + @Override + public void onAnimationUpdate(ValueAnimator animator) { + iconLayer.setProperties( + PropertyFactory.iconSize((float) animator.getAnimatedValue()) + ); + } + }); + markerAnimator.start(); + markerSelected = true; + } + + private void deselectMarker(final SymbolLayer iconLayer) { + ValueAnimator markerAnimator = new ValueAnimator(); + markerAnimator.setObjectValues(2f, 1f); + markerAnimator.setDuration(300); + markerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + + @Override + public void onAnimationUpdate(ValueAnimator animator) { + iconLayer.setProperties( + PropertyFactory.iconSize((float) animator.getAnimatedValue()) + ); + } + }); + markerAnimator.start(); + markerSelected = false; + } + + @Override + public void onResume() { + super.onResume(); + mapView.onResume(); + } + + @Override + protected void onStart() { + super.onStart(); + mapView.onStart(); + } + + @Override + protected void onStop() { + super.onStop(); + mapView.onStop(); + } + + @Override + public void onPause() { + super.onPause(); + mapView.onPause(); + } + + @Override + public void onLowMemory() { + super.onLowMemory(); + mapView.onLowMemory(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + if (mapboxMap != null) { + mapboxMap.removeOnMapClickListener(this); + } + mapView.onDestroy(); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + mapView.onSaveInstanceState(outState); + } +} diff --git a/MapboxAndroidDemo/src/main/res/layout/activity_style_basic_symbol_layer.xml b/MapboxAndroidDemo/src/main/res/layout/activity_style_basic_symbol_layer.xml new file mode 100644 index 000000000..93435981f --- /dev/null +++ b/MapboxAndroidDemo/src/main/res/layout/activity_style_basic_symbol_layer.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/MapboxAndroidDemo/src/main/res/layout/activity_basic_symbol_layer.xml b/MapboxAndroidDemo/src/main/res/layout/activity_style_symbol_icon_size_change_on_click.xml similarity index 100% rename from MapboxAndroidDemo/src/main/res/layout/activity_basic_symbol_layer.xml rename to MapboxAndroidDemo/src/main/res/layout/activity_style_symbol_icon_size_change_on_click.xml diff --git a/MapboxAndroidDemo/src/main/res/values/descriptions_strings.xml b/MapboxAndroidDemo/src/main/res/values/descriptions_strings.xml index 245926e1c..21803a875 100644 --- a/MapboxAndroidDemo/src/main/res/values/descriptions_strings.xml +++ b/MapboxAndroidDemo/src/main/res/values/descriptions_strings.xml @@ -24,7 +24,8 @@ Use GeoJSON and SymbolLayer icons to view clustered images. Create a GeoJSON line source, style it using properties, and add the layer to the map. Style a line with colored gradient. - Display markers on the map by adding a symbol layer. Query the map and animate the icon size if clicked on. + Use a SymbolLayer to display icons on the map. + Query the map and animate the change in a SymbolLayer icon\'s size if clicked on. Load a locally stored map style JSON file or custom raster style via a URL. Use an image source and a runnable to show data changes over time. Use an image source to easily display images on the map. diff --git a/MapboxAndroidDemo/src/main/res/values/titles_strings.xml b/MapboxAndroidDemo/src/main/res/values/titles_strings.xml index 7c5f0ecef..965b5706b 100644 --- a/MapboxAndroidDemo/src/main/res/values/titles_strings.xml +++ b/MapboxAndroidDemo/src/main/res/values/titles_strings.xml @@ -21,7 +21,8 @@ Create hotspots from points CircleLayer clusters Create a line layer - Marker symbol layer + Symbol layer icons + Symbol layer icon size change Local style or custom raster style Show time lapse Use an image source diff --git a/MapboxAndroidDemo/src/main/res/values/urls_strings.xml b/MapboxAndroidDemo/src/main/res/values/urls_strings.xml index 420e44a4b..c8e078594 100644 --- a/MapboxAndroidDemo/src/main/res/values/urls_strings.xml +++ b/MapboxAndroidDemo/src/main/res/values/urls_strings.xml @@ -23,8 +23,9 @@ http://i.imgur.com/fGeZhcD.png http://i.imgur.com/Iqxoing.png https://i.imgur.com/cXthmpV.png - http://i.imgur.com/TQ4iA0L.png + https://i.imgur.com/Q5TJIca.png https://i.imgur.com/ckKOHg6.png + http://i.imgur.com/TQ4iA0L.png http://i.imgur.com/ijoGPrF.png https://i.imgur.com/I6B6cCE.png https://i.imgur.com/U2OKixV.png