zoomToLayer - Javascript API for ArcGIS

1762
12
Jump to solution
03-02-2020 11:41 AM
AprilSummers
New Contributor II

I am new to JS and I don't quite know how to integrate the Zoom to Layer functionality in my code snippet. I have tried several ways and have failed. Any pointers would be very much appreciated.

I assume the zoomToLayer function must be added when the query geometry is returned by the queryForWellGeometries() function.

The complete code can be found here -> https://developers.arcgis.com/javascript/latest/sample-code/sandbox/index.html?sample=featurelayer-q... and zoomToLayer() code can be found here -> https://developers.arcgis.com/javascript/latest/sample-code/sandbox/index.html?sample=featurelayer-q...

When the option is selected from the dropdown menu, it would be useful to zoom to the extent of the queried feature. Right now, the code works but it does not zoom to the feature.

I have tried all sorts of permutations but because my knowledge is basic, I feel I am missing a link.

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

April,

   This is the updated function for your code:

        function queryForWellGeometries() {
          var wellsQuery = wellsLayer.createQuery();

          return wellsLayer.queryFeatures(wellsQuery).then(function(response) {
            wellsGeometries = response.features.map(function(feature) {
              return feature.geometry;
            });
            view.goTo(wellsGeometries);

            return wellsGeometries;
          });
        }

View solution in original post

0 Kudos
12 Replies
RobertScheitlin__GISP
MVP Emeritus

