Common_CustomDataSource_VBNet\REXMLDataSource_VBNet\MapFunctionality.vb
' 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. ' Imports Microsoft.VisualBasic Imports System Namespace REXMLDataSource_VBNet ' Along with IGISDataSource and IGISResource, IGISFunctionality is one of the three required ' interfaces for any Web ADF Data Source implementation. This interface is responsible for ' providing members to functionally interact with the underlying data. Essentially, an ' IGISFunctionality implementation can be thought of as describing what can be done with the ' data. ' ' This particular implementation inherits from IMapFunctionality, which implements ' IGISFunctionality. IMapFunctionality provides methods and properties that are the foundation ' of map operations like zoom and pan. Public Class MapFunctionality Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality #Region "Instance Variables" Private m_displaySettings As ESRI.ArcGIS.ADF.Web.DisplaySettings = Nothing Private m_webControl As System.Web.UI.WebControls.WebControl = Nothing Private m_maintainsState As Boolean = False Private m_spatialReference As ESRI.ArcGIS.ADF.Web.SpatialReference.SpatialReference = Nothing Private m_name As String = String.Empty Private m_gisResource As ESRI.ArcGIS.ADF.Web.DataSources.IGISResource = Nothing Private m_initialized As Boolean = False Private m_graphicsDataSet As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet = Nothing #End Region #Region "Constructor" ' Constructor that initializes functionality name and the resource with which the ' functionality is associated Public Sub New(ByVal name As String, ByVal resource As REXMLDataSource_VBNet.MapResource) m_name = name m_gisResource = resource End Sub #End Region #Region "REXML MapFunctionality Members" ' Allows access to the MapResource object associated with the functionality Public ReadOnly Property MapResource() As REXMLDataSource_VBNet.MapResource Get Return TryCast(m_gisResource, REXMLDataSource_VBNet.MapResource) End Get End Property ' Key for storing and retrieving object state to and from the underlying data source's state table Private ReadOnly Property FunctionalityStateKey() As String Get Dim szResource As String = CType(m_gisResource, Object).GetType().ToString() & ":" & m_gisResource.Name Dim szThis As String = Me.GetType().ToString() & ":" & m_name Return (szResource & "," & szThis) End Get End Property ' Allows read access to the GraphicsDataSet containing the REXML data Public ReadOnly Property GraphicsDataSet() As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsDataSet Get ' Check whether the functionality maintains state If (Not m_maintainsState) Then ' Get a reference to the MapResource associated with the functionality Dim mapResource As REXMLDataSource_VBNet.MapResource = TryCast(m_gisResource, REXMLDataSource_VBNet.MapResource) ' If the MapResource's GraphicsDataSet is null, return null. Otherwise, ' return the dataset. If mapResource Is Nothing Then Return Nothing Else Return mapResource.Graphics End If Else ' check whether the functionality instance's graphics dataset is null If Not m_graphicsDataSet Is Nothing Then ' return the instance graphics dataset Return m_graphicsDataSet Else ' Get a reference to the MapResource associated with the functionality Dim mapResource As REXMLDataSource_VBNet.MapResource = TryCast(m_gisResource, REXMLDataSource_VBNet.MapResource) ' Make sure neither the MapResource nor the MapResource's graphics dataset ' are null If Not mapResource Is Nothing AndAlso Not mapResource.Graphics Is Nothing Then ' Initialize the instance's graphics dataset as a clone of the associated ' MapResource's m_graphicsDataSet = mapResource.Graphics.Clone() End If ' return the functionality instance's graphics dataset Return m_graphicsDataSet End If End If End Get End Property ' Returns the extent of the Web ADF Map Control associated with the functionality Public Function GetMapExtent() As ESRI.ArcGIS.ADF.Web.Geometry.Envelope ' Attempt to get a reference to the Map Control associated with the instance by casting ' the instance's WebControl member Dim adfMap As ESRI.ArcGIS.ADF.Web.UI.WebControls.Map = TryCast(m_webControl, ESRI.ArcGIS.ADF.Web.UI.WebControls.Map) ' If a reference was successfully established, return the contents of the control's Extent ' property. Otherwise, return null. If adfMap Is Nothing Then Return Nothing Else Return adfMap.Extent End If End Function ' Returns the screen width and height in pixels of the Web ADF Map Control associated ' with the functionality Public Sub GetMapDimensions(<System.Runtime.InteropServices.Out()> ByRef width As Integer, <System.Runtime.InteropServices.Out()> ByRef height As Integer) width = -1 height = -1 ' Attempt to get a reference to the Map Control associated with the instance by casting ' the instance's WebControl member Dim adfMap As ESRI.ArcGIS.ADF.Web.UI.WebControls.Map = TryCast(m_webControl, ESRI.ArcGIS.ADF.Web.UI.WebControls.Map) ' Make sure a reference to the Map Control was successfully established If adfMap Is Nothing Then Return End If ' Make sure the Map Control has a valid TilingScheme for the REXML resource If adfMap.GetTilingScheme(m_gisResource.Name) Is Nothing Then Return End If ' Set the width and height output parameters width = adfMap.GetTilingScheme(m_gisResource.Name).ViewWidth height = adfMap.GetTilingScheme(m_gisResource.Name).ViewHeight End Sub ' Allows internal retrieval by layer ID of a layer referenced by the functionality Private Function getLayer(ByVal layerID As String) As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer ' Cast the table in the functionality's graphics dataset at the passed-in layer ID ' to a Web ADF GraphicsLayer and return Dim adfGraphicsLayer As ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer = CType(m_graphicsDataSet.Tables(layerID), ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer) Return adfGraphicsLayer End Function #End Region #Region "IMapFunctionality Members" #Region "IMapFunctionality Properties" ' Allows read/write access to the flag indicating whether the functionality maintains state Public Property MaintainsState() As Boolean Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.MaintainsState Get Return m_maintainsState End Get Set(ByVal value As Boolean) m_maintainsState = Value End Set End Property ' Allows read/write access to the DisplaySettings of the MapResource instance associated with ' the functionality Public Property DisplaySettings() As ESRI.ArcGIS.ADF.Web.DisplaySettings Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.DisplaySettings Get ' Get a reference to the functionality's associated MapResource Dim rexmlMapResource As REXMLDataSource_VBNet.MapResource = TryCast(m_gisResource, REXMLDataSource_VBNet.MapResource) ' Check the flag indicating whether the functionality maintains state. If not, return ' the associated MapResource's DisplaySettings If m_maintainsState Then ' Check whether the functionality instance's DisplaySettings object has been initialized If m_displaySettings Is Nothing Then ' Set the instance's DisplaySettings object to a clone of the associated ' MapResource's DisplaySettings m_displaySettings = CType(rexmlMapResource.DisplaySettings.Clone(), ESRI.ArcGIS.ADF.Web.DisplaySettings) End If ' Return the functionality instance's DisplaySettings Return m_displaySettings Else Return rexmlMapResource.DisplaySettings End If End Get Set(ByVal value As ESRI.ArcGIS.ADF.Web.DisplaySettings) ' Get a reference to the functionality's associated MapResource Dim rexmlMapResource As REXMLDataSource_VBNet.MapResource = TryCast(m_gisResource, REXMLDataSource_VBNet.MapResource) ' Check whether the functionality maintains state. If so, set the functionality's ' DisplaySettings object to the passed-in value. If not, set the associated MapResource's ' DisplaySettings object to the passed-in value. If m_maintainsState Then m_displaySettings = Value Else rexmlMapResource.DisplaySettings = Value End If End Set End Property ' Not implemented here, but required to be stubbed out for implementations of IMapFunctionality. Public ReadOnly Property Units() As ESRI.ArcGIS.ADF.Web.DataSources.Units Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.Units Get Throw New System.NotImplementedException() End Get End Property ' Allows read access to the IDs of the layers referenced by the functionality's graphics dataset Public ReadOnly Property LayerIDs() As Object() Get ' Make sure neither the functionality's graphics dataset nor the graphics dataset's ' tables collection are null If m_graphicsDataSet Is Nothing OrElse m_graphicsDataSet.Tables Is Nothing Then Return Nothing End If ' Dimension the layer ID array with the number of tables in the functionality's ' graphics dataset 'INSTANT VB NOTE: The local variable layerIDs was renamed since Visual Basic will not allow local variables with the same name as their method: Dim layerIDs_Renamed As Object() = New Object(m_graphicsDataSet.Tables.Count - 1) {} ' Iterate through the tables in the functionality's graphics dataset, adding the ' name of each to the layer ID array Dim i As Integer = 0 Do While i < m_graphicsDataSet.Tables.Count layerIDs_Renamed(i) = m_graphicsDataSet.Tables(i).TableName i += 1 Loop Return layerIDs_Renamed End Get End Property ' Allows read/write access to the functionality's spatial reference Public Property SpatialReference() As ESRI.ArcGIS.ADF.Web.SpatialReference.SpatialReference Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.SpatialReference Get Return m_spatialReference End Get Set(ByVal value As ESRI.ArcGIS.ADF.Web.SpatialReference.SpatialReference) m_spatialReference = Value End Set End Property ' This implementation does not support rotation, but the property must be stubbed out ' in order to implement IMapFunctionality Public ReadOnly Property Rotation() As Double Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.Rotation Get Return Double.NaN End Get End Property #End Region #Region "IMapFunctionality Methods" ' Applies the ImageDescriptor of the functionality's display settings to its graphics dataset Public Sub ApplyStateToDataSourceObjects() Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.ApplyStateToDataSourceObjects ' Make sure the functionality's graphics dataset is not null If Not m_graphicsDataSet Is Nothing Then ' If the functionality's display settings object is not null, apply its ImageDescriptor ' to the graphics dataset. This is actually applying the ImageDescriptor to the ' underlying data source, since the graphics dataset references that of the data source. If Not m_displaySettings Is Nothing Then m_graphicsDataSet.ImageDescriptor = m_displaySettings.ImageDescriptor End If End If End Sub ' Retrieves the ImageDescriptor of the functionality's graphic dataset and applies it to the ' functionality's display settings Public Sub GetStateFromDataSourceObjects() Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.GetStateFromDataSourceObjects ' Make sure the instance's graphics dataset is not null If Not m_graphicsDataSet Is Nothing Then ' If the instance's display settings object is not null, set its ImageDescriptor to ' that of the instance's graphics dataset. This is actually retrieiving the ' ImageDescriptor from the underlying data source, since the graphics dataset references ' that of the data source. If Not m_displaySettings Is Nothing Then m_displaySettings.ImageDescriptor = m_graphicsDataSet.ImageDescriptor End If End If End Sub ' Retrieves the names and IDs of the layers referenced by the functionality instance Public Sub GetLayers(<System.Runtime.InteropServices.Out()> ByRef layerIDs As String(), <System.Runtime.InteropServices.Out()> ByRef layerNames As String()) Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.GetLayers layerNames = Nothing layerIDs = layerNames ' Make sure neither the instance's graphics dataset nor the graphics dataset's tables ' collection are null If m_graphicsDataSet Is Nothing OrElse m_graphicsDataSet.Tables Is Nothing Then Return End If ' Dimension the layer ID and names arrays with the number of tables in the graphics ' dataset's tables collection layerIDs = New String(m_graphicsDataSet.Tables.Count - 1) {} layerNames = New String(m_graphicsDataSet.Tables.Count - 1) {} ' Iterate through the graphics dataset's tables collection, storing the name of each ' in both the layer ID and names arrays. Note that for graphics layers, the layer ID ' is the same as the layer name. Dim i As Integer = 0 Do While i < m_graphicsDataSet.Tables.Count layerIDs(i) = m_graphicsDataSet.Tables(i).TableName layerNames(i) = m_graphicsDataSet.Tables(i).TableName i += 1 Loop Return End Sub ' Not meaningfully implemented here, but stubbed out in order to implement IMapFunctionality Public Sub GetVisibleScale(ByVal layerid As String, <System.Runtime.InteropServices.Out()> ByRef minscale As Double, <System.Runtime.InteropServices.Out()> ByRef maxscale As Double) Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.GetVisibleScale ' At a minimum, required for MapTips minscale = Double.NaN maxscale = Double.NaN End Sub ' Not implemented Public Function GetScale(ByVal extent As ESRI.ArcGIS.ADF.Web.Geometry.Envelope, ByVal mapWidth As Integer, ByVal mapHeight As Integer) As Double Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.GetScale Throw New System.NotImplementedException() End Function ' Not meaningfully implemented Public Function GetCopyrightText() As System.Collections.Generic.Dictionary(Of String, String) Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.GetCopyrightText Return New System.Collections.Generic.Dictionary(Of String, String)() End Function ' Returns a MapImage containing a map of the layers referenced by the functionality (in MIME ' data or as a url) at the passed-in extent Public Function DrawExtent(ByVal extentToDraw As ESRI.ArcGIS.ADF.Web.Geometry.Envelope) As ESRI.ArcGIS.ADF.Web.MapImage Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.DrawExtent ' Make sure the functionality instance's graphics dataset is not null If Not m_graphicsDataSet Is Nothing Then ' Update the state of the underlying data source ApplyStateToDataSourceObjects() ' Return the MapImage generated by the graphics dataset's DrawExtent method Return m_graphicsDataSet.DrawExtent(extentToDraw) Else Return Nothing End If End Function ' Returns the visibility of the layer with the passed-in ID Public Function GetLayerVisibility(ByVal layerID As String) As Boolean Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.GetLayerVisibility Return getLayer(layerID).Visible End Function ' Sets the visibility of the layer with the passed-in ID to the passed-in boolean Public Sub SetLayerVisibility(ByVal layerID As String, ByVal visible As Boolean) Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.SetLayerVisibility getLayer(layerID).Visible = visible End Sub #End Region #End Region #Region "IGISFunctionality Members" #Region "IGISFunctionality Properties" ' Allows read/write access to the functionality instance's name Public Property Name() As String Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.Name Get Return m_name End Get Set(ByVal value As String) m_name = Value End Set End Property ' Allows read/write access to the GISResource associated with the functionality instance Public Property Resource() As ESRI.ArcGIS.ADF.Web.DataSources.IGISResource Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.Resource Get Return m_gisResource End Get Set(ByVal value As ESRI.ArcGIS.ADF.Web.DataSources.IGISResource) m_gisResource = Value End Set End Property ' Allows read access to the instance member indicating whether the functionality has been initialized Public ReadOnly Property Initialized() As Boolean Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.Initialized Get Return m_initialized End Get End Property ' Allows retrieving or setting the WebControl associated with the functionality instance Public Property WebControl() As System.Web.UI.WebControls.WebControl Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.WebControl Get Return m_webControl End Get Set(ByVal value As System.Web.UI.WebControls.WebControl) m_webControl = Value End Set End Property #End Region #Region "IGISFunctionality Methods" ' Loads the state of the functionality object from the data source's state table Public Sub LoadState() Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.LoadState ' make sure references to the functionality's associated GISResource, the GISResource's ' underlying GISDataSource, and the GISDataSource's state table are all valid If m_gisResource Is Nothing OrElse m_gisResource.DataSource Is Nothing OrElse m_gisResource.DataSource.State Is Nothing Then Throw New System.Exception("The Resource associated with this functionality is not valid.") End If ' Some of the functionality instance's properties need to be explicitly stored in the state ' table, while others do not. An overview of these properties and the reasons for storing or ' not storing them is as follows: ' These properties are shared with and managed by the associated MapResource: ' - Display Settings ' - DataSource objects: GraphicsDataSet ' These properties are shared with and managed by the associated DataSource objects: ' - DisplaySettings.ImageDescriptor ' These properties are dynamic and therefore do not need to be stored in state: ' - LayerIDs ' - Scale ' - Rotation ' - Extent ' These properties are non-dynamic and exclusive to this instance, so they need to be ' stored in state: ' - WebControl ' - MaintainsState ' - SpatialReference ' Retrieve the functionality's state from the underlying data source's state table. The ' object state will be stored in the table at the index indicated by the private property ' FunctionalityStateKey Dim functionalityState As Object = m_gisResource.DataSource.State(FunctionalityStateKey) ' Check whether the state was found If Not functionalityState Is Nothing Then ' Cast the state object to a REXML MapFunctionality Dim rexmlMapFunctionality As REXMLDataSource_VBNet.MapFunctionality = TryCast(functionalityState, REXMLDataSource_VBNet.MapFunctionality) ' Get the properties stored in functionality state (as noted above) from stored state and ' assign them to the appropriate instance variables m_maintainsState = rexmlMapFunctionality.MaintainsState m_webControl = rexmlMapFunctionality.WebControl m_spatialReference = rexmlMapFunctionality.SpatialReference ' If maintainsState, retrieve this functionality's own copies of the properties that are ' shared with the associated MapResource instance and assign them to the appropriate ' instance variables If m_maintainsState Then m_displaySettings = rexmlMapFunctionality.DisplaySettings m_graphicsDataSet = rexmlMapFunctionality.GraphicsDataSet End If End If ' Load the properties that are shared with the instance's associated DataSource objects. ' This will initialize the relevant instance variables with values from those objects. GetStateFromDataSourceObjects() ' Any necessary logic for handling dynamic properties (listed above) would go here. End Sub ' Stores the functionality's state in the underlying data source's state table. Public Sub SaveState() Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.SaveState ' make sure references to the functionality's associated GISResource, the GISResource's ' underlying GISDataSource, and the GISDataSource's state table are all valid If m_gisResource Is Nothing Then Return End If If m_gisResource.DataSource Is Nothing Then Return End If If m_gisResource.DataSource.State Is Nothing Then Return End If ' Update the state of the underlying data source objects with relevant properties of the ' functionality instance ApplyStateToDataSourceObjects() ' Store the functionality instance in the data source's state table m_gisResource.DataSource.State(FunctionalityStateKey) = Me End Sub ' Set the flag indicating whether the functionality is intitialized to true. Any necessary ' start-up logic (i.e. instance variable initialization) should go here. Public Sub Initialize() Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.Initialize m_graphicsDataSet = Me.GraphicsDataSet m_initialized = True End Sub ' Set the flag indicating whether the functionality is intitialized to false. Any necessary ' disposal logic (e.g. releasing object references) should go here. Note that, if there is ' additional logic here, users of this class will have to EXPLCITLY call dispose. It is not ' invoked by other Web ADF components or the Page life-cycle. Public Sub Dispose() Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.Dispose m_initialized = False End Sub ' Retrieves boolean indicating whether the operation defined by the passed-in string is ' supported by this implementation. Here, only GetScale is explicitly not implemented. Public Function Supports(ByVal operation As String) As Boolean Implements ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality.Supports If operation = "GetScale" Then Return False End If Return True End Function #End Region #End Region End Class End Namespace