Как нарисовать круг на карте, используя GMAP.NET в C # - PullRequest
2 голосов
/ 16 февраля 2012

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

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

Спасибо

Ответы [ 7 ]

9 голосов
/ 20 марта 2012

Единственный способ добиться такого результата, который мне известен, - это создать список с точками 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);
 }
5 голосов
/ 08 декабря 2015

Если вы хотите использовать типичные функции 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_);

(и поскольку у меня были некоторые вопросы по этому поводу) Поскольку мы унаследованы от класса маркеров, мы все еще можем воспользоваться возможностью tooltiptext:

        GMapPoint pnt = new GMapPoint(new PointLatLng(35.06, -106.36), 10);
        pnt.Size = new Size(10,10);
        pnt.ToolTipText = "Text Here";
        pnt.ToolTipMode = MarkerTooltipMode.Always;
        points_.AddMarker(pnt);
1 голос
/ 21 ноября 2017
   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);
    }
1 голос
/ 08 сентября 2016

Я столкнулся с той же проблемой и при входе у меня были 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 голосов
/ 11 января 2019
        GMapOverlay markers = new GMapOverlay("markers");
        private void CreateCircle(Double lat, Double lon, double radius, int segments)
        {
            markers.Polygons.Clear();
            PointLatLng point = new PointLatLng(lat, lon);

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

            List<PointLatLng> gpollistR = new List<PointLatLng>();
            List<PointLatLng> gpollistL = new List<PointLatLng>();
            foreach (var gp in gpollist)
            {
                if (gp.Lng > lon)
                {
                    gpollistR.Add(gp);
                }
                else
                {
                    gpollistL.Add(gp);
                }
            }
            gpollist.Clear();

            List<PointLatLng> gpollistRT = new List<PointLatLng>();
            List<PointLatLng> gpollistRB = new List<PointLatLng>();
            foreach (var gp in gpollistR)
            {
                if (gp.Lat > lat)
                {
                    gpollistRT.Add(gp);
                }
                else
                {
                    gpollistRB.Add(gp);
                }
            }
            gpollistRT.Sort(new LngComparer());
            gpollistRB.Sort(new Lng2Comparer());
            gpollistR.Clear();
            List<PointLatLng> gpollistLT = new List<PointLatLng>();
            List<PointLatLng> gpollistLB = new List<PointLatLng>();
            foreach (var gp in gpollistL)
            {
                if (gp.Lat > lat)
                {
                    gpollistLT.Add(gp);
                }
                else
                {
                    gpollistLB.Add(gp);
                }
            }
            //gpollistLT.Sort(new LngComparer());
            gpollistLB.Sort(new Lng2Comparer());
            gpollistLT.Sort(new LngComparer());
            gpollistL.Clear();


            gpollist.AddRange(gpollistRT);
            gpollist.AddRange(gpollistRB);
            gpollist.AddRange(gpollistLB);
            gpollist.AddRange(gpollistLT);
            GMapPolygon gpol = new GMapPolygon(gpollist, "pol");
            gpol.Stroke = new Pen(Color.Red, 1);
            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;
        }

и этот класс

class LngComparer : IComparer<PointLatLng>
    {
        #region IComparer Members

        public int Compare(PointLatLng x, PointLatLng y)
        {
            if (x == null || y == null)
                throw new ArgumentException("At least one argument is null");
            if (x.Lng == y.Lng)
            {
                if (x.Lat > y.Lat)
                {
                    return 1;
                }
                else if (x.Lat < y.Lat)
                {
                    return -1;
                }
                else
                {
                    return 0;
                }
            }
            if (x.Lng < y.Lng) return -1;
            return 1;
        }

        #endregion
    }
    class Lng2Comparer : IComparer<PointLatLng>
    {
        #region IComparer Members

        public int Compare(PointLatLng x, PointLatLng y)
        {
            if (x == null || y == null)
                throw new ArgumentException("At least one argument is null");
            if (x.Lng == y.Lng)
            {
                if (x.Lat > y.Lat)
                {
                    return 1;
                }
                else if (x.Lat > y.Lat)
                {
                    return -1;
                }
                else
                {
                    return 0;
                }
            }
            if (x.Lng > y.Lng) return -1;
            return 1;
        }

        #endregion
    }
0 голосов
/ 02 июня 2017

Вот как нарисовать красный круг с черной рамкой на карте в 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 голосов
/ 16 августа 2015
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`

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

...