Common_Geocoding_CSharp\Default.aspx.cs
// 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. // public partial class Default : System.Web.UI.Page { #region ASP.NET Page Event Handlers protected void Page_PreRender(object sender, System.EventArgs e) { if (!IsPostBack) { ESRI.ArcGIS.ADF.Web.Geometry.Envelope bloomingField = new ESRI.ArcGIS.ADF.Web.Geometry.Envelope(-83.3337801950437, 42.5314716926848, -83.2476061838133, 42.6123242012297); Map1.Extent = bloomingField; } try { string customScriptKey = "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 (!this.Page.ClientScript.IsClientScriptBlockRegistered(GetType(), customScriptKey) && !ScriptManager1.IsInAsyncPostBack) { // 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. string scriptBlock = @" function onLoadFunction(){{ Sys.WebForms.PageRequestManager.getInstance().add_pageLoading(AsyncResponseHandler); }} function AsyncResponseHandler(sender, args) {{ var dataItems = args.get_dataItems(); if (dataItems['{0}'] != null) ESRI.ADF.System.processCallbackResult(dataItems['{0}']); }} 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. this.Page.ClientScript.RegisterStartupScript(GetType(), customScriptKey, scriptBlock, true); } } catch (System.Exception exception) { string jsErrorAlert = string.Format("<script>{0}</script>", GetJavaScriptErrorString(exception)); Response.Write(jsErrorAlert); } } #endregion #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 void btnGeocode_Click(object sender, System.EventArgs e) { try { // Get the resource item for the first item in the GeocodeResourceManager and make sure it's initialized ESRI.ArcGIS.ADF.Web.UI.WebControls.GeocodeResourceItem geocodeResourceItem = GeocodeResourceManager1.ResourceItems.Find("Geocode Resource"); if (!geocodeResourceItem.Resource.Initialized) geocodeResourceItem.InitializeResource(); // Create a Web ADF Common API geocode functionality ESRI.ArcGIS.ADF.Web.DataSources.IGeocodeFunctionality commonGeocodeFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.IGeocodeFunctionality) (geocodeResourceItem.Resource.CreateFunctionality(typeof( ESRI.ArcGIS.ADF.Web.DataSources.IGeocodeFunctionality), null)); System.Collections.Generic.List<ESRI.ArcGIS.ADF.Web.Geocode.Field> addressFieldList = commonGeocodeFunctionality.GetAddressFields(); System.Collections.Generic.List<ESRI.ArcGIS.ADF.Web.Geocode.AddressValue> addressValueList = new System.Collections.Generic.List<ESRI.ArcGIS.ADF.Web.Geocode.AddressValue>(); // Retrieve the input street from txtAddress and store in an AddressValue object ESRI.ArcGIS.ADF.Web.Geocode.AddressValue streetAddressValue = new ESRI.ArcGIS.ADF.Web.Geocode.AddressValue("STREET", txtAddress.Text); // Retrieve the input zip from txtZipCode and store in an AddressValue object ESRI.ArcGIS.ADF.Web.Geocode.AddressValue zoneAddressValue = 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 ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer elementGraphicsLayer = GetGraphicsLayer("Graphics Resource", "Geocode Results"); elementGraphicsLayer.Clear(); // Declare a Web ADF Point object to store the result geometry ESRI.ArcGIS.ADF.Web.Geometry.Point adfPoint = null; // 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) { // Get all available match candidates // Get the minimum match score from the minimum score drop-down commonGeocodeFunctionality.MinCandidateScore = int.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 System.Data.DataTable matchDataTable = commonGeocodeFunctionality.FindAddressCandidates(addressValueList, true, true); // Find the index of the shape column from the results data table int shapeColumnIndex = -1; for (int j = 0; j < matchDataTable.Columns.Count; j++) { if (matchDataTable.Columns[j].DataType == typeof(ESRI.ArcGIS.ADF.Web.Geometry.Geometry)) { shapeColumnIndex = j; break; } } // Check that results were found if (matchDataTable.Rows.Count > 0) { // Bind the results to the GridView control grdMatchInfo.DataSource = matchDataTable; grdMatchInfo.DataBind(); grdMatchInfo.Visible = true; // Get the geometry column from the results table System.Data.DataColumn shapeColumn = matchDataTable.Columns[shapeColumnIndex]; // Add a point on the map for each candidate foreach (System.Data.DataRow dataRow in matchDataTable.Rows) { object adfPointAsObject = dataRow[shapeColumnIndex]; if (adfPointAsObject is ESRI.ArcGIS.ADF.Web.Geometry.Point) { adfPoint = (ESRI.ArcGIS.ADF.Web.Geometry.Point)adfPointAsObject; AddPointToMap(adfPoint, elementGraphicsLayer); } } // Update the match count label lblMatchCount.Text = string.Format("Number of Matches: {0}", matchDataTable.Rows.Count); } } else { // Just get the one best-matching address // Get the minimum match score from the minimum score drop-down commonGeocodeFunctionality.MinMatchScore = int.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 ((adfPoint != null) && (!adfPoint.X.Equals(double.NaN))) { 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"; } } // Check whether the match point is null or is populated with coordinates of NaN if ((adfPoint != null) && (!adfPoint.X.Equals(double.NaN))) { 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; } } catch (System.Exception exception) { ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult = GetErrorCallback(exception); Map1.CallbackResults.Add(errorCallbackResult); ScriptManager1.RegisterDataItem(Page, Map1.CallbackResults.ToString(), false); } } // Clears spatial geocode results from the map and textual/tabular geocode results from the page. // Called when the user clicks the Clear button protected void btnClearResults_Click(object sender, System.EventArgs e) { try { // Get the graphics layer where spatial geocode results are stored from the Map ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer 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 (System.Exception exception) { ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult = GetErrorCallback(exception); Map1.CallbackResults.Add(errorCallbackResult); ScriptManager1.RegisterDataItem(Page, Map1.CallbackResults.ToString(), false); } } #endregion #region Instance Methods // Adds the passed-in point to the passed-in graphics layer private void AddPointToMap(ESRI.ArcGIS.ADF.Web.Geometry.Point adfPoint, ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer elementGraphicsLayer) { try { // Create a default symbol for the point ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol defaultAdfSimpleMarkerSymbol = 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 ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol selectedAdfSimpleMarkerSymbol = 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 ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement 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 (System.Exception exception) { ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult = GetErrorCallback(exception); Map1.CallbackResults.Add(errorCallbackResult); } } // 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 ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer GetGraphicsLayer( string graphicsResourceName, string graphicsLayerName) { try { // Retrieve the graphics resource of the passed-in name ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource graphicsMapResource = (ESRI.ArcGIS.ADF.Web.DataSources.Graphics.MapResource) (MapResourceManager1.GetResource(graphicsResourceName)); // Attempt to retrieve the graphics layer having the passed-in name from the resource ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer elementGraphicsLayer = null; if (graphicsMapResource.Graphics.Tables.Contains(graphicsLayerName)) elementGraphicsLayer = graphicsMapResource.Graphics.Tables[graphicsLayerName] as ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer; // If no graphics layer with the passed-in name was found, create one if (elementGraphicsLayer == null) { 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(); } return elementGraphicsLayer; } catch (System.Exception exception) { ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult errorCallbackResult = GetErrorCallback(exception); Map1.CallbackResults.Add(errorCallbackResult); return null; } } // Constructs a callback result that will display an error message based on the passed-in // exception private ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult GetErrorCallback( System.Exception exception) { // Create a callback result to display an error message string jsAlertErrorMessage = GetJavaScriptErrorString(exception); ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult alertCallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsAlertErrorMessage); return alertCallbackResult; } // Constructs JavaScript necessary to display an error message based on the passed-in exception. private string GetJavaScriptErrorString(System.Exception exception) { // Get the website's configuration file System.Configuration.Configuration webConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration( System.Web.HttpContext.Current.Request.ApplicationPath); // Get the "compilation" section of the config file System.Web.Configuration.CompilationSection compilationSection = webConfig.GetSection("system.web/compilation") as 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. string errorMessage = null; if ((compilationSection != null) && (compilationSection.Debug)) { string stackTrace = exception.StackTrace.Replace("\\", "\\\\"); errorMessage = exception.Message + "\\n\\n" + stackTrace.Trim(); } else errorMessage = exception.Message; // Create a callback result to display an error message string jsAlertException = "alert('" + errorMessage + "')"; return jsAlertException; } #endregion }