2012-02-16 27 views
1

Я использую GMAP.NET в C#. Я могу отображать карту в форме, теперь я пытаюсь нарисовать мышь CIRCLE, нажав на точку certian, удерживая левую кнопку мыши и перетаскивая мышь до определенного места. Как только круг нарисован, я хочу получить его радиус в милях от центра, который, я уверен, GMAP способен это сделать. Я использую карты Opentstreet.Как нарисовать круг на MAP с помощью GMAP.NET в C#

Я просто не могу добиться этого, никто, кто играл с контролем GMAP, не делится своим опытом с некоторым кодом, который будет работать.

Благодаря

ответ

8

Единственный способ, который я знаю, что можно добиться такого результата, чтобы создать список с точками 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

0
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` 

так что квартира не будет эллипсы

4

Если вы хотите использовать типичный 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

+0

@JAlecksen, Могу ли я знать, как сделать то же самое с WPF? –

+0

@ Manish Jain К сожалению, у меня не было опыта работы с WPF и Gmap. Когда-нибудь мне придется перейти, но я не ожидаю этой кривой обучения: P –

1

Я столкнулся с той же проблемой, и на входе у меня был Lon, Lat и радиус, вот мое решение. Он работает как шарм :)

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 –

0

Вот как нарисовать красный круг с черной каймой на карте в 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 
0
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); 
    } 

 Смежные вопросы

  • Нет связанных вопросов^_^