美文网首页GIS常用
打造地图拼接利器(四)数据交互

打造地图拼接利器(四)数据交互

作者: 安静的林哥 | 来源:发表于2021-06-27 00:39 被阅读0次

    这里的数据交互,主要指在地图上可以选择一个范围,这个范围可以调节,同时返回所选范围的经纬度值。

    GMap.net提供一个绘制矩形的函数,但我们还需要加入一些控制点,用来随意调整区域的大小和位置。内置函数GMapPolygon可以生成一个矩形对象,然后添加到地图上。

    新建一个类SelectArea,将地图控件作为构造函数的参数传入。

      public SelectArea(GMapControl control)
            {
                this.control = control;
                //获取两个层,分别用于放置区域和控制点,如果没有,测创建
                InitOverlay(control);
                //绑定事件
                InitEvent(control);
            }
    

    同时,生成两个层,分别用来放置图形和控制点。这也是我们制作标绘的思路,即通过控制点,生成复杂图形。

     /// <summary>
            /// 初始化图层,拖动层和显示层,如果有则不创建
            /// </summary>
            /// <param name="control"></param>
            private void InitOverlay(GMapControl control)
            {
                bool haspolygons = false, hasdrags = false;
                foreach (GMapOverlay overlay in control.Overlays)
                {
                    if (overlay.Id.Equals("polygons"))
                    {
                        haspolygons = true;
                        this.polygonOverlay = overlay;
                        continue;
                    }
                    if (overlay.Id.Equals("drags"))
                    {
                        hasdrags = true;
                        this.dragOverlay = overlay;
                        break;
                    }
                }
                if (!haspolygons)
                {
                    polygonOverlay = new GMapOverlay("polygons");
                    control.Overlays.Insert(0, polygonOverlay);
                }
                if (!hasdrags)
                {
                    dragOverlay = new GMapOverlay("drags");
                    control.Overlays.Add(dragOverlay);
                }
            }
    

    在类中设置左上和右下两个关键点P1、P2,绑定鼠标按下、移动和抬起事件。当鼠标按下时,记录第一个点,当鼠标移动时,更新第二个点,当鼠标抬起时,停止更新,同步在polygons层里绘制矩形。

     /// <summary>
            /// 根据2个关键点坐标,获取矩形坐标
            /// </summary>
            /// <param name="p1"></param>
            /// <param name="p2"></param>
            /// <returns></returns>
            List<PointLatLng> GetPolygonPoints(PointLatLng p1, PointLatLng p2)
            {
                return new List<PointLatLng>(){
                    new PointLatLng(p1.Lat,p1.Lng),
                    new PointLatLng(p1.Lat,p2.Lng),
                    new PointLatLng(p2.Lat,p2.Lng),
                    new PointLatLng(p2.Lat,p1.Lng)
                };
            }
    

    鼠标抬起后,生成控制点。这里需要说明,其实控制点也是一个polygon矩形,只不过比较小,再加上描边效果,看起来像一个控制柄。控制点有3个,p1、p2和中点,分别为drag1、drag2和dragcenter,每个控制点根据中心坐标,算出边距为10的小矩形。

    Polygon对象有一个.IsMouseOver属性,可以判断是否鼠标点击在上面,但实测不好使,所以写了一个检测函数,用来判断控制点是否选中:

      /// <summary>
            /// 判断点是否在区域范围内
            /// </summary>
            /// <param name="p"></param>
            /// <param name="pm"></param>
            /// <returns></returns>
            bool isInside(GPoint p, PointLatLng pm,int radius)
            {
                bool isinside = false;
                GPoint pa = control.FromLatLngToLocal(pm);
                if (p.X > pa.X - radius && p.X < pa.X + radius && p.Y > p.Y - radius && p.Y < pa.Y + radius)
                {
                    isinside = true;
                }
                return isinside;
            }
    

    当鼠标按下时,判断选择哪个控制点,并用state标记:

        void control_MouseDown(object sender, System.Windows.Forms.MouseEventArgs e)
            {
                control.DragButton = System.Windows.Forms.MouseButtons.Right;
                isDrag = true;
                if (polygon == null&&state==0)
                {
                    p1=control.FromLocalToLatLng(e.X, e.Y);
                    p2=control.FromLocalToLatLng(e.X, e.Y);
                    List<PointLatLng> points = GetPolygonPoints(p1, p2);
                    polygon = new GMapPolygon(points, "polygon");
                    polygon.Stroke =new Pen( new SolidBrush(Color.Red),3);
                    polygonOverlay.Polygons.Add(polygon);
                }
                if (drag1 != null && isInside(new GPoint(e.X, e.Y), p1,5))
                {
                    state = 1;
                }
                if (drag2 != null && isInside(new GPoint(e.X, e.Y), p2, 5))
                {
                    state = 2;
                }
                if (dragcenter != null && isInside(new GPoint(e.X, e.Y), GetDragCenterPointsLatLng(p1, p2), 5))
                {
                    state = 3;
                }
    
    
            }
    

    添加一个代理事件,用于在矩形变化时将坐标返回主界面的左侧区域。

    \\类外:
    public  delegate  void  showInfo(SelectInfo selectinfo);
    \\类内:
     public  event  showInfo MyShowInfo;
    [\\mouseMove](file://mouseMove)事件中回馈
       SelectInfo cinfo = new SelectInfo();
                    cinfo.StartPoint = p1;
                    cinfo.EndPoint = p2;
                    MyShowInfo(cinfo);
    

    最终效果如下图:


    控制点效果图

    相关文章

      网友评论

        本文标题:打造地图拼接利器(四)数据交互

        本文链接:https://www.haomeiwen.com/subject/bohtultx.html