Common Custom tasks
Common_CustomTasks_CSharp\FindNearTask_CSharp\Tools.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.
// 

// Contains implementations of the tools on FindNearTask's toolbar
namespace FindNearTask_CSharp
{
    // Allows specification of search area by user-drawn point
    public class SearchAreaByPoint : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction, 
        ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IToolbarItemSetup
    {
        // Instance variable referencing the toolbar item encapsulating the tool
        ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo _toolbarItemInfo;

        #region IMapServerToolAction Members

        // Fires when the tool is active and the map is clicked
        public void ServerAction(ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs toolEventArgs)
        {   
            // Get a reference to the FindNearTask containing the tool
            FindNearTask_CSharp.FindNearTask findNearTask = Utility.GetContainer(_toolbarItemInfo.Toolbar, 
                typeof(FindNearTask_CSharp.FindNearTask)) as FindNearTask_CSharp.FindNearTask;
            // Make sure the task was found
            if (findNearTask == null)
                return;

            // Get a reference to the buddied Map control
            ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = 
                toolEventArgs.Control as ESRI.ArcGIS.ADF.Web.UI.WebControls.Map;
            if (adfMap == null)
                return;

            // Get the user-drawn point and put it in a geometry array
            ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs mapPointEventArgs = toolEventArgs as
                ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs;
            ESRI.ArcGIS.ADF.Web.Geometry.Geometry[] inputGeometries = new ESRI.ArcGIS.ADF.Web.Geometry.Geometry[1];
            inputGeometries[0] = mapPointEventArgs.MapPoint as ESRI.ArcGIS.ADF.Web.Geometry.Geometry;

            // Update the FindNearTask's input geometries
            findNearTask.TaskInput.SetUserInputGeometries(inputGeometries);

            // UPdate the FindNearTask's user input and buffer GraphicsLayers
            findNearTask.UpdateInputGraphicsLayers();

            // Add a callback result to the map to invoke FindNearTask's JavaScript function that hides its
            // activity indicator
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult hideActivityIndicatorCallbackResult =
                ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript("hideUpdateAreaIndicator();");
            adfMap.CallbackResults.Add(hideActivityIndicatorCallbackResult);
        }

        #endregion

        #region IToolbarItemSetup Members

        // We implement IToolbarItemSetup to gain easy access to the tool via the Initialize method.
        public void Initialize(ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo)
        {
            _toolbarItemInfo = toolbarItemInfo;
        }

        public void Unload(ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo) { }

        #endregion
    }

    // Allows specification of search area by user-drawn polyline
    public class SearchAreaByPolyline : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction, 
        ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IToolbarItemSetup
    {
        // Instance variable referencing the toolbar item encapsulating the tool
        ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo _toolbarItemInfo;

        #region IMapServerToolAction Members

        // Fires when the tool is active and the user has finished drawing a polyline on the map
        public void ServerAction(ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs toolEventArgs)
        {
            // Get a reference to the containing FindNearTask
            FindNearTask_CSharp.FindNearTask findNearTask = Utility.GetContainer(_toolbarItemInfo.Toolbar,
                typeof(FindNearTask_CSharp.FindNearTask)) as FindNearTask_CSharp.FindNearTask;

            // Get the geometry of the user-drawn polyline and put it in a geometry array
            ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPolylineEventArgs mapPolylineEventArgs =
                toolEventArgs as ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPolylineEventArgs;
            ESRI.ArcGIS.ADF.Web.Geometry.Geometry[] inputGeometries = new ESRI.ArcGIS.ADF.Web.Geometry.Geometry[1];
            inputGeometries[0] = mapPolylineEventArgs.MapPolyline as ESRI.ArcGIS.ADF.Web.Geometry.Geometry;

            // Update the FindNearTask's input geometries with the polyline
            findNearTask.TaskInput.SetUserInputGeometries(inputGeometries);

            // Update the FindNearTask's user input and buffer GraphicsLayers
            findNearTask.UpdateInputGraphicsLayers();

            // 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;

            // Add a callback to the map to invoke FindNearTask's JavaScript functiont that hides its activity indicator
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult hideActivityIndicatorCallbackResult =
                ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript("hideUpdateAreaIndicator();");
            adfMap.CallbackResults.Add(hideActivityIndicatorCallbackResult);
        }
        #endregion

        #region IToolbarItemSetup Members

        // We implement IToolbarItemSetup to gain easy access to the tool via the Initialize method.
        public void Initialize(ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo)
        {
            _toolbarItemInfo = toolbarItemInfo;
        }

        public void Unload(ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo) { }

        #endregion
    }

    // Allows specification of search area by user-drawn polygon
    public class SearchAreaByPolygon : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction,
        ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IToolbarItemSetup
    {
        // Instance variable referencing the toolbar item encapsulating the tool
        ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo _toolbarItemInfo;

        #region IMapServerToolAction Members

        public void ServerAction(ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs args)
        {
            // Get a reference to the containing FindNearTask
            FindNearTask_CSharp.FindNearTask findNearTask = Utility.GetContainer(_toolbarItemInfo.Toolbar,
                typeof(FindNearTask_CSharp.FindNearTask)) as FindNearTask_CSharp.FindNearTask;

            // Retrieve the user-drawn polygon and put it in a geometry array
            ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPolygonEventArgs mapPolygonEventArgs =
                args as ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPolygonEventArgs;
            ESRI.ArcGIS.ADF.Web.Geometry.Geometry[] inputGeometries = new ESRI.ArcGIS.ADF.Web.Geometry.Geometry[1];
            inputGeometries[0] = mapPolygonEventArgs.MapPolygon as ESRI.ArcGIS.ADF.Web.Geometry.Geometry;

            // Update FindNearTask's input geometries with the polygon
            findNearTask.TaskInput.SetUserInputGeometries(inputGeometries);

            // Update FindNearTask's user input and buffer graphics layers
            findNearTask.UpdateInputGraphicsLayers();

            // 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)args.Control;

            // Add a callback result to invoke FindNearTask's JavaScript function that hides its activity indicator
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult hideActivityIndicatorCallbackResult =
                ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript("hideUpdateAreaIndicator();");
            adfMap.CallbackResults.Add(hideActivityIndicatorCallbackResult);
        }
        #endregion

        #region IToolbarItemSetup Members

        // We implement IToolbarItemSetup to gain easy access to the tool via the Initialize method.
        public void Initialize(ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo)
        {
            _toolbarItemInfo = toolbarItemInfo;
        }

        public void Unload(ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo) { }

        #endregion
    }

