Generate, update, and display diagrams within ArcGIS Server Schematics
ArcGIS_Schematics_ServingDiagrams_CSharp\App_Code\SchematicCommands.cs
// 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.
// 

using System.Web.UI;
using System.Web.UI.WebControls;
using esriWebControls = ESRI.ArcGIS.ADF.Web.UI.WebControls;
using ESRI.ArcGIS.ADF.Web.UI.WebControls;
using ESRI.ArcGIS.ADF.Web.UI.WebControls.Tools;
using esriAgsServer = ESRI.ArcGIS.ADF.ArcGISServer;
using ESRI.ArcGIS.ADF.Web.Geometry;
using ESRI.ArcGIS.ADF.Web.DataSources;
using ESRI.ArcGIS.ADF.Web.DataSources.ArcGISServer;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Server;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Schematic;


namespace SchematicCommands
{
  public class SelectViewType : IMapServerDropDownBoxAction
  {
    #region IServerAction Members

    public void ServerAction(ToolbarItemInfo info)
    {

      esriWebControls.DropDownBox dropBox = (esriWebControls.DropDownBox)info.Toolbar.ToolbarItems.Find("ViewTypeList");
      string viewTypeName = dropBox.SelectedValue;

      dropBox = (esriWebControls.DropDownBox)info.Toolbar.ToolbarItems.Find("DiagramList");
      dropBox.Items.Clear();

      esriWebControls.Map mapctrl = (esriWebControls.Map)(info.BuddyControls[0]);
      mapctrl.Page.Session["CurrentViewType"] = viewTypeName;
      mapctrl.Page.Session["DiagramFullExtent"] = null;

      // We have named the map resource managers like the view types
      Control control = info.Toolbar.Page.FindControl(viewTypeName);
      esriWebControls.MapResourceManager mapResMgr = (esriWebControls.MapResourceManager)control;

      mapctrl.MapResourceManagerInstance = mapResMgr;

      control = info.Toolbar.Page.FindControl("FloatingPanel1");
      esriWebControls.FloatingPanel taskPanel = (esriWebControls.FloatingPanel)control;

      if (viewTypeName == "GeographicMap")
      {
        dropBox.Disabled = true;
        mapctrl.Extent = mapctrl.GetFullExtent();
        //taskPanel.Visible = true;
      }
      else
      {
        dropBox.Disabled = false;

        MapResourceLocal gisresource = null;
        gisresource = (MapResourceLocal)(mapctrl.MapResourceManagerInstance.GetResource(0));

        foreach (esriAgsServer.LayerDescription layerDescription in gisresource.MapDescription.LayerDescriptions)
        {
          layerDescription.DefinitionExpression = "DIAGRAMOBJECTID=-1";
        }

        ISchematicDiagramClass schDiagramClass = Utilities.GetCurrentDiagramClass(mapctrl);

        IEnumSchematicDiagram schEnumDiagram = schDiagramClass.SchematicDiagrams;
        schEnumDiagram.Reset();

        dropBox.Items.Add(new ListItem());

        ISchematicDiagram schDiagram = schEnumDiagram.Next();
        while (schDiagram != null)
        {
          dropBox.Items.Add(new ListItem(schDiagram.Name, schDiagram.OID.ToString()));
          schDiagram = schEnumDiagram.Next();
        }

        dropBox.SelectedIndex = 0;
      }

      info.Toolbar.Refresh();

      control = info.Toolbar.Page.FindControl("Toc1");
      esriWebControls.Toc toc1 = (esriWebControls.Toc)control;
      toc1.Refresh();
      toc1.Nodes[0].Nodes[0].Text = "";

      mapctrl.CallbackResults.CopyFrom(toc1.CallbackResults);

      mapctrl.Refresh();

    } //ServerAction

    #endregion
  } //class SelectViewType


  public class SelectDiagram : IMapServerDropDownBoxAction
  {
    #region IServerAction Members

