Show the array of longitude and latitude by using GMap.NET.WindowsForms?

147 Views Asked by At

I want to show something like a path for arrays containing longitudes and latitudes in a C# windosform application. I am using the GMap.NET.WindowsForms Nuget package. I used the following code, but it marks the last one. Actually it shows the previous points too, but it refreshes to the next one until getting the final one.

double[] lats = { 10, 50, 60 };
double[] longs = { 40, 25, 10 };
int i = 0;
    
var markersOverlay = new GMap.NET.WindowsForms.GMapOverlay("marker1");
    
var marker = new GMap.NET.WindowsForms.Markers.GMarkerGoogle(
                  new PointLatLng(Convert.ToDouble(latitude.Text), Convert.ToDouble(longitude.Text)),
                  GMap.NET.WindowsForms.Markers.GMarkerGoogleType.red_small);
    
markersOverlay.Markers.Add(marker);
gmap.Overlays.Add(markersOverlay);
       
foreach (var lat in lats)
{
    MessageBox.Show($"{lat} , {longs[i]}");
    gmap.Position = new PointLatLng(lat, longs[i]);
    i++;
}
gmap.Zoom = Convert.ToDouble(zoom_level.Text);
gmap.Update();
gmap.Refresh();

How may I show all the specified lats and longs on the map?

1

There are 1 best solutions below

5
On BEST ANSWER

It seems you are trying to draw a route based on some coordinations. To draw a path on map you should create an overlay layer for it and then add create a route from coordinations and add it to this ovaerlay. A possible solution is like this:

   PointLatLng[] coords = new PointLatLng[]
   {
           new PointLatLng(10,40),
           new PointLatLng(50,25),
           new PointLatLng(60,10)
   };

   private void draw_path()
   {
       gmap.MapProvider = OpenStreetMapProvider.Instance;

       GMapOverlay routeLayer = new GMapOverlay("routes");
       GMapRoute route = new GMapRoute(coords , string.Empty);
       routeLayer.Routes.Add(route);
       gmap.Overlays.Add(routeLayer);

       //optional: show marker for route points
       GMapOverlay markersLayer = new GMapOverlay("markers");
       markersLayer.Id = "markers";
       foreach (PointLatLng coord in coords)
       {
           GMarkerGoogle gm = new GMarkerGoogle(coord, GMarkerGoogleType.red);
           gm.ToolTipText = coord.ToString();
           markersLayer.Markers.Add(gm);
       }
       gmap.Overlays.Add(markersLayer);

       gmap.ZoomAndCenterRoute(route);
   }

UPDATE 1: Adding text to route segments using transparent marker with display-always tooltip

private void draw_path()
{
    gmap.MapProvider = GMapProviders.GoogleMap;
    GMaps.Instance.Mode = AccessMode.ServerOnly;

    GMapOverlay routeLayer = new GMapOverlay("routes");
    GMapRoute route = new GMapRoute(coords,"Route Name"); // set a name for route
    routeLayer.Routes.Add(route);
    gmap.Overlays.Add(routeLayer);

    GMapOverlay markersLayer = new GMapOverlay("markers");
    markersLayer.Id = "markers";
    foreach (PointLatLng coord in coords)
    {
        GMarkerGoogle gm = new GMarkerGoogle(coord, GMarkerGoogleType.red);
        gm.ToolTipText = coord.ToString();
        markersLayer.Markers.Add(gm);
    }

    // adding transparent markers with display-always tooltip to simulate text for each segment
    for (int i = 1; i < coords.Length;i++)
    {
        double lat = (coords[i - 1].Lat + coords[i].Lat) / 2;
        double lng = (coords[i - 1].Lng + coords[i].Lng) / 2;
        GMarkerCross cm = new GMarkerCross(new PointLatLng(lat,lng));
        cm.Pen = new Pen(Color.Transparent);
        cm.ToolTipText = route.Name;
        cm.ToolTip.Offset = new Point(-20, 0);
        cm.ToolTip.Font = new Font("Comic Sans MS", 14f,FontStyle.Bold | FontStyle.Italic);
        cm.ToolTip.Foreground = new SolidBrush(Color.Red);
        cm.ToolTip.Fill = new SolidBrush(Color.Transparent);
        cm.ToolTipMode = MarkerTooltipMode.Always;
        cm.ToolTip.Stroke = new Pen(Color.Transparent);
        markersLayer.Markers.Add(cm);
    }
    gmap.Overlays.Add(markersLayer);
    gmap.ZoomAndCenterRoute(route);
}

UPDATE 2: Using precise formula to calculating midpoints.

Using a simple average approach to calc midpoint as in flat geometry on a spherical surface is not accurate (as in update 1 to set midpoint markers).

In this update the precise formula is applied from Calculate distance, bearing and more between Latitude/Longitude points to calculate midpoints.

private PointLatLng MidPoint(PointLatLng point1, PointLatLng point2)
{
    double p1Lat = point1.Lat * Math.PI / 180d;
    double p1Lng = point1.Lng * Math.PI / 180d;
    double p2Lat = point2.Lat * Math.PI / 180d;
    double p2Lng = point2.Lng * Math.PI / 180d;
    
    double Bx = Math.Cos(p2Lat) * Math.Cos(p2Lng - p1Lng);
    double By = Math.Cos(p2Lat) * Math.Sin(p2Lng - p1Lng);
    double MidLat = Math.Atan2(Math.Sin(p1Lat) + Math.Sin(p2Lat),
        Math.Sqrt(Math.Pow((Math.Cos(p1Lat) + Bx), 2d) + By * By));
    double MidLng = p1Lng + Math.Atan2(By, Math.Cos(p1Lat) + Bx);
    return new PointLatLng(MidLat * 180d / Math.PI, MidLng * 180d / Math.PI);
}
    
    
private void draw_path()
{
    gmap.MapProvider = GMapProviders.GoogleMap;
    GMaps.Instance.Mode = AccessMode.ServerOnly;
    
    GMapOverlay routeLayer = new GMapOverlay("routes");
    GMapRoute route = new GMapRoute(coords, "Route Name"); // set a name for route
    routeLayer.Routes.Add(route);
    gmap.Overlays.Add(routeLayer);
    
    GMapOverlay markersLayer = new GMapOverlay("markers");
    markersLayer.Id = "markers";
    foreach (PointLatLng coord in coords)
    {
        GMarkerGoogle gm = new GMarkerGoogle(coord, GMarkerGoogleType.red);
        gm.ToolTipText = coord.ToString();
        markersLayer.Markers.Add(gm);
    }
    
    for (int i = 1; i < coords.Length; i++)
    {
        GMarkerCross cm = new GMarkerCross(MidPoint(coords[i - 1], coords[i]));
        cm.ToolTipText = route. Name;
        cm.ToolTip.Font = new Font("Comic Sans MS", 14f, FontStyle.Bold | FontStyle.Italic);
        cm.ToolTip.Foreground = new SolidBrush(Color.Red);
        cm.ToolTipMode = MarkerTooltipMode.Always;
        markersLayer.Markers.Add(cm);
    }
    gmap.Overlays.Add(markersLayer);
    gmap.ZoomAndCenterRoute(route);
}

As the image shows, midpoints are still not exactly on the route. This might be due to slightly distortion of earth from perfect sphere.

A solution is to add more intermediate point in route (using MidPoint function) and put markers at these points, which also tends to more precise route.