ArcGIS Engine二次开发——实现卷帘和图层闪烁

下面是卷帘和图层闪烁的屏幕截图,下面来讲解一下如何实现卷帘和图层闪烁:


首先需要定义一个成员对象ILayerEffectProperties,这个对象用于维护命令环境,指定卷帘和闪烁的图层;其次我们需要侦听地图的添加和删除图层事件,因此还需要一个ActiveViewEvents事件的侦听对象,如下:

        private ESRI.ArcGIS.Carto.IActiveViewEvents_Event MapActiveViewEvents;
        private ILayerEffectProperties m_LayerEffectProperties;
        private ICommand m_FlickCmd;
为了实现卷帘和闪烁,我们需要一个ComboBox维护一个图层列表,用于选中卷帘和闪烁的图层,也就是我们需要侦听地图的添加和删除图层事件,在这些事件发生时重新加载图层列表。对于地图的侦听事件,我们需要在窗体加载和OnMapReplaced时注册事件响应函数:
            if (MapActiveViewEvents != null)
            {
                MapActiveViewEvents.ItemAdded -= new ESRI.ArcGIS.Carto.IActiveViewEvents_ItemAddedEventHandler(MapActiveViewEvents_ItemAdded);
                MapActiveViewEvents.ItemDeleted -= new ESRI.ArcGIS.Carto.IActiveViewEvents_ItemDeletedEventHandler(MapActiveViewEvents_ItemDeleted);
                MapActiveViewEvents.ItemReordered -= new ESRI.ArcGIS.Carto.IActiveViewEvents_ItemReorderedEventHandler(MapActiveViewEvents_ItemReordered);            
            }
            IMap pMap = wndMap.ActiveView.FocusMap as IMap;
            MapActiveViewEvents = pMap as ESRI.ArcGIS.Carto.IActiveViewEvents_Event;
            MapActiveViewEvents.ItemAdded += new ESRI.ArcGIS.Carto.IActiveViewEvents_ItemAddedEventHandler(MapActiveViewEvents_ItemAdded);
            MapActiveViewEvents.ItemDeleted += new ESRI.ArcGIS.Carto.IActiveViewEvents_ItemDeletedEventHandler(MapActiveViewEvents_ItemDeleted);
            MapActiveViewEvents.ItemReordered += new ESRI.ArcGIS.Carto.IActiveViewEvents_ItemReorderedEventHandler(MapActiveViewEvents_ItemReordered);
            

在这些事件中,我们需要重新加载图层列表到我们的ComboBox里面去:

        void MapActiveViewEvents_ItemReordered(object Item, int toIndex)
        {
            ReLoadLayerList();
        }

        void MapActiveViewEvents_ItemDeleted(object Item)
        {
            ReLoadLayerList();
        }

        void MapActiveViewEvents_ItemAdded(object Item)
        {
            ReLoadLayerList();
        }

        private void ReLoadLayerList()
        {
            wndLayerListImageComboBox.Items.Clear();
            IMap pMap = wndMap.ActiveView.FocusMap;
            for (int i = 0; i < pMap.LayerCount; i++)
            {
                ILayer pLayer = pMap.get_Layer(i);
                int imageIdndex = 0;
                if(pLayer is IGeoFeatureLayer)
                {
                    IGeoFeatureLayer pGeoLayer = pLayer as IGeoFeatureLayer;
                    if(pGeoLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint) imageIdndex =0;
                    else if(pGeoLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline) imageIdndex = 1;
                    else if(pGeoLayer.FeatureClass.ShapeType == esriGeometryType.esriGeometryPolygon) imageIdndex =2;
                }
                else if(pLayer is IRasterLayer) imageIdndex = 3;
                wndLayerListImageComboBox.Items.Add(new DevExpress.XtraEditors.Controls.ImageComboBoxItem(pLayer.Name, pLayer, imageIdndex));                
            }  
        }

完成这些内容以后,我们还需要在每次选择卷帘和闪烁图层后,把选中的图层赋给LayerEffectProperties对象:

        private void wndLayerListImageComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            DevExpress.XtraEditors.ImageComboBoxEdit edit = sender as DevExpress.XtraEditors.ImageComboBoxEdit;
            if (edit.Value != null && edit.Value is ILayer)
            { 
                ILayer pLayer = edit.Value as ILayer;
                m_LayerEffectProperties.SwipeLayer = pLayer;
                m_LayerEffectProperties.FlickerLayer = pLayer;
                m_LayerEffectProperties.TransparencyLayer = pLayer;
            }           
        }	

之后,就是工具响应了,具体如下:

        /// <summary>
        /// 卷帘工具
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void wndBtnLayerSwipe_ItemClick(object sender, ItemClickEventArgs e)
        {
            ICommand pCmd = new ControlsMapSwipeTool();
            //只有MapControl支持卷帘,PageLayout不可以
            if (wndTabMainView.SelectedTabPage == wndTabPageMapView)
            {
                pCmd.OnCreate(wndMap.Object);
                wndMap.CurrentTool = pCmd as ITool;
            }
        }

        /// <summary>
        /// 图层闪烁频率
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void wndLayerFlickRateSpinEdit_EditValueChanged(object sender, EventArgs e)
        {
            if (m_LayerEffectProperties != null)
            {
                DevExpress.XtraEditors.SpinEdit edit = sender as DevExpress.XtraEditors.SpinEdit;
                int rate = int.Parse(edit.Value.ToString());
                m_LayerEffectProperties.FlickerRate = rate;
            }
        }
对于闪烁,这里一定要注意的一点是,一定要把这个命令声明为成员对象,否则会因为这个Command被析构而出现图层只会闪几下就不闪了的现象;另外还需要把它作为Tool设置给地图的CurrentTool,否则在鼠标点击地图或者移动时也会发生地图停止闪烁的问题。
        /// <summary>
        /// 图层闪烁
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void wndBtnLayerFlick_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (m_FlickCmd != null) Marshal.ReleaseComObject(m_FlickCmd);
            m_FlickCmd = new ControlsMapFlickerCommand();
            if (wndTabMainView.SelectedTabPage == wndTabPageMapView)
            {
                m_FlickCmd.OnCreate(wndMap.Object);
                wndMap.CurrentTool = m_FlickCmd as ITool;   //设置为当前的Tool,否则移动鼠标就会使地图停止闪烁
                m_FlickCmd.OnClick();
            }            
        }
最后补充一点操作技巧,当地图在卷帘工具下,按住Ctr或者Shift键,就可以实现类似ENVI的图层闪烁功能,这个小技巧你知道吗?
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

深蓝静音

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

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

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

打赏作者

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

抵扣说明:

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

余额充值