    public void ServerAction(ToolbarItemInfo info)
    {
      esriWebControls.DropDownBox dropBox = (esriWebControls.DropDownBox)info.Toolbar.ToolbarItems.Find("DiagramList");
      string diagramName = dropBox.SelectedItem.Text;
      string diagramID = dropBox.SelectedValue;

      if (diagramName == "")
        return;

      esriWebControls.Map mapctrl = (esriWebControls.Map)(info.BuddyControls[0]);
      string viewTypeName = mapctrl.Page.Session["CurrentViewType"].ToString();

      if (mapctrl.MapResourceManager != viewTypeName)
      {
        Control control = info.Toolbar.Page.FindControl(viewTypeName);
        mapctrl.MapResourceManagerInstance = (esriWebControls.MapResourceManager)control;
      }

      MapResourceLocal gisresource = null;
      gisresource = (MapResourceLocal)(mapctrl.MapResourceManagerInstance.GetResource(0));


      ISchematicDiagramClass schDiagramClass = Utilities.GetCurrentDiagramClass(mapctrl);

      IObjectClass objectClass = (IObjectClass)schDiagramClass;
      string diagramClassID = objectClass.ObjectClassID.ToString();

      // Change the definition query of each layer in order to display the selected diagram
      string definitionExpression = "DIAGRAMCLASSID=" + diagramClassID + " AND DIAGRAMOBJECTID=" + diagramID + " AND ISDISPLAYED = -1";

      foreach (esriAgsServer.LayerDescription layerDescription in gisresource.MapDescription.LayerDescriptions)
      {
        if (layerDescription.LayerID > 0)
        {
          layerDescription.DefinitionExpression = definitionExpression;
        }
      }

      Utilities.CalculateExtent(mapctrl, schDiagramClass, diagramName);
      mapctrl.Refresh();

      mapctrl.Page.Session["DiagramFullExtent"] = mapctrl.Extent;

      Control control1 = info.Toolbar.Page.FindControl("Toc1");
      esriWebControls.Toc toc1 = (esriWebControls.Toc)control1;

      // Change the diagram name in the toc
      toc1.Nodes[0].Nodes[0].Text = diagramName;

      // Redraw the toc : add a CallbackResult with the html content
      System.IO.StringWriter sw = new System.IO.StringWriter();
      HtmlTextWriter writer = new HtmlTextWriter(sw);

      toc1.RenderControl(writer);
      string htmlContent = sw.ToString();
      sw.Close();

      mapctrl.CallbackResults.Add(control1, "content", htmlContent);

      // In case the previous diagram is being updated, hide progress bar
      mapctrl.CallbackResults.Add(Utilities.ShowAjaxIndicator(false));

    } //ServerAction

    #endregion
  } //class SelectDiagram


  public class CustomFullExtent : IMapServerCommandAction
  {
    #region IServerAction Members

    public void ServerAction(ToolbarItemInfo info)
    {

      esriWebControls.Map mapctrl = (esriWebControls.Map)(info.BuddyControls[0]);

      string viewTypeName = mapctrl.Page.Session["CurrentViewType"].ToString();

      Envelope fullExtent = null;

      if (viewTypeName == "GeographicMap")
        mapctrl.Extent = mapctrl.GetFullExtent();
      else
        fullExtent = (Envelope)(mapctrl.Page.Session["DiagramFullExtent"]);

      if (fullExtent == null)
        return;

      if (mapctrl.MapResourceManager != viewTypeName)
      {
        Control control = info.Toolbar.Page.FindControl(viewTypeName);
        mapctrl.MapResourceManagerInstance = (esriWebControls.MapResourceManager)control;
      }

      mapctrl.Extent = fullExtent;

      mapctrl.Refresh();

    } //ServerAction

    #endregion
  } //class CustomFullExtent


  public class DiagramListUpdate : IMapServerCommandAction
  {
    #region IServerAction Members

