0

I am trying to select all the features which are present in the current extent of map i.e which are visible on screen. I find this link helpful but it iterates through all the graphics and check if that graphic is present in the current extent and adds to result set as shown in code below

dojo.forEach(map.graphics.graphics,function(graphic){
      if (extent.contains(graphic.geometry)) {
        graphic.setSymbol(highlightSymbol);
        results.push(graphic.getContent());
      }

The feature layer of my map consists of thousands of features and I might need selecting very few based on map extent and zoom level. I feel the above code takes lot of time as it needs to iterate through thousands for the few features. I am trying to update the result set whenever the user drags the screen as the map extent change.

Is there any other better way to select features based on the map extent?

  • What are you doing with the selection? Perhaps one workaround would be to not do the selection but instead just make your downstream action aware of the current extent. – GavinR Aug 8 at 19:40
  • @GavinR I am actually trying to display a table with all features present on the screen. When the user drags screen, the table should be updated with the list of latest features on the screen – user147504 Aug 8 at 19:45
0

That sample first puts the queried items in a graphics layer, which have to be iterated to get the cities that are within the extent that the user draw.

For your application, add the layer as a featurelayer and run a selectFeatures on it using the extent whenever the extent changes. Here's a way to do that (updating the original sample, using modern dojo)

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
  <title>Points in Extent</title>

  <link rel="stylesheet" href="https://js.arcgis.com/3.29/dijit/themes/claro/claro.css">
  <link rel="stylesheet" href="https://js.arcgis.com/3.29/esri/css/esri.css">

  <script src="https://js.arcgis.com/3.29/"></script>
  <script>
    require([
      "esri/map",
      "esri/layers/FeatureLayer",
      "esri/tasks/query",
      "dojo/dom",
      "dojo/domReady!"
    ],
      function (
        Map,
        FeatureLayer,
        Query,
        dom
      ) {

        var map = new Map("map", {
          basemap: "streets",
          center: [-120.275, 47.485],
          zoom: 6,
          slider: false,
          showInfoWindowOnClick: false
        });

        var featureLayer = new FeatureLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/0", {
          definitionExpression: "st = 'WA'",
          outFields: ['areaname'],
          mode: FeatureLayer.MODE_SNAPSHOT
        });

        map.addLayer(featureLayer);
        var query = new Query();

        map.on('extent-change', function (evt) {
          console.log(evt.extent);
          query.geometry = evt.extent;
          featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function (features) {
            dom.byId("inextent").innerHTML = features.length;
            var results = "";

            for (var i = 0; i < features.length; i++) {
              results += "<tr><td>" + features[i].attributes.areaname + "</tr></td>";
            }
            dom.byId("results").innerHTML = "<table><tbody>" + results + "</tbody></table>";
          });
        });
      });

  </script>

</head>
<body class="claro">
  Draw an Extent on the map to find all points within this extent


  <div id="map" style="width:800px; height:400px; border:1px solid #000;"></div>
  <br />


  <b># of points in extent = <span id="inextent">0</span></b>


  <div id="results" style="width:400px; height:200px; border:1px solid #000; overflow:auto;">
  </div>
</body>
</html>
  • Thanks a lot. I am new to GIS. I tried looking at the documentation for featurelayer.selectedfeatures() but unable to understand how FeatureLayer.SELECTION_NEW works. Could you help me please? – user147504 Aug 9 at 19:06
  • That means it's making a new selection from the feature layer every time. SELECTION_ADD and SELECTION_SUBTRACT will add or remove the items found from the current selection – kenbuja Aug 9 at 19:29
  • Need small help. How can I attach events for doing same job? Like doing same job for 'extent-change' and 'zoom-end' without rewriting code when using dojo on() function? – user147504 Sep 20 at 18:17
  • You can write a separate function [myFunction(evt), for example] and have both events reference that function map.on('extent-change', myFunction). The evt argument will get automatically passed using this syntax – kenbuja Sep 24 at 16:08
1

In version 4 of a ArcGIS API for JavaScript, you can utilize the FeatureLayerView (sample). I'm not aware of a better way to do what you're wanting to do in the v3 API.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.