Issues with buffering selected features/query task

5363
22
Jump to solution
10-15-2014 08:02 AM
RyanSellman
Occasional Contributor II

I am trying to give users the ability to select features from a specific feature layer, buffer that selection and query another feature layer using the geometries from the buffer.  I want results from the first selection to be sent to one datagrid and results from the second query to be sent to a different datagrid.  I think I am really close - the way I have it set up now is the user can draw a box to select features (points in this case).  When the drawing ends, it select features within the drawn extent, performs a buffer at a set distance on those features, and uses the buffer extent to select features from a polygon layer.  This all works just fine however, the issue I am having is with the two datagrids.  For some reason, data from the first selection is being pushed to both datagrids.

Here is a bit of JS:

dojo.connect(map, "onLoad", function(map) {

    //initialize the toolbar

    toolBar2 = new esri.toolbars.Draw(map);

    dojo.connect(toolBar2, "onDrawEnd", onDrawEnd);

});

var featureLayerUrl = "http://summitmaps.summitoh.net/arcgis/rest/services/DOES_Mercator/MapServer/2";

featureLayer = new esri.layers.FeatureLayer(featureLayerUrl, {

    mode: esri.layers.FeatureLayer.MODE_SELECTION,

    outFields: ["UNAME", "INSTALLYR", "DNAME", "STREET", "EASEMENT", "INVERT", "OWNERSHIP"]

});

featureLayer.setSelectionSymbol(new esri.symbol.SimpleMarkerSymbol().setSize(8).setColor(new dojo.Color([160, 214, 238])));

map.addLayer(featureLayer);

function onDrawEnd(extent) {

    var newStore = new dojo.data.ItemFileReadStore({

        data: {

            identifier: "",

            items: []

        }

    });

    var grid = dijit.byId("manholeGrid");

    manholeGrid.setStore(newStore);

    toolBar2.deactivate();

    var query = new esri.tasks.Query();

    query.geometry = extent;

    featureLayer.selectFeatures(query, esri.layers.FeatureLayer.SELECTION_NEW, function(features, selectionMethod) {

        var items30 = dojo.map(features, function(feature) {

            return feature.attributes;

        });

        var data30 = {

            identifier: "OBJECTID",

            items: items30

        };

        var store30 = new dojo.data.ItemFileReadStore({

            data: data30

        });

        var manholeGrid = registry.byId("manholeGrid");

        manholeGrid.on("rowclick", onRowClickHandler);

        manholeGrid.setStore(store30);

        map.setExtent(graphicsUtils.graphicsExtent(featureLayer.getSelectedFeatures()), true);

        gsvc = new GeometryService("http://summitmaps.summitoh.net/arcgis/rest/services/Utilities/Geometry/GeometryServer");

        var graphics = featureLayer.graphics;

        var selectedGeoms = graphicsUtils.getGeometries(graphics);

        var params = new BufferParameters();

        params.geometries = selectedGeoms;

        params.distances = [500];

        params.unit = GeometryService.UNIT_FOOT;

        params.outSpatialReference = map.spatialReference;

        gsvc.buffer(params, showBuffer);

        function showBuffer(geometries) {

            var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,

                    new Color([0, 0, 255, 0.65]), 2

                ),

                new Color([0, 0, 255, 0.35])

            );

            arrayUtils.map(geometries, function(geometry) {

                var graphic = new Graphic(geometry, symbol);

                map.graphics.add(graphic);

            });

            queryTaskNew = new esri.tasks.QueryTask("http://summitmaps.summitoh.net/arcgis/rest/services/Cadastral/Parcels/MapServer/0");

            var queryNew = new esri.tasks.Query();

            queryNew.returnGeometry = true;

            queryNew.outFields = ["PARID", "ADDR"];

            queryNew.geometry = geometries[0];

            queryTaskNew.execute(queryNew, showResults300);

            function showResults300(featureSet) {

                var resultFeatures = featureSet.features;

                for (var i = 0, il = resultFeatures.length; i < il; i++) {

                    var items300 = dojo.map(features, function(feature) {

                        return feature.attributes;

                    });

                    var data300 = {

                        identifier: "OBJECTID",

                        items: items300

                    };

                    var store300 = new dojo.data.ItemFileReadStore({

                        data: data300

                    });

                    var grid = registry.byId("parcelGrid");

                    grid.on("rowclick", onRowClickHandler);

                    grid.setStore(store300);

                }

            }

        };

    });

