Inset map
Show a smaller inset map fragment and link it to a larger map for two map interaction. Great for gaming.
package com.mapbox.maps.testapp.examples import android.graphics.Colorimport android.os.Bundleimport androidx.appcompat.app.AppCompatActivityimport com.mapbox.geojson.Featureimport com.mapbox.geojson.LineStringimport com.mapbox.geojson.Pointimport com.mapbox.maps.*import com.mapbox.maps.dsl.cameraOptionsimport com.mapbox.maps.extension.style.layers.addLayerimport com.mapbox.maps.extension.style.layers.generated.lineLayerimport com.mapbox.maps.extension.style.layers.getLayerimport com.mapbox.maps.extension.style.layers.properties.generated.LineCapimport com.mapbox.maps.extension.style.layers.properties.generated.LineJoinimport com.mapbox.maps.extension.style.layers.properties.generated.Visibilityimport com.mapbox.maps.extension.style.sources.addSourceimport com.mapbox.maps.extension.style.sources.generated.GeoJsonSourceimport com.mapbox.maps.extension.style.sources.generated.geoJsonSourceimport com.mapbox.maps.extension.style.sources.getSourceimport com.mapbox.maps.plugin.attribution.attributionimport com.mapbox.maps.plugin.compass.compassimport com.mapbox.maps.plugin.gestures.gesturesimport com.mapbox.maps.plugin.logo.logoimport com.mapbox.maps.plugin.scalebar.scalebarimport com.mapbox.maps.testapp.Rimport com.mapbox.maps.testapp.databinding.ActivityInsetMapBindingimport com.mapbox.maps.testapp.examples.fragment.MapFragment /*** Example demonstrating displaying two maps: main map and small map with lower zoom* in bottom-right corner with optional bounds showing what area is covered by main map.*/class InsetMapActivity : AppCompatActivity(), CameraChangedCallback { private lateinit var mainMapboxMap: MapboxMapprivate var insetMapboxMap: MapboxMap? = null override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val binding = ActivityInsetMapBinding.inflate(layoutInflater)setContentView(binding.root)mainMapboxMap = binding.mapView.mapboxMapmainMapboxMap.setCamera(MAIN_MAP_CAMERA_POSITION)mainMapboxMap.loadStyle(style = STYLE_URL) { mainMapboxMap.subscribeCameraChanged(this@InsetMapActivity) } var insetMapFragment: MapFragment? =supportFragmentManager.findFragmentByTag(INSET_FRAGMENT_TAG) as? MapFragmentif (insetMapFragment == null) {// Create fragment transaction for the inset fragmentval transaction = supportFragmentManager.beginTransaction()insetMapFragment = MapFragment()// Add fragmentMap fragment to parent containertransaction.add(R.id.mini_map_fragment_container, insetMapFragment, INSET_FRAGMENT_TAG)transaction.commit()}setInsetMapStyle(insetMapFragment) binding.showBoundsToggleFab.setOnClickListener {// Toggle the visibility of the camera bounds LineLayerinsetMapboxMap?.getStyle { style ->style.getLayer(BOUNDS_LINE_LAYER_LAYER_ID)?.apply {visibility(if (visibility == Visibility.VISIBLE) Visibility.NONE else Visibility.VISIBLE)}}}} private fun setInsetMapStyle(insetMapFragment: MapFragment) {insetMapFragment.getMapAsync {insetMapboxMap = itinsetMapboxMap?.apply {setCamera(INSET_CAMERA_POSITION)loadStyle(style = STYLE_URL) { style ->val source = geoJsonSource(BOUNDS_LINE_LAYER_SOURCE_ID) {feature(Feature.fromGeometry(LineString.fromLngLats(getRectanglePoints())))}style.addSource(source)// The layer properties for our line. This is where we make the line dotted, set the color, etc.val layer = lineLayer(BOUNDS_LINE_LAYER_LAYER_ID, BOUNDS_LINE_LAYER_SOURCE_ID) {lineCap(LineCap.ROUND)lineJoin(LineJoin.ROUND)lineWidth(3.0)lineColor(Color.YELLOW)visibility(Visibility.VISIBLE)}style.addLayer(layer)updateInsetMapLineLayerBounds(style)}}insetMapFragment.getMapView().apply {logo.enabled = falsescalebar.enabled = falseattribution.enabled = falsecompass.enabled = false gestures.updateSettings {scrollEnabled = falsepinchToZoomEnabled = false}}}} override fun run(cameraChanged: CameraChanged) {val mainCameraPosition = mainMapboxMap.cameraStateval insetCameraPosition = CameraOptions.Builder().zoom(mainCameraPosition.zoom.minus(ZOOM_DISTANCE_BETWEEN_MAIN_AND_INSET_MAPS)).pitch(mainCameraPosition.pitch).bearing(mainCameraPosition.bearing).center(mainCameraPosition.center).build()insetMapboxMap?.setCamera(insetCameraPosition)insetMapboxMap?.getStyle { style -> updateInsetMapLineLayerBounds(style) }} private fun updateInsetMapLineLayerBounds(fullyLoadedStyle: Style) {(fullyLoadedStyle.getSource(BOUNDS_LINE_LAYER_SOURCE_ID) as? GeoJsonSource)?.apply {feature(Feature.fromGeometry(LineString.fromLngLats(getRectanglePoints())))}} private fun getRectanglePoints(): List<Point> {val bounds = mainMapboxMap.coordinateBoundsForCamera(mainMapboxMap.cameraState.toCameraOptions())return listOf(Point.fromLngLat(bounds.northeast.longitude(), bounds.northeast.latitude()),Point.fromLngLat(bounds.northeast.longitude(), bounds.southwest.latitude()),Point.fromLngLat(bounds.southwest.longitude(), bounds.southwest.latitude()),Point.fromLngLat(bounds.southwest.longitude(), bounds.northeast.latitude()),Point.fromLngLat(bounds.northeast.longitude(), bounds.northeast.latitude()))} companion object {private const val STYLE_URL = "mapbox://styles/mapbox/cj5l80zrp29942rmtg0zctjto"private const val INSET_FRAGMENT_TAG = "com.mapbox.insetMapFragment"private const val BOUNDS_LINE_LAYER_SOURCE_ID = "BOUNDS_LINE_LAYER_SOURCE_ID"private const val BOUNDS_LINE_LAYER_LAYER_ID = "BOUNDS_LINE_LAYER_LAYER_ID"private const val ZOOM_DISTANCE_BETWEEN_MAIN_AND_INSET_MAPS = 3private val MAIN_MAP_CAMERA_POSITION = cameraOptions {center(Point.fromLngLat(106.025839, 11.302318))zoom(5.11)} private val INSET_CAMERA_POSITION = CameraOptions.Builder().zoom(MAIN_MAP_CAMERA_POSITION.zoom?.minus(ZOOM_DISTANCE_BETWEEN_MAIN_AND_INSET_MAPS)).pitch(MAIN_MAP_CAMERA_POSITION.pitch).bearing(MAIN_MAP_CAMERA_POSITION.bearing).center(MAIN_MAP_CAMERA_POSITION.center).build()}}
Was this example helpful?