Common CustomDataSource
Common_CustomDataSource_CSharp\CustomDataSource_CSharp\REXMLDataSource_CSharp\MapResource.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;
using System.Xml;

namespace REXMLDataSource_CSharp
{
    public class MapResource : IMapResource
    {
        public MapResource() { }
        public MapResource(string name, GISDataSource dataSource)
        {
            this.name = name;
            this.dataSource = dataSource;
        }

        #region Graphics Resource Specific implementation
        private GraphicsDataSet graphics = null;

        public GraphicsDataSet Graphics
        {
            get { return graphics; }
        }
        #endregion

        #region IMapResource implementation

        private IMapInformation mapInformation = null;
        private DisplaySettings displaySettings = null;

        public IMapInformation MapInformation
        {
            get { return mapInformation; }
            set { mapInformation = value; }
        }

        public DisplaySettings DisplaySettings
        {
            get { return displaySettings; }
            set { displaySettings = value; }
        }

        #endregion

        #region IGISResource implementation

        bool initialized = false;
        private string name = string.Empty;
        private string resourceDefinition = string.Empty;
        private IGISDataSource dataSource = null;
        private GISFunctionalityCollection functionalities = new GISFunctionalityCollection();
        private int validationtimeout = 0;

        public int ValidationTimeout
        {
            get { return validationtimeout; }
            set { validationtimeout = value; }
        }

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

        public string ResourceDefinition
        {
            get { return resourceDefinition; }
            set { resourceDefinition = value; }
        }

        public IGISDataSource DataSource
        {
            get { return dataSource; }
            set { dataSource = value; }
        }

        public GISFunctionalityCollection Functionalities
        {
            get { return functionalities; }
            set { functionalities = value; }
        }

        public bool SupportsFunctionality(System.Type functionalityType)
        {
            if (functionalityType == typeof(ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality)) return true;
            else if (functionalityType == typeof(ESRI.ArcGIS.ADF.Web.DataSources.IMapTocFunctionality)) return true;
            else if (functionalityType == typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality)) return true;
            else return false;
        }

        public IGISFunctionality CreateFunctionality(System.Type functionalityType, string functionalityName)
        {
            IGISFunctionality gisfunctionality = null;
            if (functionalityType == typeof(ESRI.ArcGIS.ADF.Web.DataSources.IMapFunctionality))
            {
                gisfunctionality = new MapFunctionality(functionalityName, this);
            }
            else if (functionalityType == typeof(ESRI.ArcGIS.ADF.Web.DataSources.IMapTocFunctionality))
            {
                gisfunctionality = new MapTocFunctionality(functionalityName, this);
            }
            else if (functionalityType == typeof(ESRI.ArcGIS.ADF.Web.DataSources.IQueryFunctionality))
            {
                gisfunctionality = new QueryFunctionality(functionalityName, this);
            }
            else
            {
                throw new ArgumentException("functionalityType not supported");
            }
            return gisfunctionality;
        }

        public bool Initialized
        {
            get { return initialized; }
        }

        public void LoadState()
        {
            if (dataSource == null) return;
            if (dataSource.State == null) return;

            object o = dataSource.State[key];
            if (o != null)
            {
                MapResource mr = o as MapResource;
                graphics = mr.graphics;
                mapInformation = mr.mapInformation;
                displaySettings = mr.displaySettings;
            }
        }

        public void Initialize()
        {
            if (mapInformation == null)
            {
                graphics = new GraphicsDataSet();

                // To initialize once on load, use the following two lines
                //string dataSourceConfig = DataSource.DataSourceDefinition;
                //ProcessREXML(dataSourceConfig);
                

                mapInformation = new MapInformation(graphics);
                if (DisplaySettings != null) graphics.ImageDescriptor = 
                    displaySettings.ImageDescriptor;
            }
            initialized = true;
            
            /* To initialize and read from the data source during each postback, use the following lines.  
             * This will be valuable when data source content changes during a session.
             */

            string dataSourceConfig = DataSource.DataSourceDefinition;
            ProcessREXML(dataSourceConfig);
        }

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

        public void Dispose()
        {
            initialized = false;
        }


        public void ClearState()
        {
            if (DataSource == null || DataSource.State == null) return;
            DataSource.State[key] = null;
        }

        #endregion

        #region private Key Properties
        private string key
        {
            get
            {
                string tmp = this.GetType().ToString() + ":" + name;
                return (tmp);
            }
        }
        #endregion

