Zoom to Layer Extent

2661
9
Jump to solution
09-20-2018 08:26 AM
ToddFagin
Occasional Contributor II

I am trying to create a function to zoom to the extent of a layer. I have found a good example here, but my JavaScript skills and knowledge of the JSAPI is just not good enough to cannibalize and shoehorn this into my simple example (I only attempt my hand at it about once every eight months or so). Rather than further bumbling the code (and after seeking additional examples to no avail), I thought I would seek assistance from others much more knowledgeable than I.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Intro to MapView - Create a 2D map - 4.7</title>
  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>

  <link rel="stylesheet" href="https://js.arcgis.com/4.7/esri/css/main.css">
  <script ></script>

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/geometry/support/webMercatorUtils",
      "esri/widgets/Search",
      "esri/widgets/Locate",
      "esri/widgets/Expand",
      "esri/layers/TileLayer",
      "esri/widgets/LayerList",
      "esri/widgets/BasemapGallery",
      "dojo/dom",
      "dojo/domReady!"
    ], function(Map, MapView, webMercatorUtils, Search, Locate, Expand, TileLayer, LayerList, BasemapGallery, dom) {


      var droneimage1 = new TileLayer({
          url: "https://tiles.arcgis.com/tiles/3xOwF6p0r7IHIjfn/arcgis/rest/services/a010002_1/MapServer",
          title: "Drone Image"
       });
       
       
      var map = new Map({
        basemap: "streets",
        layers: [droneimage1]
      });

      var view = new MapView({
        container: "viewDiv",
        map: map,
        zoom: 15,
        center: [-103.064, 36.175] // longitude, latitude
      });
      

      function showCoordinates(evt) {
        var point = view.toMap({x: evt.x, y: evt.y});
        //the map is in web mercator but display coordinates in geographic (lat, long)
        var mp = webMercatorUtils.webMercatorToGeographic(point);
        //display mouse coordinates
        dom.byId("info").innerHTML = mp.x.toFixed(3) + ", " + mp.y.toFixed(3);
      }

      view.when(function(){
        //after map loads, connect to listen to mouse move & drag events
        view.on("pointer-move", showCoordinates);
      });
      
      // create a search widget
       var searchWidget = new Search({
        view: view
      });

      // create the locate widget
      var locateBtn = new Locate({
        view: view
      });

      // Add the locate widget to the top left corner of the view
      view.ui.add(locateBtn, {
        position: "top-left"
      });
      

      // Add the search widget to the top right corner of the view
      view.ui.add(searchWidget, {
        position: "top-right"
      });
      
      
      
      // create a layer list widget
      var layerList = new LayerList({
        view: view,
        
     // executes for each ListItem in the LayerList
        listItemCreatedFunction: function (event) {
        
     // The event object contains properties of the
     // layer in the LayerList widget.
        var item = event.item;      
                
     // set an action for zooming to the full extent of the layer
              item.actionsSections = [[{
                title: "Zoom to layer",
                className: "esri-icon-zoom-out-fixed",
                id: "full-extent"
              }]];  
            }

      });
      view.ui.add(layerList, "bottom-left");
      
      

      
      
      // Create a BasemapGallery widget instance and set
      // its container to a div element

      var basemapGallery = new BasemapGallery({
        view: view,
        container: document.createElement("div")
      });
      
      // Create an Expand instance and set the content
      // property to the DOM node of the basemap gallery widget
      // Use an Esri icon font to represent the content inside
      // of the Expand widget

      var bgExpand = new Expand({
        view: view,
        content: basemapGallery
      });
      
      // Add the expand instance to the ui

      view.ui.add(bgExpand, "top-left");
      
      


    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
  <span id="info" style="position:absolute; right:25px; bottom: 25px; color:#000000; font-size: 12px; z-index:50;"></span>
</body>
</html>

Thanks,

Todd

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Esteemed Contributor

Todd,

  Sorry I missed that you were missing the actual zoom to layer code.

Here is your example fixed:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Intro to MapView - Create a 2D map - 4.8</title>
  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>

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

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/geometry/support/webMercatorUtils",
      "esri/widgets/Search",
      "esri/widgets/Locate",
      "esri/widgets/Expand",
      "esri/layers/TileLayer",
      "esri/layers/FeatureLayer",
      "esri/widgets/LayerList",
      "esri/widgets/BasemapGallery",
      "esri/tasks/GeometryService",
      "esri/tasks/support/ProjectParameters",
      "dojo/dom",
      "dojo/domReady!"
    ], function(Map, MapView, webMercatorUtils, Search, Locate, Expand, TileLayer, FeatureLayer, LayerList, BasemapGallery,
      GeometryService, ProjectParameters, dom) {

      var droneimage1 = new TileLayer({
        url: "https://tiles.arcgis.com/tiles/3xOwF6p0r7IHIjfn/arcgis/rest/services/a010002_1/MapServer",
        title: "Drone Image"
      });
      var eco = new FeatureLayer({
        url: "http://services.arcgis.com/3xOwF6p0r7IHIjfn/arcgis/rest/services/OK_LevelIII_Ecoregions/FeatureServe...",
        title: "Oklahoma Ecoregions"
      });


      var map = new Map({
        basemap: "streets",
        layers: [droneimage1, eco]
      });

      var view = new MapView({
        container: "viewDiv",
        map: map,
        zoom: 15,
        center: [-103.064, 36.175] // longitude, latitude
      });

      function showCoordinates(evt) {
        var point = view.toMap({
          x: evt.x,
          y: evt.y
        });
        //the map is in web mercator but display coordinates in geographic (lat, long)
        var mp = webMercatorUtils.webMercatorToGeographic(point);
        //display mouse coordinates
        dom.byId("info").innerHTML = mp.x.toFixed(3) + ", " + mp.y.toFixed(3);
      }

      view.when(function() {
        //after map loads, connect to listen to mouse move & drag events
        view.on("pointer-move", showCoordinates);
      });

      // create a search widget
      var searchWidget = new Search({
        view: view
      });

      // create the locate widget
      var locateBtn = new Locate({
        view: view
      });

      // Add the locate widget to the top left corner of the view
      view.ui.add(locateBtn, {
        position: "top-left"
      });

      // Add the search widget to the top right corner of the view
      view.ui.add(searchWidget, {
        position: "top-right"
      });

      // create a layer list widget
      var layerList = new LayerList({
        view: view,

        // executes for each ListItem in the LayerList
        listItemCreatedFunction: function(event) {

          // The event object contains properties of the
          // layer in the LayerList widget.
          var item = event.item;

          // set an action for zooming to the full extent of the layer
          item.actionsSections = [
            [{
              title: "Zoom to layer",
              className: "esri-icon-zoom-out-fixed",
              id: "full-extent"
            }]
          ];
        }

      });
      layerList.on("trigger-action", function(event) {
        // Capture the action id.
        var id = event.action.id;

        if (id === "full-extent") {
          // if the full-extent action is triggered then navigate
          // to the full extent of the visible layer
          if(event.item.layer.fullExtent.spatialReference !== view.spatialReference){
            var geomSer = new GeometryService({url: 'http://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer'});
            var params = new ProjectParameters({
              geometries: [event.item.layer.fullExtent],
              outSpatialReference: view.spatialReference
            });
            geomSer.project(params).then(function(results){
              view.goTo(results[0]);
            });
          }else{
            view.goTo(event.item.layer.fullExtent);
          }
        }
      });

      view.ui.add(layerList, "bottom-left");

      // Create a BasemapGallery widget instance and set
      // its container to a div element
      var basemapGallery = new BasemapGallery({
        view: view,
        container: document.createElement("div")
      });

      // Create an Expand instance and set the content
      // property to the DOM node of the basemap gallery widget
      // Use an Esri icon font to represent the content inside
      // of the Expand widget
      var bgExpand = new Expand({
        view: view,
        content: basemapGallery
      });

      // Add the expand instance to the ui
      view.ui.add(bgExpand, "top-left");
    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
  <span id="info" style="position:absolute; right:25px; bottom: 25px; color:#000000; font-size: 12px; z-index:50;"></span>
</body>

</html>

View solution in original post

0 Kudos
9 Replies
RobertScheitlin__GISP
MVP Esteemed Contributor

Todd,

   You are already zoomed to the fullExtent of the droneimage1 layer. based on the fullExtent property of that layer.

0 Kudos
ToddFagin
Occasional Contributor II

Robert,

I appreciate your reply and your willingness to always help newbies like me on these issues.

In this instance, I am merely using one layer and attempting to get a handle on the code before adding additional layers. So, while the map is currently at the extent of droneimage1 layer, this will not always be the case and I wish to enable users to use this functionality on other layers in a layer list, as well (which will all be in different locations and have different spatial extents).

Thanks,

Todd

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Todd,

  When you click on the ellipses next to the layer in the layer list widget you get the option to zoom to layer.

0 Kudos
ToddFagin
Occasional Contributor II

Yes, but it doesn't work. If you zoom anywhere else in the map and click it, it does nothing.

0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Only for that layer type though. If you were to add a FeatureLayer or a MapImageLayer it does work

ToddFagin
Occasional Contributor II

Ah, OK, so my issue is this is a TileLayer rather than a FeatureLayer of MapImageLayer? (Smacks forehead.)
OK, I will see what I can do if this is, indeed, the case.

Once again, I truly appreciate your assistance.

Todd

0 Kudos
ToddFagin
Occasional Contributor II

I have added a FeatureLayer and still get nothing...

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Intro to MapView - Create a 2D map - 4.7</title>
  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>

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

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/geometry/support/webMercatorUtils",
      "esri/widgets/Search",
      "esri/widgets/Locate",
      "esri/widgets/Expand",
      "esri/layers/TileLayer",
      "esri/layers/FeatureLayer",
      "esri/widgets/LayerList",
      "esri/widgets/BasemapGallery",
      "dojo/dom",
      "dojo/domReady!"
    ], function(Map, MapView, webMercatorUtils, Search, Locate, Expand, TileLayer, FeatureLayer,  LayerList, BasemapGallery, dom) {


      var droneimage1 = new TileLayer({
          url: "https://tiles.arcgis.com/tiles/3xOwF6p0r7IHIjfn/arcgis/rest/services/a010002_1/MapServer",
          title: "Drone Image"
       });
       
       var eco = new FeatureLayer({
          url: "http://services.arcgis.com/3xOwF6p0r7IHIjfn/arcgis/rest/services/OK_LevelIII_Ecoregions/FeatureServer",
          title: "Oklahoma Ecoregions"
       });
       
       
      var map = new Map({
        basemap: "streets",
        layers: [droneimage1, eco]
      });

      var view = new MapView({
        container: "viewDiv",
        map: map,
        zoom: 15,
        center: [-103.064, 36.175] // longitude, latitude
      });
      

      function showCoordinates(evt) {
        var point = view.toMap({x: evt.x, y: evt.y});
        //the map is in web mercator but display coordinates in geographic (lat, long)
        var mp = webMercatorUtils.webMercatorToGeographic(point);
        //display mouse coordinates
        dom.byId("info").innerHTML = mp.x.toFixed(3) + ", " + mp.y.toFixed(3);
      }

      view.when(function(){
        //after map loads, connect to listen to mouse move & drag events
        view.on("pointer-move", showCoordinates);
      });
      
      // create a search widget
       var searchWidget = new Search({
        view: view
      });

      // create the locate widget
      var locateBtn = new Locate({
        view: view
      });

      // Add the locate widget to the top left corner of the view
      view.ui.add(locateBtn, {
        position: "top-left"
      });
      

      // Add the search widget to the top right corner of the view
      view.ui.add(searchWidget, {
        position: "top-right"
      });
      
      
      
      // create a layer list widget
      var layerList = new LayerList({
        view: view,
        
     // executes for each ListItem in the LayerList
        listItemCreatedFunction: function (event) {
        
     // The event object contains properties of the
     // layer in the LayerList widget.
        var item = event.item;      
                
     // set an action for zooming to the full extent of the layer
              item.actionsSections = [[{
                title: "Zoom to layer",
                className: "esri-icon-zoom-out-fixed",
                id: "full-extent"
              }]];  
            }

      });
      view.ui.add(layerList, "bottom-left");
      
      

      
      
      // Create a BasemapGallery widget instance and set
      // its container to a div element

      var basemapGallery = new BasemapGallery({
        view: view,
        container: document.createElement("div")
      });
      
      // Create an Expand instance and set the content
      // property to the DOM node of the basemap gallery widget
      // Use an Esri icon font to represent the content inside
      // of the Expand widget

      var bgExpand = new Expand({
        view: view,
        content: basemapGallery
      });
      
      // Add the expand instance to the ui

      view.ui.add(bgExpand, "top-left");
      
      


    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
  <span id="info" style="position:absolute; right:25px; bottom: 25px; color:#000000; font-size: 12px; z-index:50;"></span>
</body>
</html>
0 Kudos
RobertScheitlin__GISP
MVP Esteemed Contributor

Todd,

  Sorry I missed that you were missing the actual zoom to layer code.

Here is your example fixed:

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Intro to MapView - Create a 2D map - 4.8</title>
  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>

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

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/geometry/support/webMercatorUtils",
      "esri/widgets/Search",
      "esri/widgets/Locate",
      "esri/widgets/Expand",
      "esri/layers/TileLayer",
      "esri/layers/FeatureLayer",
      "esri/widgets/LayerList",
      "esri/widgets/BasemapGallery",
      "esri/tasks/GeometryService",
      "esri/tasks/support/ProjectParameters",
      "dojo/dom",
      "dojo/domReady!"
    ], function(Map, MapView, webMercatorUtils, Search, Locate, Expand, TileLayer, FeatureLayer, LayerList, BasemapGallery,
      GeometryService, ProjectParameters, dom) {

      var droneimage1 = new TileLayer({
        url: "https://tiles.arcgis.com/tiles/3xOwF6p0r7IHIjfn/arcgis/rest/services/a010002_1/MapServer",
        title: "Drone Image"
      });
      var eco = new FeatureLayer({
        url: "http://services.arcgis.com/3xOwF6p0r7IHIjfn/arcgis/rest/services/OK_LevelIII_Ecoregions/FeatureServe...",
        title: "Oklahoma Ecoregions"
      });


      var map = new Map({
        basemap: "streets",
        layers: [droneimage1, eco]
      });

      var view = new MapView({
        container: "viewDiv",
        map: map,
        zoom: 15,
        center: [-103.064, 36.175] // longitude, latitude
      });

      function showCoordinates(evt) {
        var point = view.toMap({
          x: evt.x,
          y: evt.y
        });
        //the map is in web mercator but display coordinates in geographic (lat, long)
        var mp = webMercatorUtils.webMercatorToGeographic(point);
        //display mouse coordinates
        dom.byId("info").innerHTML = mp.x.toFixed(3) + ", " + mp.y.toFixed(3);
      }

      view.when(function() {
        //after map loads, connect to listen to mouse move & drag events
        view.on("pointer-move", showCoordinates);
      });

      // create a search widget
      var searchWidget = new Search({
        view: view
      });

      // create the locate widget
      var locateBtn = new Locate({
        view: view
      });

      // Add the locate widget to the top left corner of the view
      view.ui.add(locateBtn, {
        position: "top-left"
      });

      // Add the search widget to the top right corner of the view
      view.ui.add(searchWidget, {
        position: "top-right"
      });

      // create a layer list widget
      var layerList = new LayerList({
        view: view,

        // executes for each ListItem in the LayerList
        listItemCreatedFunction: function(event) {

          // The event object contains properties of the
          // layer in the LayerList widget.
          var item = event.item;

          // set an action for zooming to the full extent of the layer
          item.actionsSections = [
            [{
              title: "Zoom to layer",
              className: "esri-icon-zoom-out-fixed",
              id: "full-extent"
            }]
          ];
        }

      });
      layerList.on("trigger-action", function(event) {
        // Capture the action id.
        var id = event.action.id;

        if (id === "full-extent") {
          // if the full-extent action is triggered then navigate
          // to the full extent of the visible layer
          if(event.item.layer.fullExtent.spatialReference !== view.spatialReference){
            var geomSer = new GeometryService({url: 'http://sampleserver6.arcgisonline.com/arcgis/rest/services/Utilities/Geometry/GeometryServer'});
            var params = new ProjectParameters({
              geometries: [event.item.layer.fullExtent],
              outSpatialReference: view.spatialReference
            });
            geomSer.project(params).then(function(results){
              view.goTo(results[0]);
            });
          }else{
            view.goTo(event.item.layer.fullExtent);
          }
        }
      });

      view.ui.add(layerList, "bottom-left");

      // Create a BasemapGallery widget instance and set
      // its container to a div element
      var basemapGallery = new BasemapGallery({
        view: view,
        container: document.createElement("div")
      });

      // Create an Expand instance and set the content
      // property to the DOM node of the basemap gallery widget
      // Use an Esri icon font to represent the content inside
      // of the Expand widget
      var bgExpand = new Expand({
        view: view,
        content: basemapGallery
      });

      // Add the expand instance to the ui
      view.ui.add(bgExpand, "top-left");
    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
  <span id="info" style="position:absolute; right:25px; bottom: 25px; color:#000000; font-size: 12px; z-index:50;"></span>
</body>

</html>

View solution in original post

0 Kudos
ToddFagin
Occasional Contributor II

Your tenacity and willingness to help is amazing. I greatly appreciate it. This is exactly what I needed.

Again, thank you. You've saved me from multiple binds before and today is no different.

Todd

0 Kudos