基於sharpdevelop核心和ArcEngine打造插件式桌面GIS應用之五——圖層樹


  這個系列好久沒有更新了,時間拖得太久了,一來是工作確實忙,出差比較多;二來,最近公司有點動盪,部門獨立出來成立一個公司,有些其他事情耽擱了;三來,懶。這篇文章將介紹一下圖層樹,圖層樹的英文簡寫是Toc,全程Table of content。

  ArcMap的TOC功能很強大,基本上我在實現TOC的時候,也是照虎畫貓(我實現的這個和ArcMap比起來就是一只小貓,蠻丑的小貓)。閑話少扯,進入正題。

 

  Toc的功能包括:
  1、顯示(調整)圖層組織結構
  2、對圖層的顯示/隱藏狀態進行控制
  3、提供針對圖層的特殊操作,包括數據導出、選擇集管理、屬性設置等

   Toc控件本身較為簡單,繼承了UserControl的一個用戶自定義控件,增加了圖層順序拖動調整的功能。通過與右鍵菜單的結合,展示出了豐富的功能。

Toc控件右鍵菜單

  在實現右鍵菜單時,首先要獲取在Toc中選中的對象類型及狀態,比如:如果選中的是FeatureLayer,那就可以進行數據導出、選擇集操作,如果選中的FeatureLayer對應的FeatureClass的GeometryType是Polygon,就顯示“設置為工作區域”菜單……

  要達到這個目的,就需要在Toc控件中對外公開一個當前選中對象的屬性—SelectItem。具體的定義如下:

public partial class TocControl : UserControl
{
	..........
		#region 屬性定義

        public object BuddyControl
        {
            get
            {
                return this.axTOCControl1.Buddy;
            }
            set
            {
                this.axTOCControl1.SetBuddyControl(value);
            }
        }

        /// <summary>
        /// 獲取當前圖層
        /// </summary>
        public ESRI.ArcGIS.Carto.ILayer CurrentLayer
        {
            get
            {
                return m_layer;
            }
        }

        private SelectItem selectedItem = null;

        /// <summary>
        /// 當前選中的對象
        /// </summary>
        public SelectItem SeletedItem
        {
            get
            {
                return this.selectedItem;
            }
        }

        #endregion

		private void GetSelectItem(int x,int y)
        {
            esriTOCControlItem item = esriTOCControlItem.esriTOCControlItemNone;
            ILayer layer = null;
            IBasicMap map = null;
            this.axTOCControl1.HitTest(x, y, ref item, ref map, ref layer, ref m_other, ref m_index);
            switch (item)
            {
                case esriTOCControlItem.esriTOCControlItemLayer:
                    this.selectedItem = new SelectItem(item, layer);                    
                    break;
                case esriTOCControlItem.esriTOCControlItemMap:
                    this.selectedItem = new SelectItem(item, map);
                    break;
                case esriTOCControlItem.esriTOCControlItemLegendClass:
                    this.selectedItem = new SelectItem(item, m_other);
                    break;
                case esriTOCControlItem.esriTOCControlItemHeading:
                    this.selectedItem = new SelectItem(item, null);
                    break;
                case esriTOCControlItem.esriTOCControlItemNone:
                    this.selectedItem = null;
                    break;
                default:
                    this.selectedItem = null;
                    break;
            }
        }

		public class SelectItem
        {
            public SelectItem(esriTOCControlItem type,object obj)
            {
                this.itemType = type;
                this.itemObject = obj;
            }

            private esriTOCControlItem itemType = esriTOCControlItem.esriTOCControlItemLayer;

            public esriTOCControlItem ItemType
            {
                get { return itemType; }
                set { itemType = value; }
            }
            private object itemObject = null;

            public object ItemObject
            {
                get { return itemObject; }
                set { itemObject = value; }
            }
        }
		
