Limit map area/zoom in arcGIS SceneView

743 views Asked by At

I'm using arcGIS SceneView in local viewing mode to display a WebMap. I'm trying to constrain the zoom level and bounds of an area so that the user can only see the US, Hawaii, and Alaska and cannot pan outside of this. I also need to constrain the zoom level because if the user zooms out too far the over-zoom the map and see untiled/unmapped space.

Are there any potential solves for this? I first thought that using the constraints property might solve it, but it appears the properties that can be fed to this are quite limited: https://developers.arcgis.com/javascript/latest/api-reference/esri-views-SceneView.html#constraints

1

There are 1 answers

0
cabesuon On BEST ANSWER

One way to achieve what I think you want is:

  • listen to view property changes,
  • check constraints,
  • act accordingly.

Take a look a the example I made for you. In it, I wait for the view to stop updating (updating property), then I check the constraints. If it is out of scale or out of the extent I reset the view. You probably want another action, I just made it simple.

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>
    View constraints
  </title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.17/esri/themes/light/main.css" />
  <script src="https://js.arcgis.com/4.17/"></script>

  <script>
    require([
      "esri/Map",
      "esri/views/SceneView",
      "esri/geometry/Extent"
    ], function (Map, SceneView, Extent) {

      const extent = Extent.fromJSON(
        {
          "spatialReference": {
            "latestWkid":3857,
            "wkid":102100
          },
          "xmin":-13119716.983985346,
          "ymin":4024337.3961656773,
          "xmax":-13096023.097830579,
          "ymax":4030581.302795334
        }
      );

      const MIN_SCALE = 12000;
      const MAX_SCALE = 48000;

      
      const map = new Map({
        basemap: "topo-vector",
        ground: "world-elevation"
      });

      const view = new SceneView({
        container: "viewDiv",
        map: map,
        viewingMode: "local",
        center: [-117.75, 33.99],
        scale: 24000
      });

      function resetView() {
        console.log('reset');
        view.goTo(
          {
            center:[-117.75, 33.99],
            scale: 24000
          }
        );
      }

      view.watch("updating", function (value) {
        if (!value) {
          if (
            // out of scale
            view.scale < MIN_SCALE ||
            view.scale > MAX_SCALE ||
            // out of extent
            view.extent.xmin < extent.xmin ||
            extent.xmax < view.extent.xmax ||
            view.extent.ymin < extent.ymin ||
            extent.ymax < view.extent.ymax 
          ) {
            resetView();
          };
        }
      });

    });
  </script>
  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>
</head>

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

</html>