Select Multiple Features Using Identify Task?

2301
8
01-10-2012 09:09 AM
EmilyLaMunyon
Occasional Contributor
Hello,

I have a identify function that is working when I select one feature on the map at a time. The results are then sent to a datagrid. I would like the option to be able to select multiple features at a time by drawing a rectangle on the map. Ideally, the user could chose which layer to view data for through a window prompt. Is this possible or does Identify only work on one feature at a time?

Thanks so much for any advice!!


function doIdentify(evt) {
    
        map.infoWindow.hide();
        identifyParams.layerIds = [0,2];
     
       
  
      var measureMode =   dojo.query(".esriButton .dijitButtonNode").some(function(node, index, arr){
          if(node.childNodes[0].checked){
            //at least one of the measure tools is active so disable identify
            return true;
            
          }
       });
       if(! measureMode){
        map.graphics.clear();
        identifyParams.geometry = evt.mapPoint;
        identifyParams.mapExtent = map.extent;
        identifyTask.execute(identifyParams,showResults); 
      }  
       }
 
  function showResults(results) {

     map.graphics.clear();
        var symbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([98,194,204]), 2), new dojo.Color([98,94,204,0.8]));
        var idLayer;
        var highlightSymbol = new esri.symbol.SimpleMarkerSymbol().setColor(new dojo.Color([25,50,225,0.3])); 
 

        //create array of attributes
          var items = dojo.map(results,function(result){
          var graphic = result.feature;
          graphic.setSymbol(symbol);
          map.graphics.add(graphic);
      //Highlight selected feature
     graphic.setSymbol(highlightSymbol);
     return result.feature.attributes;
        }); 
    
      //Create data object to be used in store
 if (results[0].layerName == 'Control Points') {
 showPointNameGrid();
 searchType = "selControl";
 
          var data = { 
 identifier: 'POINT_NAME',  //This field needs to have unique values 
            label: 'POINT_NAME', //Name field for display. Not pertinent to a grid but may be used elsewhere. 
 items: items 
   };  
 
     //Create data store and bind to grid. 
   store = new dojo.data.ItemFileReadStore({ data:data }); 
   var grid = dijit.byId('grid4'); 
  grid.setStore(store);  
  
} else if (results[0].layerName == 'surveys') {
       showSurveysNameGrid();
 searchType = "selSurvey";
 var data = { 
 identifier: 'DOCUMENT_N',  //This field needs to have unique values 
  label: 'DOCUMENT_N', //Name field for display. Not pertinent to a grid but may be used elsewhere. 
  items: items 
}; 
   
 store = new dojo.data.ItemFileReadStore({ data:data }); 
 var grid = dijit.byId('grid5'); 
 grid.setStore(store);  
   
 } else if (results[0].layerName == 'Cities') {
 showCityGrid();
 var data = { 
  identifier: 'CITY',  //This field needs to have unique values 
 label: 'CITY', //Name field for display. Not pertinent to a grid but may be used elsewhere. 
 items: items 
 }; 
   
 store = new dojo.data.ItemFileReadStore({ data:data }); 
 var grid = dijit.byId('grid2'); 
 grid.setStore(store); 
  }
  }
0 Kudos
8 Replies
StephenLead
Regular Contributor III
Derek Swingley from the JS team posted a sample at http://jsfiddle.net/swingley/wKue4/ which should give you a head-start.
0 Kudos
EmilyLaMunyon
Occasional Contributor
Thanks so much Stephen! This is very helpful.:)

Do you know if there is a sample like this that has the ability to select multiple features by drawing a rectangle on the map?
0 Kudos
StephenLead
Regular Contributor III
Do you know if there is a sample like this that has the ability to select multiple features by drawing a rectangle on the map?


I don't know of any samples, but it should be possible. IdentifyParameters allows you to specify the geometry - you should be able to use a rectangle drawn by the user.

Good luck,
Steve
0 Kudos
EmilyLaMunyon
Occasional Contributor
I am still not having luck with this, I think I am close though.  I have 3 buttons, one for each layer I want to select(Surveys, Control Points), and one to clear the selections. Right now when I select a button, it does not seem to activate the correct layer.

