javascripthtmlarcgisarcgis-js-api

Don't allow user to navigate or zoom out the area ARCGIS


require(["esri/Map", "esri/views/MapView"], function(Map, MapView) {
  var map = new Map({
    basemap: "topo-vector"
  });
 //create mapview
  var view = new MapView({
    container: "viewDiv",
    map: map,
    zoom: 4,
    center: [106.206230, 15.047079],
    constraints: {
      rotationEnabled: false,
      geometry: { // geo
        type: "extent",
        xmin: 97.539469,
        ymin: 25.084159,
        xmax: 114.382060,
        ymax: 6.848810
      },
    }, // longitude, latitude
  });
});
html,
body,
#viewDiv {
  padding: 0;
  margin: 0;
  height: 100%;
  width: 100%;
}
<link href="https://js.arcgis.com/4.18/esri/themes/light/main.css" rel="stylesheet" />
</head>
<script src="https://js.arcgis.com/4.18/"></script>
</head>

<body>
  <div id="viewDiv"></div>
</body>

</html>

I want users to just navigate and zoom in on the area that I choose. I use geometry but it doesn't work, users still can zoom out the area.

Is there any way to achieve that feature?


Solution

  • Your attempt was good but not enough. The constraints property is useful for scales and zoom, but in your case will not be good for a an area. The reason is that the extent of constraints property is to permit lateral movement.

    So, I propose you to use constraints property for zoom levels and use a custom logic to maintain the user in a certain area. The code I made for you is just one example, listen to changes on the view and act accordingly. In this case I check if view center point is in the desire extent, if not I correct it.

    <html>
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
      <title>ArcGIS API for JavaScript Hello World App</title>
      <style>
        html, body, #viewDiv {
          padding: 0;
          margin: 0;
          height: 100%;
          width: 100%;
        }
      </style>
    
      <link rel="stylesheet" href="https://js.arcgis.com/4.15/esri/css/main.css">
      <script src="https://js.arcgis.com/4.18/"></script>
    
      <script>
        require([
          'esri/Map',
          'esri/views/MapView',
          'esri/Graphic',
          'esri/geometry/Extent',
          'esri/geometry/SpatialReference'
        ], function(Map, MapView, Graphic, Extent, SpatialReference) {
    
          const map = new Map({
            basemap: 'topo-vector'
          });
    
          const extent = new Extent({
            xmin: 97.539469,
            ymin: 25.084159,
            xmax: 114.382060,
            ymax: 6.848810,
            spatialReference: new SpatialReference({ wkid: 4326 })
          });
    
          const view = new MapView({
            container: 'viewDiv',
            map: map,
            zoom: 8,
            center: [106.206230, 15.047079],
            constraints: {
              minZoom: 8,
              maxZoom: 10
            }
          });
    
          view.graphics.add(
            new Graphic({
              geometry: extent,
              symbol: {
                type: 'simple-fill',
                fill: 'none',
                outline: {
                  color: 'red',
                  width: 2
                }
              }
            })
          );
    
          view.watch('updating', function(value) {
            if (!value && view.center) {
              const c = view.center.clone();
              if (c.longitude < extent.xmin) {
                c.longitude = extent.xmin;
              } else if (c.longitude > extent.xmax) {
                c.longitude = extent.xmax;
              }
              if (c.latitude > extent.ymin) {
                c.latitude = extent.ymin;
              } else if (c.latitude < extent.ymax) {
                c.latitude = extent.ymax;
              }
              if (!c.equals(view.center)) {
                view.goTo({ center: c }, { duration: 0 });
              }
            }
          });
        });
      </script>
    </head>
    <body>
      <div id="viewDiv"></div>
    </body>
    </html>