ArcGIS ClipShip Geoprocessing
ArcGIS_ClipShip_Geoprocessing_VBNet\Default.aspx.vb
' Copyright 2008 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.
' 

Imports Microsoft.VisualBasic
Imports System
Public Partial Class _Default
  Inherits System.Web.UI.Page
  Implements System.Web.UI.ICallbackEventHandler
  #Region "Instance Variable Declarations"

  Private m_adfCallbackFunctionString As String
  Private m_callbackResultCollection As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection

  ' Names of the layers that will hold the clipped features and user-drawn polylines
  Private m_clippedFeaturesLayerName As String = "Clip"
  Private m_polylineGraphicsLayerName As String = "Polylines"

  ' Name of the geoproccessing resource containing the ClipCounties task
  Private m_geoprocessingResourceName As String = "Buffer and Clip Resource"

  ' Name of the resource that will store clip results if m_displayResultsInMapResource is
  ' set to true
  Private m_resultsMapResourceName As String = "Clip Results"

  ' Name of the resource in which to store geoprocessing results (if 
  ' m_displayResultsInMapResource is false) and user-drawn polylines
  Private m_graphicsResourceName As String = "Web ADF Graphics"

  ' Determines whether to display the geoprocessing results in a map resource or as graphics
  Private m_displayResultsInMapResource As Boolean = True

  ' Name of the GP tool layer in the map service.  This is the layer that was created in the
  ' underlying mxd by dragging and dropping the GP tool into the mxd.  This name will be used
  ' to remove the layer from the Toc.
  Private m_toolLayerName As String = "ClipCounties"

  #End Region

  #Region "ASP.NET Page Life Cycle Event Handlers"

  Protected Sub Page_PreRender(ByVal sender As Object, ByVal eventArgs As System.EventArgs)
    Try
      ' Initialize session variable only if the page request is occurring at the beginning of a session
      If Page.Session.IsNewSession Then
        Session("graphicsResourceName") = m_graphicsResourceName
        Session("polylineGraphicsLayerName") = m_polylineGraphicsLayerName
      End If

      ' Make sure control initialization only occurs during initial page load or on page refresh
      If (Not Page.IsPostBack) Then
        ' Add all the ArcGIS Server unit types to the units drop-down list except for unknown, points, 
        ' and decimal degress
        Dim agsUnitTypes As System.Array = System.Enum.GetValues(GetType(ESRI.ArcGIS.ADF.Web.DataSources.Units))
        For Each agsUnitType As Integer In agsUnitTypes
          Dim unit As String = agsUnitTypes.GetValue(agsUnitType).ToString()
          If (unit <> "Unknown") AndAlso (unit <> "DecimalDegrees") AndAlso (unit <> "Points") Then
            unitsDropDownList.Items.Add(unit)
          End If
        Next agsUnitType
      End If
    Catch exception As System.Exception
      Dim jsErrorAlertString As String = String.Format("<script>{0}</script>", Utility.GetJavaScriptErrorString(exception))
      Response.Write(jsErrorAlertString)
    End Try
  End Sub

  ' Generates custom callback function string for non-ADF controls\elements in page that generate callbacks
  Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs)
    ' Define the parameters for a browser call to the WebForm_DoCallback JavaScript function
    ' via the GetCallbackEventReference function.  This function returns the syntax for initiating 
    ' a callback (i.e a call to WebForm_DoCallback) with the passed-in parameters.  Here the 
    ' parameters are defined as follows:
    ' this - the Page will handle the callback request
    ' "message" - a JavaScript variable named "message" will contain argument-value pairs passed 
    '      to the callback server-side
    ' "processCallbackResult" - name of the JavaScript function to process the callback 
    '      results from the server.  This function is the callback results handler included with 
    '      the Web ADF JavaScript Library.
    ' "context" - a JavaScript variable named "context" which can be used by the client to
    '      indicate the origin of the callback
    ' "postBackError" - name of the JavaScript function that will process errors returned during 
    '      callback processing.  This is the callback error handler included with the Web ADF 
    '      JavaScript Library
    ' true - define whether the callback is synchronous or asynchronous.  True is asynchronous.        
    m_adfCallbackFunctionString = Page.ClientScript.GetCallbackEventReference(Me, "message", "processCallbackResult", "context", "postBackError", True)

    RemoveLayerFromToc(m_toolLayerName)
  End Sub

  #End Region

  #Region "ICallbackEventHandler Members"

  ' Receives the arguments packaged in the callback on the client.  We parse those arguments here and 
  ' initiate server-side logic accordingly.
  Public Sub RaiseCallbackEvent(ByVal eventArgs As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
    ' Instantiate a new callback results collection to hold the callback's results
    m_callbackResultCollection = New ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection()

    Try
      ' Use the Web ADF's callback utility to parse the arguments into a NameValueCollection
      Dim callbackArgsNameValueCollection As System.Collections.Specialized.NameValueCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(eventArgs)

      ' Check the callback event argument and execute logic accordingly
      Dim eventArg As String = callbackArgsNameValueCollection("EventArg")
      Dim downloadOutputString As String = Nothing
      Dim downloadOutput As Boolean = False
      Select Case eventArg
        Case "bufferAndClip"
          ' Get the user-specified buffer and clip operation parameters
          Dim bufferDistanceString As String = callbackArgsNameValueCollection("BufferDistance")
          Dim bufferDistance As Double = 0
          Double.TryParse(bufferDistanceString, bufferDistance)
          downloadOutputString = callbackArgsNameValueCollection("DownloadOutput")
          Boolean.TryParse(downloadOutputString, downloadOutput)

          ' Invoke the method to initiate the geoprocessing task
          StartBufferAndClipJob(bufferDistance, callbackArgsNameValueCollection("Units"), downloadOutput)
        Case "clearGraphics"
          ' Invoke the method to clear the graphics from the map
          ClearGraphics()
        Case "checkGeoprocessingJob"
          ' Get parameter indicating whether geoprocessing results are to be made available for download
          downloadOutputString = callbackArgsNameValueCollection("DownloadOutput")
          Boolean.TryParse(downloadOutputString, downloadOutput)

          ' Check whether the geoprocssing job is finished and process results if so
          CheckGeoprocessingJobStatus(callbackArgsNameValueCollection("JobID"), callbackArgsNameValueCollection("TaskName"), callbackArgsNameValueCollection("TaskOutputParameters"), downloadOutput)
      End Select
    Catch exception As System.Exception
      Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = Utility.CreateErrorCallbackResult(exception)
      m_callbackResultCollection.Add(errorCallbackResult)
    End Try
  End Sub

  ' The last server-side method called before the callback returns to the browser, GetCallbackResult
  ' is where the server-side result of the callback is passed back to the browser as a string for
  ' processing by the client.
  Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
    Return m_callbackResultCollection.ToString()
  End Function


  #End Region

  #Region "Instance Properties"

  ' Provides a client-side reference to the function call that will initiate a callback to this page
  Public ReadOnly Property AdfCallbackFunctionString() As String
    Get
      Return m_adfCallbackFunctionString
    End Get
  End Property

  #End Region

  #Region "Instance Methods"

  ' Initiates the buffer and clip geoprocessing job with the passed-in parameters
  Private Sub StartBufferAndClipJob(ByVal bufferDistance As Double, ByVal units As String, ByVal downloadOutput As Boolean)
'    #Region "Initialize resources and functionalities"

    ' Initialize GP resource and functionality
    Dim geoprocessingResourceItem As ESRI.ArcGIS.ADF.Web.UI.WebControls.GeoprocessingResourceItem = GeoprocessingResourceManager1.ResourceItems.Find(m_geoprocessingResourceName)

    ' Make sure the geoprocessing resource is initialized
    If (Not geoprocessingResourceItem.Resource.Initialized) Then
      geoprocessingResourceItem.InitializeResource()
    End If

    ' Get a reference to the GP resource and its functionality
    Dim geoprocessingResource As ESRI.ArcGIS.ADF.Web.DataSources.IGeoprocessingResource = CType(geoprocessingResourceItem.Resource, ESRI.ArcGIS.ADF.Web.DataSources.IGeoprocessingResource)

    Dim commonGeoprocessingFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IGeoprocessingFunctionality = CType(geoprocessingResource.CreateFunctionality(GetType(ESRI.ArcGIS.ADF.Web.DataSources.IGeoprocessingFunctionality), Nothing), ESRI.ArcGIS.ADF.Web.DataSources.IGeoprocessingFunctionality)

    Dim agsGeoprocessingFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.GeoprocessingFunctionality = TryCast(commonGeoprocessingFunctionality, ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.GeoprocessingFunctionality)

    ' Make sure the geoprocessing functionality is initialized
    If (Not agsGeoprocessingFunctionality.Initialized) Then
      agsGeoprocessingFunctionality.Initialize()
    End If

'    #End Region

'    #Region "Prepare inputs and start the GP task"

    ' Set the name of the geoprocessing (GP) task
    Dim GPTaskName As String = "ClipCounties"

    ' Get an array of the GP task's parameters
    Dim adfGPToolInfo As ESRI.ArcGIS.ADF.Web.DataSources.GPToolInfo = agsGeoprocessingFunctionality.GetTask(GPTaskName)
    Dim adfGPParamterInfoArray As ESRI.ArcGIS.ADF.Web.DataSources.GPParameterInfo() = adfGPToolInfo.ParameterInfo

    ' Get a reference to the first input parameter (a feature set) as a Web ADF feature graphics layer
    Dim adfGPFeatureGraphicsLayer As ESRI.ArcGIS.ADF.Web.DataSources.GPFeatureGraphicsLayer = CType(adfGPParamterInfoArray(0).Value, ESRI.ArcGIS.ADF.Web.DataSources.GPFeatureGraphicsLayer)
    Dim featureGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer = adfGPFeatureGraphicsLayer.Layer

    ' Get the graphics resource containing the layer that holds the user-drawn lines
    Dim adfGraphicsMapResource As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource = TryCast(Map1.GetFunctionality(m_graphicsResourceName).Resource, ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource)

    ' Get the graphics layer containing the user-drawn lines
    Dim polylineElementGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer = TryCast(adfGraphicsMapResource.Graphics.Tables(m_polylineGraphicsLayerName), ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer)

    ' If there are no lines in the layer, alert the user and exit the function
    If (polylineElementGraphicsLayer Is Nothing) OrElse (polylineElementGraphicsLayer.Rows.Count < 1) Then
      Dim noLinesAlertCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript("alert('No lines to buffer')")
      m_callbackResultCollection.Add(noLinesAlertCallbackResult)
      m_callbackResultCollection.Add(HideActivityIndicators())
      Return
    End If

    ' Add each polyline to the feature graphics layer that we're using as input to the GP task
    For Each dataRow As System.Data.DataRow In polylineElementGraphicsLayer.Rows
      Dim adfPolyline As ESRI.ArcGIS.ADF.Web.Geometry.Polyline = TryCast(polylineElementGraphicsLayer.GeometryFromRow(dataRow), ESRI.ArcGIS.ADF.Web.Geometry.Polyline)
      featureGraphicsLayer.Add(adfPolyline)
    Next dataRow

    ' Get the Web ADF Unit enumeration value corresponding to the user-defined unit 
    Dim adfGPLinearUnit As ESRI.ArcGIS.ADF.Web.DataSources.GPLinearUnit = New ESRI.ArcGIS.ADF.Web.DataSources.GPLinearUnit()
    Dim adfUnits As ESRI.ArcGIS.ADF.Web.DataSources.Units = CType(System.Enum.Parse(GetType(ESRI.ArcGIS.ADF.Web.DataSources.Units), units, True), ESRI.ArcGIS.ADF.Web.DataSources.Units)

    ' Set the GP task's second input parameter (linear unit) using the user-defined
    ' distance and units 
    adfGPLinearUnit.Units = adfUnits
    adfGPLinearUnit.Value = bufferDistance

    ' Put the parameters in an input array and start the geoprocessing job
    Dim adfGPValueArray As ESRI.ArcGIS.ADF.Web.DataSources.GPValue() = New ESRI.ArcGIS.ADF.Web.DataSources.GPValue(1){}
    adfGPValueArray(0) = adfGPFeatureGraphicsLayer
    adfGPValueArray(1) = adfGPLinearUnit
    Dim jobID As String = agsGeoprocessingFunctionality.SubmitJob(GPTaskName, adfGPValueArray)

'    #End Region

'    #Region "Construct a callback to check the GP task's status"

    ' Get the output parameter names to use when retrieving geoprocessing job results
    Dim outputTaskParameters As String = Nothing
    Dim agsGPParameterInfo As ESRI.ArcGIS.ADF.Web.DataSources.GPParameterInfo
    Dim i As Integer = 0
    Do While i < adfGPParamterInfoArray.Length
      agsGPParameterInfo = adfGPParamterInfoArray(i)

      ' Only append output parameters to the parameter string
      If agsGPParameterInfo.Direction = ESRI.ArcGIS.ADF.Web.DataSources.GPParameterDirection.Output Then
        ' Only append the zip file parameter name if the user has checked the download
        ' checkbox
        If agsGPParameterInfo.Name = "output_zip" AndAlso (Not downloadOutput) Then
          i += 1
          Continue Do
        End If

        outputTaskParameters &= agsGPParameterInfo.Name
        If i <> adfGPParamterInfoArray.Length - 1 Then
          outputTaskParameters &= ";"
        End If
      End If
      i += 1
    Loop

    ' Construct a callback with the JavaScript needed to trigger a second callback after one second 
    ' (1000 milliseconds) that will execute logic on the server to check the GP job's status and
    ' take action accordingly
    Dim jsCheckGeoprocessingJob As String = String.Format("window.setTimeout('executeCallback(" & """checkGeoprocessingJob"", ""JobID={0}&TaskName={1}&TaskOutputParameters={2}&" & "DownloadOutput={3}"")',1000);", jobID, GPTaskName,outputTaskParameters, downloadOutput.ToString())
    Dim checkGeoprocessingJobCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsCheckGeoprocessingJob)

    ' Add the GP job status check callback to the callback results collection
    m_callbackResultCollection.Add(checkGeoprocessingJobCallbackResult)

'    #End Region
  End Sub

  ' Check the GP job status for the job with the passed-in parameters and take action accordingly
  Protected Sub CheckGeoprocessingJobStatus(ByVal jobID As String, ByVal taskName As String, ByVal taskOutputParameters As String, ByVal downloadOutput As Boolean)
'    #Region "Initialize geoprocessing resources and functionalities"

    ' Initialize GP resource and functionality
    Dim geoprocessingResourceItem As ESRI.ArcGIS.ADF.Web.UI.WebControls.GeoprocessingResourceItem = GeoprocessingResourceManager1.ResourceItems.Find(m_geoprocessingResourceName)

    ' Make sure the geoprocessing resource is initialized
    If (Not geoprocessingResourceItem.Resource.Initialized) Then
      geoprocessingResourceItem.InitializeResource()
    End If

    ' Get a reference to the GP resource and its functionality
    Dim geoprocessingResource As ESRI.ArcGIS.ADF.Web.DataSources.IGeoprocessingResource = CType(geoprocessingResourceItem.Resource, ESRI.ArcGIS.ADF.Web.DataSources.IGeoprocessingResource)

    Dim commonGeoprocessingFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IGeoprocessingFunctionality = CType(geoprocessingResource.CreateFunctionality(GetType(ESRI.ArcGIS.ADF.Web.DataSources.IGeoprocessingFunctionality), Nothing), ESRI.ArcGIS.ADF.Web.DataSources.IGeoprocessingFunctionality)

    Dim agsGeoprocessingFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.GeoprocessingFunctionality = TryCast(commonGeoprocessingFunctionality, ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.GeoprocessingFunctionality)

    ' Make sure the geoprocessing functionality is initialized
    If (Not agsGeoprocessingFunctionality.Initialized) Then
      agsGeoprocessingFunctionality.Initialize()
    End If

'    #End Region

'    #Region "Construct callback to alert user if GP task failed or to check job status again if task is not complete"

    ' Get the GP job's status
    Dim adfJobStatus As ESRI.ArcGIS.ADF.Web.DataSources.JobStatus = agsGeoprocessingFunctionality.GetJobStatus(jobID)

    ' If GP job failed, get job's last message and return it in an alert box
        If adfJobStatus = ESRI.ArcGIS.ADF.Web.DataSources.JobStatus.Failed OrElse adfJobStatus = ESRI.ArcGIS.ADF.Web.DataSources.JobStatus.TimedOut Then
            ' Get the GP job's messages
            Dim adfJobMessageArray As ESRI.ArcGIS.ADF.Web.DataSources.JobMessage() = agsGeoprocessingFunctionality.GetJobMessages(jobID)
            Dim messageCount As Integer = adfJobMessageArray.Length

            ' Create the alert javascript and package it in a callback
            Dim jsAlertGPError As String = String.Format("alert('GP job failed: {0})'", adfJobMessageArray(messageCount - 1).MessageDesc)
            Dim gpErrorAlertCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsAlertGPError)

            ' Add the error alert to the callback results collection
            m_callbackResultCollection.Add(gpErrorAlertCallbackResult)

            ' Add a callback result to hide the operaton activity indicators to the callback results collection
            m_callbackResultCollection.Add(HideActivityIndicators())
            Return
        ElseIf Not adfJobStatus = ESRI.ArcGIS.ADF.Web.DataSources.JobStatus.Succeeded Then
            ' Since the GP job is not yet complete, create the javascript necessary to trigger another callback
            ' that will check the GP job status in 5 seconds.  Package this javascript in a callback result and
            ' add it to the callback results collection
            Dim jsCheckGeoprocessingJob As String = String.Format("window.setTimeout('executeCallback(" & """checkGeoprocessingJob"", ""JobID={0}&TaskName={1}&TaskOutputParameters={2}&" & "DownloadOutput={3}"")',5000);", jobID, taskName, taskOutputParameters, downloadOutput.ToString())
            Dim checkGeoprocessingJobCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsCheckGeoprocessingJob)
            m_callbackResultCollection.Add(checkGeoprocessingJobCallbackResult)
            Return
        End If

