ArcIMS Select Buffer tool
ArcIMS_SelectBufferTool_CSharp\App_Code\BufferTool.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.
// 



using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Data;
using System.Drawing;
using System.Collections;


// For ArcMap services, graphic features (acetate layers) cannot be buffered.  As a result, the buffer tool will
// only be able to draw the graphic feature.  This is an ArcMap server limitation.
// For Image services, buffers on graphic features cannot be rendered by ArcIMS.  
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)
    {
        int resourceIndex = 0;

        ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = (ESRI.ArcGIS.ADF.Web.UI.WebControls.Map)toolEventArgs.Control;

        // User provided values included in ESRIWebADFHiddenFields (see Page_PreRender in Default.aspx.cs).  
        // Get the selected value in the active layer drop down list.
        System.Collections.Specialized.NameValueCollection nameValueCollection = null;
        if (adfMap.Page.IsCallback)
        {
            string callbackArgs = adfMap.Page.Request.Params["__CALLBACKPARAM"];
            nameValueCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(callbackArgs);
        }
        else // if full page postback
        {
            nameValueCollection = adfMap.Page.Request.Params;
        }

        // Populate buffer tool parameters
        string targetLayerName = nameValueCollection["bufferSelectLayerDropDownList"];
        string bufferDistanceString = nameValueCollection["bufferToolDistanceTextBox"];
        string bufferUnitsString = nameValueCollection["bufferToolUnitsDropDownList"];

        ESRI.ArcGIS.ADF.Web.DataSources.IMS.MapFunctionality imsMapFunctionality = 
            (ESRI.ArcGIS.ADF.Web.DataSources.IMS.MapFunctionality)adfMap.GetFunctionality(resourceIndex);
        
        ESRI.ArcGIS.ADF.IMS.Carto.MapView mapview = imsMapFunctionality.MapView;

        // Remove all dynamic layers.  Removes all previous selections, buffers, and graphics.
        foreach (string layerName in LayerNames.GetLayerNames())
        {
            ESRI.ArcGIS.ADF.IMS.Carto.Layer.Layer layer = mapview.Layers.FindByName(layerName);
            if (layer != null)
            {
                mapview.Layers.Remove(layer);
            }
        }

        // Convert user entered polyline from screen units to map units
        ESRI.ArcGIS.ADF.Web.UI.WebControls.PolylineEventArgs polylineEventArgs =
            (ESRI.ArcGIS.ADF.Web.UI.WebControls.PolylineEventArgs)toolEventArgs;
        System.Drawing.Point[] screenPoints = polylineEventArgs.Vectors;

        ESRI.ArcGIS.ADF.IMS.Geometry.Envelope imsExtentEnvelope = (ESRI.ArcGIS.ADF.IMS.Geometry.Envelope)
            ESRI.ArcGIS.ADF.Web.DataSources.IMS.Converter.ToIMSGeometry(adfMap.Extent);

        ESRI.ArcGIS.ADF.IMS.Geometry.PointCollection imsPointCollection =
            new ESRI.ArcGIS.ADF.IMS.Geometry.PointCollection();

        // Iterate through each screen point and add it to an IMS point collection
        foreach (System.Drawing.Point screenPoint in screenPoints)
        {
            ESRI.ArcGIS.ADF.IMS.Geometry.Point imsPoint =
                ESRI.ArcGIS.ADF.IMS.Geometry.Point.ToMapPoint(screenPoint, imsExtentEnvelope, adfMap.TilingScheme.TileWidth, adfMap.TilingScheme.TileHeight);
            imsPointCollection.Add(imsPoint);
        }
        // Create a path from the point collection and add it to a polyline
        ESRI.ArcGIS.ADF.IMS.Geometry.Path imsPath = new ESRI.ArcGIS.ADF.IMS.Geometry.Path();
        imsPath.Points = imsPointCollection;
        ESRI.ArcGIS.ADF.IMS.Geometry.Polyline imsPolyline = new ESRI.ArcGIS.ADF.IMS.Geometry.Polyline();
        imsPolyline.Paths.Add(imsPath);

        // Create a new acetate layer to display user entered polyline
        ESRI.ArcGIS.ADF.IMS.Carto.Layer.AcetateLayer acetatePolylineLayer = 
            new ESRI.ArcGIS.ADF.IMS.Carto.Layer.AcetateLayer(LayerNames.BufferToolLine);
        acetatePolylineLayer.Name = LayerNames.BufferToolLine;
        acetatePolylineLayer.Visible = true;

        ESRI.ArcGIS.ADF.IMS.Display.AcetateElement.AcetateElementCollection acetateElementCollection = 
            acetatePolylineLayer.AcetateElements;
        ESRI.ArcGIS.ADF.IMS.Display.AcetateElement.GeometryElement acetateGeometryElement = 
            new ESRI.ArcGIS.ADF.IMS.Display.AcetateElement.GeometryElement
            (ESRI.ArcGIS.ADF.IMS.Display.AcetateElement.AcetateUnits.Database);
        acetateGeometryElement.Element = imsPolyline;

        ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleLineSymbol imsAcetatePolylineSymbol = 
            new ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleLineSymbol();
        imsAcetatePolylineSymbol.Color = System.Drawing.Color.SpringGreen;
        imsAcetatePolylineSymbol.Type = ESRI.ArcGIS.ADF.IMS.Display.Symbol.LineType.Solid;
        imsAcetatePolylineSymbol.Width = 2;
        acetateGeometryElement.Symbol = imsAcetatePolylineSymbol;

        acetateElementCollection.Add(acetateGeometryElement);

        // *** Add dynamic acetate layer to the map
        mapview.Layers.Add(acetatePolylineLayer);

        // If target layer defined, buffer polyline and select features in the target layer
        if (targetLayerName != "none")
        {
            float bufferDistance;
            if (!Single.TryParse(bufferDistanceString, out bufferDistance))
            {
                bufferDistance = 0.0F;
            }

            ESRI.ArcGIS.ADF.IMS.Carto.Layer.BufferUnits imsBufferUnits =
                (ESRI.ArcGIS.ADF.IMS.Carto.Layer.BufferUnits)Enum.Parse(typeof(ESRI.ArcGIS.ADF.IMS.Carto.Layer.BufferUnits), bufferUnitsString, true);

            ESRI.ArcGIS.ADF.IMS.Carto.Layer.FeatureLayer targetFeatureLayer = (ESRI.ArcGIS.ADF.IMS.Carto.Layer.FeatureLayer)mapview.Layers.FindByName(targetLayerName);

            ESRI.ArcGIS.ADF.IMS.Carto.Layer.Filter filter = new ESRI.ArcGIS.ADF.IMS.Carto.Layer.Filter();
            // Use user entered polyline to select features
            filter.Geometry = imsPolyline;
            // Use tolerance and units to define the distance (buffer distance) from geometry
            filter.Tolerance = bufferDistance;
            filter.ToleranceUnits = imsBufferUnits;

            ESRI.ArcGIS.ADF.IMS.Carto.Layer.FeatureLayer bufferToolSelectionFeatureLayer = null;

            if (imsMapFunctionality.MapResource.MapService.Type == ESRI.ArcGIS.ADF.IMS.ServiceType.ArcMapServer)
            {
                bufferToolSelectionFeatureLayer = targetFeatureLayer.CreateSelectionLayer(filter, null,
                    LayerNames.BufferToolTarget);
            }
            else
            {
                ESRI.ArcGIS.ADF.IMS.Display.Renderer.SimpleRenderer targetSelectionSimpleRenderer =
                new ESRI.ArcGIS.ADF.IMS.Display.Renderer.SimpleRenderer();

                ESRI.ArcGIS.ADF.IMS.Display.Symbol.FeatureSymbol targetSelectionFeatureSymbol = null;

                ESRI.ArcGIS.ADF.IMS.FeatureType imsTargetFeatureType = targetFeatureLayer.Type;
                if (imsTargetFeatureType == ESRI.ArcGIS.ADF.IMS.FeatureType.Point)
                {
                    ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleMarkerSymbol targetSelectionSimpleMarkerSymbol =
                        new ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleMarkerSymbol();
                    targetSelectionSimpleMarkerSymbol.Color = System.Drawing.Color.Red;
                    targetSelectionSimpleMarkerSymbol.Width = 12;
                    targetSelectionFeatureSymbol = targetSelectionSimpleMarkerSymbol;
                }
                else if (imsTargetFeatureType == ESRI.ArcGIS.ADF.IMS.FeatureType.Line)
                {
                    ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleLineSymbol targetSelectionSimpleLineSymbol =
                        new ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleLineSymbol();
                    targetSelectionSimpleLineSymbol.Width = 2;
                    targetSelectionSimpleLineSymbol.Color = System.Drawing.Color.Red;
                    targetSelectionFeatureSymbol = targetSelectionSimpleLineSymbol;
                }
                else if (imsTargetFeatureType == ESRI.ArcGIS.ADF.IMS.FeatureType.Polygon)
                {
                    ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleFillSymbol targetSelectionSimpleFillSymbol =
                        new ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleFillSymbol();
                    targetSelectionSimpleFillSymbol.Color = System.Drawing.Color.Red;
                    targetSelectionFeatureSymbol = targetSelectionSimpleFillSymbol;
                }

                if (targetSelectionFeatureSymbol != null)
                {
                    targetSelectionFeatureSymbol.Transparency = 50.0;
                }

                targetSelectionSimpleRenderer.Symbol = targetSelectionFeatureSymbol;

                bufferToolSelectionFeatureLayer = targetFeatureLayer.CreateSelectionLayer(filter, 
                    targetSelectionSimpleRenderer, LayerNames.BufferToolTarget);
            }

            bufferToolSelectionFeatureLayer.Name = LayerNames.BufferToolTarget;
            // *** Add dynamic selection by buffer in target layer to the map
            mapview.Layers.Add(bufferToolSelectionFeatureLayer);
        }

        if (adfMap.ImageBlendingMode == ESRI.ArcGIS.ADF.Web.UI.WebControls.ImageBlendingMode.Browser)
        {
            adfMap.RefreshResource(imsMapFunctionality.Resource.Name);
        }
        else
        {
            adfMap.Refresh();
        }
    }
    #endregion
}