        private void ProcessREXML(string dataSourceConfig)
        {
            try
            {
                #region Use FeatureGraphicsLayer for feature type (complex) graphics
                // Read xml data doc
                XmlDocument doc = new XmlDocument();
                doc.Load(dataSourceConfig);
                XmlNode root = doc.DocumentElement;

                // Get layer information
                XmlNode layerNode = root.SelectSingleNode("LAYER");
                string layername = layerNode.Attributes.GetNamedItem("name").Value;
                string layerid = layerNode.Attributes.GetNamedItem("id").Value;

                ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer glayer = null;
                bool gvisibility = true;

                // Create graphics layer to store features
                if (graphics.Tables.Contains(layername))
                {
                    if (graphics.Tables[layername] is FeatureGraphicsLayer)
                    {
                        FeatureGraphicsLayer fgl = (FeatureGraphicsLayer)graphics.Tables[layername];
                        // Get visibility of existing layer so when it is recreated, it's visibility is correct.  
                        // This will allow 1) setting visibility of the layer (checking\unchecking the node) in the toc 
                        // and 2) data to be updated each time the map resource is initialized.
                        gvisibility = fgl.Visible;
                    }
                   
                    graphics.Tables.Remove(layername);                
                }

                glayer = new ESRI.ArcGIS.ADF.Web.Display.Graphics.FeatureGraphicsLayer();
                glayer.TableName = layername;
                glayer.FeatureType = FeatureType.Point;
                glayer.Visible = gvisibility;

                // Get renderer information
                XmlNode rendererNode = layerNode.SelectSingleNode("SIMPLERENDERER");
                XmlNode markerNode = rendererNode.SelectSingleNode("SIMPLEMARKERSYMBOL");
                string markercolor = markerNode.Attributes.GetNamedItem("color").Value;
                string markertype = markerNode.Attributes.GetNamedItem("type").Value;
                string markerwidth = markerNode.Attributes.GetNamedItem("width").Value;
                string markeroutlinecolor = markerNode.Attributes.GetNamedItem("outlinecolor").Value;

                // Create symbol set
                ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol sms = new ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol();

                string[] markerrgb = markercolor.Split(',');
                int markerr = Int32.Parse(markerrgb[0]);
                int markerg = Int32.Parse(markerrgb[1]);
                int markerb = Int32.Parse(markerrgb[2]);
                sms.Color = System.Drawing.Color.FromArgb(markerr, markerg, markerb);

                switch (markertype)
                {
                    case "circle":
                        sms.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Circle;
                        break;
                    case "square":
                        sms.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Square;
                        break;
                    case "triangle":
                        sms.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Triangle;
                        break;
                    case "star":
                        sms.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Star;
                        break;
                    default:
                        break;
                }

                int markerwidthInt;
                if (!Int32.TryParse(markerwidth, out markerwidthInt))
                {
                    markerwidthInt = 10;
                }
                sms.Width = markerwidthInt;

                string[] markeroutrgb = markeroutlinecolor.Split(',');
                int markeroutr = Int32.Parse(markeroutrgb[0]);
                int markeroutg = Int32.Parse(markeroutrgb[1]);
                int markeroutb = Int32.Parse(markeroutrgb[2]);
                sms.OutlineColor = System.Drawing.Color.FromArgb(markeroutr, markeroutg, markeroutb);

                ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer sr = new ESRI.ArcGIS.ADF.Web.Display.Renderer.SimpleRenderer(sms);
                glayer.Renderer = sr;

                // Get features
                XmlNode featuresNode = layerNode.SelectSingleNode("FEATURES");
                XmlNodeList featureNodes = featuresNode.SelectNodes("FEATURE");

                // Get shape field and create GraphicElement
                for (int t = 0; t < featureNodes.Count; ++t)
                {
                    System.Data.DataRow datarow = null;

                    XmlNodeList flds = featureNodes[t].SelectNodes("FIELD");
                    for (int s = 0; s < flds.Count; s++)
                    {
                        // The SHAPE column should be first in the config file - to create the DataRow
                        if (flds[s].Attributes["name"].Value == "SHAPE")
                        {
                            XmlNodeList fldvalues = flds[s].SelectSingleNode("FIELDVALUE").ChildNodes;
                            if (fldvalues.Count < 1)
                            {
                                break;
                            }
                            else if (fldvalues.Count == 1)
                            {
                                XmlNode fldvalue = fldvalues[0];
                                if (fldvalue.Name == "POINT")
                                {
                                    double dx = Double.Parse(fldvalue.Attributes["x"].Value);
                                    double dy = Double.Parse(fldvalue.Attributes["y"].Value);

                                    ESRI.ArcGIS.ADF.Web.Geometry.Point point = new ESRI.ArcGIS.ADF.Web.Geometry.Point(dx, dy);
                                    datarow = glayer.Add(point);                                    
                                }
                            }
                            else if (fldvalues.Count > 1)
                            {

                            }
                        } else {

                            string fldname = flds[s].Attributes["name"].Value;
                            if (!glayer.Columns.Contains(fldname))
                            {
                                System.Data.DataColumn dcol = new System.Data.DataColumn("Status", System.Type.GetType("System.String"));
                                glayer.Columns.Add(dcol);
                            }
                            XmlNode fldvalue = flds[s].SelectSingleNode("FIELDVALUE");
                            string dvalue = fldvalue.Attributes["valuestring"].Value;
                            if ((dvalue != null) || (dvalue != String.Empty))
                                datarow[fldname] = dvalue;
                        }
                    }
                }

                graphics.Tables.Add(glayer);
                #endregion

                #region Use ElementGraphicsLayer for simple graphics
                /*
                ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer glayer = null;
                glayer = new ESRI.ArcGIS.ADF.Web.Display.Graphics.ElementGraphicsLayer();
                glayer.TableName = layername;

                // Get renderer information
                XmlNode rendererNode = layerNode.SelectSingleNode("SIMPLERENDERER");
                XmlNode markerNode = rendererNode.SelectSingleNode("SIMPLEMARKERSYMBOL");
                string markercolor = markerNode.Attributes.GetNamedItem("color").Value;
                string markertype = markerNode.Attributes.GetNamedItem("type").Value;
                string markerwidth = markerNode.Attributes.GetNamedItem("width").Value;
                string markeroutlinecolor = markerNode.Attributes.GetNamedItem("outlinecolor").Value;

                // Create symbol set
                ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol sms = new ESRI.ArcGIS.ADF.Web.Display.Symbol.SimpleMarkerSymbol();

                string[] markerrgb = markercolor.Split(',');
                int markerr = Int32.Parse(markerrgb[0]);
                int markerg = Int32.Parse(markerrgb[1]);
                int markerb = Int32.Parse(markerrgb[2]);
                sms.Color = System.Drawing.Color.FromArgb(markerr, markerg, markerb);

                switch (markertype)
                {
                    case "circle":
                        sms.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Circle;
                        break;
                    case "square":
                        sms.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Square;
                        break;
                    case "triangle":
                        sms.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Triangle;
                        break;
                    case "star":
                        sms.Type = ESRI.ArcGIS.ADF.Web.Display.Symbol.MarkerSymbolType.Star;
                        break;
                    default:
                        break;
                }

                int markerwidthInt;
                if (!Int32.TryParse(markerwidth, out markerwidthInt))
                {
                    markerwidthInt = 10;
                }
                sms.Width = markerwidthInt;

                string[] markeroutrgb = markeroutlinecolor.Split(',');
                int markeroutr = Int32.Parse(markeroutrgb[0]);
                int markeroutg = Int32.Parse(markeroutrgb[1]);
                int markeroutb = Int32.Parse(markeroutrgb[2]);
                sms.OutlineColor = System.Drawing.Color.FromArgb(markeroutr, markeroutg, markeroutb);

                // Get features
                XmlNode featuresNode = layerNode.SelectSingleNode("FEATURES");
                XmlNodeList featureNodes = featuresNode.SelectNodes("FEATURE");

                // Get shape field and create GraphicElement
                for (int t = 0; t < featureNodes.Count; ++t)
                {
                    XmlNodeList flds = featureNodes[t].SelectNodes("FIELD");
                    for (int s = 0; s < flds.Count; s++)
                    {
                        if (flds[s].Attributes["name"].Value == "SHAPE")
                        {
                            XmlNodeList fldvalues = flds[s].SelectSingleNode("FIELDVALUE").ChildNodes;
                            if (fldvalues.Count < 1)
                            {
                                break;
                            }
                            else if (fldvalues.Count == 1)
                            {

                                XmlNode fldvalue = fldvalues[0];
                                if (fldvalue.Name == "POINT")
                                {
                                    double dx = Double.Parse(fldvalue.Attributes["x"].Value);
                                    double dy = Double.Parse(fldvalue.Attributes["y"].Value);

                                    ESRI.ArcGIS.ADF.Web.Geometry.Point point = new ESRI.ArcGIS.ADF.Web.Geometry.Point(dx, dy);
                                    ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement ge = new ESRI.ArcGIS.ADF.Web.Display.Graphics.GraphicElement(point, sms);
                                    glayer.Add(ge);
                                }

                            }
                            else if (fldvalues.Count > 1)
                            {

                            }
                        }
                    }
                }

                graphics.Tables.Add(glayer);
                //*/
                #endregion
            }
            catch (Exception ex)
            {
                throw new Exception("Exception: unable to load rexml data. " + ex.Message);

            }

        }
    }
}