ArcGIS_SelectBufferTool_CSharp\App_Code\Utility.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 class Utility { /// <summary> /// Retrieves the well-known ID of a unit based on its name. These names are /// taken from the ESRI.ArcGIS.ADF.Web.DataSources.Units enumeration. /// </summary> /// <param name="unitName">Name of the unit to retrieve the WKID for</param> public static int GetWkidByUnitName(string unitName) { int wkid = -1; switch (unitName) { case "Inches" : wkid = 109009; break; case "Feet" : wkid = 9003; break; case "Yards" : wkid = 109002; break; case "Miles" : wkid = 9035; break; case "NauticalMiles" : wkid = 9030; break; case "Millimeters" : wkid = 109007; break; case "Centimeters" : wkid = 109006; break; case "Meters" : wkid = 9001; break; case "Kilometers" : wkid = 9036; break; case "Decimeters" : wkid = 109005; break; } return wkid; } /// <summary> /// Gets the minimum enclosing rectangle (i.e. bounding box) of the passed-in polygon /// </summary> /// <param name="agsSoapPolygon">Polygon to retrieve the MER for</param> public static ESRI.ArcGIS.ADF.ArcGISServer.EnvelopeN GetBoundingExtent( ESRI.ArcGIS.ADF.ArcGISServer.PolygonN agsSoapPolygon) { // Instantiate an envelope with max values minimized and min values maximized ESRI.ArcGIS.ADF.ArcGISServer.EnvelopeN agsSoapBoundingBox = new ESRI.ArcGIS.ADF.ArcGISServer.EnvelopeN(); agsSoapBoundingBox.XMin = double.MaxValue; agsSoapBoundingBox.XMax = double.MinValue; agsSoapBoundingBox.YMin = double.MaxValue; agsSoapBoundingBox.YMax = double.MinValue; // Iterate through all the polygon's vertices for (int i = 0; i < agsSoapPolygon.RingArray.Length; i++) { ESRI.ArcGIS.ADF.ArcGISServer.Ring agsSoapRing = agsSoapPolygon.RingArray[i]; for (int j = 0; j < agsSoapRing.PointArray.Length; j++) { // For each vertex, expand the bounds of the minimum enclosing rectangle with the // vertex's coordinates if they fall outside the rectangle's current bounds ESRI.ArcGIS.ADF.ArcGISServer.PointN agsSoapCurrentPoint = agsSoapRing.PointArray[j] as ESRI.ArcGIS.ADF.ArcGISServer.PointN; if (agsSoapCurrentPoint.X < agsSoapBoundingBox.XMin) agsSoapBoundingBox.XMin = agsSoapCurrentPoint.X; else if (agsSoapCurrentPoint.X > agsSoapBoundingBox.XMax) agsSoapBoundingBox.XMax = agsSoapCurrentPoint.X; if (agsSoapCurrentPoint.Y < agsSoapBoundingBox.YMin) agsSoapBoundingBox.YMin = agsSoapCurrentPoint.Y; else if (agsSoapCurrentPoint.Y > agsSoapBoundingBox.YMax) agsSoapBoundingBox.YMax = agsSoapCurrentPoint.Y; } } return agsSoapBoundingBox; } /// <summary> /// Creates a spatial reference that will minimize distortion near the input polygon. Ideal for operations /// that will derive geometry based on that polygon (i.e. buffer). /// </summary> /// <param name="agsSoapPolygon">Polygon to use as the center of the spatial reference's datum</param> /// <param name="geometryServerProxy">Geometry service to use in creating the spatial reference</param> public static ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference CreateOperationSpatialReference( ESRI.ArcGIS.ADF.ArcGISServer.PolygonN agsSoapPolygon, ESRI.ArcGIS.ADF.ArcGISServer.GeometryServerProxy geometryServerProxy) { // Get the polygon's minimum enclosing rectangle (MER) ESRI.ArcGIS.ADF.ArcGISServer.EnvelopeN agsSoapBoundingEnvelope = GetBoundingExtent(agsSoapPolygon); // If the input polygon's spatial reference uses a projected coordinate system, project the MER to a // geographic coordinate system (WGS 1984 in this case). We do this because the MER's coordinates // will be used to initialize the datum of the operation spatial reference if (agsSoapPolygon.SpatialReference is ESRI.ArcGIS.ADF.ArcGISServer.ProjectedCoordinateSystem) { // Create an ArcGIS Server spatial reference initalized to use the WGS 1984 coordinate system ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference agsSoapGeographicSpatialReference = new ESRI.ArcGIS.ADF.ArcGISServer.GeographicCoordinateSystem(); agsSoapGeographicSpatialReference.WKID = 4326; agsSoapGeographicSpatialReference.WKIDSpecified = true; // Place the input MER in an array for the project operation ESRI.ArcGIS.ADF.ArcGISServer.Geometry[] agsSoapInputGeometryArray = new ESRI.ArcGIS.ADF.ArcGISServer.Geometry[1]; agsSoapInputGeometryArray[0] = agsSoapBoundingEnvelope; // Execute the projection ESRI.ArcGIS.ADF.ArcGISServer.Geometry[] agsSoapOutputGeometryArray = geometryServerProxy.Project(agsSoapPolygon.SpatialReference, agsSoapGeographicSpatialReference, true, null, null, agsSoapInputGeometryArray); // Retrieve the projected MER from the results array agsSoapBoundingEnvelope = agsSoapOutputGeometryArray[0] as ESRI.ArcGIS.ADF.ArcGISServer.EnvelopeN; } // Get the latitude (Y coordinate) at the center of the MER double centerLatitude = agsSoapBoundingEnvelope.YMax - (agsSoapBoundingEnvelope.YMax - agsSoapBoundingEnvelope.YMin) / 2; // Create the definition string for the operation spatial reference's coordinate system. We will use // the Hotine Oblique Mercator coordinate system because it lends itself well to minimizing operational // distortion anywhere on the earth string hotineObliqueMercatorDefinition = @" PROJCS[""World_Hotine"", GEOGCS[""GCS_WGS_1984"", DATUM[""D_WGS_1984"", SPHEROID[""WGS_1984"",6378137.0,298.257223563]], PRIMEM[""Greenwich"",0.0], UNIT[""Degree"",0.0174532925199433]], PROJECTION[""Hotine_Oblique_Mercator_Two_Point_Natural_Origin""], PARAMETER[""False_Easting"",0.0], PARAMETER[""False_Northing"",0.0], PARAMETER[""Latitude_Of_1st_Point"",{0}], PARAMETER[""Latitude_Of_2nd_Point"",{1}], PARAMETER[""Scale_Factor"",1.0], PARAMETER[""Longitude_Of_1st_Point"",{2}], PARAMETER[""Longitude_Of_2nd_Point"",{3}], PARAMETER[""Latitude_Of_Center"",{4}], UNIT[""Meter"",1.0]]"; // Specify the relevant coordinates of the MER for the coordinate system's datum parameters string customHotineObliqueCylindricalMercator = string.Format( hotineObliqueMercatorDefinition, agsSoapBoundingEnvelope.YMin, agsSoapBoundingEnvelope.YMax, agsSoapBoundingEnvelope.XMin, agsSoapBoundingEnvelope.XMax, centerLatitude); // Create the spatial reference ESRI.ArcGIS.ADF.ArcGISServer.SpatialReference agsSoapBufferSpatialReference = geometryServerProxy.FindSRByWKT(customHotineObliqueCylindricalMercator, null, true, true); return agsSoapBufferSpatialReference; } /// <summary> /// Creates an ArcGIS Server simple fill symbol with a solid outline and other parameters as /// specified /// </summary> /// <param name="fillColor">Fill color of the symbol</param> /// <param name="fillStyle">Fill style of the symbol</param> /// <param name="outlineColor">Outline color of the symbol</param> /// <param name="outlineWidth">Outline width of the symbol</param> public static ESRI.ArcGIS.ADF.ArcGISServer.SimpleFillSymbol CreateSimpleFillSymbol( System.Drawing.Color fillColor, ESRI.ArcGIS.ADF.ArcGISServer.esriSimpleFillStyle fillStyle, System.Drawing.Color outlineColor, int outlineWidth) { // Create an ArcGIS Server color object for the fill symbol based on the passed-in color ESRI.ArcGIS.ADF.ArcGISServer.RgbColor agsSoapFillColor = new ESRI.ArcGIS.ADF.ArcGISServer.RgbColor(); agsSoapFillColor.Red = fillColor.R; agsSoapFillColor.Green = fillColor.G; agsSoapFillColor.Blue = fillColor.B; // Create a simple fill symbol with the color and passed-in fill style ESRI.ArcGIS.ADF.ArcGISServer.SimpleFillSymbol agsSoapSimpleFillSymbol = new ESRI.ArcGIS.ADF.ArcGISServer.SimpleFillSymbol(); agsSoapSimpleFillSymbol.Style = fillStyle; agsSoapSimpleFillSymbol.Color = agsSoapFillColor; // Create an ArcGIS Server color object for the outline ESRI.ArcGIS.ADF.ArcGISServer.RgbColor agsSoapOutlineColor = new ESRI.ArcGIS.ADF.ArcGISServer.RgbColor(); agsSoapOutlineColor.Red = outlineColor.R; agsSoapOutlineColor.Green = outlineColor.G; agsSoapOutlineColor.Blue = outlineColor.B; // Create a simple line symbol with the color and passed-in width ESRI.ArcGIS.ADF.ArcGISServer.SimpleLineSymbol agsSoapBufferSimpleLineSymbol = new ESRI.ArcGIS.ADF.ArcGISServer.SimpleLineSymbol(); agsSoapBufferSimpleLineSymbol.Color = agsSoapOutlineColor; agsSoapBufferSimpleLineSymbol.Style = ESRI.ArcGIS.ADF.ArcGISServer.esriSimpleLineStyle.esriSLSSolid; agsSoapBufferSimpleLineSymbol.Width = outlineWidth; // Apply the outline to the fill symbol agsSoapSimpleFillSymbol.Outline = agsSoapBufferSimpleLineSymbol; return agsSoapSimpleFillSymbol; } /// <summary> /// Selects features that intersect the passed-in geometry. /// </summary> /// <param name="agsMapFunctionality">The map functionality of the resource containing the layer to /// select features from</param> /// <param name="agsSoapIntersectGeometry">The geometry used for selecting features</param> /// <param name="targetLayerName">The name of the layer to select features from</param> /// <param name="selectionColor">The color to use in displaying the selected features</param> public static void SelectIntersectingFeatures( ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapFunctionality agsMapFunctionality, ESRI.ArcGIS.ADF.ArcGISServer.Geometry agsSoapIntersectGeometry, string targetLayerName, System.Drawing.Color selectionColor) { // Retrieve the index of the target layer string[] layerIDs = null; string[] layerNames = null; agsMapFunctionality.GetLayers(out layerIDs, out layerNames); int targetLayerIndex = 0; for (int i = 0; i < layerNames.Length; i++) { if (layerNames[i] == targetLayerName) { targetLayerIndex = i; break; } } // Get a reference to the ArcGIS Server resource underlying the map functionality ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer.MapResourceBase mapResourceBase = agsMapFunctionality.MapResource; // Get MapLayerInfo object for the selection layer and use it to determine the name of the layer's // geometry field. ESRI.ArcGIS.ADF.ArcGISServer.MapLayerInfo[] agsSoapMapLayerInfoArray = mapResourceBase.MapServerInfo.MapLayerInfos; ESRI.ArcGIS.ADF.ArcGISServer.MapLayerInfo agsSoapActiveMapLayerInfo = agsSoapMapLayerInfoArray[targetLayerIndex]; string geometryFieldName = null; foreach (ESRI.ArcGIS.ADF.ArcGISServer.Field agsSoapField in agsSoapActiveMapLayerInfo.Fields.FieldArray) { if (agsSoapField.Type == ESRI.ArcGIS.ADF.ArcGISServer.esriFieldType.esriFieldTypeGeometry) { geometryFieldName = agsSoapField.Name; break; } } // Initialize a spatial filter to use in selecting features that intersect the buffer ESRI.ArcGIS.ADF.ArcGISServer.SpatialFilter agsSoapSpatialFilter = new ESRI.ArcGIS.ADF.ArcGISServer.SpatialFilter(); agsSoapSpatialFilter.FilterGeometry = agsSoapIntersectGeometry; agsSoapSpatialFilter.GeometryFieldName = geometryFieldName; agsSoapSpatialFilter.SpatialRel = ESRI.ArcGIS.ADF.ArcGISServer.esriSpatialRelEnum.esriSpatialRelIntersects; // Retrieve the layer's LayerDescription to use in specifying the layer ID for the query operation ESRI.ArcGIS.ADF.ArcGISServer.MapDescription agsSoapMapDescription = agsMapFunctionality.MapDescription; ESRI.ArcGIS.ADF.ArcGISServer.LayerDescription[] agsSoapLayerDescriptionArray = agsSoapMapDescription.LayerDescriptions; ESRI.ArcGIS.ADF.ArcGISServer.LayerDescription agsSoapActiveLayerDescription = agsSoapLayerDescriptionArray[targetLayerIndex]; // Create an ArcGIS Server color object from the passed-in color ESRI.ArcGIS.ADF.ArcGISServer.RgbColor selectionAgsSoapRgbColor = new ESRI.ArcGIS.ADF.ArcGISServer.RgbColor(); selectionAgsSoapRgbColor.Red = selectionColor.R; selectionAgsSoapRgbColor.Green = selectionColor.G; selectionAgsSoapRgbColor.Blue = selectionColor.B; // Set the layer's selection color to the passed-in color agsSoapActiveLayerDescription.SelectionColor = selectionAgsSoapRgbColor; // Execute a query to retrieve the IDs of features that intersect the buffer ESRI.ArcGIS.ADF.ArcGISServer.MapServerProxy agsSoapMapServerProxy = mapResourceBase.MapServerProxy; ESRI.ArcGIS.ADF.ArcGISServer.FIDSet selectionAgsSoapFIDSet = agsSoapMapServerProxy.QueryFeatureIDs(agsSoapMapDescription.Name, agsSoapActiveLayerDescription.LayerID, agsSoapSpatialFilter); // Set the selection layer's selected features to those intersecting the buffer agsSoapActiveLayerDescription.SelectionFeatures = selectionAgsSoapFIDSet.FIDArray; } /// <summary> /// Constructs a callback result that will display a javascript alert with an error message /// based on the passed-in exception /// </summary> /// <param name="exception">The exception from which the error message will be derived</param> /// <returns></returns> public static ESRI.ArcGIS.ADF.Web.UI.WebControls.CallbackResult CreateErrorCallbackResult( 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; } /// <summary> /// Constructs the syntax to display a javascript alert with an error message based on the /// passed-in exception /// </summary> /// <param name="exception">The exception from which the error message will be derived</param> /// <returns></returns> 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("\\", "\\\\"); stackTrace = stackTrace.Replace("\n", "\\n"); stackTrace = stackTrace.Replace("\r", "\\r"); stackTrace = stackTrace.Replace("'", "\\'"); errorMessage = exception.Message.Replace("\\", "\\\\"); errorMessage = errorMessage.Replace("\n", "\\n"); errorMessage = errorMessage.Replace("\r", "\\r"); errorMessage = errorMessage.Replace("'", "\\'"); errorMessage = errorMessage + "\\n\\n" + stackTrace.Trim(); } else errorMessage = exception.Message; // Create a callback result to display an error message string jsAlertException = "alert('" + errorMessage + "')"; return jsAlertException; } }