'    #End Region

'    #Region "Process the GP task's results"

    ' Parse the GP task's output parameter names
    Dim outputParametersArray As String() = taskOutputParameters.Split(";"c)
    ' Get the result of the GP task
    Dim adfGPResult As ESRI.ArcGIS.ADF.Web.DataSources.GPResult = agsGeoprocessingFunctionality.GetJobResult(taskName, jobID, outputParametersArray, m_displayResultsInMapResource)

    ' Iterate through the GP task results.  If the result is a data file and the user
    ' has checked the download results checkbox, add a callback that will enable 
    ' downloading of this file.  If the result is a graphics layer or a map resource
    ' definition, add the contents of these to the map so the results are displayed.
    Dim adfGPValueArray As ESRI.ArcGIS.ADF.Web.DataSources.GPValue() = adfGPResult.Values
    For Each adfGPValue As ESRI.ArcGIS.ADF.Web.DataSources.GPValue In adfGPValueArray
      If TypeOf adfGPValue Is ESRI.ArcGIS.ADF.Web.DataSources.GPDataFile AndAlso downloadOutput Then
'        #Region "Make the results available for download"

        ' Get the URL of the data file
        Dim adfGPDataFile As ESRI.ArcGIS.ADF.Web.DataSources.GPDataFile = CType(adfGPValue, ESRI.ArcGIS.ADF.Web.DataSources.GPDataFile)
        Dim urlZipFileString As String = adfGPDataFile.Data.URL

        ' Construct JavaScript to insert an iframe into the page that has the data file url 
        ' as its source.  The iframe will attempt to load whatever is referenced as its
        ' source, which in this case will trigger a download dialog.
        Dim jsDynamicDownload As String = "var ifrm = document.createElement('IFRAME');" & "ifrm.setAttribute('src','{0}');" & "ifrm.style.width='0px';" & "ifrm.style.height='0px';" & "ifrm.style.visibility='hidden';" & "document.body.appendChild(ifrm);"
        jsDynamicDownload = String.Format(jsDynamicDownload, urlZipFileString)

        ' Package the download-triggering JavaScript in a callback and add to the callback results
        Dim dynamicDownloadCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsDynamicDownload)
        m_callbackResultCollection.Add(dynamicDownloadCallbackResult)

