您的位置:首页 > 运维架构

基于sharpdevelop核心和ArcEngine打造插件式桌面GIS应用之五——图层树

2012-05-22 17:30 489 查看
  这个系列好久没有更新了,时间拖得太久了,一来是工作确实忙,出差比较多;二来,最近公司有点动荡,部门独立出来成立一个公司,有些其他事情耽搁了;三来,懒。这篇文章将介绍一下图层树,图层树的英文简写是Toc,全程Table of content。

  ArcMap的TOC功能很强大,基本上我在实现TOC的时候,也是照虎画猫(我实现的这个和ArcMap比起来就是一只小猫,蛮丑的小猫)。闲话少扯,进入正题。

  Toc的功能包括:
  1、显示(调整)图层组织结构
  2、对图层的显示/隐藏状态进行控制
  3、提供针对图层的特殊操作,包括数据导出、选择集管理、属性设置等

  Toc控件本身较为简单,继承了UserControl的一个用户自定义控件,增加了图层顺序拖动调整的功能。通过与右键菜单的结合,展示出了丰富的功能。



  在实现右键菜单时,首先要获取在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,具体的右键菜单功能根据需求进行开发。

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: