Buffer, Query Buffer, Return results

4272
8
Jump to solution
01-30-2014 03:32 AM
jaykapalczynski
Frequent Contributor
I was successful in doing this with a Silverlight application I wrote.  Looking to do this in Java Script and looking for some thoughts or examples on how to accomplish it in JS.


  1. Click on the map

  2. Create Buffer at specified distance

  3. Use this buffer to query for features that are in it.

  4. Return these results to a table in the HTML page itself.

Would be nice to have the ability to hover over a record in that table and have it highlight the feature in the map, and visa versa.
I was successful in doing this in silverlight but need to move over to JS

Anyone have any examples, thoughts etc?

Thanks
0 Kudos
1 Solution

Accepted Solutions
BrianLord1
Occasional Contributor
Jay,

This is how I populate a dojo datagrid within some of my apps.  My apps still use and older version of the javascript api and legacy style so it might not correlate to what you are doing with the dgrid.

the "results" variable in the following code is just the featureset reurned from a esri findTask.  I have also done this with the results from a queryTask.
//create array of attributes                 var items = dojo.map(results, function (result) {                     var graphic = result.feature;                     graphic.setSymbol(symbol);                     map.graphics.add(graphic);                     return dojo.clone(result.feature.attributes);                 });                  //Create data object to be used in store                 var data = {                     identifier: "OBJECTID",  //This field needs to have unique values                     label: "ID", //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('gridCorners');                 grid.setStore(store);


[HTML]<table id="gridCorners" dojotype="dojox.grid.EnhancedGrid"
                    data-dojo-props="plugins:{exporter: true}"
                    style="height: 220px; width:100%; overflow:auto;">
                    <!--rowsPerPage:'5', rowSelector:'20px', rowHeight:'16px'-->
                <thead>
                    <tr>
                        <th field="POINT ID" width="50px">
                            PT ID
                        </th>
                        <th field="PROJECT" width="70px" formatter="makeLink">
                            PROJECT
                        </th>
                        <th field="ROAD" width="60px">
                            ROAD
                        </th>
                        <th field="YEAR" width="50px">
                            YEAR
                        </th>
                        <th field="SIZE" width="40px">
                            SIZE
                        </th>
                        <th field="DESCRIPTION" width="60px">
                            TYPE
                        </th>
                        <th field="SURV_INV" width="100px">
                            AS SHOT ELEV
                        </th>
                        <th field="CALCD_INV" width="120px">
                            CALCULATED ELEV
                        </th>
                        <th field="LENGTH" width="60px">
                            LENGTH
                        </th>
                        <th field="APRONS" width="80px">
                            APRONS
                        </th>
                        <th field="DIRECTIONS" width="160px">
                            DIRECTIONS
                        </th>
                        <th field="SECTION" width="35px">
                            SEC
                        </th>
                        <th field="TOWNSHIP" width="35px">
                            TWP
                        </th>
                        <th field="RANGE" width="35px">
                            RNG
                        </th>
                        <th field="CONDITION" width="80px">
                            CONDITION
                        </th>
                        <th field="LAST INSPECTION" width="60px">
                            INSPECT
                        </th>
                        <th field="COMMENTS"  width="200">
                            COMMENTS
                        </th>
                        <th width="100%">
                        </th>                      
                    </tr>
                </thead>
            </table>[/HTML]

Hope that helps. 

Good luck,
Mark

View solution in original post

0 Kudos
8 Replies
SubaKrishnan
Esri Contributor
Hi Jay,

Here are some samples that has the functionality that you are interested in

Buffer and Query

https://developers.arcgis.com/javascript/jssamples/query_buffer.html

Click on the record in the datagrid, and the appropriate feature gets zoomed and highlighted

http://developers.arcgis.com/javascript/samples/fl_zoomgrid/

I hope these samples would give you an idea to move forward.

Thanks,
Suba
0 Kudos
jaykapalczynski
Frequent Contributor
Thanks Suba....gonna give this a shot over the next few days when time permits...but think I have enough to go on...thank you very much for your thoughts and example locations....very appreciated.
Cheers
0 Kudos
jaykapalczynski
Frequent Contributor
Hi Jay, 