    public void ServerAction(ToolbarItemInfo info)
    {

      esriWebControls.DropDownBox dropBox = (esriWebControls.DropDownBox)info.Toolbar.ToolbarItems.Find("ViewTypeList");
      string viewTypeName = dropBox.SelectedValue;

      if (viewTypeName == "GeographicMap")
        return;

      dropBox = (esriWebControls.DropDownBox)info.Toolbar.ToolbarItems.Find("DiagramList");
      dropBox.Items.Clear();

      esriWebControls.Map mapctrl = (esriWebControls.Map)(info.BuddyControls[0]);
      mapctrl.Page.Session["CurrentViewType"] = viewTypeName;
      mapctrl.Page.Session["DiagramFullExtent"] = null;

      // We have named the map resource managers like the view types
      Control control = info.Toolbar.Page.FindControl(viewTypeName);
      esriWebControls.MapResourceManager mapResMgr = (esriWebControls.MapResourceManager)control;

      mapctrl.MapResourceManagerInstance = mapResMgr;

      MapResourceLocal gisresource = null;
      gisresource = (MapResourceLocal)(mapctrl.MapResourceManagerInstance.GetResource(0));

      foreach (esriAgsServer.LayerDescription layerDescription in gisresource.MapDescription.LayerDescriptions)
      {
        layerDescription.DefinitionExpression = "DIAGRAMOBJECTID=-1";
      }

      ISchematicDiagramClass schDiagramClass = Utilities.GetCurrentDiagramClass(mapctrl);
      IEnumSchematicDiagram schEnumDiagram = schDiagramClass.SchematicDiagrams;

      schEnumDiagram.Reset();

      dropBox.Items.Add(new ListItem());

      ISchematicDiagram schDiagram = schEnumDiagram.Next();
      while (schDiagram != null)
      {
        dropBox.Items.Add(new ListItem(schDiagram.Name, schDiagram.OID.ToString()));
        schDiagram = schEnumDiagram.Next();
      }

      dropBox.SelectedIndex = 0;

      info.Toolbar.Refresh();

      control = info.Toolbar.Page.FindControl("Toc1");
      esriWebControls.Toc toc1 = (esriWebControls.Toc)control;
      toc1.Refresh();
      toc1.Nodes[0].Nodes[0].Text = "";

      mapctrl.CallbackResults.CopyFrom(toc1.CallbackResults);

      mapctrl.Refresh();

    } //ServerAction

    #endregion
  } //class DiagramListUpdate


  public class DiagramUpdate : IMapServerCommandAction
  {
    #region IServerAction Members

    public void ServerAction(ToolbarItemInfo info)
    {
      esriWebControls.Map mapctrl = (esriWebControls.Map)(info.BuddyControls[0]);

      System.Web.UI.Page page = info.Toolbar.Page;
      if (page.Session["UpdatingDiagram"] != null)
      {
        CallbackResult callbackResult = new CallbackResult(null, null, "javascript", "javascript", "alert('Previous update not yet finished')");
        mapctrl.CallbackResults.Add(callbackResult);
        return;
      }

      string diagramName = null;
      string diagramID = null;

      esriWebControls.DropDownBox dropBox = (esriWebControls.DropDownBox)info.Toolbar.ToolbarItems.Find("DiagramList");
      if (dropBox.SelectedIndex > 0)
      {
        diagramName = dropBox.SelectedItem.Text;
        diagramID = dropBox.SelectedValue;
      }

      if (string.IsNullOrEmpty(diagramName))
        return;

      // Initialize GP resource and functionality
      Control control = info.Toolbar.Page.FindControl("GeoprocessingResourceManager1");
      esriWebControls.GeoprocessingResourceManager gpResourceManager = (esriWebControls.GeoprocessingResourceManager)control;
      esriWebControls.GeoprocessingResourceItem gpResourceItem = (esriWebControls.GeoprocessingResourceItem)(gpResourceManager.ResourceItems[0]);

      if (gpResourceItem.FailedToInitialize)
      {
        string errorMessage = gpResourceItem.InitializationFailure.Message;
        CallbackResult callbackResultError = new CallbackResult(null, null, "javascript", "alert('Resource initialization exception: " + errorMessage + "')");
        mapctrl.CallbackResults.Add(callbackResultError);
        return;
      }

      IGeoprocessingResource gpResource = (IGeoprocessingResource)gpResourceItem.Resource;
      IGeoprocessingFunctionality gpFunctionality = (IGeoprocessingFunctionality)(gpResource.CreateFunctionality(typeof(IGeoprocessingFunctionality), null));
      GeoprocessingFunctionality agsGpFunctionality = (GeoprocessingFunctionality)gpFunctionality;

      string taskname = "Update";
      GPToolInfo adfGPToolInfo = agsGpFunctionality.GetTask(taskname);
      GPParameterInfo[] adfGPParamterInfoArray = adfGPToolInfo.ParameterInfo;

      // Set input parameter (diagram name) 
      GPString adfGPString = new GPString();
      adfGPString.Value = diagramName;

      // Submit Job
      GPValue[] adfGPValueArray = new GPValue[1];
      adfGPValueArray[0] = adfGPString;
      string jobID = agsGpFunctionality.SubmitJob(taskname, adfGPValueArray);

      mapctrl.CallbackResults.Add(Utilities.ShowAjaxIndicator(true));
      page.Session["UpdatingDiagram"] = diagramName;

      // Trigger an initial callback to check job status
      string diagramTypeName = page.Session["CurrentViewType"].ToString();
      string callbackFunctionString = page.ClientScript.GetCallbackEventReference(page, "message", "processCallbackResult", "context", "postBackError", true);
      string callbackReplaceString = callbackFunctionString.Replace("'", "\\'");
      string timerFunctionString = string.Format("window.setTimeout('checkJob(\"gpJobArgs={0},{1},{2},{3}\",\"{4}\")',3000);", jobID, diagramName, diagramID, diagramTypeName, callbackReplaceString);
      CallbackResult checkJobCallbackResult = new CallbackResult(page, "javascript", timerFunctionString);

      mapctrl.CallbackResults.Add(checkJobCallbackResult);

    } //ServerAction

