ArcGIS_AddDynamicData_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. ' ' 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 Partial Public Class _Default Inherits System.Web.UI.Page #Region "Instance Variable Declarations" Private _layerDataTable As System.Data.DataTable #End Region #Region "ASP.NET Page Life Cycle Event Handlers" Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) 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 (Not Page.IsPostBack) Then ' Create an empty data table to hold the shapefile names and paths _layerDataTable = New System.Data.DataTable("layerTable") Dim layerNameDataColumn As New System.Data.DataColumn("layerName") Dim layerPathDataColumn As 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 Dim rootPath As String = Server.MapPath("~") Dim layerCatalogPath As String = String.Format("{0}/layers.catalog", rootPath) ' Get a reader to access the layer catalog Dim layerCatalogReader As New System.IO.StreamReader(layerCatalogPath) ' Initialize the delimiter that separates shapefile names and paths in the layer catalog Dim layerDelimiterString As String = "=" Dim layerDelimiter() As Char = layerDelimiterString.ToCharArray() ' Iterate through the lines of the layer catalog, adding each pair of shapefile names and paths ' to the data table Dim layerSpecs() As String = Nothing Dim currentLine As String = Nothing Do 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 (Not currentLine.Contains("=")) Then Exit Do End If ' Split the current line into the shapefile name and path and add this data to the data table layerSpecs = currentLine.Split(layerDelimiter) Dim dataRow As System.Data.DataRow = _layerDataTable.NewRow() dataRow(0) = layerSpecs(0) dataRow(1) = layerSpecs(1) _layerDataTable.Rows.Add(dataRow) Loop layerCatalogReader.Close() End If Catch exception As System.Exception ' Since the page has not yet rendered, we write the javascript to show an alert containing error info ' directly to the page response Dim jsErrorAlert As String = String.Format("<script>{0}</script>", Utility.GetJavaScriptErrorString(exception)) Response.Write(jsErrorAlert) End Try End Sub Protected Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Try ' Bind DropDownList to data table containing layer names DropDownList1.DataSource = _layerDataTable DropDownList1.DataTextField = "layerName" DropDownList1.DataValueField = "layerPath" DropDownList1.DataBind() If (Not Page.IsPostBack) Then If Session.IsNewSession Then ' On initial page prerender, add session variables to track whether a layer was added and its id Session("dynamicLayerAdded") = False Session("addedLayerID") = Nothing ' Get the default map description from the server Dim serverContext As ESRI.ArcGIS.Server.IServerContext = Me.GetServerContext() Dim mapServer As ESRI.ArcGIS.Carto.IMapServer = TryCast(serverContext.ServerObject, ESRI.ArcGIS.Carto.IMapServer) Dim mapServerInfo As ESRI.ArcGIS.Carto.IMapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName) Dim aoMapDescription As ESRI.ArcGIS.Carto.IMapDescription = 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 Dim serverContext As ESRI.ArcGIS.Server.IServerContext = GetServerContext() Dim mapServer As ESRI.ArcGIS.Carto.IMapServer = TryCast(serverContext.ServerObject, ESRI.ArcGIS.Carto.IMapServer) Dim mapServerInfo As ESRI.ArcGIS.Carto.IMapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName) Dim aoMapDescription As ESRI.ArcGIS.Carto.IMapDescription = mapServerInfo.DefaultMapDescription If CBool(Session("dynamicLayerAdded")) Then AddSelectedLayer(serverContext) End If CreateMapImage(serverContext, aoMapDescription) RemoveDynamicLayer(serverContext) serverContext.ReleaseContext() End If End If Catch exception As System.Exception ' Since the page has not yet rendered, we write the javascript to show an alert containing error info ' directly to the page response Dim jsErrorAlert As String = String.Format("<script>{0}</script>", Utility.GetJavaScriptErrorString(exception)) Response.Write(jsErrorAlert) End Try End Sub #End Region #Region "ASP.NET Web Control Event Handlers" ' Fires when the Add Layer button is clicked Protected Sub AddLayer_Click(ByVal sender As Object, ByVal e As System.EventArgs) 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 Dim serverContext As ESRI.ArcGIS.Server.IServerContext = 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. Dim mapServer As ESRI.ArcGIS.Carto.IMapServer = CType(serverContext.ServerObject, ESRI.ArcGIS.Carto.IMapServer) Dim mapServerInfo As ESRI.ArcGIS.Carto.IMapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName) Dim aoMapDescription As ESRI.ArcGIS.Carto.IMapDescription = 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 exception As System.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 Dim jsErrorAlert As String = String.Format("<script>{0}</script>", Utility.GetJavaScriptErrorString(exception)) Response.Write(jsErrorAlert) End Try End Sub ' Fires when the Change Extent button is clicked Protected Sub ChangeExtent_Click(ByVal sender As Object, ByVal e As System.EventArgs) 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 Dim serverContext As ESRI.ArcGIS.Server.IServerContext = Me.GetServerContext() If CBool(Session("dynamicLayerAdded")) Then AddSelectedLayer(serverContext) End If ' Get the map service's description and extent Dim mapServer As ESRI.ArcGIS.Carto.IMapServer = CType(serverContext.ServerObject, ESRI.ArcGIS.Carto.IMapServer) Dim mapServerInfo As ESRI.ArcGIS.Carto.IMapServerInfo = mapServer.GetServerInfo(mapServer.DefaultMapName) Dim mapDescription As ESRI.ArcGIS.Carto.IMapDescription = mapServerInfo.DefaultMapDescription Dim mapArea As ESRI.ArcGIS.Carto.IMapArea = mapDescription.MapArea Dim mapExtent As ESRI.ArcGIS.Carto.IMapExtent = TryCast(mapArea, ESRI.ArcGIS.Carto.IMapExtent) ' Create a new envelope and update the service extent with it Dim aoEnvelope As ESRI.ArcGIS.Geometry.IEnvelope = CType(serverContext.CreateObject("esriGeometry.Envelope"), ESRI.ArcGIS.Geometry.IEnvelope) 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 exception As System.Exception ' Since the page has not yet rendered, we write the javascript to show an alert containing error info ' directly to the page response Dim jsErrorAlert As String = String.Format("<script>{0}</script>", Utility.GetJavaScriptErrorString(exception)) Response.Write(jsErrorAlert) End Try End Sub #End Region #Region "Instance Methods" ' Retrieves the server context of the map service specified by the serverName and mapServiceName variables Private Function GetServerContext() As ESRI.ArcGIS.Server.IServerContext Dim serverName As String = "localhost" Dim mapServiceName As String = "USA" Dim serverObjectManager As ESRI.ArcGIS.Server.IServerObjectManager ' 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") Is Nothing Then ' Using ADF connection library Dim agsServerConnection As New ESRI.ArcGIS.ADF.Connection.AGS.AGSServerConnection() agsServerConnection.Host = serverName agsServerConnection.Connect() serverObjectManager = agsServerConnection.ServerObjectManager Session("SOM") = serverObjectManager Else serverObjectManager = TryCast(Session("SOM"), ESRI.ArcGIS.Server.IServerObjectManager) End If ' Create a map server context with the specified map service name Dim serverContext As ESRI.ArcGIS.Server.IServerContext = serverObjectManager.CreateServerContext(mapServiceName, "MapServer") Return serverContext End Function ' Adds the currently selected layer to the map service Private Sub AddSelectedLayer(ByVal serverContext As ESRI.ArcGIS.Server.IServerContext) ' Use ArcObjects to get the ArcObjects map underlying the map service Dim mapServer As ESRI.ArcGIS.Carto.IMapServer = CType(serverContext.ServerObject, ESRI.ArcGIS.Carto.IMapServer) Dim mapServerObjects As ESRI.ArcGIS.Carto.IMapServerObjects2 = CType(mapServer, ESRI.ArcGIS.Carto.IMapServerObjects2) Dim mapName As String = mapServer.DefaultMapName Dim aoMap As ESRI.ArcGIS.Carto.IMap = mapServerObjects.Map(mapName) ' Retrieve the currently selected item and parse its value into the shapefile directory path and file name Dim listItem As System.Web.UI.WebControls.ListItem = DropDownList1.SelectedItem Dim lastSlashIndex As Integer = listItem.Value.LastIndexOf("/") Dim filePath As String = listItem.Value.Substring(0, lastSlashIndex) Dim fileName As String = listItem.Value.Substring(lastSlashIndex + 1) ' Get a reference to the shapefile directory as an ArcObjects FeatureWorkspace Dim workspaceFactory As ESRI.ArcGIS.Geodatabase.IWorkspaceFactory = CType(serverContext.CreateObject("esriDataSourcesFile.ShapefileWorkspaceFactory"), ESRI.ArcGIS.Geodatabase.IWorkspaceFactory) Dim workspace As ESRI.ArcGIS.Geodatabase.IWorkspace = workspaceFactory.OpenFromFile(filePath, 0) Dim featureWorkspace As ESRI.ArcGIS.Geodatabase.IFeatureWorkspace = CType(workspace, ESRI.ArcGIS.Geodatabase.IFeatureWorkspace) ' Get a reference to the shapefile as a GeoFeatureLayer Dim aoFeatureLayer As ESRI.ArcGIS.Carto.IFeatureLayer = CType(serverContext.CreateObject("esriCarto.FeatureLayer"), ESRI.ArcGIS.Carto.IFeatureLayer) ' 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 Dim geoFeatureLayer As ESRI.ArcGIS.Carto.IGeoFeatureLayer = CType(aoFeatureLayer, ESRI.ArcGIS.Carto.IGeoFeatureLayer) ' Create an ArcObjects color object with the color set to blue for use by the layer's renderer Dim rgbColor As ESRI.ArcGIS.Display.IRgbColor = CType(serverContext.CreateObject("esriDisplay.RgbColor"), ESRI.ArcGIS.Display.IRgbColor) rgbColor.Red = 0 rgbColor.Green = 0 rgbColor.Blue = 210 ' Set the symbol of the GeoFeatureLayer's renderer to use the color initialized above Dim aoSimpleRenderer As ESRI.ArcGIS.Carto.ISimpleRenderer = CType(geoFeatureLayer.Renderer, ESRI.ArcGIS.Carto.ISimpleRenderer) Dim geometryType As ESRI.ArcGIS.Geometry.esriGeometryType = aoFeatureLayer.FeatureClass.ShapeType If geometryType = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPoint Then Dim simpleMarkerSymbol As ESRI.ArcGIS.Display.ISimpleMarkerSymbol = CType(aoSimpleRenderer.Symbol, ESRI.ArcGIS.Display.ISimpleMarkerSymbol) simpleMarkerSymbol.Color = CType(rgbColor, ESRI.ArcGIS.Display.IColor) ElseIf geometryType = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolyline Then Dim simpleLineSymbol As ESRI.ArcGIS.Display.ISimpleLineSymbol = CType(aoSimpleRenderer.Symbol, ESRI.ArcGIS.Display.ISimpleLineSymbol) simpleLineSymbol.Color = CType(rgbColor, ESRI.ArcGIS.Display.IColor) ElseIf geometryType = ESRI.ArcGIS.Geometry.esriGeometryType.esriGeometryPolygon Then Dim simpleFillSymbol As ESRI.ArcGIS.Display.ISimpleFillSymbol = CType(aoSimpleRenderer.Symbol, ESRI.ArcGIS.Display.ISimpleFillSymbol) simpleFillSymbol.Color = CType(rgbColor, ESRI.ArcGIS.Display.IColor) Else Throw New System.Exception("No renderer or symbol selected. Shape type undetermined.") End If ' 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.LayerID(mapName, aoFeatureLayer) End Sub ' Creates a JPEG image based on the passed-in server context and map description and sets the MapImage web ' control to display it Private Sub CreateMapImage(ByVal serverContext As ESRI.ArcGIS.Server.IServerContext, ByVal aoMapDescription As ESRI.ArcGIS.Carto.IMapDescription) Dim imageType As ESRI.ArcGIS.Carto.IImageType Dim imageDescription As ESRI.ArcGIS.Carto.IImageDescription Dim imageDisplay As ESRI.ArcGIS.Carto.IImageDisplay imageType = TryCast(serverContext.CreateObject("esriCarto.ImageType"), ESRI.ArcGIS.Carto.IImageType) imageDescription = TryCast(serverContext.CreateObject("esriCarto.ImageDescription"), ESRI.ArcGIS.Carto.ImageDescription) imageDisplay = TryCast(serverContext.CreateObject("esriCarto.ImageDisplay"), 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 = CInt(Fix(MapImageOutput.Height.Value)) imageDisplay.Width = CInt(Fix(MapImageOutput.Width.Value)) imageDisplay.DeviceResolution = 96 imageDescription.Display = imageDisplay imageDescription.Type = imageType Dim mapServer As ESRI.ArcGIS.Carto.IMapServer = CType(serverContext.ServerObject, ESRI.ArcGIS.Carto.IMapServer) ' Create the map image and set the MapImage control to display it Dim mapImageout As ESRI.ArcGIS.Carto.IImageResult = mapServer.ExportMapImage(aoMapDescription, imageDescription) MapImageOutput.ImageUrl = mapImageout.URL MapImageOutput.Visible = True End Sub ' Removes the dynamically added layer from the map service Private Sub RemoveDynamicLayer(ByVal serverContext As ESRI.ArcGIS.Server.IServerContext) ' Check whether a dynamic layer has been added during the session Dim layerAdded As Boolean = CBool(Session("dynamicLayerAdded")) If layerAdded Then ' 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. Dim mapServer As ESRI.ArcGIS.Carto.IMapServer = CType(serverContext.ServerObject, ESRI.ArcGIS.Carto.IMapServer) Dim mapServerObjects As ESRI.ArcGIS.Carto.IMapServerObjects = CType(mapServer, ESRI.ArcGIS.Carto.IMapServerObjects) Dim aoMap As ESRI.ArcGIS.Carto.IMap = mapServerObjects.Map(mapServer.DefaultMapName) Dim aoLayer As ESRI.ArcGIS.Carto.ILayer = aoMap.Layer(0) aoMap.DeleteLayer(aoLayer) mapServerObjects.RefreshServerObjects() End If End Sub #End Region End Class