When either button is pushed, I want to be able to draw a box to select the features chosen by the button. Then the results will display in a datagrid at the bottom of the page. This is the relevant code, I am bascially repeating everything for each layer, probably not ideal, but it is a start. Any help would be greatly appreciated!!

//Selection Stuff for Points
var toolbar, var toolbar2

 var selectionLayer = new esri.layers.GraphicsLayer({ id: "selectionLayer" }); 
     var outfieldsarray = [];
   var symbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 50, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([25,50,225,0.3]), 1), new dojo.Color([25,50,225,0.3]));
        var highlightsymbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 20, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 0]), 1), new dojo.Color([25,50,225,0.3]));
 

            drawToolbar = new esri.toolbars.Draw(map, {
   showTooltips: false
   }); 
   
   dojo.connect(drawToolbar, "onDrawEnd", selectFeaturesAndResetMapDisplay);
    

            dojo.connect(map, "onLoad", function() {
                map.addLayer(selectionLayer);
            });

            //build query task
            queryTask = new esri.tasks.QueryTask("http://slcarcgisdev1/SLCOGIS/rest/services/public/Surveyor/MapServer/0");
            query = new esri.tasks.Query();
            query.returnGeometry = true;
        

        
        // The Selection Method, called when Selection Mode is on and selection is done.
        
        function selectFeaturesAndResetMapDisplay(extent) {
            
            selectionLayer.clear();
            


            //build query filter
            query.geometry = extent;
            query.returnGeometry = true;
            query.outFields = outfieldsarray;
        
   

 outfieldsarray = ["POINT_NAME", "SECTION", "TOWNSHIP_RANGE", "GRID_ADDRESS", "LONGITUDE_DD", "LATITUDE_DD", "MON_NOTES"];
           
           //Execute task and call showResults on completion
            queryTask.execute(query, function(fset) {
               
                var items = [];
                for (var i = 0; i < fset.features.length; i++) {
                    var attributes = fset.features.attributes;
                    items.push(attributes);

                   
                    var selectiongraphic = fset.features;
                    selectiongraphic.setSymbol(symbol);
                   
 map.graphics.add(selectiongraphic);
 searchType = "PointName";
 showPointNameGrid();
    
                }
                   
   var data = { 
     identifier: 'POINT_NAME',  //This field needs to have unique values 
     label: 'POINT_NAME', //Name field for display. Not pertinent to a grid but may be used elsewhere. 
     items: items 
   };  
 
    
   
                
                //Create data store and bind to grid.
               store = new dojo.data.ItemFileReadStore({
                    data: data
                });
                store.data = data;
        
               var grid = dijit.byId('grid4'); 
               grid.setStore(store); 
                        store.close();

               
            });
        
} 
 //Selection Stuff for Surveys

                var selectionLayer2 = new esri.layers.GraphicsLayer({ id: "selectionLayer2" }); 
   var outfieldsarray = [];
   var symbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 50, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([25,50,225,0.3]), 1), new dojo.Color([25,50,225,0.3]));
        var highlightsymbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 20, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 0]), 1), new dojo.Color([25,50,225,0.3]));
 

            drawToolbar2 = new esri.toolbars.Draw(map, {
   showTooltips: false
   }); 
   
   dojo.connect(drawToolbar2, "onDrawEnd", selectFeaturesAndResetMapDisplaySurveys);
  

            dojo.connect(map, "onLoad", function() {
                map.addLayer(selectionLayer2);
            });

            //build query task
            queryTask = new esri.tasks.QueryTask("http://slcarcgisdev1/SLCOGIS/rest/services/public/Surveyor/MapServer/2");
            query = new esri.tasks.Query();
            query.returnGeometry = true;

                 // The Selection Method, called when Selection Mode is on and selection is done.
        
        function selectFeaturesAndResetMapDisplaySurveys(extent) {
           var tolerance = 5,
    pxWidth = map.extent.getWidth() / map.width,
    padding = tolerance * pxWidth;
    queryGeometry = extent;
 queryGeometry = new esri.geometry.Extent({
      'xmin': evt.mapPoint.x - padding,
      'ymin': evt.mapPoint.y - padding,
      'xmax': evt.mapPoint.x + padding,
      'ymax': evt.mapPoint.y + padding,
      'spatialReference': evt.mapPoint.spatialReference
    });


            //build query filter
            query.geometry = extent;
            query.returnGeometry = true;
            query.outFields = outfieldsarray;
           
   
            

 outfieldsarray = ["DOCUMENT_N", "SECTION", "TOWNSHIP_RANGE"];
            
            //Execute task and call showResults on completion
            queryTask.execute(query, function(fset) {
               
                var items = [];
                for (var i = 0; i < fset.features.length; i++) {
                    var attributes = fset.features.attributes;
                    items.push(attributes);

                   
                  
                   

                    var selectiongraphic = fset.features;
                    selectiongraphic.setSymbol(symbol);
                  
                    selectionLayer2.add(selectiongraphic);
                 
 map.graphics.add(selectiongraphic);
 searchType = "SurveysName";
 showSurveysNameGrid();
    
                }
                 
   var data = { 
     identifier: 'DOCUMENT_N', //This field needs to have unique values 
     label: 'DOCUMENT_N', //Name field for display. Not pertinent to a grid but may be used elsewhere. 
     items: items 
   };  
 
    
   
                
                //Create data store and bind to grid.
               store = new dojo.data.ItemFileReadStore({
                    data: data
                });
                store.data = data;
        
               var grid = dijit.byId('grid3'); 
               grid.setStore(store); 
                        store.close();

               
            });
        
}