And here is the HTML as it pertains to the above code:

<div data-dojo-type="dijit/layout/ContentPane" title="Manhole">

                    <input type="text" id="doesManholeText" value="BA15" />

                    <button id="doesManholeSearch" data-dojo-type="dijit.form.Button" type="button" data-dojo-attach-point="button">Search</button>

                    <button data-dojo-type="dijit.form.Button" onClick="toolBar2.activate(esri.toolbars.Draw.EXTENT);">Select</button>

                    <button id="clearManholeGrid" data-dojo-type="dijit.form.Button" type="button" data-dojo-attach-point="button">Clear</button>

                    <span id="manhole-result-count"></span>

                    <table data-dojo-type="dojox/grid/DataGrid" data-dojo-id="manholeGrid" id="manholeGrid" style="height: 340px" data-dojo-props="rowsPerPage:'100', rowSelector:'20px'">

                        <thead>

                            <tr>

                                <th field="UNAME">UNAME</th>

                                <th field="INSTALLYR">Install Year</th>

                                <th field="DNAME">DNAME</th>

                                <th field="STREET">Street</th>

                                <th field="EASEMENT">Easement</th>

                                <th field="INVERT">Invert</th>

                                <th field="OWNERSHIP">Ownership</th>

                            </tr>

                        </thead>

                    </table>

                </div>

<div id="bottom" data-dojo-type="dojox/layout/ExpandoPane" title="Click the Arrow to Minimize this Panel" data-dojo-props="title: 'Parcel Search', splitter:true, startExpanded: false, region:'bottom'" style="height: 300px;">

    <div data-dojo-type="dijit/layout/ContentPane" title="Selected Parcels">

        <table data-dojo-type="dojox.grid.DataGrid" data-dojo-id="parcelGrid" id="parcelGrid" style="height: 300px" data-dojo-props="rowsPerPage:'100', rowSelector:'20px'">

            <thead>

                <tr>

                    <th field="PARID">Parcel #</th>

                    <th field="ADDR">Address</th>

                </tr>

            </thead>

        </table>

    </div>

</div>

Can anyone see why I can't get results from the second query, in this case, "queryTaskNew" into the appropriate datagrid?

Any help is much appreciated!!

0 Kudos
1 Solution

Accepted Solutions
KellyHutchins
Esri Frequent Contributor

Ryan,