Here are some samples that has the functionality that you are interested in 

Buffer and Query 

https://developers.arcgis.com/javascript/jssamples/query_buffer.html

Click on the record in the datagrid, and the appropriate feature gets zoomed and highlighted 

http://developers.arcgis.com/javascript/samples/fl_zoomgrid/

I hope these samples would give you an idea to move forward. 

Thanks, 
Suba



Thanks for your help...I was able to get the Buffer and Query working with little issue...now working on trying to get the Results from that Buffer pushed to a Table in my web page (not in the mapDiv itself.) Having some issues with that...could only look at the source code and having issues.
Have to some how grab the selected features and put them in an Array and then display the array in HTML?

Any further thoughts, hints, examples?

Im thinking that I can push teh returned features from within here? But not sure

          
          //Select features within the buffered polygon. To do so we'll create a query to use the buffer graphic
          //as the selection geometry.
          var query = new Query();
          query.geometry = bufferGeometry;
          featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){
            var totalPopulation = sumPopulation(results);
            var r = "";
            r = "<b>The total Census Block population within the buffer is <i>" + totalPopulation + "</i>.</b>";
            dom.byId('messages').innerHTML = r;
          

            var items = dojo.map(featureSet.features,function(feature){
              return feature.attributes;
            });
            var data = {
              identifier:"ObjectID",
              items:items};
            store = new dojo.data.ItemFileReadStore({data:data});
            grid.setStore(store);
            grid.setSortIndex(1,"true"); //sort on the state name 


 });


Having some sort of HTML Grid here

      <div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'left'" style="width:255px">
        <table data-dojo-type="dojox.grid.DataGrid" jsid="grid" id="grid" selectionMode="none">
         <thead>
            <tr>
              <th field="ObjectID" formatter="makeZoomButton" width="25px">
                <img alt="+" src="images/flag.png"/>
              </th>
              <th field="STATE_NAME" width="100px">State</th>
              <th field="POP2000" width="100px">Population</th>
            </tr>
          </thead>
        </table>
      </div>
0 Kudos
jaykapalczynski
Frequent Contributor
Maybe do a for each loop to build an array to pass back the selected records?
Confused
0 Kudos
jaykapalczynski
Frequent Contributor
Have been trying this...think I am closer but would be appreciated if anyone could give some thoughts...
need some help pretty bad...did this a bit ago in Silverlight and having issues moving to JS
Thanks

 //Select features within the buffered polygon. To do so we'll create a query to use the buffer graphic
          //as the selection geometry.
          var query = new Query();
          query.geometry = bufferGeometry;
          featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){
            var totalPopulation = sumPopulation(results);
            var r = "";
            r = "<b>The total Census Block population within the buffer is <i>" + totalPopulation + "</i>.</b>";
            dom.byId('messages').innerHTML = r;
     
            var data = array.map(results.features, function (feature) {
                return {
                    // property names used here match those used when creating the dgrid                  
                    "id": feature.attributes[window.outFields[0]],
                    "Name": feature.attributes[window.outFields[1]],
                    "Type": feature.attributes[window.outFields[2]]
                };
            });
            var memStore = new dojo.store.Memory({
                data: data
            });
            window.grid.set("store", memStore);

          });
        });

        function sumPopulation(features) {
          var popTotal = 0;
          for (var x = 0; x < features.length; x++) {
            popTotal = popTotal + features.attributes['Number'];
          }
          return popTotal;
        }



Then in HTML


<div id="mainWindow" style="width:100%; height:100%;">

    <div style="background-color:#EEEEEE;height:100%;width:300px;float:left;">
        <table jsid="grid" id="grid">
         <thead>
            <tr>
              <th field="ObjectID" formatter="makeZoomButton" width="25px">
                <img alt="+" src="images/flag.png"/>
              </th>
              <th field="NAME" width="100px">WMA Name</th>
              <th field="TYPE" width="100px">Region</th>
            </tr>
          </thead>
        </table>
    </div>
 
    <div id="mapDiv" style="background-color:#EEEEEE;height:100%;width:auto;float:left;"></div>

</div>
0 Kudos
BrianLord1
Occasional Contributor
Jay,

