Common Custom data source
Common_CustomDataSource_VBNet\TiledMapDataSource_VBNet\MapInformation.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.
' 

Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.Xml
Imports ESRI.ArcGIS.ADF.Web.Display.Graphics
Imports ESRI.ArcGIS.ADF.Web.Geometry
Imports ESRI.ArcGIS.ADF.Web.SpatialReference
Imports ESRI.ArcGIS.ADF.Web.DataSources

Namespace TiledMapDataSource_VBNet
    Public Class MapInformation
        Implements IMapInformation
        Public Sub New(ByVal dataSourceDefinition As String, ByVal resourceDefinition As String)
            Me.dataSourceConfig = dataSourceDefinition
            resourceConfig = resourceDefinition
            parseConfig()
        End Sub

        Private dataSourceConfig As String = String.Empty
        Private resourceConfig As String = String.Empty
        Private defaultSpatialReference_Renamed As SpatialReference = Nothing
        Private tileCacheInfo_Renamed As TileCacheInfo = Nothing
        Private defaultExtent_Renamed, fullExtent_Renamed As Envelope

        Public ReadOnly Property DataFrame() As String Implements IMapInformation.DataFrame
            Get
                Return "(default)"
            End Get
        End Property

        Public ReadOnly Property DefaultSpatialReference() As SpatialReference Implements IMapInformation.DefaultSpatialReference
            Get
                Return defaultSpatialReference_Renamed
            End Get
        End Property

        Public ReadOnly Property DefaultExtent() As Envelope Implements IMapInformation.DefaultExtent
            Get
                Return defaultExtent_Renamed
            End Get
        End Property

        Public ReadOnly Property FullExtent() As Envelope Implements IMapInformation.FullExtent
            Get
                Return fullExtent_Renamed
            End Get
        End Property

        Public Property TileCacheInfo() As ESRI.ArcGIS.ADF.Web.DataSources.TileCacheInfo Implements IMapInformation.TileCacheInfo
            Get
                Return tileCacheInfo_Renamed
            End Get
            Set(ByVal value As ESRI.ArcGIS.ADF.Web.DataSources.TileCacheInfo)
                tileCacheInfo_Renamed = New TileCacheInfo(Value)
            End Set
        End Property

        Private Sub parseConfig()
            '      #Region "Get resource config nodes from document"
            Dim doc As XmlDocument = New XmlDocument()
            doc.Load(dataSourceConfig)
            Dim root As XmlNode = doc.DocumentElement 'TileCacheInfos

            Dim tileCacheNode As XmlNode = root.SelectSingleNode("TileCacheInfo")

            Dim cacheUrl As String = tileCacheNode.SelectSingleNode("URL").InnerText

            If tileCacheNode Is Nothing Then
                Throw New Exception("Could not find configuration for resource " & resourceConfig)
            End If

            Dim tileUrls As System.Collections.Generic.Dictionary(Of Integer, String) = New Dictionary(Of Integer, String)()
            Dim layers As System.Collections.Generic.Dictionary(Of String, String) = New Dictionary(Of String, String)()
            '      #End Region

            '      #Region "Tile Cache Info"
            Dim srNode As XmlNode = tileCacheNode.SelectSingleNode("SpatialReference")
            Dim srtext As String = srNode.SelectSingleNode("WKID").InnerText
            Dim srid As Integer
            If Int32.TryParse(srtext, srid) Then
                defaultSpatialReference_Renamed = New SpatialReference(srid)
            Else
                defaultSpatialReference_Renamed = New SpatialReference(srtext)
            End If

            Dim dpi As Integer = Convert.ToInt32(tileCacheNode.SelectSingleNode("DPI").InnerText)
            Dim width As Integer = Convert.ToInt32(tileCacheNode.SelectSingleNode("TileCols").InnerText)
            Dim height As Integer = Convert.ToInt32(tileCacheNode.SelectSingleNode("TileRows").InnerText)
            Dim originNode As XmlNode = tileCacheNode.SelectSingleNode("TileOrigin")
            Dim xmin As Double = Convert.ToDouble(originNode.SelectSingleNode("X").InnerText)
            Dim ymin As Double = Convert.ToDouble(originNode.SelectSingleNode("Y").InnerText)
            Dim origin As Point = New Point(xmin, ymin)

            Dim extentNode As XmlNode = tileCacheNode.SelectSingleNode("FullExtent")
            xmin = Convert.ToDouble(extentNode.Attributes("XMin").InnerText)
            ymin = Convert.ToDouble(extentNode.Attributes("YMin").InnerText)
            Dim xmax As Double = Convert.ToDouble(extentNode.Attributes("XMax").InnerText)
            Dim ymax As Double = Convert.ToDouble(extentNode.Attributes("YMax").InnerText)
            fullExtent_Renamed = New Envelope(xmin, ymin, xmax, ymax)
            fullExtent_Renamed.SpatialReference = defaultSpatialReference_Renamed

            extentNode = tileCacheNode.SelectSingleNode("DefaultExtent")
            xmin = Convert.ToDouble(extentNode.Attributes("XMin").InnerText)
            ymin = Convert.ToDouble(extentNode.Attributes("YMin").InnerText)
            xmax = Convert.ToDouble(extentNode.Attributes("XMax").InnerText)
            ymax = Convert.ToDouble(extentNode.Attributes("YMax").InnerText)
            defaultExtent_Renamed = New Envelope(xmin, ymin, xmax, ymax)
            defaultExtent_Renamed.SpatialReference = defaultSpatialReference_Renamed
            '      #End Region

            '      #Region "Layers"
            Dim layersNode As XmlNode = tileCacheNode.SelectSingleNode("Layers")
            If Not layersNode Is Nothing Then
                Dim layerNodes As XmlNodeList = layersNode.SelectNodes("Layer")
                If Not layerNodes Is Nothing Then
                    Dim la As Integer = 0
                    Do While la < layerNodes.Count
                        Dim layerId As String = layerNodes(la).Attributes("LayerID").InnerText
                        Dim layerName As String = layerNodes(la).Attributes("Name").InnerText
                        layers.Add(layerId, layerName)
                        la += 1
                    Loop
                End If
            End If
            '      #End Region

            '      #Region "LOD Info"
            Dim lodInfos As System.Collections.Generic.List(Of LodInfo) = New List(Of LodInfo)()
            Dim levels As System.Collections.Generic.Dictionary(Of Integer, Integer) = New Dictionary(Of Integer, Integer)()
            Dim lodInfoNode As XmlNode = tileCacheNode.SelectSingleNode("LODInfos")
            Dim lodInfoNodes As XmlNodeList = lodInfoNode.SelectNodes("LODInfo")
            Dim l As Integer = 0
            Do While l < lodInfoNodes.Count
                Dim levelid As Integer = Convert.ToInt32(lodInfoNodes(l).SelectSingleNode("LevelID").InnerText)
                levels.Add(l, levelid)
                Dim scale As Double = Convert.ToDouble(lodInfoNodes(l).SelectSingleNode("Scale").InnerText)
                Dim resolution As Double = Convert.ToDouble(lodInfoNodes(l).SelectSingleNode("Resolution").InnerText)

                Dim tileExtentWidth As Double = width * resolution
                Dim tileExtentHeight As Double = height * resolution

                Dim xOffset As Double = fullExtent_Renamed.XMin - origin.X
                If xOffset < 0 Then
                    xOffset = 0 'allows for full extent to extend to the left of the tile origin
                End If

                Dim minColumn As Integer = CInt(Fix(Math.Floor((xOffset) / tileExtentWidth))) '2 //-2

                Dim maxColumn As Integer = CInt(Fix(Math.Ceiling((fullExtent_Renamed.XMax - origin.X) / tileExtentWidth) - 1)) '4 //4
                Dim columns As Integer = maxColumn - minColumn + 1 '3 //7


                Dim yOffset As Double = origin.Y - fullExtent_Renamed.YMax
                If yOffset < 0 Then
                    yOffset = 0 'allows for full extent to extend to the left of the tile origin
                End If

                Dim minRow As Integer = CInt(Fix(Math.Floor((yOffset) / tileExtentHeight)))
                Dim maxRow As Integer = CInt(Fix(Math.Ceiling((origin.Y - fullExtent_Renamed.YMin) / tileExtentHeight) - 1))
                Dim rows As Integer = maxRow - minRow + 1

                Dim lodInfo As LodInfo = New LodInfo(levelid, resolution, scale, columns, rows, tileExtentWidth, tileExtentHeight)
                lodInfos.Add(lodInfo)
                l += 1
            Loop
            '      #End Region

            tileCacheInfo_Renamed = New TileCacheInfo(width, height, dpi, origin, lodInfos.ToArray())
            tileCacheInfo_Renamed.Layers = layers
            tileCacheInfo_Renamed.Levels = levels
            tileCacheInfo_Renamed.Url = cacheUrl

            Dim tileImageNode As XmlNode = tileCacheNode.SelectSingleNode("TileImageInfo")
            Dim imgFormat As String = tileImageNode.SelectSingleNode("CacheTileFormat").InnerText
            tileCacheInfo_Renamed.CacheTileFormat = imgFormat
        End Sub
    End Class
End Namespace