Common CustomDataSource
Common_CustomDataSource_CSharp\CustomDataSource_CSharp\REXMLDataSource_CSharp\MapFunctionality.cs
// Copyright 2007 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.
//

using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using ESRI.ArcGIS.ADF.Web.Geometry;
using ESRI.ArcGIS.ADF.Web.SpatialReference;
using ESRI.ArcGIS.ADF.Web.DataSources;
using System.Collections;

using ESRI.ArcGIS.ADF.Web.Display.Graphics;
using ESRI.ArcGIS.ADF.Web.Display.Drawing;
using ESRI.ArcGIS.ADF.Web;

namespace REXMLDataSource_CSharp
{
    public class MapFunctionality : IMapFunctionality
    {
        #region Constructor

        private GraphicsDataSet graphics = null;

        public MapFunctionality(string name, MapResource resource)
        {
            this.name = name;
            this.resource = resource;
        }

        public MapResource MapResource
        {
            get
            {
                return resource as MapResource;
            }
        }

        #endregion

        #region IMapFunctionality implementation

        #region Private Member Vars

        private DisplaySettings displaySettings = null;
        private System.Web.UI.WebControls.WebControl webControl = null;
        private bool maintainsState = false;
        private SpatialReference spatialReference = null;
        //private double scale;
        //private Dictionary<string, bool> layerVisibility = null;
        //private Units units;

        #endregion

        #region Public Properties

        public GraphicsDataSet GraphicsDataSet
        {
            get
            {
                if (!maintainsState)
                {
                    MapResource mr = MapResource;
                    return mr == null ? null : mr.Graphics;
                }
                else
                {
                    if (graphics != null)
                    {
                        return graphics;
                    }
                    else
                    {
                        MapResource mr = MapResource;

                        if (mr != null && mr.Graphics != null)
                        {
                            graphics = mr.Graphics.Clone();
                        }

                        return graphics;
                    }
                }
            }
        }

        public bool MaintainsState
        {
            get
            {
                return maintainsState;
            }
            set
            {
                maintainsState = value;
            }
        }

        public System.Web.UI.WebControls.WebControl WebControl
        {
            get { return webControl; }
            set { webControl = value; }
        }

        public DisplaySettings DisplaySettings
        {
            get
            {
                if (maintainsState)
                {
                    if (displaySettings == null)
                    {
                        displaySettings = (DisplaySettings)MapResource.DisplaySettings.Clone();
                    }
                    return displaySettings;
                }
                else return MapResource.DisplaySettings;
            }
            set
            {
                if (maintainsState) displaySettings = value;
                else MapResource.DisplaySettings = value;
            }
        }

        public ESRI.ArcGIS.ADF.Web.DataSources.Units Units
        {
            get { throw new NotImplementedException(); }
        }

        public object[] LayerIDs
        {
            get
            {
                if (GraphicsDataSet == null || GraphicsDataSet.Tables == null) return null;
                object[] layerIDs = new object[GraphicsDataSet.Tables.Count];
                for (int i = 0; i < GraphicsDataSet.Tables.Count; i++)
                {
                    layerIDs[i] = GraphicsDataSet.Tables[i].TableName;
                }
                return layerIDs;
            }
        }

        public SpatialReference SpatialReference
        {
            get
            {
                return spatialReference;
            }
            set
            {
                spatialReference = value;
            }
        }
        public double Rotation
        {
            get
            {
                return double.NaN;
            }
        }
        #endregion

        #region Public Methods

        public void ApplyStateToDataSourceObjects()
        {
            if (GraphicsDataSet != null)
            {
                if (DisplaySettings != null) GraphicsDataSet.ImageDescriptor = DisplaySettings.ImageDescriptor;
            }
        }

        public void GetStateFromDataSourceObjects()
        {
            if (GraphicsDataSet != null)
            {
                if (DisplaySettings != null) DisplaySettings.ImageDescriptor = GraphicsDataSet.ImageDescriptor;
            }
        }

