Common_AddCustomTool_CSharp\App_Code\CustomToolLibrary.cs
// 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. // namespace CustomToolLibrary { public class ZoomToPointTool : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction { #region IMapServerToolAction Members void ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction.ServerAction( ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs toolEventArgs) { // Get reference to map control ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = (ESRI.ArcGIS.ADF.Web.UI.WebControls.Map)toolEventArgs.Control; try { // Cast tool event arguments to map point event arguments, which allows // easy access to the map point clicked by the user ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs mapPointEventArgs = (ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs)toolEventArgs; // Get the map point from the map point event arguments ESRI.ArcGIS.ADF.Web.Geometry.Point adfPoint = mapPointEventArgs.MapPoint; // Change map extent. The resources have not changed in the Map control, thus // a call to Map.Refresh is not required. Note that the Map will generate the // callback response automatically. You do not need to add the Map's callback // results to any other control or convert them to a string. double quarterMapExtentWidth = adfMap.Extent.Width / 4; ESRI.ArcGIS.ADF.Web.Geometry.Envelope adfEnvelope = new ESRI.ArcGIS.ADF.Web.Geometry.Envelope(adfPoint.X - quarterMapExtentWidth, adfPoint.Y - quarterMapExtentWidth, adfPoint.X + quarterMapExtentWidth, adfPoint.Y + quarterMapExtentWidth); adfMap.Extent = adfEnvelope; } catch (System.Exception exception) { // If an error occurred, get the callback result from the ProcessError // function and copy to the map control's callback results collection adfMap.CallbackResults.Add(Utility.GetErrorCallback(exception)); } } #endregion } public class IdentifyAllTool : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction { #region IMapServerToolAction Members void ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction.ServerAction( ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs toolEventArgs) { // Get reference to the map control ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = (ESRI.ArcGIS.ADF.Web.UI.WebControls.Map)toolEventArgs.Control; try { // Cast tool event arguments to map point event arguments, which allows // easy access to the map point clicked by the user ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs mapPointEventArgs = (ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs)toolEventArgs; // Get the map point from the map point event arguments ESRI.ArcGIS.ADF.Web.Geometry.Point adfPoint = mapPointEventArgs.MapPoint; // Create a master dataset to store all tables returned from Identity operation System.Data.DataSet outputDataset = new System.Data.DataSet(); // For each map functionality (resource) in the Map, do an Identify foreach (ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality mapFunctionality in adfMap.GetFunctionalities()) { // Retrieve the resource for the current map functionality object ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisResource = mapFunctionality.Resource; // Check whether the current resource supports querying bool supportsQuery = gisResource.SupportsFunctionality(typeof (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)); if (supportsQuery) { // Create a query functionality object from the current resource ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality queryFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality) gisResource.CreateFunctionality(typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null); // Get the names and ids of the queryable layers in the current resource string[] layerIDs; string[] layerNames; queryFunctionality.GetQueryableLayers(null, out layerIDs, out layerNames); // Initialize a variable to store tolerance. This will be used as the tolerance // around the point clicked by the user int pixelTolerance = 3; // Execute the identify operation System.Data.DataTable[] resultDataTableArray = queryFunctionality.Identify( mapFunctionality.Name, adfPoint, pixelTolerance, ESRI.ArcGIS.ADF.Web.IdentifyOption.VisibleLayers, layerIDs); // Exit the loop if no results were found if (resultDataTableArray == null) break; // Add each table returned to the master dataset. Give each table a unique name // composed of the resource name, layer id, and layer name. for (int index = 0; index < resultDataTableArray.Length; index++) { System.Data.DataTable resultDataTable = resultDataTableArray[index]; // Find the index of the layer name in the layerNames array // corresponding to the current results table int i; for (i = 0; i < layerNames.Length; i++) { if (resultDataTable.TableName == layerNames[i]) break; } resultDataTable.TableName = gisResource.Name + "_" + layerIDs[i] + "_" + layerNames[i]; outputDataset.Tables.Add(resultDataTable); } } } // For each table in the master dataset, create a GridView to display the content. Write the rendered // HTML content to a string for dynamic display in the browser System.Data.DataTableCollection outputDataTableCollection = outputDataset.Tables; string tableHTMLString = string.Empty; foreach (System.Data.DataTable dataTable in outputDataTableCollection) { if (dataTable.Rows.Count == 0) continue; System.Web.UI.WebControls.GridView gridView = new System.Web.UI.WebControls.GridView(); gridView.ToolTip = dataTable.TableName; gridView.Caption = dataTable.TableName; gridView.DataSource = dataTable; gridView.DataBind(); gridView.Visible = true; gridView.BorderWidth = 10; using (System.IO.StringWriter stringWriter = new System.IO.StringWriter()) { System.Web.UI.HtmlTextWriter htmlTextWriter = new System.Web.UI.HtmlTextWriter(stringWriter); gridView.RenderControl(htmlTextWriter); htmlTextWriter.Flush(); tableHTMLString = tableHTMLString + stringWriter.ToString(); } } // Use ADF callback mechanism to insert content into a div element in the page ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult tablesCallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateSetInnerContent( "datadiv", tableHTMLString); adfMap.CallbackResults.Add(tablesCallbackResult); } catch (System.Exception exception) { // If an error occurred, get the callback result from the ProcessError // function and copy to the map control's callback results collection adfMap.CallbackResults.Add(Utility.GetErrorCallback(exception)); } } #endregion } public class ExtentCommand : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerCommandAction { #region IMapServerCommandAction Members void ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IServerAction.ServerAction( ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo) { // Change map extent. Since layer or resource content is // not changed, no call to Map.Refresh is needed. ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = (ESRI.ArcGIS.ADF.Web.UI.WebControls.Map)toolbarItemInfo.BuddyControls[0]; try { adfMap.Extent = new ESRI.ArcGIS.ADF.Web.Geometry.Envelope(-120, 30, -100, 40); } catch (System.Exception exception) { // If an error occurred, get the callback result from the ProcessError // function and copy to the map control's callback results collection adfMap.CallbackResults.Add(Utility.GetErrorCallback(exception)); } } #endregion } public class ExtentListDropDownBox : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerDropDownBoxAction { #region IMapServerDropDownBoxAction Members void ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IServerAction.ServerAction( ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo) { // Get the value selected in Web ADF drop down box. Change map extent and set Map.Extent to the new extent. // Get the Web ADF map control ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = (ESRI.ArcGIS.ADF.Web.UI.WebControls.Map)toolbarItemInfo.BuddyControls[0]; try { // Get the direction drop-down box and the currently selected value ESRI.ArcGIS.ADF.Web.UI.WebControls.DropDownBox directionDropDownBox = (ESRI.ArcGIS.ADF.Web.UI.WebControls.DropDownBox)toolbarItemInfo.Toolbar.ToolbarItems.Find(toolbarItemInfo.Name); string directionQuadrant = directionDropDownBox.SelectedValue; // Get the current map extent parameters double minx, miny, maxx, maxy; minx = adfMap.Extent.XMin; miny = adfMap.Extent.YMin; maxx = adfMap.Extent.XMax; maxy = adfMap.Extent.YMax; // Calculate the width and height of the current map extent double xWidth = maxx - minx; double yHeight = maxy - miny; // Calculate new extent parameters based on the currently selected // value in the direction drop-down box switch (directionQuadrant) { case "NorthWest": miny = maxy; maxy = maxy + yHeight; maxx = minx; minx = minx - xWidth; break; case "NorthEast": minx = maxx; maxx = maxx + xWidth; miny = maxy; maxy = maxy + yHeight; break; case "SouthWest": maxx = minx; minx = minx - xWidth; maxy = miny; miny = miny - yHeight; break; case "SouthEast": minx = maxx; maxx = maxx + xWidth; maxy = miny; miny = miny - yHeight; break; } // Set the map control's extent to the new extent parameters adfMap.Extent = new ESRI.ArcGIS.ADF.Web.Geometry.Envelope(minx, miny, maxx, maxy); } catch (System.Exception exception) { // If an error occurred, get the callback result from the ProcessError // function and copy to the map control's callback results collection adfMap.CallbackResults.Add(Utility.GetErrorCallback(exception)); } } #endregion } public class HyperLinkTool : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction { #region IMapServerToolAction Members void ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerToolAction.ServerAction( ESRI.ArcGIS.ADF.Web.UI.WebControls.ToolEventArgs toolEventArgs) { // Get map control from passed-in arguments ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = (ESRI.ArcGIS.ADF.Web.UI.WebControls.Map)toolEventArgs.Control; // Cast tool event arguments to map point event arguments, which allows // easy access to the map point clicked by the user ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs mapPointEventArgs = (ESRI.ArcGIS.ADF.Web.UI.WebControls.MapPointEventArgs)toolEventArgs; // Get the map point from the map point event arguments ESRI.ArcGIS.ADF.Web.Geometry.Point adfPoint = mapPointEventArgs.MapPoint; // Get the functionality of the resource that contains the layer on which you want to hyperlink ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality commonMapFunctionality = adfMap.GetFunctionality("Server Resource"); ESRI.ArcGIS.ADF.Web.DataSources.IGISResource gisResource = commonMapFunctionality.Resource; // Create query functionality from the resource ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality queryFunctionality = (ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)gisResource.CreateFunctionality (typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality), null); // Get the ids and names of the layers in the current that can be queried string[] layerIDs; string[] layerNames; queryFunctionality.GetQueryableLayers(null, out layerIDs, out layerNames); // Set the layer name on which you want to hyperlink string activeLayerName = "states"; // Iterate through the layer names until a match is found for // activeLayerName. Include a call to ToUpper() in the comparison // to eliminate case sensitivity. string activeLayerID = null; for (int index = 0; index < layerNames.Length; index++) { if (layerNames[index].ToUpper() == activeLayerName.ToUpper()) { // Get the layer id of the match found from the layer id array activeLayerID = layerIDs[index]; break; } } // Create a spatial filter and initialize its geometry with the point clicked ESRI.ArcGIS.ADF.Web.SpatialFilter spatialFilter = new ESRI.ArcGIS.ADF.Web.SpatialFilter(); spatialFilter.Geometry = adfPoint; try { // Execute the query System.Data.DataTable resultDataTable = queryFunctionality.Query(commonMapFunctionality.Name, activeLayerID, spatialFilter); // If no features returned, show alert if (resultDataTable.Rows.Count < 1) { throw new System.Exception("No feature found"); } // Name of field containing the term to the google search url string searchName = (string)resultDataTable.Rows[0]["STATE_NAME"]; // If field contains no data, show alert if (string.IsNullOrEmpty(searchName)) { throw new System.Exception("Hyperlink field contains no data"); } // Construct the JavaScript call to change the map cursor back to original string jsChangeCursor = "map.divObject.style.cursor = map.cursor"; // Create a callback result containing the JavaScript call and add to the // map control's callback results collection ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult cursorCallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsChangeCursor); adfMap.CallbackResults.Add(cursorCallbackResult); // Construct the JavaScript call to open a new browser window. Any valid url can be used. string jsPopup = "window.open('http://www.google.com/search?q=" + searchName + "');"; // Create a callback result containing the JavaScript call and add to the // map control's callback results collection ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult popupCallbackResult = ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult.CreateJavaScript(jsPopup); adfMap.CallbackResults.Add(popupCallbackResult); } catch (System.Exception exception) { // If an error occurred, get the callback result from the ProcessError // function and copy to the map control's callback results collection adfMap.CallbackResults.Add(Utility.GetErrorCallback(exception)); } } #endregion } public class PreviousExtent : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerCommandAction { #region IMapServerCommandAction Members void ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IServerAction.ServerAction( ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo) { ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = (ESRI.ArcGIS.ADF.Web.UI.WebControls.Map)toolbarItemInfo.BuddyControls[0]; try { // Access to custom members in a page. Implement custom interface in the Page. IBaseToolbarRefresh baseToolbarRefresh = (IBaseToolbarRefresh)adfMap.Page; // A previous\next action is occurring // Initial previous\next action to skip extent hashtable adjustment adfMap.Page.Session["previousNext"] = true; // Subsequent map draw from previous\next action to skip extent hashtable adjustment adfMap.Page.Session["previousNextMapHandler"] = true; System.Collections.Hashtable extentsHashTable = null; // If there is an extent history, continue if (adfMap.Page.Session["extentHistory"] != null) { // Get the extent history extentsHashTable = (System.Collections.Hashtable)adfMap.Page.Session["extentHistory"]; // Get the current extent index. If greater than 0, decrement the index // and set the map extent to the previous extent in the extent history. int extentIndex = (int)adfMap.Page.Session["currentExtentIndex"]; if (extentIndex > 0) { extentIndex--; adfMap.Page.Session["currentExtentIndex"] = extentIndex; adfMap.Extent = (ESRI.ArcGIS.ADF.Web.Geometry.Envelope)extentsHashTable[extentIndex]; } // If the index is now less than or equal to 0, meaning there is not prior extent // in the extent history, disable the previous extent command. if (extentIndex <= 0) { baseToolbarRefresh.RefreshToolbar("previousExtent", true); } } // If there is an extent history, always enable the next extent command after the previous // extent command is executed. baseToolbarRefresh.RefreshToolbar("nextExtent", false); } catch (System.Exception exception) { // If an error occurred, get the callback result from the ProcessError // function and copy to the map control's callback results collection adfMap.CallbackResults.Add(Utility.GetErrorCallback(exception)); } } #endregion } public class NextExtent : ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IMapServerCommandAction { #region IMapServerCommandAction Members void ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.IServerAction.ServerAction( ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools.ToolbarItemInfo toolbarItemInfo) { // Get references to the map control and page via IBaseToolbarRefresh ESRI.ArcGIS.ADF.Web.UI.WebControls.Map adfMap = (ESRI.ArcGIS.ADF.Web.UI.WebControls.Map)toolbarItemInfo.BuddyControls[0]; try { IBaseToolbarRefresh baseToolbarRefresh = (IBaseToolbarRefresh)adfMap.Page; // A previous\next action is occurring // Initial previous\next action to skip extent hashtable adjustment adfMap.Page.Session["previousNext"] = true; // Subsequent map draw from previous\next action to skip extent hashtable adjustment adfMap.Page.Session["previousNextMapHandler"] = true; System.Collections.Hashtable extentsHashTable = null; // If there is an extent history, continue if (adfMap.Page.Session["extentHistory"] != null) { // Get the extent history and current extent index extentsHashTable = (System.Collections.Hashtable)adfMap.Page.Session["extentHistory"]; int extentIndex = (int)adfMap.Page.Session["currentExtentIndex"]; // Get the current extent index. If index is less than the index of the last extent in extent history, // increment the index by 1 and set the map extent to the next extent in the extent history. if (extentIndex < (extentsHashTable.Count - 1)) { extentIndex++; adfMap.Page.Session["currentExtentIndex"] = extentIndex; adfMap.Extent = (ESRI.ArcGIS.ADF.Web.Geometry.Envelope)extentsHashTable[extentIndex]; } // If the index greater than or equal to the index of the last extent in extent history, // meaning there is not another extent to move to, disable the next extent command. if (extentIndex >= (extentsHashTable.Count - 1)) { baseToolbarRefresh.RefreshToolbar("nextExtent", true); } // If there is an extent history, always enable the previous extent command after the // next extent command is executed. baseToolbarRefresh.RefreshToolbar("previousExtent", false); } } catch (System.Exception exception) { // If an error occurred, get the callback result from the ProcessError // function and copy to the map control's callback results collection adfMap.CallbackResults.Add(Utility.GetErrorCallback(exception)); } } #endregion } public class Utility { // Constructs a callback result that will display an error message based on the passed-in // exception public static 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. public static 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; } } }