> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/android/ja/maps/llms.txt)

# Restrict map panning

![Restrict the map's viewport to a specified set of coordinates for gesture-based camera changes. The viewport can still be changed programmatically.](https://docs.mapbox.com/android/ja/assets/ideal-img/maps-examples-restrict-map-panning.42caf20.480.png)

This example demonstrates how to restrict user gestures within a specified bounds using the **Mapbox Maps SDK for Android**.

Using the example UI, users can select between 4 different options to set the map bounds to:

-   San Francisco
-   Focused around the Equator
-   Around the International Date Line (IDL)
-   Removing the restriction and allowing full view of the globe.

The code below set the different bounds by grabbing the longitude and latitude of two or four different point on the maps and creating [`CoordinateBounds`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps/-coordinate-bounds/-coordinate-bounds.html), and then passing that bounds and the zoom level onto [`mapboxMap.setBounds`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps.plugin.delegates/-map-camera-manager-delegate/set-bounds.html) which creates the boundary and then is passed into the [`CameraBoundsOptions`](https://docs.mapbox.com/android/maps/api/latest/mapbox-maps-android/com.mapbox.maps/-camera-bounds-options/).

> **Note: Android Examples App Available**
> 
> This example code is part of the **Maps SDK for Android Examples App**, a working Android project [available on GitHub](https://github.com/mapbox/mapbox-maps-android/tree/v11.28.0/). Android developers are encouraged to run the examples app locally to interact with this example in an emulator and explore other features of the Maps SDK.
> 
> See our [Run the Maps SDK for Android Examples App](https://docs.mapbox.com/help/tutorials/maps-sdk-android-examples-app/) tutorial for step-by-step instructions.

**Kotlin**

Title: `RestrictBoundsActivity.kt`

[View on GitHub](https://github.com/mapbox/mapbox-maps-android/blob/v11.28.0/app/src/main/java/com/mapbox/maps/testapp/examples/camera/RestrictBoundsActivity.kt)

```kt
package com.mapbox.maps.testapp.examples.camera

import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Bundle
import android.view.Gravity
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import com.mapbox.geojson.FeatureCollection
import com.mapbox.geojson.Point
import com.mapbox.geojson.Polygon
import com.mapbox.maps.CameraBoundsOptions
import com.mapbox.maps.CoordinateBounds
import com.mapbox.maps.MapboxMap
import com.mapbox.maps.Style
import com.mapbox.maps.extension.style.layers.generated.FillLayer
import com.mapbox.maps.extension.style.layers.generated.fillLayer
import com.mapbox.maps.extension.style.layers.getLayerAs
import com.mapbox.maps.extension.style.layers.properties.generated.Visibility
import com.mapbox.maps.extension.style.sources.generated.GeoJsonSource
import com.mapbox.maps.extension.style.sources.generated.geoJsonSource
import com.mapbox.maps.extension.style.sources.getSourceAs
import com.mapbox.maps.extension.style.style
import com.mapbox.maps.testapp.R
import com.mapbox.maps.testapp.databinding.ActivityRestrictBoundsBinding

/**
 * Test activity showcasing restricting user gestures to a bounds around Iceland, almost worldview and IDL.
 */
class RestrictBoundsActivity : AppCompatActivity() {

  private lateinit var mapboxMap: MapboxMap
  private lateinit var binding: ActivityRestrictBoundsBinding

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityRestrictBoundsBinding.inflate(layoutInflater)
    setContentView(binding.root)
    mapboxMap = binding.mapView.mapboxMap
    mapboxMap.loadStyle(
      style(Style.STANDARD) {
        +geoJsonSource(BOUNDS_ID) {
          featureCollection(FeatureCollection.fromFeatures(listOf()))
        }
        +fillLayer(BOUNDS_ID, BOUNDS_ID) {
          fillColor(Color.RED)
          fillOpacity(0.15)
          visibility(Visibility.NONE)
          slot("bottom")
        }
      }
    ) { setupBounds(SAN_FRANCISCO_BOUND) }
    showCrosshair()
  }

  override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.menu_bounds, menu)
    return true
  }

  override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return when (item.itemId) {
      R.id.menu_action_san_francisco_bounds -> {
        setupBounds(SAN_FRANCISCO_BOUND)
        true
      }
      R.id.menu_action_allmost_world_bounds -> {
        setupBounds(ALMOST_WORLD_BOUNDS)
        true
      }
      R.id.menu_action_cross_idl -> {
        setupBounds(CROSS_IDL_BOUNDS)
        true
      }
      R.id.menu_action_reset -> {
        setupBounds(INFINITE_BOUNDS)
        true
      }
      R.id.menu_action_toggle_bounds -> {
        toggleShowBounds()
        true
      }
      else -> {
        super.onOptionsItemSelected(item)
      }
    }
  }

  private fun toggleShowBounds() {
    mapboxMap.getStyle {
      val boundsFillLayer = it.getLayerAs<FillLayer>(BOUNDS_ID)!!
      val visibility: Visibility = boundsFillLayer.visibility!!
      when (visibility) {
        Visibility.NONE -> boundsFillLayer.visibility(Visibility.VISIBLE)
        Visibility.VISIBLE -> boundsFillLayer.visibility(Visibility.NONE)
      }
    }
  }

  private fun setupBounds(bounds: CameraBoundsOptions) {
    mapboxMap.getStyle { style ->
      setupBoundsArea(bounds, style)
    }
  }

  private fun setupBoundsArea(boundsOptions: CameraBoundsOptions, style: Style) {
    mapboxMap.setBounds(boundsOptions)
    // In this example we always have bounds
    val bounds = boundsOptions.bounds!!
    if (!bounds.infiniteBounds) {
      val northEast = bounds.northeast
      val southWest = bounds.southwest
      val northWest = Point.fromLngLat(southWest.longitude(), northEast.latitude())
      val southEast = Point.fromLngLat(northEast.longitude(), southWest.latitude())
      val boundsBox = listOf(northEast, southEast, southWest, northWest, northEast)
      // Update the source with the new bounds
      style.getSourceAs<GeoJsonSource>(BOUNDS_ID)!!.geometry(
        // We only want one polygon: the box around the bounds
        Polygon.fromLngLats(listOf(boundsBox))
      )
    }
  }

  private fun showCrosshair() {
    val crosshair = View(this)
    crosshair.layoutParams = FrameLayout.LayoutParams(10, 10, Gravity.CENTER)
    crosshair.setBackgroundColor(Color.BLUE)
    binding.mapView.addView(crosshair)
  }

  companion object {
    private const val BOUNDS_ID = "BOUNDS_ID"
    private val SAN_FRANCISCO_BOUND: CameraBoundsOptions = CameraBoundsOptions.Builder()
      .bounds(
        CoordinateBounds(
          Point.fromLngLat(-122.66336, 37.492987),
          Point.fromLngLat(-122.250481, 37.87165),
          false
        )
      )
      .minZoom(10.0)
      .build()

    private val ALMOST_WORLD_BOUNDS: CameraBoundsOptions = CameraBoundsOptions.Builder()
      .bounds(
        CoordinateBounds(
          Point.fromLngLat(-170.0, -20.0),
          Point.fromLngLat(170.0, 20.0),
          false
        )
      )
      .minZoom(2.0)
      .build()

    @SuppressLint("Range")
    private val CROSS_IDL_BOUNDS: CameraBoundsOptions = CameraBoundsOptions.Builder()
      .bounds(
        CoordinateBounds(
          Point.fromLngLat(170.0202020, -20.0),
          Point.fromLngLat(190.0, 20.0),
          false
        )
      )
      .minZoom(2.0)
      .build()

    private val INFINITE_BOUNDS: CameraBoundsOptions = CameraBoundsOptions.Builder()
      .bounds(
        CoordinateBounds(
          Point.fromLngLat(0.0, 0.0),
          Point.fromLngLat(0.0, 0.0),
          true
        )
      )
      .build()
  }
}
```