<div id="drawToolbar" dojotype="dijit.form.Button">
        <div dojotype="dijit.form.Button" id="drawExtent" onclick="drawToolbar.activate(esri.toolbars.Draw.EXTENT);">
            Select Control Points</div>
  </div>
  <div id="drawToolbar2" dojotype="dijit.form.Button" style="left:400 px; top:10px">
        <div dojotype="dijit.form.Button" id="drawExtent2" onclick="drawToolbar2.activate(esri.toolbars.Draw.EXTENT);">
            Select Surveys</div>
  </div>
  <div id="drawToolbarClear" dojotype="dijit.form.Button" style="left:400 px; top:10px">
 <div dojotype="dijit.form.Button"  button onClick="map.graphics.clear();">
    Clear Selection
 </div> 
 </div>

0 Kudos
KellyHutchins
Esri Frequent Contributor
Emily,

There's a sample sort of buried in the help that I think does what you need.

http://help.arcgis.com/en/webapi/javascript/arcgis/help/jssamples/layout_MapContainerSplitRight.html

This sample has a button that allows you to draw an extent to select features. Once selected the attributes for the selected features are displayed in a datagrid.

Kelly
0 Kudos
EmilyLaMunyon
Occasional Contributor
Thanks Kelly for all your help!!!:)

I think this is exactly what I need. The one question I have, is it possible to select 2 feature layers using this sample? Would I just repeat the relevant code again for each layer I want to select?
0 Kudos
KellyHutchins
Esri Frequent Contributor
Emily,

