Common_SelectBufferTool_CSharp\App_Code\CustomTools.cs
// Copyright 2010 ESRI // // All rights reserved under the copyright laws of the United States // and applicable international laws, treaties, and conventions. // // You may freely redistribute and use this sample code, with or // without modification, provided you include the original copyright // notice and use restrictions. // // See the use restrictions. // namespace CustomComponents { public class SelectTool : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction { #region IMapServerToolAction Members void ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction.ServerAction( ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs toolEventArgs) { // Get a reference to the map control on which the tool was executed ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = (ESRI.ArcGIS.ADF.Web.UI.WebControls.Map)toolEventArgs.Control; try { // Set the name of the resource on which to perform the selection string resourceName = "Data Layers"; string selectionLayerName = null; bool showSelectionInTable; // Check whether the page request was issued using a callback or a postback. A callback is used if no // ScriptManager is on the page containing the tool. Otherwise, a partial postback is used. if (adfMap.Page.IsCallback) { // Get the callback arguments from the __CALLBACKPARAM argument of the page request parameters string callbackArgumentsString = toolEventArgs.Control.Page.Request.Params["__CALLBACKPARAM"]; System.Collections.Specialized.NameValueCollection callbackArgumentsCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(callbackArgumentsString); // Get the value of the selection layer and show in selection table server controls, which were explicitly added to // the callback arguments via JavaScript in Default.aspx selectionLayerName = callbackArgumentsCollection["ddlSelectionLayer"]; showSelectionInTable = bool.Parse(callbackArgumentsCollection["chkSelectionInTable"]); } else { // Get the value of the selection layer and show in selection table server controls, which are automatically // included in postbacks (partial postbacks included) due to their being server controls selectionLayerName = adfMap.Page.Request.Params["ddlSelectionLayer"]; // For the show selection in table checkbox, automatic value is passed as either null (if unchecked) or "on" // (if checked) if (adfMap.Page.Request.Params["chkSelectionInTable"] == null) showSelectionInTable = false; else showSelectionInTable = true; } // Get the map extent of the rectangle drawn on the map ESRI.ArcGIS.ADF.Web.UI.WebControls.MapRectangleEventArgs mapRectangleEventArgs = (ESRI.ArcGIS.ADF.Web.UI.WebControls.MapRectangleEventArgs)toolEventArgs; ESRI.ArcGIS.ADF.Web.Geometry.Envelope adfEnvelope = mapRectangleEventArgs.MapExtent; // Get a reference to the resource ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality commonMapFunctionality = adfMap.GetFunctionality(resourceName); ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisResource = commonMapFunctionality.Resource; // Create a query functionality to use in querying the resource ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality commonQueryFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality) gisResource.CreateFunctionality( typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null); // Get the resource's queryable layers string[] layerIDs = null; string[] layerNames = null; commonQueryFunctionality.GetQueryableLayers(null, out layerIDs, out layerNames); // Get the index of the selection layer in the layer names and ids arrays int selectionLayerIndex = 0; for (int i = 0; i < layerNames.Length; i++) { if (layerNames[i] == selectionLayerName) { if (layerIDs[i] is string) { if (!int.TryParse((string)layerIDs[i], out selectionLayerIndex)) selectionLayerIndex = i; } else { selectionLayerIndex = i; } break; } } // Set-up a spatial filter to use in querying the resource ESRI.ArcGIS.ADF.Web.SpatialFilter adfSpatialFilter = new ESRI.ArcGIS.ADF.Web.SpatialFilter(); adfSpatialFilter.ReturnADFGeometries = true; adfSpatialFilter.MaxRecords = 100; adfSpatialFilter.Geometry = adfEnvelope; // Query the selection layer with the user-drawn rectangle System.Data.DataTable resultsDataTable = commonQueryFunctionality.Query( commonMapFunctionality.Name, layerIDs[selectionLayerIndex], adfSpatialFilter); if (resultsDataTable.Rows.Count == 0) { ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult noFeaturesFoundCallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript("alert('No selected features');"); adfMap.CallbackResults.Add(noFeaturesFoundCallbackResult); } // Convert the results data table to a graphics layer ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer resultsGraphicsLayer = ESRI.ArcGIS.ADF.Web.Converter.ToGraphicsLayer(resultsDataTable, System.Drawing.Color.Yellow, System.Drawing.Color.Green); // Retrieve and clear buffer resource ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality gisFunctionality = adfMap.GetFunctionality("Buffer"); ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource bufferGraphicsMapResource = gisFunctionality.Resource as ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource; bufferGraphicsMapResource.Graphics.Tables.Clear(); // Retrieve and clear selection resource gisFunctionality = adfMap.GetFunctionality("Selection"); ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource selectionGraphicsMapResource = gisFunctionality.Resource as ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource; selectionGraphicsMapResource.Graphics.Tables.Clear(); // Add the selection graphics layer to the resource selectionGraphicsMapResource.Graphics.Tables.Add(resultsGraphicsLayer); // Call method to display or hide the selection table, depending on whether // the "Display selection in table" checkbox is checked or not CustomToolUtility.DisplayOrHideSelectionTable(adfMap, resultsGraphicsLayer, showSelectionInTable); // Set the transparency of the selection graphics resource map resource item ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceItem selectionMapResourceItem = adfMap.MapResourceManagerInstance.ResourceItems.Find(selectionGraphicsMapResource.Name); selectionMapResourceItem.DisplaySettings.Transparency = 50; // Refresh the selection and buffer resources adfMap.RefreshResource(selectionGraphicsMapResource.Name); adfMap.RefreshResource(bufferGraphicsMapResource.Name); } catch (System.Exception exception) { adfMap.CallbackResults.Add(Utility.GetErrorCallback(exception)); } } #endregion } public class BufferTool : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction { #region IMapServerToolAction Members void ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction.ServerAction( ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs toolEventArgs) { ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = (ESRI.ArcGIS.ADF.Web.UI.WebControls.Map)toolEventArgs.Control; try { ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs mapPointEventArgs = (ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs)toolEventArgs; ESRI.ArcGIS.ADF.Web.Geometry.Point adfPoint = mapPointEventArgs.MapPoint; string bufferDistanceString = null; string selectionLayerName = null; bool showSelectionInTable; // Check whether the page request was issued using a callback or a postback. A callback is used if no // ScriptManager is on the page containing the tool. Otherwise, a partial postback is used. if (adfMap.Page.IsCallback) { // Get the callback arguments from the __CALLBACKPARAM argument of the page request parameters string callbackArgumentsString = toolEventArgs.Control.Page.Request.Params["__CALLBACKPARAM"]; System.Collections.Specialized.NameValueCollection callbackArgumentsCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(callbackArgumentsString); // Get the value of the buffer distance, selection layer, and show in selection table server controls, which were // explicitly added to the tool's arguments via JavaScript in Default.aspx bufferDistanceString = callbackArgumentsCollection["txtBufferDistance"]; selectionLayerName = callbackArgumentsCollection["ddlSelectionLayer"]; showSelectionInTable = bool.Parse(callbackArgumentsCollection["chkSelectionInTable"]); } else { // Get the value of the buffer distance, selection layer, and show in selection table server controls, which are // automatically included in postbacks (partial postbacks included) due to their being server controls bufferDistanceString = adfMap.Page.Request.Params["txtBufferDistance"]; selectionLayerName = adfMap.Page.Request.Params["ddlSelectionLayer"]; // For the show selection in table checkbox, automatic value is passed as either null (if unchecked) or "on" // (if checked) if (adfMap.Page.Request.Params["chkSelectionInTable"] == null) showSelectionInTable = false; else showSelectionInTable = true; } // Attempt to retrieve buffer distance from session. If the attempt fails, initialize // buffer distance as 0. float bufferDistanceFloat; if (!System.Single.TryParse(bufferDistanceString, out bufferDistanceFloat)) { bufferDistanceFloat = 0.0F; } // Create an ellipse based on the buffer distance System.Drawing.Drawing2D.GraphicsPath graphicsPath = new System.Drawing.Drawing2D.GraphicsPath(); graphicsPath.AddEllipse((float)adfPoint.X - (bufferDistanceFloat / 2), (float)adfPoint.Y - (bufferDistanceFloat / 2), bufferDistanceFloat, bufferDistanceFloat); // Flatten the ellipse. This will make it appear smooth. float flattening = bufferDistanceFloat / 1000; graphicsPath.Flatten(null, flattening); // Create a Web ADF Point Collection, and add each point in the graphics path to it ESRI.ArcGIS.ADF.Web.Geometry.PointCollection adfPointCollection = new ESRI.ArcGIS.ADF.Web.Geometry.PointCollection(); foreach (System.Drawing.PointF pointF in graphicsPath.PathPoints) { adfPointCollection.Add(new ESRI.ArcGIS.ADF.Web.Geometry.Point(pointF.X, pointF.Y)); } // Construct a Web ADF Polygon containing the buffer by populating a ring with the // buffer point collection, a ring collection with the ring, and a polygon with the // ring collection ESRI.ArcGIS.ADF.Web.Geometry.Ring adfRing = new ESRI.ArcGIS.ADF.Web.Geometry.Ring(); adfRing.Points = adfPointCollection; ESRI.ArcGIS.ADF.Web.Geometry.RingCollection adfRingCollection = new ESRI.ArcGIS.ADF.Web.Geometry.RingCollection(); adfRingCollection.Add(adfRing); ESRI.ArcGIS.ADF.Web.Geometry.Polygon adfBufferPolygon = new ESRI.ArcGIS.ADF.Web.Geometry.Polygon(); adfBufferPolygon.Rings = adfRingCollection; // Get the graphics resource that will hold the buffer ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality gisFunctionality = adfMap.GetFunctionality("Buffer"); ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource bufferGraphicsMapResource = gisFunctionality.Resource as ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource; // If the resource was not found, throw an exception if (bufferGraphicsMapResource == null) throw new System.Exception("Buffer graphics resource not in MapResourceManager"); // Clear the buffer resource of any previous results bufferGraphicsMapResource.Graphics.Tables.Clear(); // Add an element graphics layer to store the buffer geometry to the resource ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer elementGraphicsLayer = new ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer(); bufferGraphicsMapResource.Graphics.Tables.Add(elementGraphicsLayer); // Create a graphic element out of the buffer polygon and add it to the // buffer graphics layer ESRI.ArcGIS.ADF.Web.Geometry.Geometry adfGeometry = (ESRI.ArcGIS.ADF.Web.Geometry.Geometry)adfBufferPolygon; ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement graphicElement = new ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(adfGeometry, System.Drawing.Color.Green); graphicElement.Symbol.Transparency = 70.0; elementGraphicsLayer.Add(graphicElement); // Get the resource containing the selection layer ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality commonMapFunctionality = adfMap.GetFunctionality("Data Layers"); ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisResource = commonMapFunctionality.Resource; // Create a query functionality and use it to retrieve the IDs and names of the // resource's queryable layers ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality commonQueryFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality) gisResource.CreateFunctionality( typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null); string[] layerIDs; string[] layerNames; commonQueryFunctionality.GetQueryableLayers(null, out layerIDs, out layerNames); // Get the index of the selection layer in the ID and names arrays int selectionLayerIndex = 0; for (int i = 0; i < layerNames.Length; i++) { if (layerNames[i] == selectionLayerName) { selectionLayerIndex = i; break; } } // Initialize a Web ADF spatial filter with the buffer geometry and use // it to query the resource on which the selection will be performed ESRI.ArcGIS.ADF.Web.SpatialFilter adfSpatialFilter = new ESRI.ArcGIS.ADF.Web.SpatialFilter(); adfSpatialFilter.ReturnADFGeometries = true; adfSpatialFilter.MaxRecords = 1000; adfSpatialFilter.Geometry = adfBufferPolygon; System.Data.DataTable featuresInBufferDataTable = commonQueryFunctionality.Query( null, layerIDs[selectionLayerIndex], adfSpatialFilter); if (featuresInBufferDataTable.Rows.Count == 0) { ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult noFeaturesFoundCallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript("alert('No selected features');"); adfMap.CallbackResults.Add(noFeaturesFoundCallbackResult); } // Convert the query results to a graphics layer ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer selectionGraphicsLayer = ESRI.ArcGIS.ADF.Web.Converter.ToGraphicsLayer(featuresInBufferDataTable, System.Drawing.Color.Blue, System.Drawing.Color.Blue); // Get the graphics resource that will hold the selection and add the selection // graphics layer to it gisFunctionality = adfMap.GetFunctionality("Selection"); ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource selectionGraphicsMapResource = gisFunctionality.Resource as ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource; selectionGraphicsMapResource.Graphics.Tables.Clear(); selectionGraphicsMapResource.Graphics.Tables.Add(selectionGraphicsLayer); CustomToolUtility.DisplayOrHideSelectionTable(adfMap, selectionGraphicsLayer, showSelectionInTable); // Set the transparency of the buffer graphics resource map resource item ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceItem bufferMapResourceItem = adfMap.MapResourceManagerInstance.ResourceItems.Find(bufferGraphicsMapResource.Name); bufferMapResourceItem.DisplaySettings.Transparency = 50; // Set the transparency of the selection graphics resource map resource item ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceItem selectionMapResourceItem = adfMap.MapResourceManagerInstance.ResourceItems.Find(selectionGraphicsMapResource.Name); selectionMapResourceItem.DisplaySettings.Transparency = 50; adfMap.RefreshResource(bufferGraphicsMapResource.Name); adfMap.RefreshResource(selectionGraphicsMapResource.Name); } catch (System.Exception exception) { adfMap.CallbackResults.Add(Utility.GetErrorCallback(exception)); } } #endregion } internal class CustomToolUtility { public static void DisplayOrHideSelectionTable(ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap, ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer resultsGraphicsLayer, bool showTable) { try { // Get the GridView control that will be used to display selection results System.Web.UI.WebControls.GridView gridViewResults = (System.Web.UI.WebControls.GridView)adfMap.Page.FindControl("grdSelectionResults"); System.Web.UI.UpdatePanel updatepanel = (System.Web.UI.UpdatePanel)adfMap.Page.FindControl("UpdatePanel1"); System.Data.DataTable resultsDataTable = resultsGraphicsLayer; // Check whether to show selection results tabularly if (showTable) { // Make sure results were actually found if (resultsDataTable.Rows.Count > 0) { // Load the graphicsLayer into a new data table and remove the IS_SELECTED column System.Data.DataTable newDataTable = new System.Data.DataTable(); newDataTable.Load(resultsGraphicsLayer.CreateDataReader()); newDataTable.Columns.Remove("IS_SELECTED"); // Bind the results table to the GridView control gridViewResults.DataSource = newDataTable; gridViewResults.DataBind(); gridViewResults.Visible = true; } else { gridViewResults.Visible = false; } } else { gridViewResults.Visible = false; } updatepanel.Update(); } catch (System.Exception exception) { adfMap.CallbackResults.Add(Utility.GetErrorCallback(exception)); } } } }