This is how I populate a dojo datagrid within some of my apps.  My apps still use and older version of the javascript api and legacy style so it might not correlate to what you are doing with the dgrid.

the "results" variable in the following code is just the featureset reurned from a esri findTask.  I have also done this with the results from a queryTask.
//create array of attributes                 var items = dojo.map(results, function (result) {                     var graphic = result.feature;                     graphic.setSymbol(symbol);                     map.graphics.add(graphic);                     return dojo.clone(result.feature.attributes);                 });                  //Create data object to be used in store                 var data = {                     identifier: "OBJECTID",  //This field needs to have unique values                     label: "ID", //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('gridCorners');                 grid.setStore(store);


[HTML]<table id="gridCorners" dojotype="dojox.grid.EnhancedGrid"
                    data-dojo-props="plugins:{exporter: true}"
                    style="height: 220px; width:100%; overflow:auto;">
                    <!--rowsPerPage:'5', rowSelector:'20px', rowHeight:'16px'-->
                <thead>
                    <tr>
                        <th field="POINT ID" width="50px">
                            PT ID
                        </th>
                        <th field="PROJECT" width="70px" formatter="makeLink">
                            PROJECT
                        </th>
                        <th field="ROAD" width="60px">
                            ROAD
                        </th>
                        <th field="YEAR" width="50px">
                            YEAR
                        </th>
                        <th field="SIZE" width="40px">
                            SIZE
                        </th>
                        <th field="DESCRIPTION" width="60px">
                            TYPE
                        </th>
                        <th field="SURV_INV" width="100px">
                            AS SHOT ELEV
                        </th>
                        <th field="CALCD_INV" width="120px">
                            CALCULATED ELEV
                        </th>
                        <th field="LENGTH" width="60px">
                            LENGTH
                        </th>
                        <th field="APRONS" width="80px">
                            APRONS
                        </th>
                        <th field="DIRECTIONS" width="160px">
                            DIRECTIONS
                        </th>
                        <th field="SECTION" width="35px">
                            SEC
                        </th>
                        <th field="TOWNSHIP" width="35px">
                            TWP
                        </th>
                        <th field="RANGE" width="35px">
                            RNG
                        </th>
                        <th field="CONDITION" width="80px">
                            CONDITION
                        </th>
                        <th field="LAST INSPECTION" width="60px">
                            INSPECT
                        </th>
                        <th field="COMMENTS"  width="200">
                            COMMENTS
                        </th>
                        <th width="100%">
                        </th>                      
                    </tr>
                </thead>
            </table>[/HTML]

Hope that helps. 

Good luck,
Mark
0 Kudos
BrianLord1
Occasional Contributor
I forgot this code.  This is how I zoom to the feature on the map when the record is selected in the datagrid.

I put this in the main "init" function of the app.
dojo.connect(dijit.byId('gridCorners'), "onRowClick", onRowClickHandler);


Here is the function.
//Zoom to the parcel when the user clicks a row
            function onRowClickHandler(evt) {
                map.getLayer(selectedCulvertsID).clear;
                var clickedTaxLotId = dijit.byId('gridCorners').getItem(evt.rowIndex).OBJECTID;
                var selectedTaxLot;
                var symbol = new esri.symbol.SimpleMarkerSymbol(esri.symbol.SimpleMarkerSymbol.STYLE_X, 15, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 0, 0, .01]));

                dojo.forEach(map.graphics.graphics, function (graphic) {
                    if ((graphic.attributes) && graphic.attributes.OBJECTID === clickedTaxLotId[0]) {
                        selectedTaxLot = graphic;
                        return;
                    }
                });
                AddGraphic(map.getLayer(selectedCulvertsID), symbol, selectedTaxLot.geometry);

                var culvertGeometry = selectedTaxLot.geometry;

                var factor = 1; //some factor for converting point to extent
                var culvertExtent = new esri.geometry.Extent(culvertGeometry.x - factor, culvertGeometry.y - factor, culvertGeometry.x + factor, culvertGeometry.y + factor, culvertGeometry.SpatialReference);

                map.setExtent(culvertExtent.expand(80));
            }


