如何捕获和响应MapControl的添加图层事件

    通常地图都需要加上一个鹰眼,要实现鹰眼功能,不可避免的就需要实现主地图和鹰眼的同步。令人失望的是ArcGIS的帮助文档和范例中都采用同时在主地图和鹰眼中加载mxd文档的方式来实现同步的,确切的说,这样只是加载了地图,并没有实现同步。如果程序启动后并没有加载任何地图文档,而只是添加图层,那么这种处理方式就暴露马脚了。其实会出问题的不仅仅是这种情况,当我们修改主地图的符号、样式等时,也会有问题,因此我们必须使用同步加载图层的方式来才能实现主图和鹰眼的同步。所谓同步加载图层,就是指直接在鹰眼中加载主图的图层,同步就是指主地图中的图层发生变化时这些变化也都要反映到鹰眼中去。
    加载mxd文档好办,根据AE的帮助说明,当加载mxd文档后,MapControl会触发OnMapReplaced事件,我们可以在这个事件中添加相应的处理。但是当添加图层时,MapControl并没有并没有LayerAdded之类的事件,这种情况下,如果要同步鹰眼和主地图,就需要捕获类似于LayerAdded之类的事件。如何实现呢,答案就是IActiveViewEvents,具体如下:

    using ESRI.ArcGIS.Carto;
    public partial class FrmMain : DevExpress.XtraEditors.XtraForm
    {

        private IActiveViewEvents_Event m_MapActiveViewEvents;
        public FrmMain()
        {
            InitializeComponent();

            //侦听地图的事件
            m_MapActiveViewEvents = wndMapCtr.Map as IActiveViewEvents_Event;

            //对于Map,在添加图层后触发,对于PageLayout在添加任何要素时都会触发
            m_MapActiveViewEvents.ItemAdded += new IActiveViewEvents_ItemAddedEventHandler(m_MapActiveViewEvents_ItemAdded);
        }

        /// <summary>
        /// 当MapCtr加载地图文档后触发。
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void wndMapCtr_OnMapReplaced(object sender, IMapControlEvents2_OnMapReplacedEvent e)
        {
            //主地图发生变化时将图层同步添加到鹰眼窗口中。
            ReLoadLayersToHawkEye();
        }

        /// <summary>
        /// 当在主地图中添加图层后触发。
        /// </summary>
        /// <param name="Item"></param>
        void m_MapActiveViewEvents_ItemAdded(object Item)
        {
            //主地图发生变化时将图层同步添加到鹰眼窗口中。
            ReLoadLayersToHawkEye();
        }

        /// <summary>
        /// 重新加载图层到鹰眼窗口
        /// </summary>
        private void ReLoadLayersToHawkEye()
        {
            m_MapChanged = true;
            wndBtnSave.Enabled = true;
            wndBtnSaveAs.Enabled = true;
            IMap oldMap = wndOverviewMapCtr.Map;         //Release original map
            Marshal.ReleaseComObject(oldMap);
            wndOverviewMapCtr.Map = new MapClass();
            for (int i = 1; i <= wndMapCtr.LayerCount; i++)
            {
                wndOverviewMapCtr.AddLayer(wndMapCtr.get_Layer(wndMapCtr.LayerCount - i));
            }
            this.wndOverviewMapCtr.Extent = this.wndMapCtr.FullExtent;
            this.wndOverviewMapCtr.Refresh();
        }
    }

    以上代码实现了主地图和鹰眼的同步,但是存在一个问题,那就是加载地图文档,相当于添加了多个图层,这样会不会触发多次ItemAdded事件呢?如果触发多次,那岂不是每次打开地图文档,这个鹰眼同步的函数就会被调用很多次?

    幸好,实验发现,加载mxd文档并不触发MapActiveViewEvents的ItemAdded事件,因此以上代码可以放心使用。

    当然,对于完整的鹰眼和地图同步,以上代码还不完整,因为还需要在修改图层的颜色、符号、填充样式等时也做相应的同步,这些有待后续完善。

你可能感兴趣的:(object,Class,文档,layer)