You could do the feature layer selection for each layer or you could use the identify task (looks like that was your original question anyway). Here's an example that shows displaying selected items in a datagrid.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7" /> 
    <!--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>
    </title>
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.6/js/dojo/dijit/themes/soria/soria.css">
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.6/js/dojo/dojox/grid/resources/Grid.css"> 
    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.6/js/dojo/dojox/grid/resources/SoriaGrid.css"> 
    <style type="text/css">
      html, body { 
        height: 100%; width: 100%; margin: 0; 
      } 
      body{
        background-color:white; overflow:hidden; 
        font-family: "Trebuchet MS"; 
      }
      .roundedCorners{
        -moz-border-radius: 4px;      
      }
      #header {
        border: solid 2px #7EABCD;
        background-color:white; color:peru; font-size:18pt; 
        text-align:center; font-weight:bold; height:60px;
      }
      #subheader {
        font-size:small;
        color: peru;
      }
      #rightPane{
        background-color:white;
        color:peru;
        border: solid 2px cornflowerblue;
        width:30%;
        overflow:hidden;
      }
      #map {
        background-color:white;
        border:solid 2px cornflowerblue;
      }
      #footer {
        border: solid 2px #7EABCD;
        background-color:white;color:peru;font-size:10pt; text-align:center; height:40px;
      }
      .soria .dojoxGridHeader .dojoxGridCell   {
        color:peru !important;
      }
    </style>
    <script type="text/javascript">
      var djConfig = {
        parseOnLoad: true
      };
    </script>
    <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.6">
    </script>
    <script type="text/javascript">
      dojo.require("dijit.dijit"); // optimize: load dijit layer
      dojo.require("dijit.layout.BorderContainer");
      dojo.require("dijit.layout.ContentPane");
      dojo.require("esri.map");
      dojo.require("esri.toolbars.draw");
      dojo.require("esri.layers.FeatureLayer");
      dojo.require("esri.tasks.query");
      dojo.require("dojox.grid.DataGrid");
      dojo.require("dojo.data.ItemFileReadStore");
      dojo.require("dijit.layout.TabContainer");
      
      
      var map, toolbar;
      var featureLayer;
      function init() {
      var initExtent = new esri.geometry.Extent({"xmin":-9270392,"ymin":5247043,"xmax":-9269914,"ymax":5247401,"spatialReference":{"wkid":102100}});
        
        map = new esri.Map("map", {
          extent: initExtent
        });
        
        dojo.connect(map, 'onLoad', function(map) {
        
           identifyTask = new esri.tasks.IdentifyTask("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/MapServer");
           
           identifyParams = new esri.tasks.IdentifyParameters();
           identifyParams.tolerance = 3;
           identifyParams.returnGeometry = true;
           identifyParams.layerIds = [0,2];
           identifyParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_ALL;
           identifyParams.width  = map.width;
           identifyParams.height = map.height;
       
          //initialize the toolbar
          toolBar = new esri.toolbars.Draw(map);
          dojo.connect(toolBar, "onDrawEnd",onDrawEnd);          
          
          //resize the map when the browser resizes
          dojo.connect(dijit.byId('map'), 'resize', map,map.resize);
          
          
        });
        
        var basemapUrl = "http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer";
        var basemap = new esri.layers.ArcGISTiledMapServiceLayer(basemapUrl);


       var landBaseLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/MapServer",{opacity:.55});
        
        map.addLayer(basemap);
        map.addLayer(landBaseLayer);
      }
      
      function onDrawEnd(extent){
          toolBar.deactivate();
          executeIdentifyTask(extent);
      }
      
      
    function executeIdentifyTask(geom) {
        //clear the graphics layer 
        map.graphics.clear();
        var polygonSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DOT, new dojo.Color([151, 249,0,.80]), 3), new dojo.Color([151, 249, 0, 0.45]));
        
        identifyParams.geometry = geom;
        identifyParams.mapExtent = map.extent;
        identifyTask.execute(identifyParams,function(response){
            var buildingItems = [];
            var parcelItems = [];
           dojo.forEach(response,function(result){
               var feature = result.feature;
                //add selected feature to graphics layer
                feature.setSymbol(polygonSymbol);
                map.graphics.add(feature);
                
                if(result.layerName === 'Tax Parcels'){
                    parcelItems.push(feature.attributes);
                }else if(result.layerName === 'Building Footprints'){
                    buildingItems.push(feature.attributes);
                }
           });
           //update the data grid 
           var bldgStore = new dojo.data.ItemFileReadStore({data:{identifier:'PARCELID',items:buildingItems}});
           gridBldg.setStore(bldgStore);
           
           var parcelsStore = new dojo.data.ItemFileReadStore({data:{identifier:'OBJECTID',items:parcelItems}});
            gridParcels.setStore(parcelsStore);
        });


      }
      //show map on load 
      dojo.addOnLoad(init);
    </script>
  </head> 
  <body class="soria">
    <div id="mainWindow" dojotype="dijit.layout.BorderContainer" design="headline"
    gutters="false" style="width:100%; height:100%;">
      <div id="header" dojotype="dijit.layout.ContentPane"  class="roundedCorners" region="top">
        This is the header section
      </div>
      <div id="map" dojotype="dijit.layout.ContentPane" class="roundedCorners" region="center"></div>
      <div dojotype="dijit.layout.ContentPane" id="rightPane" class="roundedCorners" region="right"  splitter="true" >
        <button dojoType="dijit.form.Button"  onClick="toolBar.activate(esri.toolbars.Draw.EXTENT);">Select</button>
        <div dojotype='dijit.layout.TabContainer'>
            <div dojotype='dijit.layout.ContentPane' title = 'Buildings' selected='true'>
                <table dojotype="dojox.grid.DataGrid" jsid="gridBldg" id="gridBldg" style="width:100%;height:100%;" selectionMode="none"> 
                 <thead> 
                    <tr> 
                      <th field="PARCELID">ID</th> 
                      <th field="Full Site Address" width="100%">Address</th> 
                    </tr> 
                  </thead> 
                </table>
            </div>
            <div dojotype='dijit.layout.ContentPane' title='Parcels'>
                <table dojotype="dojox.grid.DataGrid" jsid="gridParcels" id="gridParcels" style="width:100%;height:100%;" selectionMode="none"> 
                 <thead> 
                    <tr> 
                      <th field="Parcel Identification Number">Parcel ID</th> 
                      <th field='School District Description'>School</th>
                      <th field='Postal Address'>Address</th>
                    </tr> 
                  </thead> 
                </table>            
                </div>
        </div>

        
        
      </div>
      <div id="footer" class="roundedCorners" dojotype="dijit.layout.ContentPane" region="bottom">
        This is the footer section
      </div> 
      </div>
  </body>
