GIS二次开发实习——鹰眼功能模块的实现(鹰眼锁定不能动,红框与主地图联动)

GIS二次开发实习(一)——鹰眼功能实现

学期末为期2周的实习结束了,对实习要求所做 太湖水资源管理系统 的功能的实现一一做一个记录,今天先来鹰眼部分(细节部分这里就不说了看前面的文章(一))。

实现效果

实现步骤

(一)技术路线

GIS二次开发实习——鹰眼功能模块的实现(鹰眼锁定不能动,红框与主地图联动)_第1张图片

(二)实现步骤

1功能分析

鹰眼,其功能是使用者在大比例尺进行浏览地图时全局显示地图的一个小地图窗口,为使用者提供一个当前浏览地图在全局地图上的相对位置,所以我们分析得以下几个功能。

  • 1.1鹰眼窗口全局显示关键图层且不可缩放
    加载地图后鹰眼部分全局锁定显示地图,并为防止地图信息过多,只显示关键信息方便浏览。

axMapControl2.AutoMouseWheel = false;//使鼠标中键滚轮无效

  • 1.2主图平移缩放时与鹰眼图中范围框(红框)的联动
    • a.主图进行平移缩放时,在平移完成后将主图所全局显示的地图地理坐标范围传出。
    • b.鹰眼图监听到该平移缩放事件,获取到地图主图传出的地图地理坐标范围后,在对应鹰眼地图上对应地图地理坐标显示范围框(红框),实现鹰眼地图的联动。
  • 1.3鹰眼范围框(红框)拖动使主题联动
    • a.在鹰眼部分点击鼠标右键,范围框(红框)中心移至鼠标点击中心,传出范围框(红框)相对地图地理坐标范围。
    • b.主图监听到范围框(红框)的地图地理坐标范围,将地图全局缩放至改地理坐标范围,实现联动。
  • 1.4鹰眼中右键绘制范围框(红框)使主图缩放到所框范围
    • a.鹰眼中左键拖动绘制范围框(红框),传出范围框所包含的地理坐标范围
    • b.主图中监听到鹰眼中范围框(红框)传来的地理坐标范围,在控件中全局显示。
2添加鹰眼控件
  • (1)在设计视图中,选择splitcontainer控件,即有2个panl的那个容器,将其Dock属性设为Fill。再第二个SplitContainer控件拖到窗体的左窗格,并将其Orientation属性设置为Horizontal,将其Dock属性也设为Fill,如图1。

    GIS二次开发实习——鹰眼功能模块的实现(鹰眼锁定不能动,红框与主地图联动)_第2张图片GIS二次开发实习——鹰眼功能模块的实现(鹰眼锁定不能动,红框与主地图联动)_第3张图片GIS二次开发实习——鹰眼功能模块的实现(鹰眼锁定不能动,红框与主地图联动)_第4张图片
    图1

  • (2)将TOCControl控件, 到splitcontainer2的panl1中,再将2个MapControl控件分别拖入SplitContainer1的Panel2中和SplitContainer2的Panel2中,操作完成后效果如图2所示。

GIS二次开发实习——鹰眼功能模块的实现(鹰眼锁定不能动,红框与主地图联动)_第5张图片
图2

  • (3)在TOCControl1中右键选择属性,将buddy control设置为axMapControl1,如图3.
    GIS二次开发实习——鹰眼功能模块的实现(鹰眼锁定不能动,红框与主地图联动)_第6张图片
    图3

  • (4)从工具箱中选择MapControl控件并拖到SplitContainer2的Panel2,作为鹰眼控件。最终效果如图4所示。
    此外在有两层splitcontainer中的axTOCControl1不能正常显示图层,所以在主窗体的Form1_Load_1事件中加入下如下代码,保证axTOCControl1控件与axMapControl1控件连接并可显示。

private void Form1_Load_1(object sender, EventArgs e)       //绑定鹰眼窗体
        {
           MessageBox.Show("欢迎使用太湖流域水资源信息管理系统!请您先加载地图");
            try
            {
                axTOCControl1.SetBuddyControl(axMapControl1);
                CreateOverviewSymbol();             //矩形框创建函数调用
            }
            catch { MessageBox.Show("请先加载地图文件");}
 
        }
3代码的实现
  • 3.1申明一个画矩形框的函数,以便鹰眼中的范围框(红框)调用。代码及详细说明如下
private void CreateOverviewSymbol()     //创建一个绘制矩形框的函数
        {
            IRgbColor iRgb = new RgbColorClass();//创建一个颜色对象,以便后面将颜色赋予线要素pOutline
            iRgb.RGB = 0;             //将黑色赋予iRgb颜色对象
 
            ILineSymbol pOutline = new SimpleLineSymbolClass();             //创建线要素对象pOutline
            pOutline.Color = iRgb;        //将iRgb的颜色赋予线要素对象pOutline
            pOutline.Width =2.3;         //对线要素对象pOutline设置线的宽度
 
            //将此面要素除了轮廓线之外没有填充色,也就是中间透明的黑色轮廓线宽度为2.3的矩形框
            ISimpleFillSymbol pSimpleFS = new SimpleFillSymbolClass();              //创建带填充属性的面要素
            pSimpleFS.Outline = pOutline;           //将线要素pOutline的设置赋予面要素pSimpleFS的轮廓线pSimpleFS.Outline 
            pSimpleFS.Style = esriSimpleFillStyle.esriSFSHollow;    //将pSimpleFS.Style面要素的填充方式,设置为esri包里定义的空(esriSFSHollow),到此矩形框就设置好了
            oFillobject = pSimpleFS;//将可填充的面要素pSimpleFS的设置赋予在前面函数外设置的全局面要素变量(对象),以便后面用到和pSimpleFS的设置相同的面要素时直接调用
        }                           //也就是将设好的矩形框模式赋予oFillobject
 
  • 3.2 axMapControl1控件的OnMapReplaced事件主要是要说明在axMapControl1控件中的地图文件更换后要执行的内容,代码和详解如下
private void axMapControl1_OnMapReplaced (object sender, IMapControlEvents2_OnMapReplacedEvent e)//axMapControl1控件的OnMapReplaced事件主要是要说明在axMapControl1控件中的地图文件更换后要执行的内容
        {
 
        
            axMapControl2.AutoMouseWheel = false;//使鼠标中键滚轮无效
            if (axMapControl1.DocumentMap != null)//判断axMapControl1控件中加载的地图文件是否为空
            {
                axMapControl2.LoadMxFile(axMapControl1.DocumentFilename);//如果axMapControl1控件中加载的地图文件不为空,在axMapControl2控件中也加载相同的地图文件
				 if (axMapControl2.get_Layer(0) == null) return;
               for (int i = 0; i < 12; i++)//
               将太湖水资源地图的前8个次要要素图层隐藏,显示第9层以后的
               {
                   if(i<8)axMapControl2.get_Layer(i).Visible = false;
                   if (i > 8) axMapControl2.get_Layer(i).Visible = true;
 
               }
 
               axMapControl2.Extent = axMapControl2.FullExtent;        //将axMapControl2显示的地图范围/视图全局显示
           }
           else { MessageBox.Show("空地图"); }
        }
  • 3.3使鹰眼窗口中的地图在界面改变使重新全局显示地图,代码和详解如下:
	private void axMapControl2_OnExtentUpdated (object sender, IMapControlEvents2_OnExtentUpdatedEvent e)//使鹰眼窗口中的地图在界面改变使重新全局显示地图
        {
            axMapControl2.Extent = axMapControl2.FullExtent;        //将axMapControl2显示的地图范围/视图全局显示
            }
  • 3.4 在鹰眼窗体上操作时绘制框和刷新地图的代码实现,详解如下:
        /// 
        /// 在鹰眼窗体上操作时绘制框和刷新地图
        /// 
        /// 
        /// 
        private void axMapControl2_OnMouseDown (object sender, IMapControlEvents2_OnMouseDownEvent e)////axMapControl1控件的OnMouseDown事件主要是要说明在axMapControl1控件中的地图文件更换后要执行的内容
        {
            if (e.button == 2)//判断鼠标点击是否是右键——右键画红框
            {
                pEn = axMapControl2.TrackRectangle();//如果是右键,将axMapControl2的TrackRectangle的绘制方法赋予之前创建的矩形要素pEn
                axMapControl1.Extent = pEn;//将axMapControl1控件中铺开地图的位置与大小设置为绘制的pEn矩形框选的地图部分
                axMapControl2.DrawShape(pEn, ref oFillobject);//将axMapControl2的绘制形状的方法(DrawShape),设置为以pEn为形状,oFillobject为填充填充模式的方法
                if (e.button == 1)  //左键拖动红框
                {
                    Point_pSV_MouseDown = new PointClass();     //开始已定义的全局变量点对象Point_pSV_MouseDown,新建一个IPoint类型,以便下面将鼠标的落脚点赋予它
                    Point_pSV_MouseDown.PutCoords(e.mapX, e.mapY);//将鼠标在地图上的横纵坐标赋予点对象Point_pSV_MouseDown
                    IEnvelope pEnvelope = this.axMapControl1.Extent;//将axMapControl1控件所显示的地图边界形状赋予新创建的pEnvelope
                    pEnvelope.CenterAt(Point_pSV_MouseDown);        //将这个“矩形”中心移到鼠标所在axMapControl2控件中地图的坐标点点
                    axMapControl1.Extent = pEnvelope;//将移动后的矩形pEnvelope中所框的地图显示在axMapControl1控件中
                    this.axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);//将axMapControl1控件中的变化刷新显示
                    //局部刷新
 
                    isTrackSV = true;//将全局bool变量isTrackSV 设置为true,代表鼠标在拖动
                    if (pSViEnv == null)//判断鼠标绘制的矩形框是否是否有移动反馈(pSViEnv是一个之前在函数外用IMoveEnvelopeFeedback接口创建的对象)
                    {
                        pSViEnv = new MoveEnvelopeFeedbackClass();//没有就新建一个,相当于刷新
                        pSViEnv.Display = axMapControl2.ActiveView.ScreenDisplay;//再将axMapControl2新的显示赋予 pSViEnv的显示方法Display
                        pSViEnv.Symbol = (ISymbol)oFillobject;//将新的矩形pSViEnv的填充方法设置为oFillobject的方法,不过得把oFillobject的类型转换为ISymbol
                    }
                    pSViEnv.Start(pEn, Point_pSV_MouseDown);    //执行移动
                }
            }
        }
  • 3.5将主地图窗口的边框所框住地图范围传递给鹰眼窗口,代码及详解如下:
   private void axMapControl1_OnAfterDraw (object sender, IMapControlEvents2_OnAfterDrawEvent e)////axMapControl1控件的OnAfterDraw事件主要是要说明在axMapControl1控件中的用鼠标拖动绘制后要执行的内容
        {
            esriViewDrawPhase viewDrawPhase = (esriViewDrawPhase)e.viewDrawPhase;//将鼠标按压时拖动所绘制的的动态赋予esriViewDrawPhase接口新创建的 viewDrawPhase里
            if (viewDrawPhase == esriViewDrawPhase.esriViewForeground)//判断鼠标按压状态下绘制的的动态是否赋予了viewDrawPhase
            {
                axMapControl2.DrawShape(pEn, ref oFillobject);      //如果鼠标按压状态下绘制的的动态赋予了viewDrawPhase 就以pEn的形状和绘制方式绘制图形要素,这里绘制的就是之前设置的矩形框pEn
            }
        }
  • 3.6为使鹰眼中范围框保持连续,需每获取移动实践2次就重绘一次矩形框,代码如下:
   private void axMapControl2_OnMouseMove (object sender, IMapControlEvents2_OnMouseMoveEvent e)
        {
            if (isTrackSV)
            {
                moveCount++;
                if (moveCount % 2 == 0)     //因为刷新,红框消失→每移动2次就刷新一下,保持红框的连续性
                    axMapControl2.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewForeground, null, null);
                Point_pSV_MouseDown.PutCoords(e.mapX, e.mapY);
                pSViEnv.MoveTo(Point_pSV_MouseDown);
            }
 
            // 如果不是左键按下就直接返回,代码对应axMapControl2_OnMouseDown中的左键拖动红框
            if (e.button != 1) return;
            IPoint pPoint = new PointClass();
            pPoint.PutCoords(e.mapX, e.mapY);
            this.axMapControl1.CenterAt(pPoint);
            this.axMapControl1.ActiveView.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
        }
  • 3.7当松开鼠标后,以鼠标松开的点为矩形框的结束点绘制完成代码如下
private void axMapControl1_OnMouseUp (object sender, IMapControlEvents2_OnMouseUpEvent e) //若鼠标结束绘制,即松开鼠标键……
    {
 
        if (pSViEnv != null)
        {
            pEn = pSViEnv.Stop();将此时矩形框的结束点赋予pEn
            axMapControl1.Extent = pEn;
            isTrackSV = false;
        }
    }

(三)实现效果

太湖水资源管理系统实现心得
  • 先简单说一下这个学期一个课程学完后因为自己的基础不行,还懵懵懂懂,对于代码的编写还是一窍不通,只能做到复制粘贴,而实习当中,经过几天无忧无虑的代码复制粘贴,加上在老师和同学的帮助下的编写,自己对C#算是简单入门了。虽然自己现在技术还不咋的,但是感觉自己成长的还是蛮多的,从窗口控件的布置越来越流畅,到接口互操作的行行代码的类型转换,再到一些必要的逻辑语句嵌套,最后到整个程序的测试修改,最后还进行了UI的设计,自己设计的UI好几个同学都喜欢,如果我很是开心,自己体验了一次全套的轻便软件的开发,对于技术类的工作也管中窥豹了解了几分,话说还是挺有意思的,这种自己创造一种产品的感觉着实振奋人心!使自己对技术行业产生了些许兴趣。
  • 当然也得知道我们每一个人实现的功能,难易不同,虽然我在同学的帮助下实现了鹰眼,点选、框选、多边形选择要素,和UI设计,但其他小组成员的数据库维护,和过程线绘制这部分更难的功能,我还没来得及了解,课下得抓紧机会学习。

你可能感兴趣的:(AE,C#开发,实习)