In your second query shouldn't it be dojo.map(resultFeatures instead of features?

  1.      var resultFeatures = featureSet.features; 
  2.                 for (var i = 0, il = resultFeatures.length; i < il; i++) { 
  3.  
  4.  
  5.                     var items300 = dojo.map(features, function(feature) { 
  6.                         return feature.attributes; 
  7.                     }); 
  8.                     var data300 = { 
  9.                         identifier: "OBJECTID"
  10.                         items: items300 
  11.                     }; 
  12.                     var store300 = new dojo.data.ItemFileReadStore({ 
  13.                         data: data300 
  14.                     }); 

View solution in original post

0 Kudos
22 Replies
KellyHutchins
Esri Frequent Contributor

Ryan,

In your second query shouldn't it be dojo.map(resultFeatures instead of features?

  1.      var resultFeatures = featureSet.features; 
  2.                 for (var i = 0, il = resultFeatures.length; i < il; i++) { 
  3.  
  4.  
  5.                     var items300 = dojo.map(features, function(feature) { 
  6.                         return feature.attributes; 
  7.                     }); 
  8.                     var data300 = { 
  9.                         identifier: "OBJECTID"
  10.                         items: items300 
  11.                     }; 
  12.                     var store300 = new dojo.data.ItemFileReadStore({ 
  13.                         data: data300 
  14.                     }); 
0 Kudos
RyanSellman
Occasional Contributor II

Hi Kelly,

Thank you for the note!   I think I have it working now. Along with your suggestion, I did have to add the "OBJECTID" field to the queryNew.outFields included in the FeatureSet.  Thank you for the help!

Here is the working code:

function onDrawEnd(extent) {

                    var newStore = new dojo.data.ItemFileReadStore({

                        data: {

                            identifier: "",

                            items: []

                        }

                    });

                    var grid = dijit.byId("manholeGrid");

                    manholeGrid.setStore(newStore);

                    toolBar2.deactivate();

                    var query = new esri.tasks.Query();

                    query.geometry = extent;

                featureLayer.selectFeatures(query, esri.layers.FeatureLayer.SELECTION_NEW, function(features, selectionMethod) {

                        var items30 = dojo.map(features, function(feature) {

                            return feature.attributes;

                        });

                        var data30 = {

                            identifier: "OBJECTID",

                            items: items30

                        };

                        var store30 = new dojo.data.ItemFileReadStore({

                            data: data30

                        });

                        var manholeGrid = registry.byId("manholeGrid");

                        manholeGrid.on("rowclick", onRowClickHandler);

                        manholeGrid.setStore(store30);

  map.setExtent(graphicsUtils.graphicsExtent(featureLayer.getSelectedFeatures()), true);

  gsvc = new GeometryService("http://summitmaps.summitoh.net/arcgis/rest/services/Utilities/Geometry/GeometryServer");

  var graphics = featureLayer.graphics;

  var selectedGeoms = graphicsUtils.getGeometries(graphics);

  var params = new BufferParameters();

  params.geometries = selectedGeoms;

  params.distances = [500];           

  params.unit = GeometryService.UNIT_FOOT; 

  params.outSpatialReference = map.spatialReference;  

  gsvc.buffer(params, showBuffer);

  function showBuffer(geometries) {

   var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, 

   new Color([0,0,255,0.65]), 2 

  ), 

  new Color([0,0,255,0.35]) 

   ); 

  

   arrayUtils.map(geometries, function(geometry) { 

  var graphic = new Graphic(geometry,symbol); 

  map.graphics.add(graphic);     

   

   });

  

  queryTaskNew = new esri.tasks.QueryTask("http://summitmaps.summitoh.net/arcgis/rest/services/Cadastral/Parcels/MapServer/0");

  var queryNew = new esri.tasks.Query();

  queryNew.returnGeometry = true;

  queryNew.outFields = ["OBJECTID", "PARID", "ADDR"];

  queryNew.geometry = geometries[0]; 

  queryTaskNew.execute(queryNew, showResults300);

  function showResults300(featureSet) {

  var resultFeatures = featureSet.features;

  for (var i=0, il=resultFeatures.length; i<il; i++) {

  var items300 = dojo.map(resultFeatures, function(feature) {

  return feature.attributes;

  });

  var data300 = {

  identifier: "OBJECTID",

  items: items300

  };

  var store300 = new dojo.data.ItemFileReadStore({

  data: data300

  });

  var grid = registry.byId("parcelGrid");

  grid.on("rowclick", onRowClickHandler);

  grid.setStore(store300);

  }

  }

  };

             

DavidChrest
Occasional Contributor II

Ryan,

Thank you so much for this post! I'm glad I found it. I am trying to do the exact same thing. I already have the functionality of the user selecting points with results going to a datagrid (dgrid). But I wanted to have the ability of that selection being buffered and selecting features from another layer, just as you do.

Is your site public? I'd love to see it in action and the complete code. Can you provide a link?

Thank you very much,

David

0 Kudos
RyanSellman
Occasional Contributor II

Hi David!

I am going to have to do some digging to see which app that exact snippet of code came from.  In the meantime, take a look at this application I put together:

County of Summit: Parcel Viewer

If you expand the left "Parcel Search" pane and do a parcel query (either by attribute or spatial selection) the results are fed into the dgrid below.  Above that grid, click the Mailing Labels button.  In this dialog, I am using the public notification geoprocessing services from Esri's Public Notification template to create Avery mailing labels or CSV files. I think the logic is still the same in that I am buffering selected features (in this case parcels) by a user specified distance and selecting parcels within that buffer. 

One thing to note - instead of using my geometry service to create the buffers, I am using the API's geometryEngine to generate the buffer and union the buffered geometries. Wanted to mention that because I believe the class is still in beta and its a slight difference that whats posted above.

I will continue to hunt down the snippet from above, but thought in the meantime the above sample could help.

Ryan

0 Kudos
DavidChrest
Occasional Contributor II

Ryan,

OK, great! Thanks so much!

David

0 Kudos
RyanSellman
Occasional Contributor II

David,

I think I found it.  Check this page out:

County of Summit: D.O.E.S. Viewer

The required workflow in this app was to search/select a manhole, buffer selected manholes and display parcels intersecting the buffer.  You can find this workflow by expanding the right pane ("Utility Search") and selecting the "Manhole" tab.  Not pretty but it works.

Let me know if you need anything else.

Best,

Ryan

DavidChrest
Occasional Contributor II

Ryan,

Thanks again! I'll take a look at this. Nice web sites.

David

0 Kudos
DavidChrest
Occasional Contributor II

Ryan,

I am a bit desperate here. I utilized your code above in this post, but after I select some points from my layer, all of them get buffered instead of just the ones I selected. It has something to do with line 74 below, "var graphics1 = activitiesDay1.graphics;" Somehow all the features get treated as graphics instead of just my selected subset. Can you see what I am doing wrong. I have tried many things but nothing seems to work.

Thanks so much,

David

//<<<DRAW POLYGON TO SELECT FEATURES TEST




  //Draw Day 1 tool initialization function
  map.on("load", initDrawToolTest);


  function initDrawToolTest(evt) {
  tbDrawTest = new Draw(evt.map);
  tbDrawTest.on("draw-end", displayPolygonTest);
  }




  //Draw Freehand Polygon for Day 1 Activities
  on(dom.byId("TestSelect"), "click", function () {
  tbDrawTest.activate(Draw.FREEHAND_POLYGON);
  });




  //Get geometry from Day 1 Activities drawn polygon, symbolize polygon, start Day 1 query 
  function displayPolygonTest(evt) {
  // Get the geometry from the event object
  var geometryInput = evt.geometry;
  // Define symbol for finished polygon
  var tbDrawSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([53, 119, 221]), 2), new Color([53, 119, 221, 0.3]));
  map.graphics.clear();
  var graphicPolygon = new Graphic(geometryInput, tbDrawSymbol);
  map.graphics.add(graphicPolygon);
  selectDay1ActivitiesTest(geometryInput); // Call the next function below...vvv
  }




  //Symbolize Day1 Activities, create new Query, select features
  function selectDay1ActivitiesTest(geometryInput) {
  // Define symbol for selected features (using JSON syntax for improved readability)
  var symbolSelectedTest = new SimpleMarkerSymbol({
  "type": "esriSMS",
  "style": "esriSMSCircle",
  "color": [255, 115, 0, 128],
  "size": 6,
  "outline": {
  "color": [255, 0, 0, 214],
  "width": 1
  }
  });


  //Set the selection symbol to Day 1 Activities
  activitiesDay1.setSelectionSymbol(symbolSelectedTest);
  //Initialize the query
  var queryDay1ActivitiesTest = new Query();
  tbDrawTest.deactivate(); //turns off selection tool so it does not stay on in map.
  queryDay1ActivitiesTest.geometry = geometryInput;
  //Wire the layer's selection complete event
  activitiesDay1.on("selection-complete", populateGrid1);
  //Day 1 Activities selection
  activitiesDay1.selectFeatures(queryDay1ActivitiesTest, FeatureLayer.SELECTION_NEW);




  //Create buffer of selection
  gsvc = new GeometryService("http://sushi:6080/arcgis/rest/services/Utilities/Geometry/GeometryServer");


  var graphics1 = activitiesDay1.graphics;
  var selectedGeoms = graphicsUtils.getGeometries(graphics1);
  var params = new BufferParameters();
  params.geometries = selectedGeoms;


  params.distances = [500];
  params.unit = GeometryService.UNIT_FOOT;
  params.outSpatialReference = map.spatialReference;
  gsvc.buffer(params, showBuffer);




  function showBuffer(geometries) {
  var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
  new Color([0, 0, 255, 0.65]), 2
  ),
  new Color([0, 0, 255, 0.35])
  );


  array.map(geometries, function (geometry) {
  var graphic = new Graphic(geometry, symbol);
  map.graphics.add(graphic);
  });
  };


  };
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

David,

   Your buffering code is not inside the selection-complete event handler so you get all the graphics instead of the selected ones.

0 Kudos