'        #End Region
      ElseIf TypeOf adfGPValue Is ESRI.ArcGIS.ADF.Web.DataSources.GPFeatureGraphicsLayer Then
'        #Region "Add the clipped features to the map as graphics"

        ' The clip results will be returned as a feature graphics layer if 
        ' m_displayResultsInMapResource is set to false

        ' Get output feature set containing buffers as a Web ADF feature graphics layer
        Dim adfGPFeatureGraphicsLayer As ESRI.ArcGIS.ADF.Web.DataSources.GPFeatureGraphicsLayer = TryCast(adfGPValue, ESRI.ArcGIS.ADF.Web.DataSources.GPFeatureGraphicsLayer)
        Dim featureGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer = adfGPFeatureGraphicsLayer.Layer

        ' If the graphics layer has no features, alert the user that the operation did not create 
        ' any output
        If (featureGraphicsLayer Is Nothing) OrElse (featureGraphicsLayer.Rows.Count < 1) Then
          Dim noResultsAlertCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript("alert('No results returned');")
          m_callbackResultCollection.Add(noResultsAlertCallbackResult)

          ' Add a callback result to hide the operation activity indicators and enable the
          ' Buffer and Clip button
          m_callbackResultCollection.Add(HideActivityIndicators())
          Return
        End If

        ' Get the graphics layer's symbols and set their transparency to 50%
        Dim featureSymbolList As System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.Display.Symbol.FeatureSymbol) = New System.Collections.Generic.List(Of  ESRI.ArcGIS.ADF.Web.Display.Symbol.FeatureSymbol)()
        featureGraphicsLayer.Renderer.GetAllSymbols(featureSymbolList)
        For Each featureSymbol As ESRI.ArcGIS.ADF.Web.Display.Symbol.FeatureSymbol In featureSymbolList
          featureSymbol.Transparency = 50
        Next featureSymbol

        ' Set the feature graphics layer's name
        featureGraphicsLayer.TableName = m_clippedFeaturesLayerName

        ' Get the graphics resource to put the results layer in
        Dim graphicsMapResource As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource = TryCast(Map1.GetFunctionality(m_graphicsResourceName).Resource, ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource)

        ' If the resource already has a results graphics layer, remove it
        If graphicsMapResource.Graphics.Tables.Contains(m_clippedFeaturesLayerName) Then
          graphicsMapResource.Graphics.Tables.Remove(m_clippedFeaturesLayerName)
        End If

        ' Add new graphics layer to display new buffers
        graphicsMapResource.Graphics.Tables.Add(featureGraphicsLayer)

        ' Refresh the graphics resource and copy the map's callback results to the callback collection
        ' so the operation results are displayed
        Map1.RefreshResource(graphicsMapResource.Name)
        m_callbackResultCollection.CopyFrom(Map1.CallbackResults)

'        #End Region
      ElseIf TypeOf adfGPValue Is ESRI.ArcGIS.ADF.Web.DataSources.GPMapResourceDefinition Then
'        #Region "Add the clipped features to the map as features                "

        ' The clip results will be returned in a map resource definition if 
        ' m_displayResultsInMapResource is set to true.
        '
        ' Note that the code here makes use of the map resource definition created from the
        ' GP results by the Web ADF.  For more information on how to associate GP results 
        ' and ArcGIS Server map resources, see the LayerDescription help.

        ' Get the GP map resource definition 
        Dim gpMapResourceDefinition As ESRI.ArcGIS.ADF.Web.DataSources.GPMapResourceDefinition = TryCast(adfGPValue, ESRI.ArcGIS.ADF.Web.DataSources.GPMapResourceDefinition)

        ' Check whether a results map resource item has already been added
        Dim mapResourceItem As ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceItem = MapResourceManager1.ResourceItems.Find(m_resultsMapResourceName)
        If mapResourceItem Is Nothing Then
          ' Create a new map resource item to hold the results since one doesn't yet exist

          ' Instantiate the map resource item with the name specified in the class member.
          mapResourceItem = New ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceItem()
          mapResourceItem.Name = m_resultsMapResourceName

          ' Apply the GP results resource definition to the map resource item
          mapResourceItem.Definition = New ESRI.ArcGIS.ADF.Web.UI.WebControls.GISResourceItemDefinition(gpMapResourceDefinition.Value)

          ' Initialize the map resource item's display properties
          Dim displaySettings As ESRI.ArcGIS.ADF.Web.DisplaySettings = New ESRI.ArcGIS.ADF.Web.DisplaySettings()
          displaySettings.Transparency = 50
          displaySettings.Visible = True
          displaySettings.ImageDescriptor.TransparentColor = System.Drawing.Color.White
          displaySettings.ImageDescriptor.TransparentBackground = True
          mapResourceItem.DisplaySettings = displaySettings

          ' Add the new map resource item to the resource manager
          MapResourceManager1.ResourceItems.Insert(0, mapResourceItem)

          ' Refresh the Toc and copy its callback results to the callback results collection so the new
          ' resource has a Toc node
          Toc1.Refresh()
          m_callbackResultCollection.CopyFrom(Toc1.CallbackResults)
        Else
          ' Since the map resource item to hold the results has already been created, simply apply
          ' the definition returned with the GP results
          mapResourceItem.Definition = New ESRI.ArcGIS.ADF.Web.UI.WebControls.GISResourceItemDefinition(gpMapResourceDefinition.Value)
        End If

        ' Refresh the results resource and copy the map's callback results to the callback results 
        ' collection so the result features are displayed on the map
        Map1.RefreshResource(m_resultsMapResourceName)
        m_callbackResultCollection.CopyFrom(Map1.CallbackResults)

'        #End Region
      End If
    Next adfGPValue

    m_callbackResultCollection.Add(HideActivityIndicators())

'    #End Region
  End Sub

  ' Creates a callback result with the client-side code needed to hide the operation activity indicator
  ' and enable the operation execution button
  Private Function HideActivityIndicators() As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult
    Dim jsHideIndicators As String = "toggleActivityIndicators(false);"
    Dim hideIndicatorsCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsHideIndicators)
    Return hideIndicatorsCallbackResult
  End Function

  ' Clears features from all graphics layers in the resource specified by m_graphicsResourceName
  Private Sub ClearGraphics()
    ' Retrieve the resource and clear its graphics dataset
    Dim graphicsMapResource As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource = TryCast(Map1.GetFunctionality(m_graphicsResourceName).Resource, ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource)
    graphicsMapResource.Graphics.Clear()

    ' Refresh the resource and copy the map's callback results to the callback results collection so
    ' the graphics are removed from the map
    Map1.RefreshResource(graphicsMapResource.Name)
    m_callbackResultCollection.CopyFrom(Map1.CallbackResults)
  End Sub


  ' Removes the layer matching the input name from the TOC
  Private Sub RemoveLayerFromToc(ByVal layerName As String)
    ' Iterate through the nodes at the top level of the Toc.  Each of these should correspond to a resource.
    For Each resourceTreeViewPlusNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode In Toc1.Nodes
      Dim treeViewPlusNodeToRemove As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode = Nothing

      ' Iterate through the nodes below the current top-level node.  Each of these should 
      ' correspond to a layer.
      For Each layerTreeViewPlusNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode In resourceTreeViewPlusNode.Nodes
        ' Attempt to retrieve a node with text matching the passed-in layer name.  This could be
        ' the current node or any node below it.  Note that we need to search both the current node
        ' and any child nodes to handle group layers.
        Dim matchingTreeViewPlusNode As ESRI.ArcGIS.ADF.Web.UI.WebControls.TreeViewPlusNode = Utility.FindNodeRecursive(layerTreeViewPlusNode, layerName)

        ' If a matching node was found, store a reference to it to be accessed outside the loop
        If Not matchingTreeViewPlusNode Is Nothing Then
          treeViewPlusNodeToRemove = matchingTreeViewPlusNode
          Exit For
        End If
      Next layerTreeViewPlusNode

      ' Remove the matching node, if found
      If Not treeViewPlusNodeToRemove Is Nothing Then
        treeViewPlusNodeToRemove.Remove()
      End If
    Next resourceTreeViewPlusNode
  End Sub
  #End Region
End Class