April,

   This is how you would combine the two samples. The zooming occurs in the displayResults function.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>Query features from a FeatureLayer - 4.14</title>

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

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

      #infoDiv {
        background-color: white;
        color: black;
        padding: 6px;
        width: 400px;
      }

      #results {
        font-weight: bolder;
        padding-top: 10px;
      }
      .slider {
        width: 100%;
        height: 60px;
      }
      #drop-downs {
        padding-bottom: 15px;
      }
    </style>

    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/FeatureLayer",
        "esri/layers/GraphicsLayer",
        "esri/geometry/geometryEngine",
        "esri/Graphic",
        "esri/widgets/Slider"
      ], function(
        Map,
        MapView,
        FeatureLayer,
        GraphicsLayer,
        geometryEngine,
        Graphic,
        Slider
      ) {
        var quakesUrl =
          "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/ks_earthquakes_since_2000/FeatureServer/0";

        var wellBuffer, wellsGeometries, magnitude;

        var wellTypeSelect = document.getElementById("well-type");

        var magSlider = new Slider({
          container: "mag",
          min: 0,
          max: 5,
          steps: 0.1,
          values: [2],
          rangeLabelsVisible: true,
          labelsVisible: true
        });

        var distanceSlider = new Slider({
          container: "distance",
          min: 100,
          max: 10000,
          steps: 100,
          labelFormatFunction: function(value, type) {
            if (type === "value") {
              return parseInt(value);
            }
            return value;
          },
          values: [5000],
          rangeLabelsVisible: true,
          labelsVisible: true
        });

        var queryQuakes = document.getElementById("query-quakes");

        // oil and gas wells
        var wellsLayer = new FeatureLayer({
          portalItem: {
            // autocasts as new PortalItem()
            id: "8af8dc98e75049bda6811b0cdf9450ee"
          },
          outFields: ["*"],
          visible: false
        });

        // historic earthquakes
        var quakesLayer = new FeatureLayer({
          url: quakesUrl,
          outFields: ["*"],
          visible: false
        });

        // GraphicsLayer for displaying results
        var resultsLayer = new GraphicsLayer();

        var map = new Map({
          basemap: "dark-gray",
          layers: [wellsLayer, quakesLayer, resultsLayer]
        });

        var view = new MapView({
          container: "viewDiv",
          map: map,
          center: [-97.75188, 37.23308],
          zoom: 10
        });
        view.ui.add("infoDiv", "top-right");

        // query all features from the wells layer
        view
          .when(function() {
            return wellsLayer.when(function() {
              var query = wellsLayer.createQuery();
              return wellsLayer.queryFeatures(query);
            });
          })
          .then(getValues)
          .then(getUniqueValues)
          .then(addToSelect)
          .then(createBuffer);

        // return an array of all the values in the
        // STATUS2 field of the wells layer
        function getValues(response) {
          var features = response.features;
          var values = features.map(function(feature) {
            return feature.attributes.STATUS2;
          });
          return values;
        }

        // return an array of unique values in
        // the STATUS2 field of the wells layer
        function getUniqueValues(values) {
          var uniqueValues = [];

          values.forEach(function(item, i) {
            if (
              (uniqueValues.length < 1 || uniqueValues.indexOf(item) === -1) &&
              item !== ""
            ) {
              uniqueValues.push(item);
            }
          });
          return uniqueValues;
        }

        // Add the unique values to the wells type
        // select element. This will allow the user
        // to filter wells by type.
        function addToSelect(values) {
          values.sort();
          values.forEach(function(value) {
            var option = document.createElement("option");
            option.text = value;
            wellTypeSelect.add(option);
          });

          return setWellsDefinitionExpression(wellTypeSelect.value);
        }

        // set the definition expression on the wells
        // layer to reflect the selection of the user
        function setWellsDefinitionExpression(newValue) {
          wellsLayer.definitionExpression = "STATUS2 = '" + newValue + "'";

          if (!wellsLayer.visible) {
            wellsLayer.visible = true;
          }

          return queryForWellGeometries();
        }

        // Get all the geometries of the wells layer
        // the createQuery() method creates a query
        // object that respects the definitionExpression
        // of the layer
        function queryForWellGeometries() {
          var wellsQuery = wellsLayer.createQuery();

          return wellsLayer.queryFeatures(wellsQuery).then(function(response) {
            wellsGeometries = response.features.map(function(feature) {
              return feature.geometry;
            });

            return wellsGeometries;
          });
        }

        // creates a single buffer polygon around
        // the well geometries

        var bufferGraphic = null;
        function createBuffer(wellPoints) {
          var bufferDistance = distanceSlider.values[0];
          var wellBuffers = geometryEngine.geodesicBuffer(
            wellPoints,
            [bufferDistance],
            "meters",
            true
          );
          wellBuffer = wellBuffers[0];

          if (bufferGraphic) {
            bufferGraphic.geometry = wellBuffer;
          } else {
            // add the buffer to the view as a graphic
            bufferGraphic = new Graphic({
              geometry: wellBuffer,
              symbol: {
                type: "simple-fill", // autocasts as new SimpleFillSymbol()
                outline: {
                  width: 1.5,
                  color: [255, 128, 0, 0.5]
                },
                style: "none"
              }
            });
            view.graphics.add(bufferGraphic);
          }
        }

        // Get the magnitude value set by the user
        magSlider.on("thumb-drag", function(event) {
          magnitude = event.value;
        });
        // create a buffer around the queried geometries
        distanceSlider.on("thumb-drag", function(event) {
          if (event.state === "stop") {
            createBuffer(wellsGeometries);
          }
        });
        // set a new definitionExpression on the wells layer
        // and create a new buffer around the new wells
        wellTypeSelect.addEventListener("change", function() {
          var type = event.target.value;
          setWellsDefinitionExpression(type).then(createBuffer);
        });

        // query for earthquakes with the specified magnitude
        // within the buffer geometry when the query button
        // is clicked
        queryQuakes.addEventListener("click", function() {
          queryEarthquakes().then(displayResults);
        });

        function queryEarthquakes() {
          var query = quakesLayer.createQuery();
          query.where = "mag >= " + magSlider.values[0];
          query.geometry = wellBuffer;
          query.spatialRelationship = "intersects";

          return quakesLayer.queryFeatures(query);
        }

        // display the earthquake query results in the
        // view and print the number of results to the DOM
        function displayResults(results) {
          resultsLayer.removeAll();
          var features = results.features.map(function(graphic) {
            graphic.symbol = {
              type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
              style: "diamond",
              size: 6.5,
              color: "darkorange"
            };
            return graphic;
          });
          var numQuakes = features.length;
          document.getElementById("results").innerHTML =
            numQuakes + " earthquakes found";
          resultsLayer.addMany(features);
          var query = quakesLayer.createQuery();
          query.where = "mag >= " + magSlider.values[0];
          query.geometry = wellBuffer;
          query.spatialRelationship = "intersects";
          quakesLayer.queryExtent(query).then(function(response) {
            view.goTo(response.extent);
          });
        }
      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
    <div id="infoDiv" class="esri-widget">
      <div id="drop-downs">
        Select well type:
        <select id="well-type" class="esri-widget"></select>
      </div>
      Well buffer distance (meters):
      <div id="distance" class="slider"></div>
      Earthquake magnitude:
      <div id="mag" class="slider"></div>
      <button id="query-quakes" class="esri-widget">Query Earthquakes</button>
      <div id="results" class="esri-widget"></div>
    </div>
  </body>
</html>
0 Kudos
AprilSummers
New Contributor II

Robert Scheitlin, GISP‌, I tried your code but i couldn't make it work. I tried incorporating in this piece of code below

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>Query features from a FeatureLayer - 4.14</title>

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

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

      #infoDiv {
        background-color: white;
        color: black;
        padding: 6px;
        width: 400px;
      }

      #results {
        font-weight: bolder;
        padding-top: 10px;
      }
      .slider {
        width: 100%;
        height: 60px;
      }
      #drop-downs {
        padding-bottom: 15px;
      }
    </style>

    <script>
      require([
        "esri/Map",
        "esri/views/MapView",
        "esri/layers/FeatureLayer",
        "esri/layers/GraphicsLayer",
        "esri/geometry/geometryEngine",
        "esri/Graphic",
        "esri/widgets/Slider"
      ], function(
        Map,
        MapView,
        FeatureLayer,
        GraphicsLayer,
        geometryEngine,
        Graphic,
        Slider
      ) {
        var wellsGeometries;

        var wellTypeSelect = document.getElementById("well-type");

        // oil and gas wells
        var wellsLayer = new FeatureLayer({
          portalItem: {
            // autocasts as new PortalItem()
            id: "8af8dc98e75049bda6811b0cdf9450ee"
          },
          outFields: ["*"],
          visible: false
        });

        // GraphicsLayer for displaying results
        var resultsLayer = new GraphicsLayer();

        var map = new Map({
          basemap: "dark-gray",
          layers: [wellsLayer, resultsLayer]
        });

        var view = new MapView({
          container: "viewDiv",
          map: map,
          center: [-97.75188, 37.23308],
          zoom: 10
        });
        view.ui.add("infoDiv", "top-right");

        // query all features from the wells layer
        view
          .when(function() {
            return wellsLayer.when(function() {
              var query = wellsLayer.createQuery();
              return wellsLayer.queryFeatures(query);
            });
          })
          .then(getValues)
          .then(getUniqueValues)
          .then(addToSelect);

        // return an array of all the values in the
        // STATUS2 field of the wells layer
        function getValues(response) {
          var features = response.features;
          var values = features.map(function(feature) {
            return feature.attributes.STATUS2;
          });
          return values;
        }

        // return an array of unique values in
        // the STATUS2 field of the wells layer
        function getUniqueValues(values) {
          var uniqueValues = [];

          values.forEach(function(item, i) {
            if (
              (uniqueValues.length < 1 || uniqueValues.indexOf(item) === -1) &&
              item !== ""
            ) {
              uniqueValues.push(item);
            }
          });
          return uniqueValues;
        }

        // Add the unique values to the wells type
        // select element. This will allow the user
        // to filter wells by type.
        function addToSelect(values) {
          values.sort();
          values.forEach(function(value) {
            var option = document.createElement("option");
            option.text = value;
            wellTypeSelect.add(option);
          });

          return setWellsDefinitionExpression(wellTypeSelect.value);
        }

        // set the definition expression on the wells
        // layer to reflect the selection of the user
        function setWellsDefinitionExpression(newValue) {
          wellsLayer.definitionExpression = "STATUS2 = '" + newValue + "'";

          if (!wellsLayer.visible) {
            wellsLayer.visible = true;
          }

          return queryForWellGeometries();
        }

        // Get all the geometries of the wells layer
        // the createQuery() method creates a query
        // object that respects the definitionExpression
        // of the layer
        function queryForWellGeometries() {
          var wellsQuery = wellsLayer.createQuery();

          return wellsLayer.queryFeatures(wellsQuery).then(function(response) {
            wellsGeometries = response.features.map(function(feature) {
              return feature.geometry;
            });

            return wellsGeometries;
          });
        }

        // set a new definitionExpression on the wells layer
        // and create a new buffer around the new wells
        wellTypeSelect.addEventListener("change", function() {
          var type = event.target.value;
          setWellsDefinitionExpression(type).then(createBuffer);
        });
      });
    </script>
  </head>

  <body>
    <div id="viewDiv"></div>
    <div id="infoDiv" class="esri-widget">
      <div id="drop-downs">
        Select well type:
        <select id="well-type" class="esri-widget"></select>
      </div>
    </div>
  </body>
