如何在C#中使用GMAP.NET在MAP上绘制圆圈#

问题描述:

我在c#中使用GMAP.NET。我能够在窗体上显示地图,现在我试图通过点击一个圆点来绘制CIRCLE鼠标,保留鼠标左键并将鼠标拖动到特定位置。一旦圆圈被绘制出来,我想从中心点获得其半径,我相信GMAP有能力做到这一点。我正在使用Opentstreet地图。如何在C#中使用GMAP.NET在MAP上绘制圆圈#

我只是无法实现这个功能,任何玩过GMAP控件的人都会分享你的经验与一些代码将工作。

感谢

,我知道的,可以取得这样的成绩,唯一的方法是创建PointLatLng点列表,并吸引他们为多边形。这里有一个例子:

private void CreateCircle(PointF point, double radius, int segments) 
{ 

    List<PointLatLng> gpollist = new List<PointLatLng>(); 

    double seg = Math.PI * 2/segments; 

    int y = 0; 
    for (int i = 0; i < segments; i++) 
    { 
     double theta = seg * i; 
     double a = point.X + Math.Cos(theta) * radius; 
     double b = point.Y + Math.Sin(theta) * radius; 

     PointLatLng gpoi = new PointLatLng(a,b); 

     gpollist.Add(gpoi); 
    } 
    GMapPolygon gpol = new GMapPolygon(gpollist, "pol"); 

    overlayOne.Polygons.Add(gpol); 
} 
+1

好的代码,谢谢。小调整:** Math.Cos **和** Math.Sin **,笔记大小写和半径需要非常小,如.01,如果您映射到一两英里的比例。 – TonyG 2014-03-04 03:55:44

private void CreateCircle(PointF point, double radius, int segments) 
{ 

List<PointLatLng> gpollist = new List<PointLatLng>(); 

double seg = Math.PI * 2/segments; 

int y = 0; 
for (int i = 0; i < segments; i++) 
{ 
    double theta = seg * i; 
    double a = point.x + Math.cos(theta) * radius; 
    double b = point.y + Math.sin(theta) * radius; 

    PointLatLng gpoi = new PointLatLng(a,b); 

    gpollist.Add(gpoi); 
} 
GMapPolygon gpol = new GMapPolygon(gpollist, "pol"); 

overlayOne.Polygons.Add(gpol); 
}`enter code here` 

所以公寓是不会椭圆

如果您想使用的典型特征GDI与绘图类关联,你可以简单地继承GMapMarker类。这使您可以绘制简单的形状,如圆形,并创建自定义属性(例如,一个将计算形状英里半径):

public class GMapPoint : GMap.NET.WindowsForms.GMapMarker 
{ 
    private PointLatLng point_; 
    private float size_; 
    public PointLatLng Point 
    { 
     get 
     { 
      return point_; 
     } 
     set 
     { 
      point_ = value; 
     } 
    } 
    public GMapPoint(PointLatLng p, int size) 
     : base(p) 
    { 
     point_ = p; 
     size_ = size; 
    } 

    public override void OnRender(Graphics g) 
    { 
     g.FillRectangle(Brushes.Black, LocalPosition.X, LocalPosition.Y, size_, size_); 
     //OR 
     g.DrawEllipse(Pens.Black, LocalPosition.X, LocalPosition.Y, size_, size_); 
     //OR whatever you need 

    } 
} 

要在地图上绘制点:

 GMapOverlay points_ = new GMapOverlay("pointCollection"); 
     points_.Markers.Add(new GMapPoint(new PointLatLng(35.06, -106.36), 10)); 

     gMapControl1.Overlays.Add(points_); 
+0

...你摇滚的男人! – Andres 2016-04-23 13:32:32

+0

@JAlecksen,我可以知道如何对WPF执行相同的操作吗? – 2017-05-10 10:01:36

+0

@Manish Jain不幸的是我没有任何WPF和Gmap的经验。有一天,我将不得不过渡,但我并不期待这种学习曲线:P – 2017-05-10 15:28:26

我遇到同样的问题,并在入口我有Lon,Lat和radius,这里是我的解决方案。它的工作原理就像一个魅力:)

private void CreateCircle(Double lat, Double lon, double radius) 
{ 
    PointLatLng point = new PointLatLng(lat, lon); 
    int segments = 1000; 

    List<PointLatLng> gpollist = new List<PointLatLng>(); 

    for (int i = 0; i < segments; i++) 
     gpollist.Add(FindPointAtDistanceFrom(point, i, radius/1000)); 

    GMapPolygon gpol = new GMapPolygon(gpollist, "pol"); 

    markers.Polygons.Add(gpol); 
} 