		..........
}

  接下來做的就是需要根據Toc的SelectItem類型進行菜單顯示狀態控制。大家或許已經猜到了實現方法——使用IConditionEvaluator。沒錯,在我的框架中,為Toc控件實現了兩個ConditionEvaluator,分別是TocItemSelectedConditionEvaluator和LayerFeatureSelectedConditionEvaluator。

  TocItemSelectedConditionEvaluator用來判斷Toc當前選中對象的具體類型,實現代碼:

 /// <summary>
    /// Toc控件選擇對象條件計算器
    /// Toc控件選擇對象類型包括:圖層:layer,feautrelayer,rasterlayer,grouplayer,地圖:map,圖例:legend
    /// wangyuxiang 2010-12-16
    /// </summary>
    class TocItemSelectedConditionEvaluator : IConditionEvaluator
	{
		public bool IsValid(object caller, Condition condition)
		{
			if (WorkbenchSingleton.Workbench == null) {
				return false;
			}
			
			string itemtype = condition.Properties["itemtype"];           

            GISP.Lib.ArcGIS.ArcMap.GUI.MapDisplayBinding.TocControl tocControl = null;

            foreach (PadDescriptor pad in WorkbenchSingleton.Workbench.PadContentCollection)
            {
                if (pad.PadContent != null &&  pad.PadContent.Control is GISP.Lib.ArcGIS.ArcMap.GUI.MapDisplayBinding.TocControl)
                {
                    tocControl = pad.PadContent.Control as GISP.Lib.ArcGIS.ArcMap.GUI.MapDisplayBinding.TocControl;
                    if (tocControl.SeletedItem != null)
                    {
                        if (itemtype == "*")
                        {
                            return true;
                        }
                        if (Convert.ToString(itemtype).ToLower().Equals("layer"))
                        {
                            return tocControl.SeletedItem.ItemType == ESRI.ArcGIS.Controls.esriTOCControlItem.esriTOCControlItemLayer;
                        }
                        else if (Convert.ToString(itemtype).ToLower().Equals("map"))
                        {
                            return tocControl.SeletedItem.ItemType == ESRI.ArcGIS.Controls.esriTOCControlItem.esriTOCControlItemMap;
                        }
                        else if (Convert.ToString(itemtype).ToLower().Equals("legend"))
                        {
                            return tocControl.SeletedItem.ItemType == ESRI.ArcGIS.Controls.esriTOCControlItem.esriTOCControlItemLegendClass;
                        }
                        else if (Convert.ToString(itemtype).ToLower().Equals("featurelayer"))
                        {
                            return (tocControl.SeletedItem.ItemType == ESRI.ArcGIS.Controls.esriTOCControlItem.esriTOCControlItemLayer && tocControl.SeletedItem.ItemObject is IFeatureLayer);
                        }
                        else if (Convert.ToString(itemtype).ToLower().Equals("rasterlayer"))
                        {
                            return (tocControl.SeletedItem.ItemType == ESRI.ArcGIS.Controls.esriTOCControlItem.esriTOCControlItemLayer && tocControl.SeletedItem.ItemObject is IRasterLayer);
                        }
                        else if (Convert.ToString(itemtype).ToLower().Equals("grouplayer"))
                        {
                            return (tocControl.SeletedItem.ItemType == ESRI.ArcGIS.Controls.esriTOCControlItem.esriTOCControlItemLayer && tocControl.SeletedItem.ItemObject is IGroupLayer);
                        }
                    }
                    break;
                }
            }
			return false;
		}
    }

    LayerFeatureSelectedConditionEvaluator用來判斷當前選中的FeatureLayer是否存在選擇集,實現代碼:

 /// <summary>
    /// 圖層要素選擇條件計算器    
    /// wangyuxiang 2010-12-17
    /// </summary>
    class LayerFeatureSelectedConditionEvaluator : IConditionEvaluator
	{
		public bool IsValid(object caller, Condition condition)
		{
			if (WorkbenchSingleton.Workbench == null) {
				return false;
            }
            GISP.Lib.ArcGIS.ArcMap.GUI.MapDisplayBinding.TocControl tocControl = null;

            foreach (PadDescriptor pad in WorkbenchSingleton.Workbench.PadContentCollection)
            {
                if (pad.PadContent.Control is GISP.Lib.ArcGIS.ArcMap.GUI.MapDisplayBinding.TocControl)
                {
                    tocControl = pad.PadContent.Control as GISP.Lib.ArcGIS.ArcMap.GUI.MapDisplayBinding.TocControl;
                    if (tocControl.SeletedItem != null)
                    {
                        if (tocControl.SeletedItem.ItemObject is IFeatureLayer)
                        {
                            IFeatureSelection featureSelection = tocControl.SeletedItem.ItemObject as IFeatureSelection;
                            if (featureSelection != null)
                            {
                                ISelectionSet selectionSet = featureSelection.SelectionSet;
                                return (selectionSet != null && selectionSet.Count > 0);
                            }
                        }
                    }
                    break;
                }
            }
			return false;
		}
    }

  整個右鍵菜單的Addin配置如下:

<!--二維地圖Toc控件右鍵菜單-->
  <Path name = "/SDF/Pads/ArcMap/TocPad/ContextMenu">
    <Condition name = "TocItemSelected" itemtype="layer">
      <MenuItem id    = "RemoveLayer"
                type="ContextMenu"
                label = "移除"
                icon="ArcGIS.LayerTreeDelete16"
                class = "GISP.Addin.ArcMap.Commands.TocCommand_RemoveSelectedLayer"/>
      <MenuItem id    = "RemoveLayer"
                type="ContextMenu"
               label = "標注"
               icon="ArcGIS.LayerTreeDelete16"
               class = "GISP.Addin.ArcMap.Commands.TocCommand_ShowLayerLabel"/>
      <ComplexCondition>
        <And>
          <Condition name = "TocItemSelected"  itemtype="featurelayer" action="Disable"/>
        </And>
        <MenuItem id    = "ZoomToLayer"
                  type="ContextMenu"
                 label = "查看屬性表"
                 icon ="ArcGIS.LayerTableOpen16"
                 class = "GISP.Addin.ArcMap.Commands.TocCommand_ShowLayerAttribute"/>
      </ComplexCondition>
      <MenuItem id    = "ZoomToLayer"
                type="ContextMenu"
               label = "縮放到圖層"
               icon="GIS.MapControl.FullScreen"
               class = "GISP.Addin.ArcMap.Commands.TocCommand_ZoomToSelectedLayer"/>
      <ComplexCondition>
        <And>
          <Condition name = "MapScaleOutOfLayerScale" action="Disable"/>
        </And>
        <MenuItem id    = "ZoomToVisible"
                  type="ContextMenu"
                 label = "縮放到圖層顯示比例尺"
                 class = "GISP.Addin.ArcMap.Commands.TocCommand_ZoomToShowLayer"/>
      </ComplexCondition>
      <ComplexCondition>
        <And>
          <Condition name = "TocItemSelected"  itemtype="featurelayer" action="Disable"/>
        </And>
        <MenuItem id    = "LayerSection" label = "選擇集" type ="Menu">
          <ComplexCondition>
            <And>
              <Condition name = "LayerFeatureSelected" action="Disable"/>
            </And>
            <MenuItem id    = "ZoomToSection"
                      type="ContextMenu"
                  label = "縮放到選中要素"
                  icon="ArcGIS.ScreenPosition16"
                  class = "GISP.Addin.ArcMap.Commands.TocCommand_ZoomToSelectedFeatures"/>
            <MenuItem id    = "PanToSection"
                      type="ContextMenu"
                  label = "移動到選中要素"
                  class = "GISP.Addin.ArcMap.Commands.TocCommand_PanToSelectedFeatures"/>
            <MenuItem id    = "ClearSelectFeatures"
                      type="ContextMenu"
                  label = "取消選中狀態"
                  class = "GISP.Addin.ArcMap.Commands.TocCommand_ClearFeaturelayerSelection"/>
            <MenuItem id    = "SwtichSelectFeatures"
                      type="ContextMenu"
                  label = "切換選中狀態"
                  class = ""/>
            <MenuItem id    = "AddSelectFeaturesToWorkArea"
                      type="ContextMenu"
                  label = "添加到工作區域"
                  class = "GISP.Addin.ArcMap.Commands.TocCommand_SetSelectFeaturesAsWorkAreas"/>
          </ComplexCondition>
          <ComplexCondition>
            <And>
              <Condition name = "WorkAreaIsValid" action="Disable"/>
            </And>
            <MenuItem id    = "selectIntersectWIthWorkArea"
                      type="ContextMenu"
                  label = "選擇工作區域內要素"
                      icon="ArcGIS.GenericAddGreen16"
                  class = "GISP.Addin.ArcMap.Commands.TocCommand_SelectFeaturesIntersectsWithWorkAreas"/>
          </ComplexCondition>
          <MenuItem id    = "SelectAllFeatures"
                    type="ContextMenu"
                label = "全部選中"
                    class = "GISP.Addin.ArcMap.Commands.TocCommand_SelectAllFeatures"/>
        </MenuItem>
      </ComplexCondition>
      <ComplexCondition>
        <And>
          <Condition name = "TocItemSelected"  itemtype="featurelayer" action="Disable"/>
        </And>
        <MenuItem id = "Separator"  type = "Separator" />
        <MenuItem id = "FeatureLayerData"

                label = "數據"
                icon="ArcGIS.ContentsWindowDrapedLayers16"
                type = "Menu">
          <MenuItem id = "ExportFeatureLayerData" type="ContextMenu" label = "導出" icon="ArcGIS.LayerToLayer16" class = "GISP.Addin.ArcMap.Commands.TocCommand_ExportFeatureLayer"/>
        </MenuItem>
        <MenuItem id = "SetAsWorkArea"
                  type="ContextMenu"
              label = "設置為工作區域"
                icon ="ArcGIS.GenericOptions16"
              class = "GISP.Addin.ArcMap.Commands.WorkArea_SetLayerAsWorkAreaCommand"/>

        <MenuItem id = "Separator"  type = "Separator" />
      </ComplexCondition>
    </Condition>
    <Condition name = "TocItemSelected" itemtype="*">
      <MenuItem id = "LayerProperties"
                type="ContextMenu"
              label = "屬性"
                icon ="ArcGIS.GenericOptions16"
              class = "GISP.Addin.ArcMap.Commands.TocCommand_ShowTocItemProperty"/>
    </Condition>
  </Path>

  至此Toc控件Over,具體的右鍵菜單功能根據需求進行開發。

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM