Common_SelectBufferTool_VBNet\App_Code\CustomTools.vb
' Copyright 2011 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 Namespace CustomComponents Public Class SelectTool Implements ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction #Region "IMapServerToolAction Members" Private Sub ServerAction(ByVal toolEventArgs As ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs) Implements ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction.ServerAction ' Get a reference to the map control on which the tool was executed Dim adfMap As ESRI.ArcGIS.ADF.Web.UI.WebControls.Map = CType(toolEventArgs.Control, ESRI.ArcGIS.ADF.Web.UI.WebControls.Map) Try ' Set the name of the resource on which to perform the selection Dim resourceName As String = "Data Layers" Dim selectionLayerName As String = Nothing Dim showSelectionInTable As Boolean ' 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 Then ' Get the callback arguments from the __CALLBACKPARAM argument of the page request parameters Dim callbackArgumentsString As String = toolEventArgs.Control.Page.Request.Params("__CALLBACKPARAM") Dim callbackArgumentsCollection As System.Collections.Specialized.NameValueCollection = 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 = Boolean.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") Is Nothing Then showSelectionInTable = False Else showSelectionInTable = True End If End If ' Get the map extent of the rectangle drawn on the map Dim mapRectangleEventArgs As ESRI.ArcGIS.ADF.Web.UI.WebControls.MapRectangleEventArgs = CType(toolEventArgs, ESRI.ArcGIS.ADF.Web.UI.WebControls.MapRectangleEventArgs) Dim adfEnvelope As ESRI.ArcGIS.ADF.Web.Geometry.Envelope = mapRectangleEventArgs.MapExtent ' Get a reference to the resource Dim commonMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality = adfMap.GetFunctionality(resourceName) Dim gisResource As ESRI.ArcGIS.ADF.Web.DataSources.IGISResource = commonMapFunctionality.Resource ' Create a query functionality to use in querying the resource Dim commonQueryFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality = CType(gisResource.CreateFunctionality(GetType(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), Nothing), ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality) ' Get the resource's queryable layers Dim layerIDs As String() = Nothing Dim layerNames As String() = Nothing commonQueryFunctionality.GetQueryableLayers(Nothing, layerIDs, layerNames) ' Get the index of the selection layer in the layer names and ids arrays Dim selectionLayerIndex As Integer = 0 Dim i As Integer = 0 Do While i < layerNames.Length If layerNames(i) = selectionLayerName Then If TypeOf layerIDs(i) Is String Then If (Not Integer.TryParse(CStr(layerIDs(i)), selectionLayerIndex)) Then selectionLayerIndex = i End If Else selectionLayerIndex = i End If Exit Do End If i += 1 Loop ' Set-up a spatial filter to use in querying the resource Dim adfSpatialFilter As ESRI.ArcGIS.ADF.Web.SpatialFilter = New ESRI.ArcGIS.ADF.Web.SpatialFilter() adfSpatialFilter.ReturnADFGeometries = True adfSpatialFilter.MaxRecords = 100 adfSpatialFilter.Geometry = adfEnvelope ' Query the selection layer with the user-drawn rectangle Dim resultsDataTable As System.Data.DataTable = commonQueryFunctionality.Query(commonMapFunctionality.Name, layerIDs(selectionLayerIndex), adfSpatialFilter) If resultsDataTable.Rows.Count = 0 Then Dim noFeaturesFoundCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript("alert('No selected features');") adfMap.CallbackResults.Add(noFeaturesFoundCallbackResult) End If ' Convert the results data table to a graphics layer Dim resultsGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer = ESRI.ArcGIS.ADF.Web.Converter.ToGraphicsLayer(resultsDataTable, System.Drawing.Color.Yellow, System.Drawing.Color.Green) ' Retrieve and clear buffer resource Dim gisFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality = adfMap.GetFunctionality("Buffer") Dim bufferGraphicsMapResource As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource = TryCast(gisFunctionality.Resource, ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource) bufferGraphicsMapResource.Graphics.Tables.Clear() ' Retrieve and clear selection resource gisFunctionality = adfMap.GetFunctionality("Selection") Dim selectionGraphicsMapResource As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource = TryCast(gisFunctionality.Resource, 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 Dim selectionMapResourceItem As ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceItem = 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 exception As System.Exception adfMap.CallbackResults.Add(Utility.GetErrorCallback(exception)) End Try End Sub #End Region End Class Public Class BufferTool Implements ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction #Region "IMapServerToolAction Members" Private Sub ServerAction(ByVal toolEventArgs As ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs) Implements ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction.ServerAction Dim adfMap As ESRI.ArcGIS.ADF.Web.UI.WebControls.Map = CType(toolEventArgs.Control, ESRI.ArcGIS.ADF.Web.UI.WebControls.Map) Try Dim mapPointEventArgs As ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs = CType(toolEventArgs, ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs) Dim adfPoint As ESRI.ArcGIS.ADF.Web.Geometry.Point = mapPointEventArgs.MapPoint Dim bufferDistanceString As String = Nothing Dim selectionLayerName As String = Nothing Dim showSelectionInTable As Boolean ' 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 Then ' Get the callback arguments from the __CALLBACKPARAM argument of the page request parameters Dim callbackArgumentsString As String = toolEventArgs.Control.Page.Request.Params("__CALLBACKPARAM") Dim callbackArgumentsCollection As System.Collections.Specialized.NameValueCollection = 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 = Boolean.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") Is Nothing Then showSelectionInTable = False Else showSelectionInTable = True End If End If ' Attempt to retrieve buffer distance from session. If the attempt fails, initialize ' buffer distance as 0. Dim bufferDistanceFloat As Single If (Not System.Single.TryParse(bufferDistanceString, bufferDistanceFloat)) Then bufferDistanceFloat = 0.0F End If ' Create an ellipse based on the buffer distance Dim graphicsPath As System.Drawing.Drawing2D.GraphicsPath = New System.Drawing.Drawing2D.GraphicsPath() graphicsPath.AddEllipse(CSng(adfPoint.X) - (bufferDistanceFloat / 2), CSng(adfPoint.Y) - (bufferDistanceFloat / 2), bufferDistanceFloat, bufferDistanceFloat) ' Flatten the ellipse. This will make it appear smooth. Dim flattening As Single = bufferDistanceFloat / 1000 graphicsPath.Flatten(Nothing, flattening) ' Create a Web ADF Point Collection, and add each point in the graphics path to it Dim adfPointCollection As ESRI.ArcGIS.ADF.Web.Geometry.PointCollection = New ESRI.ArcGIS.ADF.Web.Geometry.PointCollection() For Each pointF As System.Drawing.PointF In graphicsPath.PathPoints adfPointCollection.Add(New ESRI.ArcGIS.ADF.Web.Geometry.Point(pointF.X, pointF.Y)) Next pointF ' 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 Dim adfRing As ESRI.ArcGIS.ADF.Web.Geometry.Ring = New ESRI.ArcGIS.ADF.Web.Geometry.Ring() adfRing.Points = adfPointCollection Dim adfRingCollection As ESRI.ArcGIS.ADF.Web.Geometry.RingCollection = New ESRI.ArcGIS.ADF.Web.Geometry.RingCollection() adfRingCollection.Add(adfRing) Dim adfBufferPolygon As ESRI.ArcGIS.ADF.Web.Geometry.Polygon = New ESRI.ArcGIS.ADF.Web.Geometry.Polygon() adfBufferPolygon.Rings = adfRingCollection ' Get the graphics resource that will hold the buffer Dim gisFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IGISFunctionality = adfMap.GetFunctionality("Buffer") Dim bufferGraphicsMapResource As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource = TryCast(gisFunctionality.Resource, ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource) ' If the resource was not found, throw an exception If bufferGraphicsMapResource Is Nothing Then Throw New System.Exception("Buffer graphics resource not in MapResourceManager") End If ' 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 Dim elementGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.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 Dim adfGeometry As ESRI.ArcGIS.ADF.Web.Geometry.Geometry = CType(adfBufferPolygon, ESRI.ArcGIS.ADF.Web.Geometry.Geometry) Dim graphicElement As ESRI.ArcGIS.ADF.Web.Display.Graphics.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 Dim commonMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality = adfMap.GetFunctionality("Data Layers") Dim gisResource As ESRI.ArcGIS.ADF.Web.DataSources.IGISResource = commonMapFunctionality.Resource ' Create a query functionality and use it to retrieve the IDs and names of the ' resource's queryable layers Dim commonQueryFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality = CType(gisResource.CreateFunctionality(GetType(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), Nothing), ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality) Dim layerIDs As String() Dim layerNames As String() commonQueryFunctionality.GetQueryableLayers(Nothing, layerIDs, layerNames) ' Get the index of the selection layer in the ID and names arrays Dim selectionLayerIndex As Integer = 0 Dim i As Integer = 0 Do While i < layerNames.Length If layerNames(i) = selectionLayerName Then selectionLayerIndex = i Exit Do End If i += 1 Loop ' Initialize a Web ADF spatial filter with the buffer geometry and use ' it to query the resource on which the selection will be performed Dim adfSpatialFilter As ESRI.ArcGIS.ADF.Web.SpatialFilter = New ESRI.ArcGIS.ADF.Web.SpatialFilter() adfSpatialFilter.ReturnADFGeometries = True adfSpatialFilter.MaxRecords = 1000 adfSpatialFilter.Geometry = adfBufferPolygon Dim featuresInBufferDataTable As System.Data.DataTable = commonQueryFunctionality.Query(Nothing, layerIDs(selectionLayerIndex), adfSpatialFilter) If featuresInBufferDataTable.Rows.Count = 0 Then Dim noFeaturesFoundCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript("alert('No selected features');") adfMap.CallbackResults.Add(noFeaturesFoundCallbackResult) End If ' Convert the query results to a graphics layer Dim selectionGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer = ESRI.ArcGIS.ADF.Web.Converter.ToGraphicsLayer(featuresInBufferDataTable, System.Drawing.Color.Yellow, System.Drawing.Color.Yellow) ' Get the graphics resource that will hold the selection and add the selection ' graphics layer to it gisFunctionality = adfMap.GetFunctionality("Selection") Dim selectionGraphicsMapResource As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource = TryCast(gisFunctionality.Resource, 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 Dim bufferMapResourceItem As ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceItem = adfMap.MapResourceManagerInstance.ResourceItems.Find(bufferGraphicsMapResource.Name) bufferMapResourceItem.DisplaySettings.Transparency = 50 ' Set the transparency of the selection graphics resource map resource item Dim selectionMapResourceItem As ESRI.ArcGIS.ADF.Web.UI.WebControls.MapResourceItem = adfMap.MapResourceManagerInstance.ResourceItems.Find(selectionGraphicsMapResource.Name) selectionMapResourceItem.DisplaySettings.Transparency = 50 adfMap.RefreshResource(bufferGraphicsMapResource.Name) adfMap.RefreshResource(selectionGraphicsMapResource.Name) Catch exception As System.Exception adfMap.CallbackResults.Add(Utility.GetErrorCallback(exception)) End Try End Sub #End Region End Class Friend Class CustomToolUtility Public Shared Sub DisplayOrHideSelectionTable(ByVal adfMap As ESRI.ArcGIS.ADF.Web.UI.WebControls.Map, ByVal resultsGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer, ByVal showTable As Boolean) Try ' Get the GridView control that will be used to display selection results Dim gridViewResults As System.Web.UI.WebControls.GridView = CType(adfMap.Page.FindControl("grdSelectionResults"), System.Web.UI.WebControls.GridView) Dim updatepanel As System.Web.UI.UpdatePanel = CType(adfMap.Page.FindControl("UpdatePanel1"), System.Web.UI.UpdatePanel) Dim resultsDataTable As System.Data.DataTable = resultsGraphicsLayer ' Check whether to show selection results tabularly If showTable Then ' Make sure results were actually found If resultsDataTable.Rows.Count > 0 Then ' Load the graphicsLayer into a new data table and remove the IS_SELECTED column Dim newDataTable As System.Data.DataTable = 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 ' Create a callback result to update the content of the selection results div ' with a message informing the user that no features were selected. gridViewResults.Visible = False End If Else gridViewResults.Visible = False End If updatepanel.Update() Catch exception As System.Exception adfMap.CallbackResults.Add(Utility.GetErrorCallback(exception)) End Try End Sub End Class End Namespace