</html>

I think it should be added to queryforWellGeometries but it doesn't work

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

April,

   This is the updated function for your code:

        function queryForWellGeometries() {
          var wellsQuery = wellsLayer.createQuery();

          return wellsLayer.queryFeatures(wellsQuery).then(function(response) {
            wellsGeometries = response.features.map(function(feature) {
              return feature.geometry;
            });
            view.goTo(wellsGeometries);

            return wellsGeometries;
          });
        }
0 Kudos
AprilSummers
New Contributor II

Robert Scheitlin, GISP

It works on this code but I am using an organizational layer but with the exact same piece of code (with variable names changed) and it does not still work for me  I have been struggling with this for last 4 days or so. Is there a setting I must make or something? I know that the code should be quite simple but I simply cannot get it to work! I tried everything I could like clearing our browser cache etc. Still, it does not work for my map layer 

Any pointers would be of great help

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

April,

   If your layer that you are querying is in a different spatial reference then the view then you would have to specify the outSpatailReference on the query class.

0 Kudos
AprilSummers
New Contributor II

Hi Robert,

My basemap, featurelayer and the sub-query that selects certain features are all in the same spatial reference. 

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Strange. Is the layer coming from your own ArcGIS Server or AGOL?

0 Kudos
AprilSummers
New Contributor II

From AGOL

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Sorry that makes no sense then. I would have to see your exact code with webmap id to test on my end.

0 Kudos