Selecting a group of features

4419
23
09-18-2015 08:34 AM
DaveSouthern
New Contributor II

I'm looking for a way to use the mouse to select a group of features on a map by dragging a rectangle around them.  I can select a single feature on the map by simply clicking on that feature - that much I have working.  But now I want to be able to drag a rectangle around a group of features and select all of them so I can do something with all of them.  So far I haven't found any code examples out there that discuss this.

0 Kudos
23 Replies
JakeSkinner
Esri Esteemed Contributor

Hi Dave,

Here is a quick example on how to select features using a freehand drawn polygon:

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

    <!--The viewport meta tag is used to improve the presentation and behavior of the samples
      on iOS devices-->
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Select Features</title>

    <link rel="stylesheet" href="http://js.arcgis.com/3.14/esri/css/esri.css">

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

    <script src="http://js.arcgis.com/3.14/"></script>
    <script>
      var map, tb, polygon;

      require([
        "esri/map", "esri/toolbars/draw", "esri/layers/FeatureLayer", "esri/tasks/query",
        "esri/symbols/SimpleFillSymbol", "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleMarkerSymbol", 
        "esri/graphic", "esri/geometry/Polygon",
        "dojo/_base/Color", "dojo/dom", "dojo/on", "dojo/_base/array", "dojo/domReady!"
      ], function(
        Map, Draw, FeatureLayer, Query,
        SimpleFillSymbol, SimpleLineSymbol, SimpleMarkerSymbol,     
        Graphic, Polygon,
        Color, dom, on, array
      ) {
        map = new Map("mapDiv", {
          basemap: "streets",
          center: [-81.792107, 26.150807],
          zoom: 8
        });
        map.on("load", initToolbar);
       
        var featureLayer = new FeatureLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer/0",{
            mode: FeatureLayer.MODE_ONDEMAND,
        });
       
        var symbol = new SimpleMarkerSymbol(
          SimpleMarkerSymbol.STYLE_CIRCLE,
          12,
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_NULL,
            new Color([247, 34, 101, 0.9]),
            1
          ),
          new Color([207, 34, 171, 0.5])
        );
        featureLayer.setSelectionSymbol(symbol);

        map.addLayer(featureLayer);

     
      var fillSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_NULL,
            new SimpleLineSymbol(SimpleLineSymbol.STYLE_DASHDOT,
            new Color([255,0,0]), 2)
        );


        function initToolbar() {
          tb = new Draw(map);
          tb.on("draw-end", addGraphic);
          //map.disableMapNavigation();
          tb.activate(Draw.FREEHAND_POLYGON);         
        }

        function addGraphic(evt) {
          map.graphics.clear()

          map.graphics.add(new Graphic(evt.geometry, fillSymbol));
         
          polygon = new Polygon(evt.geometry)
         
          var query = new Query();
          query.geometry = polygon.getExtent();
         
          featureLayer.queryFeatures(query, selectInBuffer);                                 
        }
       
        function selectInBuffer(response){
          var feature;
          var features = response.features;
          var inBuffer = [];

          for (var i = 0; i < features.length; i++) {
            feature = features;
            if(polygon.contains(feature.geometry)){
              inBuffer.push(feature.attributes[featureLayer.objectIdField]);
            }
          }
          var query = new Query();
          query.objectIds = inBuffer;
       
          featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(features, index){             
              for(var i = 0; i < features.length; i++){
                  console.log(features.geometry.x + ", " + features.geometry.y)
              }
          })         
        }

      });
    </script>
  </head>

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

  </body>
</html>
DaveSouthern
New Contributor II

I've been working with this code, but have a problem with this line:

featureLayer.queryFeatures(query, selectInBuffer)

The error I'm getting is that queryFeatures is not a member of featureLayer.  Now there is a wrinkle on my end that isn't in your example code - I'm extracting the layer from the existing map object - not just creating one. Now as far as I know the layer is a featureLayer, but I may be wrong about that.  The code that creates the layer was written by another developer - I haven't dug it out yet to see if something is amiss there.

0 Kudos
ChrisSmith7
Frequent Contributor
DaveSouthern
New Contributor II

With regard to the example you gave, I get the following:

if (extent.contains(graphic.geometry)) {

contains is not a member of extent. 

I tried a hybrid of what you and Jake said, but still can't get things working.  I would show you what I have, but for some reason this editor won't accept the pasted code.


0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Dave,

  It really sounds like you have your Requires out of line/out of sync with your vars. Here is an example:

require([

'dojo/on',

'dojo/aspect',

'dojo/_base/lang'], function(

on, aspect, lang) {

0 Kudos
DaveSouthern
New Contributor II

Did part of your reply get cut off?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Dave,

   Nope. That was it. Notice that the first require "dojo/on" is the first var "on" then the second require "dojo/aspect" is the second var "aspect". Requires and vars have to have this exact one to one ordering. If you mis-order this then you may have your "aspect" var that is actually a "dojo/_base/lang" object and thus it would not have the same properties and methods as you are expecting.

0 Kudos
DaveSouthern
New Contributor II

Yes, I have my requires setup correctly. 

0 Kudos
ChrisSmith7
Frequent Contributor

David,

Just a heads-up, if you're having trouble with the editor, try:

-> copy code from application

-> paste into a blank notepad document

-> click "use advanced editor"

-> copy code from notepad

-> paste into geonet editor box

-> add a few newlines after the paste with some dummy text

-> select your code block

-> click the ">>" insert function

-> choose "syntax highlighting"

-> then select JavaScript

This should resolve any issues with adding code to geonet.

0 Kudos