I am trying to add a tool to my app where the user can perform a selection on multiple layers and have the results from all layers return to one datagrid. I feel like I am close but I am missing something. I am using an IdentifyTask to do the selection. Identifying the features is working fine-at the end of drawing my selection, graphics are drawn and the extent zooms to the selection area. Getting data into the grid is my problem. Because I am selecting from multiple layers, I am trying to push the selected feature's layerName and value. Can anyone see whjat I am missing? Here is the JS:
selectFeaturesTask = new IdentifyTask("http://summitmaps.summitoh.net/arcgis/rest/services/CountyEngineer_MercatorPublic/MapServer/"); selectFeaturesParams = new IdentifyParameters(); selectFeaturesParams.tolerance = 3; selectFeaturesParams.returnGeometry = true; selectFeaturesParams.layerIds = [0, 1, 2, 3, 4, 5, 6, 7, 8]; selectFeaturesParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_ALL; selectFeaturesParams.width = map.width; selectFeaturesParams.height = map.height; selectToolbar = new esri.toolbars.Draw(map); dojo.connect(selectToolbar, "onDrawEnd", onSelectEnd); function onSelectEnd(extent) { selectToolbar.deactivate(); executeFeatureSelection(extent); } function executeFeatureSelection(geom) { map.graphics.clear(); selectFeaturesParams.geometry = geom; selectFeaturesParams.mapExtent = map.extent; selectFeaturesTask.execute(selectFeaturesParams, showSelectionResults) } function showSelectionResults(results) { console.log('Features found: ', results); map.graphics.clear(); var dataForGrid = []; var polygonSymbol = new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_NONE, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DASHDOT, new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 255, 0, 0.25])); var markerSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.STYLE_SQUARE, 10, new SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 1), new dojo.Color([0, 255, 0, 0.25])); var lineSymbol = new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_DASH, new dojo.Color([255, 0, 0]), 1); arrayUtils.map(results, function(result) { var graphic = result.feature; switch (graphic.geometry.type) { case "point": graphic.setSymbol(markerSymbol); break; case "polyline": graphic.setSymbol(lineSymbol); break; case "polygon": graphic.setSymbol(polygonSymbol); break; } map.graphics.add(graphic); return result.feature.attributes; var layer = result.layerName; var value = result.value; dataForGrid.push([layer, value]); graphic.setSymbol(graphic); map.graphics.add(graphic); return result.feature.attributes; }); var selectData = { items: dataForGrid }; var selectStore = new ItemFileReadStore({ data: selectData }); selectGrid.setStore(selectStore); selectGrid.on("rowclick", onRowClickHandler); var graExtent = esri.graphicsExtent(map.graphics.graphics); map.setExtent(graExtent, true); }
And the HTML showing the grid:
<div data-dojo-type="dijit/layout/ContentPane" title="Select From Multiple Layers"> Select from multiple layers: <button dojoType="dijit.form.Button" onClick="selectToolbar.activate(esri.toolbars.Draw.EXTENT);">Select</button> <table data-dojo-type="dojox.grid.DataGrid" jsid="selectGrid" id="selectGrid"> <thead> <tr> <th field="0">Layer</th> <th field="1">Value</th> </tr> </thead> </table> </div>
Solved! Go to Solution.
Remove the return statements at lines 56 and 64.
Remove the return statements at lines 56 and 64.
Heiko,
That was it. Thanks so much for your help.
Ryan
So, now my onRowClickHandler function will not work with the grid mentioned in my previous post. I get the error, Cannot read property, 'geometry' of undefined. Any ideas the code below produces this error?
function onRowClickHandler(evt) { var clickedObjectf = evt.grid.getItem(evt.rowIndex).OBJECTID; var selectedObjectf; var distance = 50; if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Point') { var PointExtent = new esri.geometry.Extent({ "xmin": selectedObjectf.geometry.x - distance, "ymin": selectedObjectf.geometry.y - distance, "xmax": selectedObjectf.geometry.x + distance, "ymax": selectedObjectf.geometry.y + distance, "spatialReference": { "wkid": 102100 } }); map.setExtent(PointExtent); } else if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Polygon') { var selectedParcel = selectedObjectf.geometry.getExtent(); map.setExtent(selectedParcel.expand(3)); } else if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Polyline') { var selectedStreetl = selectedObjectf.geometry.getExtent(); map.setExtent(selectedStreetl.expand(3)); } }
because you didn't assign anything to selectedObjectf
Okay I tried this:
function onRowClickHandler2(evt) { var clickedObjectf = evt.grid.getItem(evt.rowIndex).OBJECTID; var selectedObjectf = arrayUtils.filter(map.graphics.graphics, function (graphic) { return ((graphic.attributes) && graphic.attributes.PARCELID === clickedObjectf); }); var distance = 50; if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Point') { var PointExtent = new esri.geometry.Extent({ "xmin": selectedObjectf.geometry.x - distance, "ymin": selectedObjectf.geometry.y - distance, "xmax": selectedObjectf.geometry.x + distance, "ymax": selectedObjectf.geometry.y + distance, "spatialReference": { "wkid": 102100 } }); map.setExtent(PointExtent); } else if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Polygon') { var selectedParcel = selectedObjectf.geometry.getExtent(); map.setExtent(selectedParcel.expand(3)); } else if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Polyline') { var selectedStreetl = selectedObjectf.geometry.getExtent(); map.setExtent(selectedStreetl.expand(3)); } }
Now I'm getting an issue with declaredClass - Cannot read property 'declaredClass' of undefined.
Am I at least on the right track?
Almost, the selectedObjectf object is an array which probably contains 1 element (provided the feature you're looking for was found). So after line 5 you need to add something like:
selectedObjectf = selectedObjectf[0]; if (selectedObjectf) { ...do other stuff
If I use selectedObjectf = selectedObjectf[0] wont that just give me the extent of the first feature in the array? The IdentifyTask will likely return an array of more than 1 feature. Any thoughts on how to handle multiple features?
arrayUtils.filter
returns a subset of an array, so this line in your code:
var selectedObjectf = arrayUtils.filter(map.graphics.graphics, function(graphic) { return ((graphic.attributes) && graphic.attributes.PARCELID === clickedObjectf); });
returns an array with all graphics in map.graphics.graphics
where graphic.attributes.PARCELID === clickedObjectf
. Assuming that PARCELID is unique you'll end up with an array with only one graphic, so you need to grab the first graphic from that array.
You can also use arrayUtils.some
like this:
function onRowClickHandler2(evt) { var clickedObjectf = evt.grid.getItem(evt.rowIndex).OBJECTID; var selectedObjectf; if (arrayUtils.some(map.graphics.graphics, function(graphic) { if (graphic.attributes && graphic.attributes.PARCELID === clickedObjectf) { selectedObjectf = graphic; return true; } })) { var distance = 50; if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Point') { var PointExtent = new esri.geometry.Extent({ "xmin": selectedObjectf.geometry.x - distance, "ymin": selectedObjectf.geometry.y - distance, "xmax": selectedObjectf.geometry.x + distance, "ymax": selectedObjectf.geometry.y + distance, "spatialReference": { "wkid": 102100 } }); map.setExtent(PointExtent); } else if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Polygon') { var selectedParcel = selectedObjectf.geometry.getExtent(); map.setExtent(selectedParcel.expand(3)); } else if (selectedObjectf.geometry.declaredClass == 'esri.geometry.Polyline') { var selectedStreetl = selectedObjectf.geometry.getExtent(); map.setExtent(selectedStreetl.expand(3)); } } }
I appreciate the help but still no luck, even after trying to implement your function using arrayUtils.some. Because I am doing the IdentifyTask on multiple layers, could the issue be the lack of a unique value field. All layers being identified have an OBJECTID field with unique values in it for each layer. When I push data from all layers in the identify (layerName and value), that unique value may not be unique when the array is created.