Thanks,
Mark
0 Kudos
jaykapalczynski
Frequent Contributor
Think I got it.....Seems to be working well....nothing really formatted here just snips of my code.
Thank you all for your help, thoughts, and patience....VERY appreciated.

The below is doing a few things:

  • When the user clicks the map a buffer is created

  • This buffer is used to select a Point Feature

  • These results are then displayed in the map and the table

  • When you hover over one if the features it displays its attributes.


Note there were 3 external CSS files
https://js.arcgis.com/3.8/js/dojo/dojox/grid/resources/Grid.css
https://js.arcgis.com/3.8/js/esri/css/esri.css
http://js.arcgis.com/3.8/js/dojo/dijit/themes/tundra/tundra.css

THANK YOU ALL....now on to the next puzzle...

1. Get the Table to jump to the record and highlight it when hover or click the selected features
2. Zoom to the Feature in the map when click on it in the table


  <body class="tundra">
    <div id="grid"></div> 
    <div id="mapDiv">
      <div id="info"></div>
    </div>
  </body>


var map;
      require([
        "esri/map", "esri/layers/FeatureLayer",
        "esri/tasks/query", "esri/tasks/QueryTask",
        "esri/tasks/GeometryService", "esri/tasks/BufferParameters",
        "esri/graphic", "esri/InfoTemplate", "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol",
          
        "esri/TimeExtent", "dojo/number", "dojo/date/locale", 
        "dojo/_base/array", "dojo/store/Memory", "dgrid/OnDemandGrid",
          
        "esri/renderers/SimpleRenderer", "esri/lang", "dojo/dom-style", "dijit/TooltipDialog", "dijit/popup",
          
        "esri/config", "dojo/_base/Color", "dojo/dom", "dojo/domReady"
      ], function(
        Map, FeatureLayer,
        Query, QueryTask,
        GeometryService, BufferParameters,
        Graphic, InfoTemplate, SimpleMarkerSymbol,
        SimpleLineSymbol, SimpleFillSymbol,
          
        TimeExtent, number, locale,
        arrayUtils, Memory, OnDemandGrid,
          
        SimpleRenderer, esriLang, domStyle, TooltipDialog, dijitPopup,
          
        esriConfig, Color, dom
      ) {

      // create a dgrid 
      var sortAttr = [{
        attribute: "SITENAME",
        descending: true
      }];
      grid = new OnDemandGrid({
        store: Memory({
          idProperty: "SITENAME"
        }),
        columns:{
          NAME: "SiteNames",
          REGION: "Regions",
        },
        sort: sortAttr
      }, "grid");
   

 esri.config.defaults.io.proxyUrl = "https://fwisweb1.dgif.virginia.gov/proxypage_net/proxy.ashx";

        map = new Map("mapDiv", {
          basemap: "streets",
          center: [-77.4329, 37.5410],
          zoom: 7,
          slider: false
        });

          var featureLayer = new FeatureLayer("https://SOMESERVER/arcgis/rest/services/Test/RampTEST/FeatureServer/0", {
            mode: FeatureLayer.MODE_SELECTION,
            outFields: ['*']
          });
          
        map.infoWindow.resize(245,125);
          
        dialog = new TooltipDialog({
          id: "tooltipDialog",
          style: "position: absolute; width: 250px; font: normal normal normal 10pt Helvetica;z-index:100"
        });
        dialog.startup();

       // selection symbol used to draw the selected census block points within the buffer polygon
        var point = new SimpleMarkerSymbol(
          SimpleMarkerSymbol.STYLE_CIRCLE,
          25,
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_NULL,
            new Color([137, 214, 171, 0.9]),
            1
          ),
          new Color([137, 214, 171, 0.5])
        );
        // Blue new Color([160, 177, 232, 0.5])
        // Green new Color([137, 214, 171, 0.9]),
        //close the dialog when the mouse leaves the highlight graphic
        map.on("load", function(){
          map.graphics.enableMouseEvents();
          map.graphics.on("mouse-out", closeDialog);
        });
                
        //listen for when the onMouseOver event fires on the countiesGraphicsLayer
        //when fired, create a new graphic with the geometry from the event.graphic and add it to the maps graphics layer
        featureLayer.on("mouse-over", function(evt){
          var t = "<b>${SITENAME}</b><hr><b>Region: </b>${REGION}<br>";
          var content = esriLang.substitute(evt.graphic.attributes,t);
          var highlightGraphic = new Graphic(evt.graphic.geometry,point);
          map.graphics.add(highlightGraphic);
          
          dialog.setContent(content);

          domStyle.set(dialog.domNode, "opacity", 0.85);
          dijitPopup.open({
            popup: dialog, 
            x: evt.pageX,
            y: evt.pageY
          });
        });
    
        function closeDialog() {
          map.graphics.clear();
          dijitPopup.close(dialog);
        }          
          
        // selection symbol used to draw the selected census block points within the buffer polygon
        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);
          
        // change cursor to indicate features are click-able          
        featureLayer.on("mouse-over", function () {
            map.setMapCursor("pointer");
        });
        featureLayer.on("mouse-out", function () {
            map.setMapCursor("default");
        });
          
        // Add the Feature Layer To Map  
        map.addLayer(featureLayer);

        // geometry service that will be used to perform the buffer
        var geometryService = new GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
          
        //when the map is clicked create a buffer around the click point of the specified distance.
        map.on("click", function(evt){
          //define input buffer parameters
          var params = new BufferParameters();
          params.geometries  = [ evt.mapPoint ];
          params.distances = [ 40 ];
          params.unit = GeometryService.UNIT_STATUTE_MILE;

          geometryService.buffer(params);
        });

        geometryService.on("buffer-complete", function(result){
          map.graphics.clear();
          // draw the buffer geometry on the map as a map graphic
          var symbol = new SimpleFillSymbol(
            SimpleFillSymbol.STYLE_NULL,
            new SimpleLineSymbol(
              SimpleLineSymbol.STYLE_SHORTDASHDOTDOT,
              new Color([105,105,105]),
              2
            ),new Color([255,255,0,0.25])
          );
          var bufferGeometry = result.geometries[0]
          var graphic = new Graphic(bufferGeometry, symbol);
          map.graphics.add(graphic);

 //Select features within the buffered polygon. To do so we'll create a query to use the buffer graphic
          //as the selection geometry.
          var query = new Query();
          query.geometry = bufferGeometry;
          featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){
             var totalPopulation = sumPopulation(results);
                var r = "";
                r = "<b>The total Census Block population within the buffer is <i>" + totalPopulation + "</i>.</b>";
                dom.byId('messages').innerHTML = r;  
            });
     
          // Query for the records with the given object IDs and populate the grid
          featureLayer.queryFeatures(query, function (featureSet) {
            updateGrid(featureSet);
            });                                   
      });
  
      function updateGrid(featureSet) {
        var data = arrayUtils.map(featureSet.features, function (entry, i) {
          return {
            NAME: entry.attributes.SITENAME,
            REGION: entry.attributes.REGION
          };
        });
        grid.store.setData(data);
        grid.refresh();
      }

});


      html, body, #mapDiv {
        padding: 0;
        margin: 0;
        height: 100%;
      }
      #messages{
        background-color: #fff;
        box-shadow: 0 0 5px #888;
        font-size: 1.1em;
        max-width: 15em;
        padding: 0.5em;
        position: absolute;
        right: 20px;
        top: 20px;
        z-index: 40;
      }

#grid {
      height: 336px;
      width: 100%;
    }

    .field-name {
      width: 100px;
      font-size: .80em;
      font-weight: normal;
    }

    .field-magnitude {
      width: 50px;
      font-size: .80em;
      font-weight: normal;
    }

    .field-deaths {
      width: 70px;
      font-size: .80em;
      font-weight: normal;
    }

    .field-date {
      width: 70px;
      font-size: .80em;
      font-weight: normal;
    }

    #grid .dgrid-row-odd {
      background: #F2F5F9;
    }
#info {
        background: #fff;
        box-shadow: 0 0 5px #888;
        left: 1em;
        padding: 0.5em;
        position: absolute;
        top: 1em;
        z-index: 40;
      }
0 Kudos