public static GMap.NET.PointLatLng FindPointAtDistanceFrom(GMap.NET.PointLatLng startPoint, double initialBearingRadians, double distanceKilometres) 
{ 
    const double radiusEarthKilometres = 6371.01; 
    var distRatio = distanceKilometres/radiusEarthKilometres; 
    var distRatioSine = Math.Sin(distRatio); 
    var distRatioCosine = Math.Cos(distRatio); 

    var startLatRad = DegreesToRadians(startPoint.Lat); 
    var startLonRad = DegreesToRadians(startPoint.Lng); 

    var startLatCos = Math.Cos(startLatRad); 
    var startLatSin = Math.Sin(startLatRad); 

    var endLatRads = Math.Asin((startLatSin * distRatioCosine) + (startLatCos * distRatioSine * Math.Cos(initialBearingRadians))); 

    var endLonRads = startLonRad + Math.Atan2(
       Math.Sin(initialBearingRadians) * distRatioSine * startLatCos, 
       distRatioCosine - startLatSin * Math.Sin(endLatRads)); 

    return new GMap.NET.PointLatLng(RadiansToDegrees(endLatRads), RadiansToDegrees(endLonRads)); 
} 

public static double DegreesToRadians(double degrees) 
{ 
    const double degToRadFactor = Math.PI/180; 
    return degrees * degToRadFactor; 
} 

public static double RadiansToDegrees(double radians) 
{ 
    const double radToDegFactor = 180/Math.PI; 
    return radians * radToDegFactor; 
} 

呼叫

CreateCircle(51.640980, -2.673544, 1143.899431); 
+0

谢谢!稍作修改后,我可以在wpf中执行相同的操作 – 2017-05-11 05:24:40

下面是如何画一个红圈,与黑色边框的地图在WPF上:

public class YourMapControl : GMapControl 
{ 
    protected override void OnRender(DrawingContext drawingContext) 
    { 
     base.OnRender(drawingContext); 

     Point center(40.730610, -73.935242); 
     double radius = 0.1; 

     drawingContext.DrawEllipse(Brushes.Red, Pens.Black, center, radius, radius); 
    } 
} 

至于问题本身的第二部分,您将使用以下内置的MapControl功能:

public bool DisableAltForSelection; //if true, selects area just by holding mouse and moving 
public bool SelectionUseCircle; //use circle for selection 
public event SelectionChange OnSelectionChange; //occurs when mouse selection is changed 
public RectLatLng SelectedArea { get; set; } //returns rect with coordinates of the selected area 

private void CreateCircle(Double lat, Double lon, double radius, int ColorIndex) 
    { 
     PointLatLng point = new PointLatLng(lat, lon); 
     int segments = 1080; 

     List<PointLatLng> gpollist = new List<PointLatLng>(); 

     for (int i = 0; i < segments; i++) 
     { 
      gpollist.Add(FindPointAtDistanceFrom(point, i*(Math.PI/180), radius/1000)); 
     } 

     GMapPolygon polygon = new GMapPolygon(gpollist, "Circle"); 
     switch (ColorIndex) { 

      case 1: 
       polygon.Fill = new SolidBrush(Color.FromArgb(80, Color.Red)); 
       break; 
      case 2: 
       polygon.Fill = new SolidBrush(Color.FromArgb(80, Color.Orange)); 
       break; 
      case 3: 
       polygon.Fill = new SolidBrush(Color.FromArgb(20, Color.Aqua)); 
       break; 
      default: 
       MessageBox.Show("No search zone found!"); 
       break; 
     } 


     polygon.Stroke = new Pen(Color.Red, 1); 
     markers.Polygons.Add(polygon); 
     gMapCtl.Overlays.Add(markers); 
    } 


    public static GMap.NET.PointLatLng FindPointAtDistanceFrom(GMap.NET.PointLatLng startPoint, double initialBearingRadians, double distanceKilometres) 
    { 
     const double radiusEarthKilometres = 6371.01; 
     var distRatio = distanceKilometres/radiusEarthKilometres; 
     var distRatioSine = Math.Sin(distRatio); 
     var distRatioCosine = Math.Cos(distRatio); 

     var startLatRad = DegreesToRadians(startPoint.Lat); 
     var startLonRad = DegreesToRadians(startPoint.Lng); 

     var startLatCos = Math.Cos(startLatRad); 
     var startLatSin = Math.Sin(startLatRad); 

     var endLatRads = Math.Asin((startLatSin * distRatioCosine) + (startLatCos * distRatioSine * Math.Cos(initialBearingRadians))); 
     var endLonRads = startLonRad + Math.Atan2(Math.Sin(initialBearingRadians) * distRatioSine * startLatCos,distRatioCosine - startLatSin * Math.Sin(endLatRads)); 

     return new GMap.NET.PointLatLng(RadiansToDegrees(endLatRads), RadiansToDegrees(endLonRads)); 
    } 

    public static double DegreesToRadians(double degrees) 
    { 
     const double degToRadFactor = Math.PI/180; 
     return degrees * degToRadFactor; 
    } 

    public static double RadiansToDegrees(double radians) 
    { 
     const double radToDegFactor = 180/Math.PI; 
     return radians * radToDegFactor; 
    } 



    public static double DistanceTwoPoint(double startLat, double startLong, double endLat, double endLong) { 

     var startPoint = new GeoCoordinate(startLat, startLong); 
     var endPoint = new GeoCoordinate(endLat, endLong); 

     return startPoint.GetDistanceTo(endPoint); 
    }