ArcIMS_SelectBufferTool_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 Imports System.Data Imports System.Configuration Imports System.Web Imports System.Web.Security Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.Web.UI.WebControls.WebParts Imports System.Web.UI.HtmlControls Imports System.Collections Public Partial Class _Default Inherits System.Web.UI.Page Implements System.Web.UI.ICallbackEventHandler Private m_ADFCallbackFunctionString As String Private m_ADFCallbackResultCollection As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection Private m_ResourceIndex As Integer = 0 Private m_NameValueCollection As System.Collections.Specialized.NameValueCollection ' ICallbackEventHandler implementation Public Sub RaiseCallbackEvent(ByVal eventArgs As String) Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent m_ADFCallbackResultCollection = New ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResultCollection() m_NameValueCollection = ESRI.ArcGIS.ADF.Web.UI.WebControls. CallbackUtility.ParseStringIntoNameValueCollection(eventArgs) Dim eventArg As String = m_NameValueCollection("EventArg") If eventArg.Equals("selectButton") Then ' Only select features, no buffer SelectionToolSelectAndBuffer(False) ElseIf eventArg.Equals("bufferSelectButton") Then ' Buffer and select from target layer, if set SelectionToolSelectAndBuffer(True) ElseIf eventArg.Equals("clearAllButton") OrElse eventArg.Equals("activeLayerDropDownList") Then ' Clear all dynamic layers and refresh map resource ClearAllLayers(True) End If End Sub Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult Return m_ADFCallbackResultCollection.ToString() End Function Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) ' Generate custom callback function string for html buttons and active layer drop down list ' Page will process callback. m_ADFCallbackFunctionString = Page.ClientScript.GetCallbackEventReference(Me, "message", "processCallbackResult", "context", "postBackError", True) ' Upon change of active layer, map will clear all dynamic layers. activeLayerDropDownList.Attributes.Add("onchange", "CustomCallback(this.id)") End Sub Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As EventArgs) If (Not IsPostBack) Then ' On initial prerender, update dropdown lists with layer names and unit options Dim mapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality = CType(Map1.GetFunctionality(m_ResourceIndex), ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality) Dim gisResource As ESRI.ArcGIS.ADF.Web.DataSources.IGISResource = mapFunctionality.Resource Dim supported As Boolean = gisResource.SupportsFunctionality(GetType(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)) If supported Then Dim queryFunctionality 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() = Nothing Dim layerNames As String() = Nothing queryFunctionality.GetQueryableLayers(Nothing, layerIDs, layerNames) selectLayerDropDownList.Items.Add("none") bufferSelectLayerDropDownList.Items.Add("none") Dim i As Integer = 0 Do While i < layerNames.Length activeLayerDropDownList.Items.Add(layerNames(i)) selectLayerDropDownList.Items.Add(layerNames(i)) bufferSelectLayerDropDownList.Items.Add(layerNames(i)) i += 1 Loop End If Dim imsBufferUnits As Array = System.Enum.GetValues(GetType(ESRI.ArcGIS.ADF.IMS.Carto.Layer.BufferUnits)) For Each imsBufferUnit As Integer In imsBufferUnits bufferToolUnitsDropDownList.Items.Add(imsBufferUnits.GetValue(imsBufferUnit).ToString()) bufferActiveUnitsDropDownList.Items.Add(imsBufferUnits.GetValue(imsBufferUnit).ToString()) Next imsBufferUnit End If ' On load of page content in the browser, execute some JavaScript to add custom element parameters to all ' Web ADF postbacks. Also, create a custom JavaScript function to initiate custom callback to the page and ' package element values. Dim scriptKeyCustom As String = "customChangeScript" If (Not Me.Page.ClientScript.IsClientScriptBlockRegistered(Me.GetType(), scriptKeyCustom)) AndAlso (Not Page.IsPostBack) Then Dim scriptBlock As String = "" & ControlChars.CrLf & " " & ControlChars.CrLf & " function onLoadFunction() {" & ControlChars.CrLf & " var theform = document.forms[0];" & ControlChars.CrLf & " var original_value = theform.elements[""ESRIWebADFHiddenFields""].value;" & ControlChars.CrLf & " var new_value = original_value + "",{0},{1},{2},{3}"";" & ControlChars.CrLf & " theform.elements[""ESRIWebADFHiddenFields""].value = new_value; " & ControlChars.CrLf & " }" & ControlChars.CrLf & ControlChars.CrLf & " function CustomCallback(argument){" & ControlChars.CrLf & " var message = ""EventArg="" + argument + ""&"";" & ControlChars.CrLf & " message += ""{0}="" + document.getElementById('{0}').value + ""&"";" & ControlChars.CrLf & " message += ""{4}="" + document.getElementById('{4}').value + ""&"";" & ControlChars.CrLf & " message += ""{5}="" + document.getElementById('{5}').value + ""&"";" & ControlChars.CrLf & " message += ""{6}="" + document.getElementById('{6}').value;" & ControlChars.CrLf & " var context = null;" & ControlChars.CrLf & " {7}" & ControlChars.CrLf & " }" & ControlChars.CrLf & " " & ControlChars.CrLf & " " scriptBlock = scriptBlock.Replace("{0}", activeLayerDropDownList.UniqueID) scriptBlock = scriptBlock.Replace("{1}", bufferToolDistanceTextBox.UniqueID) scriptBlock = scriptBlock.Replace("{2}", bufferToolUnitsDropDownList.UniqueID) scriptBlock = scriptBlock.Replace("{3}", bufferSelectLayerDropDownList.UniqueID) scriptBlock = scriptBlock.Replace("{4}", selectLayerDropDownList.UniqueID) scriptBlock = scriptBlock.Replace("{5}", bufferActiveDistanceTextBox.UniqueID) scriptBlock = scriptBlock.Replace("{6}", bufferActiveUnitsDropDownList.UniqueID) scriptBlock = scriptBlock.Replace("{7}", m_ADFCallbackFunctionString) Me.Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), scriptKeyCustom, scriptBlock, True) End If Dim scriptKey As String = "loadScript" If (Not Me.Page.ClientScript.IsClientScriptBlockRegistered(Me.GetType(), scriptKey)) AndAlso (Not Page.IsPostBack) Then ' if Mozilla browser, use DOMContentLoaded event, else add to body onload Dim scriptBlock As String = "" & ControlChars.CrLf & " if (document.addEventListener) { " & ControlChars.CrLf & " document.addEventListener(""DOMContentLoaded"", onLoadFunction , false);" & ControlChars.CrLf & " } else {" & ControlChars.CrLf & " top.document.body.onload = onLoadFunction;" & ControlChars.CrLf & " }" & ControlChars.CrLf & " " Me.Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), scriptKey, scriptBlock, True) End If End Sub Private Sub ClearAllLayers(ByVal initialCallback As Boolean) Dim imsMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IMS.MapFunctionality = CType(Map1.GetFunctionality(m_ResourceIndex), ESRI.ArcGIS.ADF.Web.DataSources.IMS.MapFunctionality) Dim mapView As ESRI.ArcGIS.ADF.IMS.Carto.MapView = imsMapFunctionality.MapView For Each layerName As String In New LayerNames() Dim layer As ESRI.ArcGIS.ADF.IMS.Carto.Layer.Layer = mapView.Layers.FindByName(layerName) If Not layer Is Nothing Then If layer.Name = LayerNames.SelectionToolActive Then ' Remove active selection layer and filter from session if ' the clearAllButton button is pressed. Otherwise, keep active ' selection layer. If initialCallback Then Session("activeLayerFilter") = Nothing mapView.Layers.Remove(layer) End If Else mapView.Layers.Remove(layer) End If End If Next layerName ' Only refresh Map and return callback response if the clearAllButton button is pressed. If initialCallback Then If Map1.ImageBlendingMode = ESRI.ArcGIS.ADF.Web.UI.WebControls.ImageBlendingMode.Browser Then Map1.RefreshResource(imsMapFunctionality.Resource.Name) Else Map1.Refresh() End If m_ADFCallbackResultCollection.CopyFrom(Map1.CallbackResults) End If End Sub ' For ArcMap services, all dynamic feature layers must have a null renderer. ' Renderers are defined in the mxd document. Each feature layer can define its own selection renderer. ' Buffers on feature layers use the default selection color for the data frame. Private Sub SelectionToolSelectAndBuffer(ByVal bufferAndSelect As Boolean) ' Get argument values from client. Popluated in RaiseCallbackEvent() method. Dim activeLayerName As String = m_NameValueCollection("activeLayerDropDownList") Dim targetLayerName As String = m_NameValueCollection("selectLayerDropDownList") Dim bufferDistanceString As String = m_NameValueCollection("bufferActiveDistanceTextBox") Dim bufferUnitsString As String = m_NameValueCollection("bufferActiveUnitsDropDownList") Dim imsMapFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IMS.MapFunctionality = CType(Map1.GetFunctionality(m_ResourceIndex), ESRI.ArcGIS.ADF.Web.DataSources.IMS.MapFunctionality) Dim mapview As ESRI.ArcGIS.ADF.IMS.Carto.MapView = imsMapFunctionality.MapView Dim imsLayerCollection As ESRI.ArcGIS.ADF.IMS.Carto.Layer.LayerCollection = mapview.Layers ' Clear dynamic layers (selections, buffers, IMS acetate layers) except active layer selection ClearAllLayers(False) Dim activeLayer As ESRI.ArcGIS.ADF.IMS.Carto.Layer.FeatureLayer = CType(imsLayerCollection.FindByName(activeLayerName), ESRI.ArcGIS.ADF.IMS.Carto.Layer.FeatureLayer) ' Get the filter applied by the selection tool on the active layer Dim activeLayerFilter As ESRI.ArcGIS.ADF.IMS.Carto.Layer.Filter = CType(Session("activeLayerFilter"), ESRI.ArcGIS.ADF.IMS.Carto.Layer.Filter) ' If target layer is set, get it Dim targetLayer As ESRI.ArcGIS.ADF.IMS.Carto.Layer.FeatureLayer = Nothing If targetLayerName <> "none" Then targetLayer = CType(imsLayerCollection.FindByName(targetLayerName), ESRI.ArcGIS.ADF.IMS.Carto.Layer.FeatureLayer) End If ' Default buffer distance of 0, unless explicitly set in a request. Dim bufferDistance As Single If (Not Single.TryParse(bufferDistanceString, bufferDistance)) Then bufferDistance = 0.0F End If ' Default buffer units of Decimal Degrees, unless explicitly set in a request. ' As an enumeration, this is only a placeholder. The default of Decimal Degrees ' is only used when buffering polygons and the distance is 0. Dim imsBufferUnits As ESRI.ArcGIS.ADF.IMS.Carto.Layer.BufferUnits = ESRI.ArcGIS.ADF.IMS.Carto.Layer.BufferUnits.Decimal_Degrees If bufferAndSelect Then ' Get buffer units from user imsBufferUnits = CType(System.Enum.Parse(GetType(ESRI.ArcGIS.ADF.IMS.Carto.Layer.BufferUnits), bufferUnitsString, True), ESRI.ArcGIS.ADF.IMS.Carto.Layer.BufferUnits) ' Draw the buffer Dim displayBuffer As ESRI.ArcGIS.ADF.IMS.Carto.Layer.DisplayBuffer = New ESRI.ArcGIS.ADF.IMS.Carto.Layer.DisplayBuffer() displayBuffer.Distance = bufferDistance displayBuffer.Units = imsBufferUnits ' Construct dynamic buffer feature layer. ArcMap services require a null renderer. Dim bufferLayer As ESRI.ArcGIS.ADF.IMS.Carto.Layer.FeatureLayer = Nothing If imsMapFunctionality.MapResource.MapService.Type = ESRI.ArcGIS.ADF.IMS.ServiceType.ArcMapServer Then bufferLayer = activeLayer.CreateBufferLayer(activeLayerFilter, displayBuffer, Nothing, LayerNames.SelectionToolBuffer) Else ' Renderer for buffer, always a polygon Dim bufferSimpleRenderer As ESRI.ArcGIS.ADF.IMS.Display.Renderer.SimpleRenderer = New ESRI.ArcGIS.ADF.IMS.Display.Renderer.SimpleRenderer() Dim bufferSimpleFillSymbol As ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleFillSymbol = New ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleFillSymbol() bufferSimpleFillSymbol.Color = System.Drawing.Color.Green ' Transparency in percent instead of 0-1 bufferSimpleFillSymbol.Transparency = 50.0 bufferSimpleRenderer.Symbol = bufferSimpleFillSymbol bufferLayer = activeLayer.CreateBufferLayer(activeLayerFilter, displayBuffer, bufferSimpleRenderer, LayerNames.SelectionToolBuffer) End If bufferLayer.Name = LayerNames.SelectionToolBuffer ' *** Add dynamic buffer layer to the map mapview.Layers.Add(bufferLayer) End If ' If selecting feature in a target layer, the following code executes If Not targetLayer Is Nothing Then ' Create a layer to store the selected features in the target layer Dim targetSelectionLayer As ESRI.ArcGIS.ADF.IMS.Carto.Layer.FeatureLayer = Nothing ' In ArcIMS, all feature layers of geometry type point, line, or polygon can be buffered using a value ' great than 0. Only feature layers of type polygon can be buffered using a distance of 0 ' (essentially a layer on layer selection). So if the buffer distance is greater than 0 or the feature ' type is polygon, a buffer can be constructed to select features in a target layer. If bufferDistance > 0 OrElse activeLayer.Type = ESRI.ArcGIS.ADF.IMS.FeatureType.Polygon Then Dim activeLayerSelectionBuffer As ESRI.ArcGIS.ADF.IMS.Carto.Layer.SelectionBuffer = New ESRI.ArcGIS.ADF.IMS.Carto.Layer.SelectionBuffer(targetLayer, String.Empty) ' If bufferSelectButton is pressed If bufferAndSelect Then activeLayerSelectionBuffer.Distance = bufferDistance activeLayerSelectionBuffer.Units = imsBufferUnits Else ' Only used if the active layer is of type polygon activeLayerSelectionBuffer.Distance = 0 activeLayerSelectionBuffer.Units = ESRI.ArcGIS.ADF.IMS.Carto.Layer.BufferUnits.Decimal_Degrees End If If imsMapFunctionality.MapResource.MapService.Type = ESRI.ArcGIS.ADF.IMS.ServiceType.ArcMapServer Then targetSelectionLayer = activeLayer.CreateBufferSelectionLayer(activeLayerFilter, activeLayerSelectionBuffer, Nothing, LayerNames.SelectionToolTarget) Else targetSelectionLayer = activeLayer.CreateBufferSelectionLayer(activeLayerFilter, activeLayerSelectionBuffer, SelectionToolTargetLayerRenderer(targetLayer.Type), LayerNames.SelectionToolTarget) End If Else ' If buffer distance is 0 and active layer is of type point or line ' Construct a query to return feature geometry selected in the active layer Dim activeLayerQueryParameters As ESRI.ArcGIS.ADF.IMS.Carto.Layer.QueryParameters = New ESRI.ArcGIS.ADF.IMS.Carto.Layer.QueryParameters(activeLayerFilter) activeLayerQueryParameters.ReturnGeometries = True Dim activeLayerQueryFeatureTable As ESRI.ArcGIS.ADF.IMS.Carto.Layer.FeatureTable = activeLayer.Query(activeLayerQueryParameters) ' Find the shape field Dim shapeFieldIndex As Integer = -1 Dim index As Integer = 0 Do While index < activeLayerQueryFeatureTable.Columns.Count If activeLayerQueryFeatureTable.Columns(index).DataType Is GetType(ESRI.ArcGIS.ADF.IMS.Geometry.Geometry) Then shapeFieldIndex = index Exit Do End If index += 1 Loop ' Package the selected feature geometry in a simple Multipoint or Polyline used to create ' a selection layer Dim imsGeometry As ESRI.ArcGIS.ADF.IMS.Geometry.Geometry = Nothing If activeLayer.Type = ESRI.ArcGIS.ADF.IMS.FeatureType.Point Then Dim imsSelectionMultipoint As ESRI.ArcGIS.ADF.IMS.Geometry.Multipoint = New ESRI.ArcGIS.ADF.IMS.Geometry.Multipoint() For Each dataRow As DataRow In activeLayerQueryFeatureTable.Rows Dim imsFeatureMultipoint As ESRI.ArcGIS.ADF.IMS.Geometry.Multipoint = CType(dataRow(shapeFieldIndex), ESRI.ArcGIS.ADF.IMS.Geometry.Multipoint) For Each imsPoint As ESRI.ArcGIS.ADF.IMS.Geometry.Point In imsFeatureMultipoint.Points imsSelectionMultipoint.Points.Add(imsPoint) Next imsPoint Next dataRow imsGeometry = imsSelectionMultipoint ElseIf activeLayer.Type = ESRI.ArcGIS.ADF.IMS.FeatureType.Line Then Dim imsSelectionPolyline As ESRI.ArcGIS.ADF.IMS.Geometry.Polyline = New ESRI.ArcGIS.ADF.IMS.Geometry.Polyline() For Each dataRow As DataRow In activeLayerQueryFeatureTable.Rows Dim imsFeaturePolyline As ESRI.ArcGIS.ADF.IMS.Geometry.Polyline = CType(dataRow(shapeFieldIndex), ESRI.ArcGIS.ADF.IMS.Geometry.Polyline) For Each imsPath As ESRI.ArcGIS.ADF.IMS.Geometry.Path In imsFeaturePolyline.Paths imsSelectionPolyline.Paths.Add(imsPath) Next imsPath Next dataRow imsGeometry = imsSelectionPolyline End If ' Create a filter to select features in the target layer activeLayerFilter = New ESRI.ArcGIS.ADF.IMS.Carto.Layer.Filter() activeLayerFilter.Geometry = imsGeometry If imsMapFunctionality.MapResource.MapService.Type = ESRI.ArcGIS.ADF.IMS.ServiceType.ArcMapServer Then targetSelectionLayer = targetLayer.CreateSelectionLayer(activeLayerFilter, Nothing, LayerNames.SelectionToolTarget) Else targetSelectionLayer = targetLayer.CreateSelectionLayer(activeLayerFilter, SelectionToolTargetLayerRenderer(targetLayer.Type), LayerNames.SelectionToolTarget) End If End If targetSelectionLayer.Name = LayerNames.SelectionToolTarget ' *** Add dynamic selection from the target layer to the map mapview.Layers.Add(targetSelectionLayer) End If If Map1.ImageBlendingMode = ESRI.ArcGIS.ADF.Web.UI.WebControls.ImageBlendingMode.Browser Then Map1.RefreshResource(imsMapFunctionality.Resource.Name) Else Map1.Refresh() End If m_ADFCallbackResultCollection.CopyFrom(Map1.CallbackResults) End Sub ' Create a renderer for the selected features in the target layer defined in the SelectionTool Private Function SelectionToolTargetLayerRenderer(ByVal targetFeatureType As ESRI.ArcGIS.ADF.IMS.FeatureType) As ESRI.ArcGIS.ADF.IMS.Display.Renderer.SimpleRenderer Dim targetSelectionSimpleRenderer As ESRI.ArcGIS.ADF.IMS.Display.Renderer.SimpleRenderer = New ESRI.ArcGIS.ADF.IMS.Display.Renderer.SimpleRenderer() Dim targetSelectionFeatureSymbol As ESRI.ArcGIS.ADF.IMS.Display.Symbol.FeatureSymbol = Nothing If targetFeatureType = ESRI.ArcGIS.ADF.IMS.FeatureType.Point Then Dim targetSelectionSimpleMarkerSymbol As ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleMarkerSymbol = New ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleMarkerSymbol() targetSelectionSimpleMarkerSymbol.Color = System.Drawing.Color.Red targetSelectionSimpleMarkerSymbol.Width = 8 targetSelectionFeatureSymbol = targetSelectionSimpleMarkerSymbol ElseIf targetFeatureType = ESRI.ArcGIS.ADF.IMS.FeatureType.Line Then Dim targetSelectionSimpleLineSymbol As ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleLineSymbol = New ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleLineSymbol() targetSelectionSimpleLineSymbol.Width = 2 targetSelectionSimpleLineSymbol.Color = System.Drawing.Color.Red targetSelectionFeatureSymbol = targetSelectionSimpleLineSymbol ElseIf targetFeatureType = ESRI.ArcGIS.ADF.IMS.FeatureType.Polygon Then Dim targetSelectionSimpleFillSymbol As ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleFillSymbol = New ESRI.ArcGIS.ADF.IMS.Display.Symbol.SimpleFillSymbol() targetSelectionSimpleFillSymbol.Color = System.Drawing.Color.Red targetSelectionFeatureSymbol = targetSelectionSimpleFillSymbol End If If Not targetSelectionFeatureSymbol Is Nothing Then targetSelectionFeatureSymbol.Transparency = 50.0 End If targetSelectionSimpleRenderer.Symbol = targetSelectionFeatureSymbol Return targetSelectionSimpleRenderer End Function End Class