</html>

0 Kudos
EmilyLaMunyon
Occasional Contributor
Thanks so much again Kelly, this is almost exactly what I need!!:D

Sorry to be such a pain, I have one more question. :confused:

I have the multiple identify code working great, however if I select features from 2 layers, my map seems unable to know which grid to display. It would be great to have a window pop-up asking the user which grid they want to see. Is this possible? I have changed the code a little bit, maybe incorrectly.

function executeIdentifyTask(geom) {
        //clear the graphics layer 
        navToolbar.deactivate();
        //map.graphics.clear();
        var polygonSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DOT, new dojo.Color([151, 249,0,.80]), 3), new dojo.Color([151, 249, 0, 0.45]));
        var markerSymbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE, 20, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([0, 0, 0]), 1), new dojo.Color([25,50,225,0.3]));
        
        identifyParams.geometry = geom;
        identifyParams.mapExtent = map.extent;
        identifyTask.execute(identifyParams,function(response){
            var controlItems = [];
            var surveyItems = [];
           dojo.forEach(response,function(result){
               var feature = result.feature;
                //add selected feature to graphics layer
                feature.setSymbol(polygonSymbol);
                feature.setSymbol(markerSymbol);
                map.graphics.add(feature);
                
                if(result.layerName === 'Control Points'){
                 showPointNameGrid();
                   controlItems.push(feature.attributes);
                   map.graphics.clear;
                }else if(result.layerName === 'surveys'){
                 showSurveysNameGrid();
                    surveyItems.push(feature.attributes);
                }
           });
           
           
           
  
           
           
           
           //update the data grid 
          
           var controlStore = new dojo.data.ItemFileReadStore({data:{identifier:'POINT_NAME',items:controlItems}});
           var grid = dijit.byId('grid4');
           grid.setStore(controlStore);
           
         
           var surveysStore = new dojo.data.ItemFileReadStore({data:{identifier:'DOCUMENT_NUM',items:surveyItems}});
            var grid = dijit.byId('grid3');
            alert("I'm a Survey");
            grid.setStore(surveysStore);
        });


      }



0 Kudos