zoukankan      html  css  js  c++  java
  • 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进行进一步操作。

    测试结果如下:

  • 相关阅读:
    同一域环境下SQLServer DB Failover故障转移配置详解
    WebAPI项目中使用SwaggerUI
    Failed to initialize the Common Language Runtime
    WCF Throttling 限流的三道闸口
    Entity Framework 乐观并发控制
    MVC3不能正确识别JSON中的Enum枚举值
    编写高质量代码改善C#程序的157个建议读书笔记【11-20】
    如果下次做模板,我就使用Nvelocity
    对于react中的this.setState的理解
    对于react中rredux的理解
  • 原文地址:https://www.cnblogs.com/makeowner/p/7345212.html
Copyright © 2011-2022 走看看