1,Arcgis地图组成,注记(Annotation),图形图层(GraphicsLayer),普通数据图层(我们称之为DataLayer)。
他们的叠放顺序分析:annotation和Graphicslayer都在数据图层之上,而且是始终在上面。annotation和Graphicslayer的顺序,我还不清楚。总之,现在我们可以得出,Graphicslayer在DataLayer之上。
2,所有的Graphicslayer都隶属于IMap对象,IPageLayout没有包含此类东西。Map对象有个默认的图形层,BasicGraphicslayer,类型为IGraphicslayer。通过它,我们可以得到map所有的图形层,方法如下:
p.BasicGraphicsLayer as ICompositeLayer;
for (int i = 0; i < cl.Count; i++)
{
ILayer lyr = cl.get_Layer(i);
IGraphicsLayer gl = lyr as IGraphicsLayer;
}
添加,删除Graphicslayer,是通过IComposteGraphicsLayer接口,
ICompositeGraphicsLayer cgl = _map.BasicGraphicsLayer as ICompositeGraphicsLayer;
cgl.DeleteLayer(LayerName);
1,Element前置、后置等改变顺序已经实现,但如果有多个Graphicslayer,则当前操作的Element所在的Layer必须是Map的ActiveGraphicslayer,否则函数会报异常。
而且只能在单个图层上改变顺序,想要直接前置到所有图层的最上面,可以把它“剪贴”到最上层或最下层,但此时元素已经脱离了原图层。
2,Element复制粘贴已经实现,支持跨图层粘贴。
3,图层移动还真不支持,目前还没想到其它可行办法。
直接贴代码了
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.SystemUI;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using DevExpress.XtraEditors;
using ESRI.ArcGIS.esriSystem;
namespace ElementResearch
{
public enum ChangeOrderType
{
BringToFront,SendToBack,BringForward,SendBackward
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
string mxd = System.IO.Path.Combine(Application.StartupPath, "data\\专题图.mxd");
axMapControl1.LoadMxFile(mxd);
}
private void Form1_Load(object sender, EventArgs e)
{
ICommand cmdGlobal = new ControlsMapFullExtentCommand();
cmdGlobal.OnCreate(axMapControl1.Object);
cmdGlobal.OnClick();
ITool select = new ControlsSelectToolClass();
((ICommand)select).OnCreate(axMapControl1.Object);
axMapControl1.CurrentTool = select;
}
private void axMapControl1_OnMouseUp(object sender, IMapControlEvents2_OnMouseUpEvent e)
{
if (e.button != 2)
{
return;
}
IGraphicsContainerSelect gcs = (IGraphicsContainerSelect)axMapControl1.Map;
if (gcs.ElementSelectionCount <= 0 && DViewClipboard.Data == null)
{
return;//没有选择元素就不弹出右键菜单
}
contextMenuStrip1.Show(MousePosition);
}
private void setElementOrder(ChangeOrderType type)
{
IGraphicsContainer gc = axMapControl1.ActiveView as IGraphicsContainer;
ILayer glayer = getGraphicslayer("省会城市");
if (glayer == null)
{
return;
}
//系统初始的时候,ActiveGraphicslayer是默认图层。
//所有改变元素顺序的操作,前提条件:元素所在的图层必须是活动图层。
axMapControl1.Map.ActiveGraphicsLayer = glayer;
IGraphicsContainerSelect gcs = (IGraphicsContainerSelect)axMapControl1.Map;
switch (type)
{
case ChangeOrderType.BringToFront:
gc.BringToFront(gcs.SelectedElements);
break;
case ChangeOrderType.SendToBack:
gc.SendToBack(gcs.SelectedElements);
break;
case ChangeOrderType.BringForward:
gc.BringForward(gcs.SelectedElements);
break;
case ChangeOrderType.SendBackward:
gc.SendBackward(gcs.SelectedElements);
break;
}
axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
private ILayer getGraphicslayer(string lyrName)
{
ICompositeGraphicsLayer cgl = axMapControl1.Map.BasicGraphicsLayer as ICompositeGraphicsLayer;
ICompositeLayer cl = cgl as ICompositeLayer;
for (int i = 0; i < cl.Count; i++)
{
ILayer lyr = cl.get_Layer(i);
if (lyr.Name == lyrName)
{
return lyr;
}
}
return null;
}
#region 改变顺序
private void 置于顶层ToolStripMenuItem_Click(object sender, EventArgs e)
{
setElementOrder(ChangeOrderType.BringToFront);
}
private void 置于底层ToolStripMenuItem_Click(object sender, EventArgs e)
{
setElementOrder(ChangeOrderType.SendToBack);
}
private void 上移一层ToolStripMenuItem_Click(object sender, EventArgs e)
{
setElementOrder(ChangeOrderType.BringForward);
}
private void 下移一层ToolStripMenuItem_Click(object sender, EventArgs e)
{
setElementOrder(ChangeOrderType.SendBackward);
}
#region 跨图层改变顺序
//GraphicsLayer列表,排在最上面(索引最小)的,在地图中其实在最底层,<默认>图层放最底层
//索引最大的,在地图中,在所有图层(具体说应该是图形层,而且图形层永远在地图层上面)的最上面。
//新添加的图形层,放到列表末尾,索引最大,所以放到最上层。
/*跨图层改变顺序思路:
类似剪切,粘贴操作。获取到元素后,克隆,再删除原来的,到目标层粘贴。但此时元素就不在原图层中了。
*/
private void 置于最顶层ToolStripMenuItem_Click(object sender, EventArgs e)
{
//找到最顶层
ICompositeLayer cl = axMapControl1.Map.BasicGraphicsLayer as ICompositeLayer;
ILayer topGraphicsLayer = cl.get_Layer(cl.Count - 1);
//克隆
IGraphicsContainerSelect gcs = (IGraphicsContainerSelect)axMapControl1.Map;
IClone clone = gcs.SelectedElements.Next() as IClone;
IElement ele = clone.Clone() as IElement;
//“粘贴”
IGraphicsContainer gc = topGraphicsLayer as IGraphicsContainer;
gc.AddElement(ele, 0);
axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
private void 置于最底层ToolStripMenuItem_Click(object sender, EventArgs e)
{
//最底层就是BasicGraphicslayer
}
#endregion
#endregion
private void 复制ToolStripMenuItem_Click(object sender, EventArgs e)
{
IGraphicsContainerSelect gcs = (IGraphicsContainerSelect)axMapControl1.Map;
DViewClipboard.Data = gcs.SelectedElements;
XtraMessageBox.Show("已经复制");
}
private void 粘贴ToolStripMenuItem_Click(object sender, EventArgs e)
{
ILayer lyr = getGraphicslayer("主要铁路");
IGraphicsContainer gc = lyr as IGraphicsContainer;
IGraphicsContainer gc2 = axMapControl1.Map as IGraphicsContainer;//活动图层
IEnumElement enele = DViewClipboard.Data as IEnumElement;
IElement ele = enele.Next();
while (null != ele)
{
IElement ele2 = cloneElement(ele);
//gc.AddElement(ele2,0);//粘贴到指定图层“主要铁路”
gc2.AddElement(ele2, 0);//粘贴到活动图层
offsetElement(ele2);
ele = enele.Next();
//gc.AddElements//批量操作
}
axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}
//克隆Element
private IElement cloneElement(IElement ele)
{
IClone clone = ele as IClone;
return clone.Clone() as IElement;
}
//偏移Element
private void offsetElement(IElement ele)
{
ITransform2D transform2D = ele as ITransform2D;
transform2D.Move(ele.Geometry.Envelope.XMin / 10, ele.Geometry.Envelope.YMin / 10);
}
}
}