ArcGIS_Buffer_Geoprocessing_VBNet\Default.aspx.vb
' 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. ' Imports Microsoft.VisualBasic Imports System Public Partial Class _Default Inherits System.Web.UI.Page #Region "Instance Variable Declarations" ' Name of the geoproccessing resource containing the BufferPoints task Private _geoprocessingResourceName As String = "Buffer Resource" ' Name of the resource in which to store geoprocessing results Private _graphicsResourceName As String = "Web ADF Graphics" ' Name of the graphics layers that will hold result buffers and user-placed points Private _bufferGraphicsLayerName As String = "Buffer" Private _pointGraphicsLayerName As String = "Points" Private _callbackResultCollection As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection = New ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection() #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 variables only if the page request is occurring at the beginning of a session If Page.Session.IsNewSession Then Session("graphicsResourceName") = _graphicsResourceName Session("pointGraphicsLayerName") = _pointGraphicsLayerName End If 'Make sure control initialization only occurs during initial page load or on page refresh If (Not ScriptManager1.IsInAsyncPostBack) 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 ' Generate custom callback function string for non-ADF controls\elements in page that generate callbacks Protected Sub Page_Load(ByVal sender As Object, ByVal eventArgs As System.EventArgs) ScriptManager1.RegisterAsyncPostBackControl(BufferButton) ScriptManager1.RegisterAsyncPostBackControl(ClearGraphicsButton) End Sub #End Region #Region "Request Handling" Protected Sub PostbackManager1_RequestReceived1(ByVal sender As Object, ByVal args As PostbackManager_VBNet.AdfRequestEventArgs) Handles PostbackManager1.RequestReceived ' Use the Web ADF's callback utility to parse the arguments into a NameValueCollection Dim requestArgs As System.Collections.Specialized.NameValueCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackUtility.ParseStringIntoNameValueCollection(args.RequestArguments) If requestArgs("EventArg") = "CheckJobStatus" Then Try ' Call the method to heck whether the geoprocssing job is finished and process results if so CheckJobStatus(requestArgs("JobID"), requestArgs("TaskName"), requestArgs("OutputParameters")) Catch exception As System.Exception Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = Utility.CreateErrorCallbackResult(exception) _callbackResultCollection.Add(errorCallbackResult) Finally PostbackManager1.CallbackResults.CopyFrom(_callbackResultCollection) End Try End If End Sub #End Region #Region "ASP.NET Web Control Event Handlers" Protected Sub BufferButton_Click1(ByVal sender As Object, ByVal e As System.EventArgs) Handles BufferButton.Click Try ' Get the buffer operation parameters specified by the user Dim bufferDistanceString As String = BufferDistanceTextBox.Text Dim bufferDistance As Double = 0 Double.TryParse(bufferDistanceString, bufferDistance) ' Invoke the method to initiate the geoprocessing task StartBufferJob(bufferDistance, UnitsDropDownList.SelectedValue) Catch exception As System.Exception Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = Utility.CreateErrorCallbackResult(exception) _callbackResultCollection.Add(errorCallbackResult) Finally ScriptManager1.RegisterDataItem(Page, _callbackResultCollection.ToString(), False) End Try End Sub Protected Sub ClearGraphicsButton_Click1(ByVal sender As Object, ByVal e As System.EventArgs) Handles ClearGraphicsButton.Click Try ' Invoke the method to clear the graphics from the map ClearGraphics() Catch exception As System.Exception Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = Utility.CreateErrorCallbackResult(exception) _callbackResultCollection.Add(errorCallbackResult) Finally ScriptManager1.RegisterDataItem(Page, _callbackResultCollection.ToString(), False) End Try End Sub #End Region #Region "Instance Methods" ' Initiates the buffer points geoprocessing job with the passed-in parameters Private Sub StartBufferJob(ByVal bufferDistance As Double, ByVal units As String) ' #Region "Initialize resources and functionalities" ' Initialize GP resource and functionality Dim geoprocessingResourceItem As ESRI.ArcGIS.ADF.Web.UI.WebControls.GeoprocessingResourceItem = GeoprocessingResourceManager1.ResourceItems.Find(_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 = "BufferPoints" ' 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-placed points Dim adfGraphicsMapResource As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource = TryCast(Map1.GetFunctionality(_graphicsResourceName).Resource, ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource) ' Get the graphics layer containing the user-placed points Dim pointElementGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer = TryCast(adfGraphicsMapResource.Graphics.Tables(_pointGraphicsLayerName), ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer) ' If there are no points in the layer, alert the user and exit the function If (pointElementGraphicsLayer Is Nothing) OrElse (pointElementGraphicsLayer.Rows.Count < 1) Then Dim noPointsAlertCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript("alert('No points to buffer')") _callbackResultCollection.Add(noPointsAlertCallbackResult) _callbackResultCollection.Add(HideActivityIndicators()) Return End If ' Add each point to the feature graphics layer that we're using as input to the GP task For Each dataRow As System.Data.DataRow In pointElementGraphicsLayer.Rows Dim adfPoint As ESRI.ArcGIS.ADF.Web.Geometry.Point = TryCast(pointElementGraphicsLayer.GeometryFromRow(dataRow), ESRI.ArcGIS.ADF.Web.Geometry.Point) featureGraphicsLayer.Add(adfPoint) Next dataRow ' Get the Web ADF Unit enumeration value corresponding to the user-defined unit Dim adfGPLinearUnit As 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(1) As ESRI.ArcGIS.ADF.Web.DataSources.GPValue 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 outputParameters As String = Nothing Dim agsGPParameterInfo As ESRI.ArcGIS.ADF.Web.DataSources.GPParameterInfo For i As Integer = 0 To adfGPParamterInfoArray.Length - 1 agsGPParameterInfo = adfGPParamterInfoArray(i) ' Only append output parameters to the parameter string If agsGPParameterInfo.Direction = ESRI.ArcGIS.ADF.Web.DataSources.GPParameterDirection.Output Then outputParameters &= agsGPParameterInfo.Name If i <> adfGPParamterInfoArray.Length - 1 Then outputParameters &= ";" End If End If Next i Dim checkJobStatusCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = GetStatusCheckJavaScript(GPTaskName, jobID, outputParameters, 1000) _callbackResultCollection.Add(checkJobStatusCallbackResult) ' #End Region End Sub ' Check the GP job status for the job with the passed-in parameters and take action accordingly Protected Sub CheckJobStatus(ByVal jobID As String, ByVal taskName As String, ByVal outputParameters As String) 'Initialize geoprocessing resources and functionalities" ' Initialize GP resource and functionality Dim geoprocessingResourceItem As ESRI.ArcGIS.ADF.Web.UI.WebControls.GeoprocessingResourceItem = GeoprocessingResourceManager1.ResourceItems.Find(_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 '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 _callbackResultCollection.Add(gpErrorAlertCallbackResult) ' Add a callback result to hide the operation activity indicators to the callback results collection _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 _callbackResultCollection.Add(GetStatusCheckJavaScript(taskName, jobID, outputParameters, 5000)) Return End If 'Process the GP task's results ' Parse the GP task's output parameter names Dim outputParametersArray() As String = outputParameters.Split(";"c) ' Get the result of the GP task Dim adfGPResult As ESRI.ArcGIS.ADF.Web.DataSources.GPResult = agsGeoprocessingFunctionality.GetJobResult(taskName, jobID, outputParametersArray, False) ' Get the results of the GP operation Dim adfGPValueArray() As ESRI.ArcGIS.ADF.Web.DataSources.GPValue = adfGPResult.Values ' Get the output feature set containing buffers as a Web ADF feature graphics layer Dim adfGPFeatureGraphicsLayer As ESRI.ArcGIS.ADF.Web.DataSources.GPFeatureGraphicsLayer = TryCast(adfGPValueArray(0), 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');") _callbackResultCollection.Add(noResultsAlertCallbackResult) ' Add a callback result to hide the operation activity indicators and enable the ' Buffer Points button _callbackResultCollection.Add(HideActivityIndicators()) Return End If ' Get the graphics layer's symbols and set their transparency to 50% Dim featureSymbolList As 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 buffer graphics layer's name featureGraphicsLayer.TableName = _bufferGraphicsLayerName ' Get the graphics resource to put the results layer in Dim graphicsMapResource As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource = TryCast(Map1.GetFunctionality(_graphicsResourceName).Resource, ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource) ' If the resource already has a buffer graphics layer, remove it If graphicsMapResource.Graphics.Tables.Contains(_bufferGraphicsLayerName) Then graphicsMapResource.Graphics.Tables.Remove(_bufferGraphicsLayerName) End If ' Add new graphics layer to display the 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) _callbackResultCollection.CopyFrom(Map1.CallbackResults) ' Since the operation is complete, hide its activity indicators _callbackResultCollection.Add(HideActivityIndicators()) 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 Protected Sub ClearGraphics() ' Retrieve the resource and clear its graphics dataset Dim graphicsMapResource As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource = TryCast(Map1.GetFunctionality(_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) _callbackResultCollection.CopyFrom(Map1.CallbackResults) End Sub Private Function GetStatusCheckJavaScript(ByVal GPTaskName As String, ByVal jobID As String, ByVal outputParameters As String, ByVal timeout As Integer) As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult Dim arguments As String = String.Format("EventArg=CheckJobStatus&JobID={0}&TaskName={1}&OutputParameters={2}", jobID, GPTaskName, outputParameters) ' 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 jsCheckJobStatus As String = "window.setTimeout(""ESRI.ADF.Samples.PostbackManager.doAsyncRequest('{0}');"",{1});" jsCheckJobStatus = String.Format(jsCheckJobStatus, arguments, timeout) Dim checkJobStatusCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsCheckJobStatus) Return checkJobStatusCallbackResult End Function #End Region End Class