ArcGIS_AddDynamicData_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. // // Illustrates how to add a new layer dynamically to a pooled ArcGIS Server map service and display the map image // using ArcObjects and ASP.NET only - no Web ADF controls public partial class _Default : System.Web.UI.Page { #region Instance Variable Declarations System.Data.DataTable _layerDataTable; #endregion #region ASP.NET Page Life Cycle Event Handlers protected void Page_Init(object sender, System.EventArgs e) { try { // Read the contents of the layers.config file, which is assumed to contained the names and paths of the // shapefiles that can be dynamically added to the map. Store this data in a data table member variable. if (!Page.IsPostBack) { // Create an empty data table to hold the shapefile names and paths _layerDataTable = new System.Data.DataTable("layerTable"); System.Data.DataColumn layerNameDataColumn = new System.Data.DataColumn("layerName"); System.Data.DataColumn layerPathDataColumn = new System.Data.DataColumn("layerPath"); _layerDataTable.Columns.Add(layerNameDataColumn); _layerDataTable.Columns.Add(layerPathDataColumn); // Get the root path of the web application and append the name of the file containing the // shapefile list string rootPath = Server.MapPath("~"); string layerCatalogPath = string.Format("{0}/layers.catalog", rootPath); // Get a reader to access the layer catalog System.IO.StreamReader layerCatalogReader = new System.IO.StreamReader(layerCatalogPath); // Initialize the delimiter that separates shapefile names and paths in the layer catalog string layerDelimiterString = "="; char[] layerDelimiter = layerDelimiterString.ToCharArray(); // Iterate through the lines of the layer catalog, adding each pair of shapefile names and paths // to the data table string[] layerSpecs = null; string currentLine = null; while (layerCatalogReader.Peek() != -1) { currentLine = layerCatalogReader.ReadLine(); // If the current line does not contain the delimiter, assume the end of the file has been reached if (!currentLine.Contains("=")) break; // Split the current line into the shapefile name and path and add this data to the data table layerSpecs = currentLine.Split(layerDelimiter); System.Data.DataRow dataRow = _layerDataTable.NewRow(); dataRow[0] = layerSpecs[0]; dataRow[1] = layerSpecs[1]; _layerDataTable.Rows.Add(dataRow); } layerCatalogReader.Close(); } } catch (System.Exception exception) { // Since the page has not yet rendered, we write the javascript to show an alert containing error info // directly to the page response string jsErrorAlert = string.Format("<script>{0}</script>", Utility.GetJavaScriptErrorString(exception)); Response.Write(jsErrorAlert); } } protected void Page_PreRender(object sender, System.EventArgs e) { try { // Bind DropDownList to data table containing layer names DropDownList1.DataSource = _layerDataTable; DropDownList1.DataTextField = "layerName"; DropDownList1.DataValueField = "layerPath"; DropDownList1.DataBind(); if (!Page.IsPostBack) { if (Session.IsNewSession) { // On initial page prerender, add session variables to track whether a layer was added and its id Session["dynamicLayerAdded"] = false; Session["addedLayerID"] = null; // Get the default map description from the server ESRI.ArcGIS.Server.IServerContext serverContext = this.GetServerContext(); ESRI.ArcGIS.Carto.IMapServer mapServer = serverContext.ServerObject as ESRI.ArcGIS.Carto.IMapServer; ESRI.ArcGIS.Carto.IMapServerInfo mapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName); ESRI.ArcGIS.Carto.IMapDescription aoMapDescription = mapServerInfo.DefaultMapDescription; // Create a new map image and display in the page CreateMapImage(serverContext, aoMapDescription); serverContext.ReleaseContext(); } else { // If this is not the initial page prerender, then the map image must be recreated with the // dynamically added layer, if one has been added. So we create the server context, get the // map description that's holding layer visibility information from session, add the dynamic // layer to the server state, create the map image based on server state, then remove the layer // from server state so it does not remain part of the map service ESRI.ArcGIS.Server.IServerContext serverContext = GetServerContext(); ESRI.ArcGIS.Carto.IMapServer mapServer = serverContext.ServerObject as ESRI.ArcGIS.Carto.IMapServer; ESRI.ArcGIS.Carto.IMapServerInfo mapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName); ESRI.ArcGIS.Carto.IMapDescription aoMapDescription = mapServerInfo.DefaultMapDescription; if ((bool)Session["dynamicLayerAdded"]) AddSelectedLayer(serverContext); CreateMapImage(serverContext, aoMapDescription); RemoveDynamicLayer(serverContext); serverContext.ReleaseContext(); } } } catch (System.Exception exception) { // Since the page has not yet rendered, we write the javascript to show an alert containing error info // directly to the page response string jsErrorAlert = string.Format("<script>{0}</script>", Utility.GetJavaScriptErrorString(exception)); Response.Write(jsErrorAlert); } } #endregion #region ASP.NET Web Control Event Handlers // Fires when the Add Layer button is clicked protected void AddLayer_Click(object sender, System.EventArgs e) { try { // Set the session variable indicating that a layer has been added during the current session Session["dynamicLayerAdded"] = true; // Add the currently selected layer to the map service ESRI.ArcGIS.Server.IServerContext serverContext = GetServerContext(); AddSelectedLayer(serverContext); // Create a map image. The image will contain the dynamic layer because that layer has been added // to the map service, meaning the default map description will include this layer. ESRI.ArcGIS.Carto.IMapServer mapServer = (ESRI.ArcGIS.Carto.IMapServer)serverContext.ServerObject; ESRI.ArcGIS.Carto.IMapServerInfo mapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName); ESRI.ArcGIS.Carto.IMapDescription aoMapDescription = mapServerInfo.DefaultMapDescription; CreateMapImage(serverContext, aoMapDescription); // Since we do not want to make a persistent change to the map service, we remove the layer once we // have created an image containing it RemoveDynamicLayer(serverContext); serverContext.ReleaseContext(); } catch (System.Exception exception) { // Since the page is in a full page postback, we write the javascript to show an alert containing error info // directly to the page response string jsErrorAlert = string.Format("<script>{0}</script>", Utility.GetJavaScriptErrorString(exception)); Response.Write(jsErrorAlert); } } // Fires when the Change Extent button is clicked protected void ChangeExtent_Click(object sender, System.EventArgs e) { try { // If a dynamic layer has been added during the current session, it needs to be re-added, since we // are not persistently adding the layer to the service ESRI.ArcGIS.Server.IServerContext serverContext = this.GetServerContext(); if ((bool)Session["dynamicLayerAdded"]) AddSelectedLayer(serverContext); // Get the map service's description and extent ESRI.ArcGIS.Carto.IMapServer mapServer = (ESRI.ArcGIS.Carto.IMapServer)serverContext.ServerObject; ESRI.ArcGIS.Carto.IMapServerInfo mapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName); ESRI.ArcGIS.Carto.IMapDescription mapDescription = mapServerInfo.DefaultMapDescription; ESRI.ArcGIS.Carto.IMapArea mapArea = mapDescription.MapArea; ESRI.ArcGIS.Carto.IMapExtent mapExtent = mapArea as ESRI.ArcGIS.Carto.IMapExtent; // Create a new envelope and update the service extent with it ESRI.ArcGIS.Geometry.IEnvelope aoEnvelope = (ESRI.ArcGIS.Geometry.IEnvelope)serverContext.CreateObject("esriGeometry.Envelope"); aoEnvelope.PutCoords(-120, 30, -50, 50); mapExtent.Extent = aoEnvelope; // Create a map image CreateMapImage(serverContext, mapDescription); // Since we do not want to make a persistent change to the map service, we remove the layer once we // have created the map image containing it RemoveDynamicLayer(serverContext); serverContext.ReleaseContext(); } catch (System.Exception exception) { // Since the page has not yet rendered, we write the javascript to show an alert containing error info // directly to the page response string jsErrorAlert = string.Format("<script>{0}</script>", Utility.GetJavaScriptErrorString(exception)); Response.Write(jsErrorAlert); } } #endregion #region Instance Methods // Retrieves the server context of the map service specified by the serverName and mapServiceName variables private ESRI.ArcGIS.Server.IServerContext GetServerContext() { string serverName = "localhost"; string mapServiceName = "USA"; ESRI.ArcGIS.Server.IServerObjectManager serverObjectManager; // Check whether the session variable storing the ServerObjectManager is null and initialize it if so. // This code only executes once because we only want to create one connection per session. if (Session["SOM"] == null) { // Using ADF connection library ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection agsServerConnection = new ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection(); agsServerConnection.Host = serverName; agsServerConnection.Connect(); serverObjectManager = agsServerConnection.ServerObjectManager; Session["SOM"] = serverObjectManager; } else { serverObjectManager = Session["SOM"] as ESRI.ArcGIS.Server.IServerObjectManager; } // Create a map server context with the specified map service name ESRI.ArcGIS.Server.IServerContext serverContext = serverObjectManager.CreateServerContext(mapServiceName, "MapServer"); return serverContext; } // Adds the currently selected layer to the map service private void AddSelectedLayer(ESRI.ArcGIS.Server.IServerContext serverContext) { // Use ArcObjects to get the ArcObjects map underlying the map service ESRI.ArcGIS.Carto.IMapServer mapServer = (ESRI.ArcGIS.Carto.IMapServer)serverContext.ServerObject; ESRI.ArcGIS.Carto.IMapServerObjects2 mapServerObjects = (ESRI.ArcGIS.Carto.IMapServerObjects2)mapServer; string mapName = mapServer.DefaultMapName; ESRI.ArcGIS.Carto.IMap aoMap = mapServerObjects.get_Map(mapName); // Retrieve the currently selected item and parse its value into the shapefile directory path and file name System.Web.UI.WebControls.ListItem listItem = DropDownList1.SelectedItem; int lastSlashIndex = listItem.Value.LastIndexOf("/"); string filePath = listItem.Value.Substring(0, lastSlashIndex); string fileName = listItem.Value.Substring(lastSlashIndex + 1); // Get a reference to the shapefile directory as an ArcObjects FeatureWorkspace ESRI.ArcGIS.Geodatabase.IWorkspaceFactory workspaceFactory = (ESRI.ArcGIS.Geodatabase.IWorkspaceFactory)serverContext.CreateObject("esriDataSourcesFile.ShapefileWorkspaceFactory"); ESRI.ArcGIS.Geodatabase.IWorkspace workspace = workspaceFactory.OpenFromFile(filePath, 0); ESRI.ArcGIS.Geodatabase.IFeatureWorkspace featureWorkspace = (ESRI.ArcGIS.Geodatabase.IFeatureWorkspace)workspace; // Get a reference to the shapefile as a GeoFeatureLayer ESRI.ArcGIS.Carto.IFeatureLayer aoFeatureLayer = (ESRI.ArcGIS.Carto.IFeatureLayer)serverContext.CreateObject("esriCarto.FeatureLayer"); // Or use the guid for esriCarto.FeatureLayer //IFeatureLayer layer = (IFeatureLayer)in_mapcontext.CreateObject("{E663A651-8AAD-11D0-BEC7-00805F7C4268}"); aoFeatureLayer.FeatureClass = featureWorkspace.OpenFeatureClass(fileName); aoFeatureLayer.Name = listItem.Text; ESRI.ArcGIS.Carto.IGeoFeatureLayer geoFeatureLayer = (ESRI.ArcGIS.Carto.IGeoFeatureLayer)aoFeatureLayer; // Create an ArcObjects color object with the color set to blue for use by the layer's renderer ESRI.ArcGIS.Display.IRgbColor rgbColor = (ESRI.ArcGIS.Display.IRgbColor)serverContext.CreateObject("esriDisplay.RgbColor"); rgbColor.Red = 0; rgbColor.Green = 0; rgbColor.Blue = 210; // Set the symbol of the GeoFeatureLayer's renderer to use the color initialized above ESRI.ArcGIS.Carto.ISimpleRenderer aoSimpleRenderer = (ESRI.ArcGIS.Carto.ISimpleRenderer)geoFeatureLayer.Renderer; ESRI.ArcGIS.Geometry.esriGeometryType geometryType = aoFeatureLayer.FeatureClass.ShapeType; if (geometryType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint) { ESRI.ArcGIS.Display.ISimpleMarkerSymbol simpleMarkerSymbol = (ESRI.ArcGIS.Display.ISimpleMarkerSymbol)aoSimpleRenderer.Symbol; simpleMarkerSymbol.Color = (ESRI.ArcGIS.Display.IColor)rgbColor; } else if (geometryType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline) { ESRI.ArcGIS.Display.ISimpleLineSymbol simpleLineSymbol = (ESRI.ArcGIS.Display.ISimpleLineSymbol)aoSimpleRenderer.Symbol; simpleLineSymbol.Color = (ESRI.ArcGIS.Display.IColor)rgbColor; } else if (geometryType == ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon) { ESRI.ArcGIS.Display.ISimpleFillSymbol simpleFillSymbol = (ESRI.ArcGIS.Display.ISimpleFillSymbol)aoSimpleRenderer.Symbol; simpleFillSymbol.Color = (ESRI.ArcGIS.Display.IColor)rgbColor; } else { throw new System.Exception("No renderer or symbol selected. Shape type undetermined."); } // Add the layer to the map service's map aoMap.AddLayer(aoFeatureLayer); mapServerObjects.RefreshServerObjects(); // Store the map service ID of the layer in session Session["addedLayerID"] = mapServerObjects.get_LayerID(mapName, aoFeatureLayer); } // Creates a JPEG image based on the passed-in server context and map description and sets the MapImage web // control to display it private void CreateMapImage(ESRI.ArcGIS.Server.IServerContext serverContext, ESRI.ArcGIS.Carto.IMapDescription aoMapDescription) { ESRI.ArcGIS.Carto.IImageType imageType; ESRI.ArcGIS.Carto.IImageDescription imageDescription; ESRI.ArcGIS.Carto.IImageDisplay imageDisplay; imageType = serverContext.CreateObject("esriCarto.ImageType") as ESRI.ArcGIS.Carto.IImageType; imageDescription = serverContext.CreateObject("esriCarto.ImageDescription") as ESRI.ArcGIS.Carto.ImageDescription; imageDisplay = serverContext.CreateObject("esriCarto.ImageDisplay") as ESRI.ArcGIS.Carto.ImageDisplay; // Set properties to have the image output a JPEG and refer to it via URL imageType.Format = ESRI.ArcGIS.Carto.esriImageFormat.esriImageJPG; imageType.ReturnType = ESRI.ArcGIS.Carto.esriImageReturnType.esriImageReturnURL; // Initialize image height and width based on the dimensions of the MapImage Image control imageDisplay.Height = (int)MapImage.Height.Value; imageDisplay.Width = (int)MapImage.Width.Value; imageDisplay.DeviceResolution = 96; imageDescription.Display = imageDisplay; imageDescription.Type = imageType; ESRI.ArcGIS.Carto.IMapServer mapServer = (ESRI.ArcGIS.Carto.IMapServer)serverContext.ServerObject; // Create the map image and set the MapImage control to display it ESRI.ArcGIS.Carto.IImageResult mapImage = mapServer.ExportMapImage(aoMapDescription, imageDescription); MapImage.ImageUrl = mapImage.URL; MapImage.Visible = true; } // Removes the dynamically added layer from the map service private void RemoveDynamicLayer(ESRI.ArcGIS.Server.IServerContext serverContext) { // Check whether a dynamic layer has been added during the session bool layerAdded = (bool)Session["dynamicLayerAdded"]; if (layerAdded) { // Retrieve the dynamic layer from the map service and delete it. Note that we know the layer has been // added at index 0, so we can safely delete the layer at this index. ESRI.ArcGIS.Carto.IMapServer mapServer = (ESRI.ArcGIS.Carto.IMapServer)serverContext.ServerObject; ESRI.ArcGIS.Carto.IMapServerObjects mapServerObjects = (ESRI.ArcGIS.Carto.IMapServerObjects)mapServer; ESRI.ArcGIS.Carto.IMap aoMap = mapServerObjects.get_Map(mapServer.DefaultMapName); ESRI.ArcGIS.Carto.ILayer aoLayer = aoMap.get_Layer(0); aoMap.DeleteLayer(aoLayer); mapServerObjects.RefreshServerObjects(); } } #endregion }