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.
Ryan,
In your second query shouldn't it be dojo.map(resultFeatures instead of features?
Ryan,
In your second query shouldn't it be dojo.map(resultFeatures instead of features?
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);
}
}
};
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
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
Ryan,
OK, great! Thanks so much!
David
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
Ryan,
Thanks again! I'll take a look at this. Nice web sites.
David
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); }); }; };
David,
Your buffering code is not inside the selection-complete event handler so you get all the graphics instead of the selected ones.