    #endregion
  } //class DiagramUpdate


  public class Utilities
  {
    public static ISchematicDiagramClass GetCurrentDiagramClass(esriWebControls.Map mapctrl)
    {
      MapResourceLocal gisresource;
      gisresource = (MapResourceLocal)(mapctrl.MapResourceManagerInstance.GetResource(0));

      IMapServerObjects mso = (IMapServerObjects)(gisresource.MapServer);
      IMap map = mso.get_Map(gisresource.DataFrame);

      ISchematicLayer schLayer = (ISchematicLayer)(map.get_Layer(0));
      ISchematicDiagram schDiagram = schLayer.SchematicDiagram;

      return schDiagram.SchematicDiagramClass;

    } //GetCurrentDiagramClass


    public static void CalculateExtent(esriWebControls.Map mapctrl, ISchematicDiagramClass schDiagramClass, string diagramName)
    {
      ISchematicDiagram schDiagram;
      schDiagram = schDiagramClass.get_SchematicDiagramByName(diagramName);

      ISchematicElementContainer schEltContainer;
      schEltContainer = (ISchematicElementContainer)schDiagram;

      IEnumSchematicElement schElements = schEltContainer.SchematicElements;
      schElements.Reset();

      IFeature feature = null;
      ESRI.ArcGIS.Geometry.IEnvelope env = null;

      ISchematicElement schElement = schElements.Next();

      while (schElement != null)
      {
        feature = (IFeature)schElement;

        if (env == null)
          env = feature.Extent;
        else
          env.Union(feature.Extent);

        schElement = schElements.Next();
      }

      Envelope extent = mapctrl.Extent;

      if (env != null)
      {
        double dx = (env.XMax - env.XMin) * 0.05;
        double dy = (env.YMax - env.YMin) * 0.05;

        extent.XMin = env.XMin - dx;
        extent.XMax = env.XMax + dx;
        extent.YMin = env.YMin - dy;
        extent.YMax = env.YMax + dy;
      }

      mapctrl.Extent = extent;

    } //CalculateExtent


    public static CallbackResult ShowAjaxIndicator(bool visible)
    {
      string showIndicatorString = "document.getElementById('ProgressBar').style.visibility = ";

      if (visible)
        showIndicatorString += "'visible'";
      else
        showIndicatorString += "'hidden'";

      CallbackResult showIndicatorCallbackResult= new CallbackResult("div", "ProgressBar", "javascript", showIndicatorString);

      return showIndicatorCallbackResult;

    } //ShowAjaxIndicator

  } //class Utilities

} //namespace SchematicCommands