    // Allows specification of search area by selecting a task result.  All the implementation logic
    // is handled in the Node_Clicked event of the TaskResults control buddied to the parent FindNearTask.
    // This is necessary because the tool's ServerAction only fires when the Map is clicked.  We use a
    // Web ADF Tool nonetheless because it provides a simple framework for integration with a Web ADF
    // Toolbar and task.
    public class SearchAreaByTaskResult : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction
    {

        #region IMapServerToolAction Members

        public void ServerAction(ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs args)
        {
        }
        #endregion
    }

    // Allows specification of a search area by selecting features on the map
    public class SearchAreaBySelection : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction, ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IToolbarItemSetup
    {
        // Instance variable referencing the toolbar item encapsulating the tool
        ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo _toolbarItemInfo;

        #region IMapServerToolAction Members

        public void ServerAction(ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs toolEventArgs)
        {
            // Get a reference to the containing FindNearTask
            FindNearTask_CSharp.FindNearTask findNearTask = Utility.GetContainer(_toolbarItemInfo.Toolbar, 
                typeof(FindNearTask_CSharp.FindNearTask)) as FindNearTask_CSharp.FindNearTask;

            // 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;

            // 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 the user-specified tool parameters specified via the page's interface

            string selectionInput = null;
            if (adfMap.Page.IsCallback)
            {
                // Since the page is using the callback framework, the tool parameters have been packaged 
                // along with the callback parameters.  This is done via custom javascript.
                string callbackArguments = adfMap.Page.Request.Params["__CALLBACKPARAM"];
                System.Collections.Specialized.NameValueCollection callbackArgsCollection =
                    ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(
                    callbackArguments);
                selectionInput = callbackArgsCollection["SelectionLayer"];
            }
            else
            {
                // Since the page is using the PartialPostback framework, and the controls receiving user
                // input are ASP.NET server controls, the tool parameters are automatically passed in
                // the page's request parameters.
                selectionInput = adfMap.Page.Request.Params["SelectionLayer"];
            }

            string[] selectionInputArray = selectionInput.Split(',');

            // Get the name of the resource on which to perform the selection
            string resourceName = selectionInputArray[0];

            // 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);

            string selectionLayerID = selectionInputArray[1];

            // 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, selectionLayerID, adfSpatialFilter);

            // Convert the results data table to a graphics layer
            ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer resultsGraphicsLayer =
                ESRI.ArcGIS.ADF.Web.Converter.ToGraphicsLayer(resultsDataTable);

            // Put the geometries of the results features in a geometry array
            ESRI.ArcGIS.ADF.Web.Geometry.Geometry[] inputGeometries =
                new ESRI.ArcGIS.ADF.Web.Geometry.Geometry[resultsGraphicsLayer.Rows.Count];
            for (int i = 0; i < resultsGraphicsLayer.Rows.Count; i++)
                inputGeometries[i] = resultsGraphicsLayer.GeometryFromRow(resultsGraphicsLayer.Rows[i]);

            // Update FindNearTask's input geometries with those of the selected features
            findNearTask.TaskInput.SetUserInputGeometries(inputGeometries);

            // Update FindNearTask's user input and buffer GraphicsLayers
            findNearTask.UpdateInputGraphicsLayers();

            // Create a callback invoking FindNearTask's client-side function to hide its activity indicator
            ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult hideActivityIndicatorCallbackResult =
                ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript("hideUpdateAreaIndicator();");
            adfMap.CallbackResults.Add(hideActivityIndicatorCallbackResult);

            return;
        }
        #endregion


        #region IToolbarItemSetup Members
        
        // We implement IToolbarItemSetup to gain easy access to the tool via the Initialize method.
        public void Initialize(ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo)
        {
            _toolbarItemInfo = toolbarItemInfo;
        }

        public void Unload(ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo) { }

        #endregion
    }

    public class ClearInput : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerCommandAction
    {
        #region IMapServerCommandAction Members

        void ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IServerAction.ServerAction(
            ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo)
        {
            // Get a reference to the containing FindNearTask and call the method to clear all task input
            FindNearTask_CSharp.FindNearTask findNearTask = Utility.GetContainer(toolbarItemInfo.Toolbar,
                typeof(FindNearTask_CSharp.FindNearTask)) as FindNearTask_CSharp.FindNearTask;
            findNearTask.ClearTaskInput();
        }

        #endregion
    }

    public class Utility
    {
        // Traverses the ancestors of the passed-in control until the first ancestor of the passed-in type is found
        public static System.Web.UI.Control GetContainer(System.Web.UI.Control control, System.Type typeOfContainer)
        {
            System.Web.UI.Control containerControl = null;
            if (control.Parent != null)
            {
                if (typeOfContainer.IsAssignableFrom(control.Parent.GetType()))
                    containerControl = control.Parent;
                else
                    containerControl = GetContainer(control.Parent, typeOfContainer);
            }

            return containerControl;
        }
    }

}