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!!
Solved! Go to Solution.
Robert,
OK, I believe I did this right but all points are still getting buffered instead of only the ones I select. I put the buffering in a function following the selection. See line 10 below. I do not see what I am doing wrong. Any help is immensely appreciated. (I'm a bit of a newbie at some of this)
David
//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, function (features, selectionMethod) { //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); }); }; }); };
David,
Nope not quite there yet. You need to work with the features that are returned from the selection method and not the layers original graphics.
//Day 1 Activities selection activitiesDay1.selectFeatures(queryDay1ActivitiesTest, FeatureLayer.SELECTION_NEW, function (features, selectionMethod) { //Create buffer of selection gsvc = new GeometryService("http://sushi:6080/arcgis/rest/services/Utilities/Geometry/GeometryServer"); //No need for this //var graphics1 = activitiesDay1.graphics; var selectedGeoms = graphicsUtils.getGeometries(features); var params = new BufferParameters(); params.geometries = selectedGeoms;
Ryan,
See my notes and code below to Robert. I am having trouble trying get only my selected points to buffer. Instead, all points in my layer get buffered. Can you see where I am going wrong?
Thanks so much for any help you can provide.
David
David,
Did you see my last reply?
Robert,
Yes! I missed it earlier this morning. Your corrections to my code worked wonderfully! Thanks so very much. My working snipped is below. I interactively select some points from my layer and now just those get buffered. Very nice! Now I can move on tp the rest of Ryan's sample code to have that buffer select features from another layer, which I understand much better and should go more smoothly.
I get individual buffers for every point I select but looks like they can easily be unioned to look neater utilizing "esri/geometry/geometryEngine." Ryan used this method in his web site he mentions above. See API page for geometryEngine here: https://developers.arcgis.com/javascript/jssamples/ge_geodesic_buffers.html.
Thanks so much again! I'll post my complete code once all complete. This seems to be functionality a lot of people would like in their web sites.
David
activitiesDay1.selectFeatures(queryDay1ActivitiesTest, FeatureLayer.SELECTION_NEW, function (features, selectionMethod) { //Create buffer of selection gsvc = new GeometryService("http://sushi:6080/arcgis/rest/services/Utilities/Geometry/GeometryServer"); //var graphics1 = activitiesDay1.graphics; var selectedGeoms = graphicsUtils.getGeometries(features); 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); }); }; });
Thanks so much to Ryan and Robert for their HUGE help. Below is my working code. I have the buffer distance hard-coded but plan to use an insert value. Use of the geometryEngine is a wonderful way to create buffers and have them union into a single polygon. The JS code below lets the user select points from FeatureLayer1, those selected points then get buffered (500 feet in this case). That buffer is then used to query and select any intersecting points from FeatureLayer2. Some incredibly handy functionality.
//<<<BUFFER OF SELECTED POINTS THEN SELECTS ANOTHER LAYER'S POINTS>>> //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 FeatureLayer1 on(dom.byId("TestSelect"), "click", function () { tbDrawTest.activate(Draw.FREEHAND_POLYGON); }); //Get geometry from FeatureLayer1 drawn polygon, symbolize polygon, start FeatureLayer1 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 FeatureLayer1, 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 FeatureLayer1 FeatureLayer1.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, call function to populate grid with selection results FeatureLayer1.on("selection-complete", populateGrid1); //Day 1 Activities selection FeatureLayer1.selectFeatures(queryDay1ActivitiesTest, FeatureLayer.SELECTION_NEW, function (features, selectionMethod) { //Create buffer of selection var selectedGeoms = graphicsUtils.getGeometries(features); var distance = [500]; var bufferedGeometries = geometryEngine.geodesicBuffer(selectedGeoms, distance, GeometryService.UNIT_FOOT, true); 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(bufferedGeometries, function (geometry) { var graphic = new Graphic(geometry, symbol); map.graphics.add(graphic); }); //Variable represents Query area to select intersecting FeatureLayer2 points var geoBuffer = geometryEngine.union(bufferedGeometries); //Symbolize FeatureLayer2 selection var symbolSelected = new PictureMarkerSymbol({ "type": "esriPMS", "url": "images/coffeeselect.png", "contentType": "image/png", "width": 20, "height": 22 }); symbolSelected.setOffset(-1, 0); //Set the selection symbol to FeatureLayer2 FeatureLayer2.setSelectionSymbol(symbolSelected); //Select FeatureLayer2 points that intersect buffer var querySBTest = new Query(); querySBTest.geometry = geoBuffer; querySBTest.spatialRelationship = Query.SPATIAL_REL_INTERSECTS; //Wire the layer's selection complete event, call function to populate grid with selection results FeatureLayer2.on("selection-complete", populateGrid2); //FeatureLayer2 selection FeatureLayer2.selectFeatures(querySBTest, FeatureLayer.SELECTION_NEW); }); };
Hi David,
So sorry for not getting back to you sooner - I have been out of the office. Glad you were able to get things working!!
Ryan
Hi all,
can u please post the complete working code and i what know which version you are using 3.5 or 3.8
thanks and regards
bharath
Hi Bharath,
I have a working example here:
This is using version 3.14 of the API.
-Ryan
Hi Ryan,
The example which u sent is helpful but what i'm trying to do is please see the follow link
ArcGIS API for JavaScript Sandbox
im unable to get the buffer on click please suugest me
Bharath