ArcGIS Engine-鹰眼图的实现


实现鹰眼图的功能需要两个AxMapControl控件,我们就让axMapControl1作为主视图,axMapControl2作为鹰眼图,在窗体中的摆放位置可以自定义,我是用SplitContainer将Form分割开来:

在这里插入图片描述

实现鹰眼图前需要明白鹰眼图的功能

  1. 鹰眼图是主视图的缩略图,鹰眼图是主视图的全局视图
  2. 主视图的当前视图对应鹰眼图中的红框范围
  3. 鼠标可以点击鹰眼图,主视图对应转换成以点击位置为中心的视图,也可以在鹰眼图上拖出显示范围

整个过程的消息传递机制:

axMapControl1加载主图时,触发其OnMapReplaced事件,将加载的图层同样加载到鹰眼控件axMapControl2中,当主图的extent变化例如放大缩小事件,会触发主图的OnExtentUpdated事件,此时设置矩形边框的颜色等参数。另外需要在点击鹰眼图层时(OnMouseDown事件)使得主图范围随之变化。

1.OnMapReplaced实现

通过这个事件实现主视图axMapControl1和鹰眼图axMapControl2之间的数据共享

官方文档对OnMapReplaced的描述:

The OnMapReplaced event is triggered whenever the IMapControl2::Mapis replaced by another map, such as when the IMapControl2::LoadMxFilemethod is used or when the map property is explicitly replaced. Use this event to keep in synch with the current map.

在这里我是通过下面的语句来加载mxd文档而触发OnMapReplaced事件

axMapControl1.LoadMxFile(string MxdPath);

在这之前我只是通过给axMapControl1以AddShapeFile的形式添加图层,发现这样无法触发该事件,具体的原因还得学习

/// <summary>
/// 实现主视图axMapControl1和鹰眼图axMapControl2之间的数据共享
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void axMapControl1_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e)
{
    if (axMapControl1.LayerCount > 0)
    {
        for (int i = 0; i < axMapControl1.LayerCount; i++)
            axMapControl2.AddLayer(axMapControl1.get_Layer(i));
        axMapControl2.Extent = axMapControl1.FullExtent;    // 初始化时设置鹰眼视图为全局视图
        axMapControl2.Refresh();	// Extent变化后记得要Refresh
    }
}

2.OnMouseDown实现

因为要实现鼠标在鹰眼图中点击的位置是主视图的中心,所以这里获取的是e.mapX和e.mapY而不是普通的e.X和e.Y,它们的区别在于前者获取的是地理坐标,后者获取的是屏幕坐标,前者可以在两个视图中对应,而后者不可以

/// <summary>
/// 鼠标在鹰眼图上的点击事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void axMapControl2_OnMouseDown(object sender, IMapControlEvents2_OnMouseDownEvent e)
{
    if(axMapControl1.LayerCount > 0)
    {
        if(e.button == 1)   // 左键所点击的位置设置为主视图的中心
        {
            IPoint pPoint = new PointClass();
            pPoint.PutCoords(e.mapX, e.mapY);
            axMapControl1.CenterAt(pPoint);
            axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);	//对所有数据所有范围刷新
        }
        else if(e.button == 2)  // 右键则拉框范围设置为主试图显示范围
        {
            IEnvelope pEnv = axMapControl2.TrackRectangle();
            axMapControl1.Extent = pEnv;
            axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
        }
    }
}

/// <summary>
/// 鹰眼视图上鼠标长按拖动事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void axMapControl2_OnMouseMove(object sender, IMapControlEvents2_OnMouseMoveEvent e)
{
    if(e.button==1)
    {
        IPoint pPoint = new PointClass();
        pPoint.PutCoords(e.mapX, e.mapY);
        axMapControl1.CenterAt(pPoint);
        axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
    }
}

3.OnExtentUpdated实现

当主视图的视图发生变化时,对应在鹰眼图上用红色框框住显示范围

因为是图层元素的设置,需要在IActiveView上设置,又需要先清除此时鹰眼图上的元素,需要用到IGraphicsContainer,而这两个接口都在PageLayout和Map中被实现,根据COM对象协议,可以利用axMapControl.Map进行接口转换,得到当前地图对应的ActiveView和IGraphicsContainer

对红色框的获取,通过创建这样的一个IElement,添加到MapIGraphicsContainer中,再用ActiveView刷新。

具体的绘制过程可以看下面的代码

/// <summary>
/// 主窗体视图范围变化
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void axMapControl1_OnExtentUpdated(object sender, IMapControlEvents2_OnExtentUpdatedEvent e)
{
    // 获取当前地图视图的外包矩形
    IEnvelope pEnvelope = (IEnvelope)e.newEnvelope;
    // 获得GraphicsContainer对象
    IGraphicsContainer pGraphicsContainer = axMapControl2.Map as IGraphicsContainer;

    IActiveView pActiveView = pGraphicsContainer as IActiveView;
    // 清除对象中的所有图形元素
    pGraphicsContainer.DeleteAllElements();

    // 获得矩形图形元素
    IRectangleElement pRectangleEle = new RectangleElementClass();
    IElement pElement = pRectangleEle as IElement;
    pElement.Geometry = pEnvelope;

    //设置FillShapeElement对象的symbol
    IFillShapeElement pFillShapeEle = pElement as IFillShapeElement;
    pFillShapeEle.Symbol = getFillSymbol();
    // 进行填充
    pGraphicsContainer.AddElement((IElement)pFillShapeEle, 0);
    // 刷新试图
    pActiveView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, null, null);
}

/// <summary>
/// 获得鹰眼视图显示方框的symbol
/// </summary>
/// <returns></returns>
private IFillSymbol getFillSymbol()
{
    // 矩形框的边界线颜色
    IRgbColor pColor = new RgbColorClass();
    pColor.Red = 255;
    pColor.Green = 0;
    pColor.Blue = 0;
    pColor.Transparency = 255;
    // 边界线
    ILineSymbol pOutline = new SimpleLineSymbolClass();
    pOutline.Width = 3;
    pOutline.Color = pColor;
    // symbol的背景色
    pColor = new RgbColorClass();
    pColor.Red = 255;
    pColor.Green = 0;
    pColor.Blue = 0;
    pColor.Transparency = 0;
    // 获得显示的图形元素
    IFillSymbol pFillSymbol = new SimpleFillSymbolClass();
    pFillSymbol.Color = pColor;
    pFillSymbol.Outline = pOutline;
    return pFillSymbol;
}

参考博客
c#鹰眼地图的实现(理解消息传递机制)
ArcGIS Engine 开发 (五)鹰眼功能的实现,将图像元素(element)显示在视图上的步骤

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

linengcs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值