オーバーラップの検知
<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:mapbox="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="match_parent"> <com.mapbox.mapboxsdk.maps.MapViewandroid:id="@+id/mapView"android:layout_width="match_parent"android:layout_height="match_parent"mapbox:mapbox_cameraTargetLat="36.132522"mapbox:mapbox_cameraTargetLng="16.156205"mapbox:mapbox_cameraZoom="2.494647" /> <androidx.cardview.widget.CardViewandroid:id="@+id/cardView4"android:layout_width="match_parent"android:layout_height="70dp"android:layout_marginStart="8dp"android:layout_marginLeft="8dp"android:layout_marginEnd="8dp"android:layout_marginRight="8dp"android:layout_marginBottom="16dp"mapbox:layout_constraintBottom_toTopOf="@+id/cardView5"mapbox:layout_constraintEnd_toEndOf="parent"mapbox:layout_constraintStart_toStartOf="parent"> <androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"> <TextViewandroid:id="@+id/textView3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:layout_marginLeft="8dp"android:layout_marginTop="8dp"android:text="@string/placement_explanation"mapbox:layout_constraintStart_toStartOf="parent"mapbox:layout_constraintTop_toTopOf="parent" /> <Switchandroid:id="@+id/toggle_text_ignore_placement_switch"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="end|bottom"android:layout_marginTop="8dp"android:layout_marginBottom="8dp"mapbox:layout_constraintBottom_toBottomOf="parent"mapbox:layout_constraintStart_toStartOf="@+id/textView3"mapbox:layout_constraintTop_toBottomOf="@+id/textView3" /> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.cardview.widget.CardView> <androidx.cardview.widget.CardViewandroid:id="@+id/cardView5"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:layout_marginLeft="8dp"android:layout_marginEnd="8dp"android:layout_marginRight="8dp"android:layout_marginBottom="48dp"mapbox:layout_constraintBottom_toBottomOf="@+id/mapView"mapbox:layout_constraintEnd_toEndOf="parent"mapbox:layout_constraintStart_toStartOf="parent"> <androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"> <TextViewandroid:id="@+id/textView4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:layout_marginLeft="8dp"android:layout_marginTop="8dp"android:text="@string/overlap_explanation"mapbox:layout_constraintStart_toStartOf="parent"mapbox:layout_constraintTop_toTopOf="parent" /> <Switchandroid:id="@+id/toggle_text_ignore_overlap_switch"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="end|bottom"android:layout_marginTop="8dp"mapbox:layout_constraintStart_toStartOf="@+id/textView4"mapbox:layout_constraintTop_toBottomOf="@+id/textView4" /> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.cardview.widget.CardView> <androidx.cardview.widget.CardViewandroid:id="@+id/cardView6"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:layout_marginLeft="8dp"android:layout_marginEnd="8dp"android:layout_marginRight="8dp"android:layout_marginBottom="24dp"mapbox:layout_constraintBottom_toTopOf="@+id/cardView4"mapbox:layout_constraintEnd_toEndOf="@+id/mapView"mapbox:layout_constraintStart_toStartOf="@+id/mapView"> <androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"> <TextViewandroid:id="@+id/textView5"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:layout_marginLeft="8dp"android:layout_marginTop="8dp"android:text="@string/icon_overlap_explanation"mapbox:layout_constraintStart_toStartOf="parent"mapbox:layout_constraintTop_toTopOf="parent" /> <Switchandroid:id="@+id/toggle_icon_ignore_overlap_switch"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="end|bottom"android:layout_marginTop="8dp"mapbox:layout_constraintStart_toStartOf="@+id/textView5"mapbox:layout_constraintTop_toBottomOf="@+id/textView5" /> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.cardview.widget.CardView> <androidx.cardview.widget.CardViewandroid:layout_width="395dp"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:layout_marginLeft="8dp"android:layout_marginEnd="8dp"android:layout_marginRight="8dp"android:layout_marginBottom="16dp"mapbox:layout_constraintBottom_toTopOf="@+id/cardView6"mapbox:layout_constraintEnd_toEndOf="@+id/mapView"mapbox:layout_constraintStart_toStartOf="@+id/mapView"> <androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"> <TextViewandroid:id="@+id/textView6"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:layout_marginLeft="8dp"android:layout_marginTop="8dp"android:text="@string/icon_placement_explanation"mapbox:layout_constraintStart_toStartOf="parent"mapbox:layout_constraintTop_toTopOf="parent" /> <Switchandroid:id="@+id/toggle_icon_ignore_placement_switch"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="end|bottom"android:layout_marginTop="8dp"mapbox:layout_constraintStart_toStartOf="@+id/textView6"mapbox:layout_constraintTop_toBottomOf="@+id/textView6" /> </androidx.constraintlayout.widget.ConstraintLayout> </androidx.cardview.widget.CardView> </androidx.constraintlayout.widget.ConstraintLayout>
SymbolCollisionDetectionActivity.java
package com.mapbox.mapboxandroiddemo.examples.dds; import android.graphics.BitmapFactory;import android.os.Bundle;import androidx.annotation.NonNull;import androidx.appcompat.app.AppCompatActivity;import android.widget.CompoundButton;import android.widget.Switch; 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.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.Layer;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.iconIgnorePlacement;import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.iconOffset;import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textAllowOverlap;import static com.mapbox.mapboxsdk.style.layers.PropertyFactory.textIgnorePlacement; /*** Use {@link com.mapbox.mapboxsdk.style.layers.PropertyFactory#iconIgnorePlacement(Boolean)},* {@link com.mapbox.mapboxsdk.style.layers.PropertyFactory#iconAllowOverlap(Boolean)},* {@link com.mapbox.mapboxsdk.style.layers.PropertyFactory#textIgnorePlacement(Boolean)},* and {@link com.mapbox.mapboxsdk.style.layers.PropertyFactory#iconAllowOverlap(Boolean)},* to handle icon and text collisions.*/public class SymbolCollisionDetectionActivity extends AppCompatActivity implements OnMapReadyCallback { private static final String ICON_SOURCE_ID = "ICON_SOURCE_ID";private static final String ICON_ID = "ICON_ID";private static final String ICON_LAYER_ID = "ICON_LAYER_ID";private MapView mapView;private MapboxMap mapboxMap;private List<Feature> symbolLayerIconFeatureList; @Overrideprotected 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_dds_symbol_collision); mapView = findViewById(R.id.mapView);mapView.onCreate(savedInstanceState);mapView.getMapAsync(this);} @Overridepublic void onMapReady(final MapboxMap mapboxMap) {initIconCoordinates(); mapboxMap.setStyle(new Style.Builder().fromUri(Style.MAPBOX_STREETS) // Add the SymbolLayer icon image to the map style.withImage(ICON_ID, BitmapFactory.decodeResource(SymbolCollisionDetectionActivity.this.getResources(), R.drawable.red_marker)) // Adding a GeoJson source for the SymbolLayer icons..withSource(new GeoJsonSource(ICON_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(ICON_LAYER_ID, ICON_SOURCE_ID).withProperties(PropertyFactory.iconImage(ICON_ID),iconOffset(new Float[] {0f, -9f}))), new Style.OnStyleLoaded() {@Overridepublic void onStyleLoaded(@NonNull Style style) { SymbolCollisionDetectionActivity.this.mapboxMap = mapboxMap;setUpCheckListener(R.id.toggle_text_ignore_placement_switch, true, false);setUpCheckListener(R.id.toggle_text_ignore_overlap_switch, false, false);setUpCheckListener(R.id.toggle_icon_ignore_placement_switch, false, true);setUpCheckListener(R.id.toggle_icon_ignore_overlap_switch, false, false);}});} /*** Add a {@link android.widget.CompoundButton.OnCheckedChangeListener} to a switch button and then* use the Maps SDK's runtime-styling to adjust overlap and placement logic.** @param checkboxId the id of the switch button to add a listener to* @param adjustTextIgnorePlacement whether or not text placement should be ignored* @param adjustIconIgnorePlacement whether or not icon placement should be ignored*/private void setUpCheckListener(int checkboxId, boolean adjustTextIgnorePlacement,boolean adjustIconIgnorePlacement) {Switch switchUi = findViewById(checkboxId);switchUi.setText(getString(R.string.collision_disabled));switchUi.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(CompoundButton compoundButton, boolean checked) {switchUi.setText(checked ? getString(R.string.collision_enabled) : getString(R.string.collision_disabled)); mapboxMap.getStyle(new Style.OnStyleLoaded() {@Overridepublic void onStyleLoaded(@NonNull Style style) {Layer singleLayer = style.getLayer(adjustIconIgnorePlacement ? ICON_LAYER_ID : "country-label");if (singleLayer != null) {singleLayer.setProperties(adjustTextIgnorePlacement ? textIgnorePlacement(checked) : textAllowOverlap(checked),adjustIconIgnorePlacement ? iconIgnorePlacement(checked) : iconAllowOverlap(checked));}}});}});} /*** Initialize a list of Features to use to show SymbolLayer icons.*/private void initIconCoordinates() {symbolLayerIconFeatureList = new ArrayList<>();symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(10.338784, 49.481615)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(15.081775, 49.957444)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(11.810747, 50.53269)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(16.308411, 51.35705)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(19.661215, 49.161803)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(16.799065, 46.864746)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(13.364485, 52.764672)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(8.457943, 51.203595)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(12.873831, 51.459068)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(14.836448, 52.814126)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(9.193924, 52.516561)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(12.219625, 47.143578)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(14.182242, 48.893705)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(16.717289, 50.324313)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(22.686916, 45.905823)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(7.967289, 49.904804)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(6.98598, 47.916571)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(18.925233, 44.231107)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(18.843458, 49.957444)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(-17.999544, 62.216028)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(20.151869, 46.415586)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(9.193924, 51.864868)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(16.144859, 48.732152)));symbolLayerIconFeatureList.add(Feature.fromGeometry(Point.fromLngLat(5.105139, 50.324313)));} // Add the mapView lifecycle to the activity's lifecycle methods@Overridepublic void onStart() {super.onStart();mapView.onStart();} @Overridepublic void onResume() {super.onResume();mapView.onResume();} @Overridepublic void onPause() {super.onPause();mapView.onPause();} @Overridepublic void onStop() {super.onStop();mapView.onStop();} @Overridepublic void onLowMemory() {super.onLowMemory();mapView.onLowMemory();} @Overrideprotected void onDestroy() {super.onDestroy();mapView.onDestroy();} @Overrideprotected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);mapView.onSaveInstanceState(outState);}}