Common_Geocoding_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 "ASP.NET Page Event Handlers" Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Try If Not IsPostBack Then Dim bloomingField As ESRI.ArcGIS.ADF.Web.Geometry.Envelope = New ESRI.ArcGIS.ADF.Web.Geometry.Envelope( _ -83.3337801950437, 42.5314716926848, -83.2476061838133, 42.6123242012297) Map1.Extent = bloomingField End If Dim customScriptKey As String = "customDataItemScript" ' Check whether a script block with the name stored in customScriptKey has already ' been registered on the client, and whether the page is in an asynchronous postback. ' If neither of these is true, create and register the script block. Note that replacing ' ScriptManager1.IsInAsyncPostBack with Page.IsPostback will work initially, but if a ' full page postback occurs, the script may be lost. If (Not Me.Page.ClientScript.IsClientScriptBlockRegistered(Me.GetType(), customScriptKey)) AndAlso (Not ScriptManager1.IsInAsyncPostBack) Then ' Construct the JavaScript block that will be responsible for processing data items. ' ' onLoadFunction specifies AsyncResponseHandler as a handler for the pageLoading AJAX ' client-side event. This event fires during asynchronous postbacks after the response ' has been received from the server, but before any content on the page is updated. ' ' AsyncResponseHandler retrieves the data items registered server-side during the ' asynchronous postback by accessing the dataItems property on the second argument ' passed to the handler. It then gets the particular data item corresponding to the ' page by passing the page's client ID to the dataItems array as an array index. This ' data item, assumed to be formatted as a Web ADF callback result, is then passed to ' ESRI.ADF.System.processCallbackResult - the client-side Web ADF function responsible ' for parsing callback results and updating Web ADF controls accordingly. ' ' Below the function declarations, onLoadFunction is added as a handler for the AJAX ' client-side event init, which is raised once when the page is first rendered. This ' is therefore the appropriate place for onLoadFunction to be called, since the ' asynchronous pageLoading handler in this case can remain unchanged for the life ' of the application. ' ' The functions are enclosed in an extra pair of curly braces to allow the subsequent ' call to String.Format. String.Format is designed to replace the contents of curly ' braces with the parameters passed to the function call. These extra braces "escape" ' the braces that must enclose a JavaScript function's logic, essentially telling ' String.Format to not replace the contents of these particular braces. Dim scriptBlock As String = "" & ControlChars.CrLf & " " & ControlChars.CrLf & " function onLoadFunction(){{" & ControlChars.CrLf & " Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(AsyncResponseHandler);" & ControlChars.CrLf & " }}" & ControlChars.CrLf & ControlChars.CrLf & " function AsyncResponseHandler(sender, args) {{" & ControlChars.CrLf & " var dataItems = args.get_dataItems();" & ControlChars.CrLf & " if (dataItems['{0}'] != null)" & ControlChars.CrLf & " ESRI.ADF.System.processCallbackResult(dataItems['{0}']);" & ControlChars.CrLf & " }}" & ControlChars.CrLf & ControlChars.CrLf & " Sys.Application.add_init(onLoadFunction);" ' Insert the client ID of the page into the script block. scriptBlock = String.Format(scriptBlock, Page.ClientID) ' Register the script on the client. This will make the script block available client-side ' and execute statements that are not function or object declarations, in this case adding ' onLoadFunction as a handler for the init event. Me.Page.ClientScript.RegisterStartupScript(Me.GetType(), customScriptKey, scriptBlock, True) End If Catch exception As System.Exception Dim jsErrorAlert As String = String.Format("<script>{0}</script>", GetJavaScriptErrorString(exception)) Response.Write(jsErrorAlert) End Try End Sub #End Region #Region "ASP.NET Web Control Event Handlers" ' Geocodes the input address, adds spatial results to the map, and adds text/tabular results to the page. ' Called when the user clicks the Geocode button. Protected Sub btnGeocode_Click(ByVal sender As Object, ByVal e As System.EventArgs) Try ' Get the resource item for the first item in the GeocodeResourceManager and make sure it's initialized Dim geocodeResourceItem As ESRI.ArcGIS.ADF.Web.UI.WebControls.GeocodeResourceItem = GeocodeResourceManager1.ResourceItems.Find("Geocode Resource") If (Not geocodeResourceItem.Resource.Initialized) Then geocodeResourceItem.InitializeResource() End If ' Create a Web ADF Common API geocode functionality Dim commonGeocodeFunctionality As ESRI.ArcGIS.ADF.Web.DataSources.IGeocodeFunctionality = CType(geocodeResourceItem.Resource.CreateFunctionality(GetType(ESRI.ArcGIS.ADF.Web.DataSources.IGeocodeFunctionality), Nothing), ESRI.ArcGIS.ADF.Web.DataSources.IGeocodeFunctionality) Dim addressFieldList As System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.Geocode.Field) = commonGeocodeFunctionality.GetAddressFields() Dim addressValueList As System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.Geocode.AddressValue) = New System.Collections.Generic.List(Of ESRI.ArcGIS.ADF.Web.Geocode.AddressValue)() ' Retrieve the input street from txtAddress and store in an AddressValue object Dim streetAddressValue As ESRI.ArcGIS.ADF.Web.Geocode.AddressValue = New ESRI.ArcGIS.ADF.Web.Geocode.AddressValue("STREET", txtAddress.Text) ' Retrieve the input zip from txtZipCode and store in an AddressValue object Dim zoneAddressValue As ESRI.ArcGIS.ADF.Web.Geocode.AddressValue = New ESRI.ArcGIS.ADF.Web.Geocode.AddressValue("Zip", txtZipCode.Text) ' Add the input street and zip to the list of address values addressValueList.Add(streetAddressValue) addressValueList.Add(zoneAddressValue) ' Get graphics layer from Map and clear it of all graphic elements Dim elementGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer = GetGraphicsLayer("Graphics Resource", "Geocode Results") elementGraphicsLayer.Clear() ' Declare a Web ADF Point object to store the result geometry Dim adfPoint As ESRI.ArcGIS.ADF.Web.Geometry.Point = Nothing ' Hide the controls that may display textual/tabular results to false. If one is used to ' display results, it will be set to visible when necessary. lblResults.Visible = False grdMatchInfo.Visible = False ' Check whether all the match candidates are being returned or not If chkAllCandidates.Checked Then ' Get all available match candidates ' Get the minimum match score from the minimum score drop-down commonGeocodeFunctionality.MinCandidateScore = Integer.Parse(ddlMinScore.SelectedValue) ' Execute the geocode operation. Here we call FindAddressCandidates because we wish ' to find all the match candidates that meet or exceed the minimum score Dim matchDataTable As System.Data.DataTable = commonGeocodeFunctionality.FindAddressCandidates(addressValueList, True, True) ' Find the index of the shape column from the results data table Dim shapeColumnIndex As Integer = -1 Dim j As Integer = 0 Do While j < matchDataTable.Columns.Count If matchDataTable.Columns(j).DataType Is GetType(ESRI.ArcGIS.ADF.Web.Geometry.Geometry) Then shapeColumnIndex = j Exit Do End If j += 1 Loop ' Check that results were found If matchDataTable.Rows.Count > 0 Then ' Bind the results to the GridView control grdMatchInfo.DataSource = matchDataTable grdMatchInfo.DataBind() grdMatchInfo.Visible = True ' Get the geometry column from the results table Dim shapeColumn As System.Data.DataColumn = matchDataTable.Columns(shapeColumnIndex) ' Add a point on the map for each candidate For Each dataRow As System.Data.DataRow In matchDataTable.Rows Dim adfPointAsObject As Object = dataRow(shapeColumnIndex) If TypeOf adfPointAsObject Is ESRI.ArcGIS.ADF.Web.Geometry.Point Then adfPoint = CType(adfPointAsObject, ESRI.ArcGIS.ADF.Web.Geometry.Point) AddPointToMap(adfPoint, elementGraphicsLayer) End If Next dataRow ' Update the match count label lblMatchCount.Text = String.Format("Number of Matches: {0}", matchDataTable.Rows.Count) End If Else ' Just get the one best-matching address ' Get the minimum match score from the minimum score drop-down commonGeocodeFunctionality.MinMatchScore = Integer.Parse(ddlMinScore.SelectedValue) ' Execute the geocode operation. In this case, we call GeocodeAddress, which returns ' only the best match as a Web ADF Point adfPoint = commonGeocodeFunctionality.GeocodeAddress(addressValueList) ' If a match was found, put it on the map If (Not adfPoint Is Nothing) AndAlso ((Not adfPoint.X.Equals(Double.NaN))) Then AddPointToMap(adfPoint, elementGraphicsLayer) ' Update the results and match count label controls. Use string.Format with N as the ' format provider to specify that the coordinates be presented in general numeric format. lblResults.Text = String.Format("Address found at {0:N}, {1:N}", adfPoint.X.ToString(), adfPoint.Y.ToString()) lblResults.Visible = True lblMatchCount.Text = "Number of Matches: 1" End If End If ' Check whether the match point is null or is populated with coordinates of NaN If (Not adfPoint Is Nothing) AndAlso ((Not adfPoint.X.Equals(Double.NaN))) Then Map1.RefreshResource("Graphics Resource") ScriptManager1.RegisterDataItem(Page, Map1.CallbackResults.ToString(), False) Else ' No results were found, so inform the user by setting the Label control ' accordingly lblResults.Text = "No matches found" lblResults.Visible = True End If Catch exception As System.Exception Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = GetErrorCallback(exception) Map1.CallbackResults.Add(errorCallbackResult) ScriptManager1.RegisterDataItem(Page, Map1.CallbackResults.ToString(), False) End Try End Sub ' Clears spatial geocode results from the map and textual/tabular geocode results from the page. ' Called when the user clicks the Clear button Protected Sub btnClearResults_Click(ByVal sender As Object, ByVal e As System.EventArgs) Try ' Get the graphics layer where spatial geocode results are stored from the Map Dim elementGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer = GetGraphicsLayer("Graphics Resource", "Geocode Results") ' Remove all graphics from the layer elementGraphicsLayer.Clear() ' Hide textual/tabular results elements grdMatchInfo.Visible = False lblResults.Visible = False ' Update the number of matches label lblMatchCount.Text = "Number of Matches:" ' Refresh the graphics resource Map1.RefreshResource("Graphics Resource") ' Register the Map's callback results as a data item. This sends the results back ' to the client, where they can be accessed by handlers of the pageLoading, pageLoaded, or ' endRequest events on the PageRequestManager object. More specifically, the callback ' results will be inserted into the dataItems array, which is passed to the client as a ' property of the second argument passed to any of the three aforementioned event ' handlers. The response can be retrieved from the array by specifying the client ID of ' the control passed into the RegisterDataItem call (in this case Page) as the array ' index. In this case, a pageLoading handler was declared in the script block ' registered in the Page's PreRender event, and this handler retrieves the dataItem and ' passes it to ESRI.ADF.System.processCallbackResult. ScriptManager1.RegisterDataItem(Page, Map1.CallbackResults.ToString(), False) Catch exception As System.Exception Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = GetErrorCallback(exception) Map1.CallbackResults.Add(errorCallbackResult) ScriptManager1.RegisterDataItem(Page, Map1.CallbackResults.ToString(), False) End Try End Sub #End Region #Region "Instance Methods" ' Adds the passed-in point to the passed-in graphics layer Private Sub AddPointToMap(ByVal adfPoint As ESRI.ArcGIS.ADF.Web.Geometry.Point, ByVal elementGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer) Try ' Create a default symbol for the point Dim defaultAdfSimpleMarkerSymbol As ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol = New ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol() defaultAdfSimpleMarkerSymbol.Color = System.Drawing.Color.GreenYellow defaultAdfSimpleMarkerSymbol.Width = 20 defaultAdfSimpleMarkerSymbol.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Star ' Create a selected symbol for the point Dim selectedAdfSimpleMarkerSymbol As ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol = New ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol() selectedAdfSimpleMarkerSymbol.Color = System.Drawing.Color.Yellow selectedAdfSimpleMarkerSymbol.Width = 20 selectedAdfSimpleMarkerSymbol.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Star ' Create a graphic based on the passed-in point, the default symbol, and the selected symbol Dim graphicElement As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement = New ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(adfPoint, defaultAdfSimpleMarkerSymbol, selectedAdfSimpleMarkerSymbol) ' Add the graphic to the passed-in graphics layer elementGraphicsLayer.Add(graphicElement) Catch exception As System.Exception Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = GetErrorCallback(exception) Map1.CallbackResults.Add(errorCallbackResult) End Try End Sub ' Retrieves the graphics layer of the passed-in name from the graphics resource of the passed-in name. ' If the graphics layer does not exist, it is created. Private Function GetGraphicsLayer(ByVal graphicsResourceName As String, ByVal graphicsLayerName As String) As ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer Try ' Retrieve the graphics resource of the passed-in name Dim graphicsMapResource As ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource = CType(MapResourceManager1.GetResource(graphicsResourceName), ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource) ' Attempt to retrieve the graphics layer having the passed-in name from the resource Dim elementGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer = Nothing If graphicsMapResource.Graphics.Tables.Contains(graphicsLayerName) Then elementGraphicsLayer = TryCast(graphicsMapResource.Graphics.Tables(graphicsLayerName), ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer) End If ' If no graphics layer with the passed-in name was found, create one If elementGraphicsLayer Is Nothing Then elementGraphicsLayer = New ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer() elementGraphicsLayer.TableName = graphicsLayerName graphicsMapResource.Graphics.Tables.Add(elementGraphicsLayer) ' Refresh the Toc so the layer is displayed in it Toc1.Refresh() End If Return elementGraphicsLayer Catch exception As System.Exception Dim errorCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = GetErrorCallback(exception) Map1.CallbackResults.Add(errorCallbackResult) Return Nothing End Try End Function ' Constructs a callback result that will display an error message based on the passed-in ' exception Private Function GetErrorCallback(ByVal exception As System.Exception) As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult ' Create a callback result to display an error message Dim jsAlertErrorMessage As String = GetJavaScriptErrorString(exception) Dim alertCallbackResult As ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsAlertErrorMessage) Return alertCallbackResult End Function ' Constructs JavaScript necessary to display an error message based on the passed-in exception. Private Function GetJavaScriptErrorString(ByVal exception As System.Exception) As String ' Get the website's configuration file Dim webConfig As System.Configuration.Configuration = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration(System.Web.HttpContext.Current.Request.ApplicationPath) ' Get the "compilation" section of the config file Dim compilationSection As System.Web.Configuration.CompilationSection = TryCast(webConfig.GetSection("system.web/compilation"), System.Web.Configuration.CompilationSection) ' If the config file's compilation section specifies debug mode, include ' stack trace information in the error message. Otherwise, just return ' the exception message. Dim errorMessage As String = Nothing If (Not compilationSection Is Nothing) AndAlso (compilationSection.Debug) Then Dim stackTrace As String = exception.StackTrace.Replace("\", "\\") errorMessage = exception.Message & "\n\n" & stackTrace.Trim() Else errorMessage = exception.Message End If ' Create a callback result to display an error message Dim jsAlertException As String = "alert('" & errorMessage & "')" Return jsAlertException End Function #End Region End Class