ArcEngine|实现图层交换功能与使用Itool封装功能

所有的代码已经传到了我的GitHub,需要的请自取,GitHub项目地址:https://github.com/weltme/T_ArcMap

1 图层功能

1.1 实现图层顺序交换功能

(1)功能分析

图层顺序交换场景和功能:

首先鼠标在TOCControl范围中,并单击左键不放,对图层进行拖拽。如果拖拽后鼠标从选中图层标题处移动至其他图层的位置时,可将选中图层与先前的图层互换。另外,当鼠标向下移动时显示为向下的黑色箭头,向上移动时显示为向上的黑色箭头,当遇到可交换的图层时,鼠标显示为黑色的横线。

(2)添加资源文件

在工程中新建文件夹Resources

image-20230322170611859

在Properties中导入资源图片:

ArcEngine→Properties→资源→添加资源→添加现有文件→资源图片

image-20230322170753842

(3)代码分析及其实现

OnMouseDown:
代码实现:

void _tocControl_OnMouseDown(object sender, ITOCControlEvents_OnMouseDownEvent e)
{
    _tocControl.HitTest(e.x, e.y, ref itemType, ref map, ref _hitTestLayer, ref other, ref index);
    if (_hitTestLayer != null /*&& itemType == esriTOCControlItem.esriTOCControlItemLayer */)
    {
        _mouseDownLayer = _hitTestLayer;
    }
    if (e.button == 1)
    {
        this.leftIsDowm = true;
        this.initialY = e.y;
        //记录初始的index值
        int Move2Index;
        for (Move2Index = 0; Move2Index < map.LayerCount; Move2Index++)
        {
            if (map.get_Layer(Move2Index) == _hitTestLayer)
            {
                break;
            }
        }
        initialIndex = Move2Index;
    }
    else if (e.button == 2)
    {
        switch (itemType)
        {
            case esriTOCControlItem.esriTOCControlItemHeading:
                break;
            case esriTOCControlItem.esriTOCControlItemLayer:

                _layerPopMenu.Show(_tocControl, e.x, e.y);

                break;
            case esriTOCControlItem.esriTOCControlItemLegendClass:
                this._legentPopMenu.Show(_tocControl, e.x, e.y);
                break;
            case esriTOCControlItem.esriTOCControlItemMap:
                this._mapPopMenu.Show(_tocControl, e.x, e.y);
                break;
            case esriTOCControlItem.esriTOCControlItemNone:
                break;
            default:
                break;
        }
    }
    else
    {
        return;
    }
}

思路分析:
在按下左键后,传入leftIsDowm和initialY变量的值,并将二者分别设置为true和当前指针的y值。

OnMouseMove:

代码实现:

void _tocControl_OnMouseMove(object sender, ITOCControlEvents_OnMouseMoveEvent e)
{

    if (this.leftIsDowm == true)
    {
        _tocControl.HitTest(e.x, e.y, ref itemType, ref map, ref _hitTestLayer, ref other, ref index);

        if (itemType == esriTOCControlItem.esriTOCControlItemLayer && _hitTestLayer != null)
        {
            if (_tocControl.MousePointer != esriControlsMousePointer.esriPointerCustom)
            {
                _tocControl.MousePointer = esriControlsMousePointer.esriPointerCustom;
            }
            _tocControl.MouseIcon = TArcMap.Properties.Resources.GenericBlackSubtractSmall;
        }
        else
        {
            if (_tocControl.MousePointer != esriControlsMousePointer.esriPointerCustom)
            {
                _tocControl.MousePointer = esriControlsMousePointer.esriPointerCustom;
            }
            if (e.y > this.initialY)
            {
                _tocControl.MouseIcon = TArcMap.Properties.Resources.GenericBlackArrowDown;
            }
            else
            {
                _tocControl.MouseIcon = TArcMap.Properties.Resources.GenericBlackArrowUp;
            }
        }
    }
}

思路分析:
首先判断鼠标是否在图层的标题上,如果在则将鼠标的图标设置成黑色短线;如果不在,则判断鼠标的位置和初始位置之间的关系(对比y值),如果现在的位置在原始的之上,则变成向上的黑色箭头,反之变成向下的黑色箭头。
OnMouseUp:
代码实现:

void _tocControl_OnMouseUp(object sender, ITOCControlEvents_OnMouseUpEvent e)
{
    if (e.button == 1)
    {
        this.leftIsDowm = false;
        _tocControl.MousePointer = esriControlsMousePointer.esriPointerDefault;
        if (_mouseDownLayer != null)
        {
            _tocControl.HitTest(e.x, e.y, ref itemType, ref map, ref _hitTestLayer, ref other, ref index);
            if (_hitTestLayer != null && itemType == esriTOCControlItem.esriTOCControlItemLayer)
            {
                //移动图层
                /*
                    int Move2Index;
                    for (Move2Index = 0; Move2Index < map.LayerCount; Move2Index++)
                    {
                        if (map.get_Layer(Move2Index) == _hitTestLayer)
                        {
                            break;
                        }
                    }
                    IMap curMap = map as IMap;
                    curMap.MoveLayer(_mouseDownLayer, Move2Index);
                    */
                //交换图层
                int Move2Index;
                for (Move2Index = 0; Move2Index < map.LayerCount; Move2Index++)
                {
                    if (map.get_Layer(Move2Index) == _hitTestLayer)
                    {
                        break;
                    }
                }
                move2Layer = map.get_Layer(Move2Index);
                IMap curMap = map as IMap;
                curMap.MoveLayer(_mouseDownLayer, Move2Index);
                curMap.MoveLayer(move2Layer, initialIndex);
            }
            else
            {
                return;
            }
        }
        else
        {
            return;
        }
    }
}

思路分析:
首先利用if语句进行条件判断,如果鼠标左键按下且抬起,记录下图层的索引,与之前记录的图层交换位置。

2 ITool实现地图缩放

2.1 放大

(1)新建项

新建文件夹(Navigation)→添加→新建项

image-20230322204555607

(2)新建Base Tool

已安装的模板→ArcGIS→Extending ArcObjects→Base Tool

image-20230325163925444

(3)BaseTool内部功能实现

在OnMouseDown下填充如下图所示的内容:

按圆形放大:

public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
    IMapControl2 mapControl = m_hookHelper.Hook as IMapControl2;
    IGeometry circle = mapControl.TrackCircle();
    mapControl.Extent = circle.Envelope;
    mapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
}

按多边形放大:

public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
    IMapControl2 mapControl = m_hookHelper.Hook as IMapControl2;
    IGeometry circle = mapControl.TrackPolygon();
    mapControl.Extent = circle.Envelope;
    mapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
}

按矩形放大:

public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
    IMapControl2 mapControl = m_hookHelper.Hook as IMapControl2;
    IGeometry Rectangle = mapControl.TrackRectangle();
    mapControl.Extent = Rectangle.Envelope;
    mapControl.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
}

2.2 缩小

(1)在navigation文件夹中新建所有Tool

image-20230322215836942

(3)缩小功能的封装

//封装缩小方法:zoom_out函数,以便对于不同的形状进行缩小操作。
public static IEnvelope zoom_out(IMapControl2 mapcontrol, IEnvelope pEnvelop)
{
    double x_scale = mapcontrol.Extent.Width / pEnvelop.Width;//XY尺寸
    double y_scale = mapcontrol.Extent.Height / pEnvelop.Width;
    //新窗口的高度宽度=原地图窗口*比例
    double width = mapcontrol.Extent.Width * x_scale;
    double height = mapcontrol.Extent.Width * y_scale;
    //找到窗口的最小值 即XY的最小值
    double x_min = pEnvelop.XMin - (pEnvelop.XMin - mapcontrol.Extent.XMin) * x_scale;
    double y_min = pEnvelop.YMin - (pEnvelop.YMin - mapcontrol.Extent.YMin) * y_scale;

    //取矩形框的取最大值
    double x_max = x_min + width;
    double y_max = y_min + height;

    //新的envelop
    pEnvelop.PutCoords(x_min, y_min, x_max, y_max);
    return pEnvelop;
}

(3)BaseTool内部功能实现

在OnMouseDown事件下填充如下图所示内容

按圆形缩小:

public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
    IMapControl2 mapControl = m_hookHelper.Hook as IMapControl2;
    IGeometry Circle = mapControl.TrackCircle();
    IEnvelope pEnvelop = Circle.Envelope;
    if (pEnvelop == null || pEnvelop.IsEmpty || pEnvelop.Height == 0 || pEnvelop.Width == 0)
    {
        return;
    }
    IEnvelope pEnvelop2_1 = CoClass.zoom_out(mapControl, pEnvelop);
    mapControl.Extent = pEnvelop2_1;
    mapControl.Refresh();
}

按多边形缩小:

public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
    IMapControl2 mapControl = m_hookHelper.Hook as IMapControl2;
    IGeometry Circle = mapControl.TrackPolygon();
    IEnvelope pEnvelop = Circle.Envelope;
    if (pEnvelop == null || pEnvelop.IsEmpty || pEnvelop.Height == 0 || pEnvelop.Width == 0)
    {
        return;
    }
    IEnvelope pEnvelop_1 = CoClass.zoom_out(mapControl, pEnvelop);
    mapControl.Extent = pEnvelop_1;
    mapControl.Refresh();
}

按矩形缩小:

public override void OnMouseDown(int Button, int Shift, int X, int Y)
{
    IMapControl2 mapControl = m_hookHelper.Hook as IMapControl2;
    IGeometry Circle = mapControl.TrackRectangle();
    IEnvelope pEnvelop = Circle.Envelope;
    if (pEnvelop == null || pEnvelop.IsEmpty || pEnvelop.Height == 0 || pEnvelop.Width == 0)
    {
        return;
    }
    IEnvelope pEnvelop_1 = CoClass.zoom_out(mapControl, pEnvelop);
    mapControl.Extent = pEnvelop_1;
    mapControl.Refresh();
}

3.2.3 主界面调用Tool

在主界面的菜单项的点击事件下调用之前写好的navigation文件夹中的Tool:

//定义按矩形框放大ToolStripMenuItem_Click事件
private void 按矩形框放大ToolStripMenuItem_Click(object sender, EventArgs e)
{
    TArcMap.navigation.ZoomInByRectangle tool1 = new TArcMap.navigation.ZoomInByRectangle();
    tool1.OnCreate(axMapControl1.Object);
    axMapControl1.CurrentTool = tool1;
}

//定义按矩形框缩小ToolStripMenuItem_Click事件
private void 按矩形框缩小ToolStripMenuItem_Click(object sender, EventArgs e)
{
    TArcMap.navigation.ZoomOutByRectangle tool1 = new TArcMap.navigation.ZoomOutByRectangle();
    tool1.OnCreate(axMapControl1.Object);
    axMapControl1.CurrentTool = tool1;
}

//定义按多边形放大ToolStripMenuItem_Click事件
private void 按多边形放大ToolStripMenuItem_Click(object sender, EventArgs e)
{
    TArcMap.navigation.ZoomInByPolygon tool1 = new TArcMap.navigation.ZoomInByPolygon();
    tool1.OnCreate(axMapControl1.Object);
    axMapControl1.CurrentTool = tool1;
}

//定义按多边形缩小ToolStripMenuItem_Click事件
private void 按多边形缩小ToolStripMenuItem_Click(object sender, EventArgs e)
{
    TArcMap.navigation.ZoomOutByPolygon tool1 = new TArcMap.navigation.ZoomOutByPolygon();
    tool1.OnCreate(axMapControl1.Object);
    axMapControl1.CurrentTool = tool1;
}

//定义按圆形放大ToolStripMenuItem_Click事件
private void 按圆形放大ToolStripMenuItem_Click(object sender, EventArgs e)
{
    TArcMap.navigation.ZoomInByCircle tool1 = new TArcMap.navigation.ZoomInByCircle();
    tool1.OnCreate(axMapControl1.Object);
    axMapControl1.CurrentTool = tool1;
}

//定义按圆形缩小ToolStripMenuItem_Click事件
private void 按圆形缩小ToolStripMenuItem_Click(object sender, EventArgs e)
{
    TArcMap.navigation.ZoomOutByCircle tool1 = new TArcMap.navigation.ZoomOutByCircle();
    tool1.OnCreate(axMapControl1.Object);
    axMapControl1.CurrentTool = tool1;
}
posted @ 2023-03-25 16:43  Weltㅤ  阅读(105)  评论(0编辑  收藏  举报