        public void GetLayers(out string[] layerids, out string[] layernames)
        {
            throw new NotImplementedException();
        }

        public void GetVisibleScale(string layerid, out double minscale, out double maxscale)
        {
            // At a minimum, required for MapTips
            minscale = double.NaN;
            maxscale = double.NaN;
        }

        public double GetScale(ESRI.ArcGIS.ADF.Web.Geometry.Envelope extent, int mapWidth, int mapHeight)
        {
            throw new NotImplementedException();
        }

        public System.Collections.Generic.Dictionary<string, string> GetCopyrightText()
        {
            return new Dictionary<string, string>();
        }

        public ESRI.ArcGIS.ADF.Web.MapImage DrawExtent
            (ESRI.ArcGIS.ADF.Web.Geometry.Envelope extentToDraw)
        {
            if (GraphicsDataSet != null)
            {
                ApplyStateToDataSourceObjects();
                return GraphicsDataSet.DrawExtent(extentToDraw);
            }
            else return null;
        }

        private ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer getLayer(string layerID)
        {
            ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer graphicslayer =
              (ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicsLayer)GraphicsDataSet.Tables[layerID];
            return graphicslayer;
        }

        public bool GetLayerVisibility(string layerID)
        {
            return getLayer(layerID).Visible;
        }

        public void SetLayerVisibility(string layerID, bool visible)
        {
            getLayer(layerID).Visible = visible;
        }

        #endregion

        #endregion

        #region IGISFunctionality implementation

        private string name = string.Empty;
        private IGISResource resource = null;
        bool initialized = false;

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        public IGISResource Resource
        {
            get { return resource; }
            set { resource = value; }
        }

        public bool Initialized
        {
            get { return initialized; }
        }

        public void LoadState()
        {
            if (resource == null || resource.DataSource == null || resource.DataSource.State == null)
            {
                throw new Exception("The Resource associated with this functionality is not valid.");
            }

            // Shared properties with MapResource
            // - Display Settings
            // - DataSource objects: GraphicsDataSet

            // Shared properties with the DataSource objects
            // - DisplaySettings.ImageDescriptor

            // Dynamic properties - no need to address these in LoadState.
            // - LayerIDs, Scale, Rotation, Extent

            // Other properties, we need to store in state.
            // - WebControl
            // - MaintainsState
            // - SpatialReference

            // Load previous state if it was saved before.
            object o = resource.DataSource.State[key];
            if (o != null)
            {
                MapFunctionality mf = o as MapFunctionality;
                // Get the "other properties" (as noted above) from stored state.
                this.maintainsState = mf.MaintainsState;
                this.webControl = mf.WebControl;
                this.spatialReference = mf.spatialReference;
                // If maintainsState, load this functionalities own copies of the shared properties with the MapResource.
                if (maintainsState)
                {
                    displaySettings = mf.displaySettings;
                    graphics = mf.graphics;
                }
            }

            // Load shared properties with datasource objects. These will be initialized with values from the datasource objects
            GetStateFromDataSourceObjects();

            // Need to do anything here for the dynamic properties: LayerIDs, Scale and Rotation, Extent.
        }

        public void Initialize()
        {
            initialized = true;
        }

        public void SaveState()
        {
            if (resource == null) return;
            if (resource.DataSource == null) return;
            if (resource.DataSource.State == null) return;
            ApplyStateToDataSourceObjects();
            resource.DataSource.State[key] = this;
        }

        public void Dispose()
        {
            initialized = false;
        }

        public bool Supports(string operation)
        {
            if (operation == "GetScale")
                return false;
            return true;
        }

        #endregion

        #region Private Properties

        private string key
        {
            get
            {
                string szResource = resource.GetType().ToString() + ":" + resource.Name;
                string szThis = this.GetType().ToString() + ":" + name;
                return (szResource + "," + szThis);
            }
        }

        #endregion

    }
}