首页 > 代码库 > GMAP.NET控件画圆

GMAP.NET控件画圆

关于GMAP.NET地图控件在地图上操作的例子很多,但是关于画圆形的描述很少,我找到了GMAP官方的例子并在此基础上进行了部分的改动,实现了对GMAP地图控件的画圆操作。

技术分享
  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.Threading.Tasks;
  6 using System.Drawing;
  7 using System.Runtime.Serialization;
  8 using GMap.NET;
  9 using GMap.NET.WindowsForms;
 10 
 11 namespace tgmap
 12 {
 13 #if !PocketPC
 14     [Serializable]
 15     public class GMapMarkerCircle : GMapMarker, ISerializable
 16 #else
 17    public class GMapMarkerCircle : GMapMarker
 18 #endif
 19     {
 20         /// <summary>
 21         /// In Meters 用米数确定圆
 22         /// </summary>
 23         public int Radius;
 24 
 25         /// <summary>
 26         /// 用两个点确定圆
 27         /// </summary>
 28         public PointLatLng P2;
 29 
 30         /// <summary>
 31         /// 是否用米数确定圆
 32         /// </summary>
 33         public bool IsMeter = true;
 34 
 35 
 36         /// <summary>
 37         /// specifies how the outline is painted
 38         /// </summary>
 39         [NonSerialized]
 40 #if !PocketPC
 41         public Pen Stroke = new Pen(Color.FromArgb(155, Color.MidnightBlue));
 42 #else
 43       public Pen Stroke = new Pen(Color.MidnightBlue);
 44 #endif
 45 
 46         /// <summary>
 47         /// background color
 48         /// </summary>
 49         [NonSerialized]
 50 #if !PocketPC
 51         public Brush Fill = new SolidBrush(Color.FromArgb(155, Color.AliceBlue));
 52 #else
 53       public Brush Fill = new System.Drawing.SolidBrush(Color.AliceBlue);
 54 #endif
 55 
 56         /// <summary>
 57         /// is filled
 58         /// </summary>
 59         public bool IsFilled = true;
 60 
 61         public GMapMarkerCircle(PointLatLng p)
 62            : base(p)
 63         {
 64             Radius = 0; // 0m
 65             P2 = p;
 66             IsHitTestVisible = false;
 67         }
 68 
 69         public override void OnRender(Graphics g)
 70         {
 71             if (!IsMeter)
 72                 Radius = (int)Overlay.Control.MapProvider.Projection.GetDistance(Position, P2) * 1000;
 73 
 74             int R = (int)((Radius) / Overlay.Control.MapProvider.Projection.GetGroundResolution((int)Overlay.Control.Zoom, Position.Lat)) * 2;
 75 
 76             if (IsFilled)
 77             {
 78                 g.FillEllipse(Fill, new System.Drawing.Rectangle(LocalPosition.X - R / 2, LocalPosition.Y - R / 2, R, R));
 79             }
 80             g.DrawEllipse(Stroke, new System.Drawing.Rectangle(LocalPosition.X - R / 2, LocalPosition.Y - R / 2, R, R));
 81         }
 82 
 83         public override void Dispose()
 84         {
 85             if (Stroke != null)
 86             {
 87                 Stroke.Dispose();
 88                 Stroke = null;
 89             }
 90 
 91             if (Fill != null)
 92             {
 93                 Fill.Dispose();
 94                 Fill = null;
 95             }
 96 
 97             base.Dispose();
 98         }
 99 
100         public bool IsInside(PointLatLng p)
101         {
102             return (int)Overlay.Control.MapProvider.Projection.GetDistance(Position, p) * 1000 < Radius;
103         }
104 
105 #if !PocketPC
106 
107         #region ISerializable Members
108 
109         void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
110         {
111             base.GetObjectData(info, context);
112 
113             // TODO: Radius, IsFilled
114         }
115 
116         protected GMapMarkerCircle(SerializationInfo info, StreamingContext context)
117            : base(info, context)
118         {
119             // TODO: Radius, IsFilled
120         }
121 
122         #endregion
123 
124 #endif
125     }
126 }
View Code

里面描述了两种画圆的方法,一种是根据半径(米)和Marker的Position来画圆,一种是根据Marker的Position和另外一个PointLatLng点来画圆。添加了IsInside方法来确认另一个点是否在圆内。第二种方法是为了实现鼠标点击拖动画圆,鼠标事件代码如下

技术分享
 1 private GMapOverlay circles = new GMapOverlay("circle"); //放置circle的图层
 2         private GMapMarkerCircle drawingCircle = null; //正在画的circle
 3         private bool IsDrawingCircle = false;
 4 
 5         private void MapControl_MouseDown(object sender, MouseEventArgs e)
 6         {
 7             circles.Markers.Clear();
 8             IsDrawingCircle = true;
 9             drawingCircle = new GMapMarkerCircle(mapControl.FromLocalToLatLng(e.X, e.Y));
10             drawingCircle.IsMeter = false;
11             circles.Markers.Add(drawingCircle);
12 
13             //polygons.Polygons.Clear();
14             //IsDrawingPolygon = true;
15             //startX = e.X;
16             //startY = e.Y;
17             //drawingPolygon = new GMapPolygon(new List<PointLatLng>() { mapControl.FromLocalToLatLng(e.X,e.Y)}, "polygon");
18             //polygons.Polygons.Add(drawingPolygon);
19         }
20 
21         private void MapControl_MouseUp(object sender, MouseEventArgs e)
22         {
23             IsDrawingCircle = false;
24             int count = 0;
25             markersOverlay.Markers.ToList().ForEach(ma=> {
26                 if (drawingCircle.IsInside(ma.Position))
27                 {
28                     count++;
29                 }
30             });
31             MessageBox.Show("区域内一共有" + count + "个marker(s)");
32 
33             //IsDrawingPolygon = false;
34             //int count = 0;
35             //markersOverlay.Markers.ToList().ForEach(ma => {
36             //    if (drawingPolygon.IsInside(ma.Position))
37             //    {
38             //        count++;
39             //    }
40             //});
41             //MessageBox.Show("区域内一共有" + count  +"个marker(s)");
42         }
43 
44         private void MapControl_MouseMove(object sender, MouseEventArgs e)
45         {
46             if (IsDrawingCircle)
47             {
48                 drawingCircle.P2 = mapControl.FromLocalToLatLng(e.X,e.Y);
49                 mapControl.UpdateMarkerLocalPosition(drawingCircle);
50                 mapControl.Refresh();
51             }
52 
53             //if (IsDrawingPolygon)
54             //{
55             //    drawingPolygon.Points.Clear();
56             //    drawingPolygon.Points.Add(mapControl.FromLocalToLatLng(startX,startY));
57             //    drawingPolygon.Points.Add(mapControl.FromLocalToLatLng(startX, e.Y));
58             //    drawingPolygon.Points.Add(mapControl.FromLocalToLatLng(e.X, e.Y));
59             //    drawingPolygon.Points.Add(mapControl.FromLocalToLatLng(e.X, startY));
60             //    mapControl.UpdatePolygonLocalPosition(drawingPolygon);
61             //    mapControl.Refresh();
62             //}
63         }
View Code

注释的代码是我当初写拖动画矩形的部分,最终实现了鼠标放开后自动数出所画区域内Marker的数量,其实以后也可以对所有区域内的Marker进行进一步操作。

测试结果如下:

技术分享

 

GMAP.NET控件画圆