Markers Redraw Problems

Topics: Bugs, General, Windows Forms
Nov 6, 2012 at 3:36 PM
Edited Nov 6, 2012 at 3:52 PM

Im trying to refresh the markers on the screen:

Code:

        private void MissionWorkspaceView_VisibleChanged(object sender, EventArgs e)
        {
            if (Visible)
            {
                GetMarkersFromNodeWorkspaceView(); // Where I put all my markers
                CreateMissionLines(); // Some drawing of route
                gMapControl1.Invalidate(); // doesnt work
                overlay.Control.Refresh(); // doesnt work
            }
        }

First the are showing ok , the form because not visible and when Visible is true , they are not at the good position. Moving the map is not helping.

The only way to draw it back correctly , is to resize the GMap Control. It doesnt make the same behavior for every zoom level.

Coordinator
Nov 6, 2012 at 5:00 PM

o.O

Nov 6, 2012 at 5:14 PM

Anything I can do to diagnostic this?

Coordinator
Nov 6, 2012 at 5:32 PM

i still don't get where is the problem..

Nov 6, 2012 at 6:09 PM

Sorry my english is not pretty good. I have refresh/draw issue with custom marker. Just doing a minimize or a resize of the gmap control seem to fix it. I would like to do it via code.

My markers are type : GMapMarkerCircle

 

Collection<GMapMarker> marks = view.GetMarkeurs();
overlay.Markers.Clear();
foreach (GMapMarker mark in marks)
{
     overlay.Markers.Add(mark);
}

 

This is the code of the render method of the marker:     

public override void OnRender(Graphics g)
        {
            g.FillEllipse(InnerBrush, new Rectangle(LocalPosition.X, LocalPosition.Y, diameter, diameter));
            g.DrawEllipse(OuterPen, new Rectangle(LocalPosition.X, LocalPosition.Y, diameter, diameter));
                       
            if (!String.IsNullOrEmpty(this.Text))
            {
                SizeF sizeOfString = g.MeasureString(this.Text, this.TextFont);
                int x = (LocalPosition.X + diameter / 2) - (int)(sizeOfString.Width / 2);
                int y = (LocalPosition.Y + diameter / 2) - (int)(sizeOfString.Height / 2);
                g.DrawString(this.Text, this.TextFont, this.TextBrush, x, y);
            }
        }

gMapControl1.Refresh(); -> This should call OnRender for each marker right?


Image and video hosting by TinyPic

Image and video hosting by TinyPic

Coordinator
Nov 6, 2012 at 6:36 PM

so you add circles, and whats wrong with them?

Nov 6, 2012 at 6:43 PM

They are not draw correctly in the first screen , I do a minimize of the application and they are okay after that. I would like  to have them always as the second screen.

Coordinator
Nov 6, 2012 at 6:52 PM

there is something wrong with your marker Offset, show me full code

Nov 6, 2012 at 7:12 PM

 

		public int CircleDiameter
		{
			get
			{
				return this.diameter;
			}
			set
			{
				diameter = value;
				this.Size = new System.Drawing.Size(diameter, diameter);
				Offset = new System.Drawing.Point(-Size.Width / 2, -Size.Height / 2);
			}
		}

 

		private void gMapControl1_OnMapZoomChanged()
		{
			MainForm main = this.MainForm as MainForm;
			if (main == null)
				return;

			foreach (GMapMarker mark in overlay.Markers)
			{
				bool issMall = false;
				GMapMarkerCircle customMark = mark as GMapMarkerCircle;
				if (customMark == null)
					continue;
				string tag = (customMark.Tag) as string;
				if (tag.Contains("_SMALL"))
				{
					issMall = true;
				}
				tag = tag.Replace("_SMALL", "");

				NodeWorkspaceView view = main.GetWorkspaceView("NodeWorkspaceView") as NodeWorkspaceView;
				Dictionary<string,Station> stationList = view.GetStations();

				Station station = null;
				if (stationList.ContainsKey(tag))
				{
					station = stationList[tag];
				}
			
				if (station != null)
				{
					string radius;

					if (issMall)
					{
						radius = station.ArrivalRadius.Replace("M", "");
					}
					else
					{
						radius = station.ApproachRadius.Replace("M", "");
						customMark.ToolTipText = string.Format("Nom:{0} \n  Longitude:{1} \n Latitude:{2} \n Rayon d'approche:{3} \n Rayon d'arriv�:{4} \n", station.Name, mark.Position.Lng, mark.Position.Lat, station.ApproachRadius, station.ArrivalRadius);
					}

					// M to KM
					double newApro = Convert.ToDouble(radius) / 1000;
					int newDiameter = CalculateNewDiameterForZoomLevel(mark.Position, newApro);
					customMark.CircleDiameter = newDiameter;
				}
			}
			gMapControl1.Refresh();
		}	
		private void BranchWorkspaceView_VisibleChanged(object sender, EventArgs e)
		{
			if (Visible)
			{
				GetMarkersFromNodeWorkspaceView();
				CreateLines();
				gMapControl1_OnMapZoomChanged();
			}
		}
		private int CalculateNewDiameterForZoomLevel(PointLatLng point, double RadiusInKM)
		{
			double groundResolution = gMapControl1.MapProvider.Projection.GetGroundResolution(Convert.ToInt32(gMapControl1.Zoom), point.Lat);
			int diam = (int)(RadiusInKM * 2 * 1000 / groundResolution);
			return diam;
		}

		private void CreateLines()
		{
			overlay.Routes.Clear();

			List<GMap.NET.PointLatLng> list = new List<GMap.NET.PointLatLng>();
			for (int index = 0; index < overlay.Markers.Count; index++)
			{
				GMapMarker marker = overlay.Markers[index];
				string stationName = marker.Tag as string;

				if (stationName.Contains("LATTES") ||
					stationName.Contains("Cougourlude"))
				{
					continue;
				}
				list.Add(marker.Position);
			}

			route2 = new GMapRoute(list, "route2");
			SetBranchColor(route2, "Branche 2,", Color.Red);
			overlay.Routes.Add(route2);

			List<GMap.NET.PointLatLng> list2 = new List<GMap.NET.PointLatLng>();
			for (int index = 0; index < overlay.Markers.Count; index++)
			{
				GMapMarker marker = overlay.Markers[index];
				string stationName = marker.Tag as string;	
				if (stationName.Contains("P�ROLS : �tant de l'or") ||
					stationName.Contains("P�rols Centre") ||
					stationName.Contains("EchoP�le") ||
					stationName.Contains("Parc Expo") ||
					stationName.Contains("Boirargues") ||
					stationName.Contains("Cougourlude") ||
					stationName.Contains("LATTES Centre"))
				{
					list2.Add(marker.Position);
				}
			}
			
			route1 = new GMapRoute(list2, "route1");
			SetBranchColor(route1, "Branche 1,", Color.Blue);
			overlay.Routes.Add(route1);
		}
 

Nov 6, 2012 at 7:20 PM

You maybe found something with the offset, im using another gmap control markers.

Coordinator
Nov 6, 2012 at 7:37 PM

well original GMapMarkerCircle renders at the center, so no need for offset:

g.DrawEllipse(Stroke, new System.Drawing.Rectangle(LocalPosition.X - R / 2, LocalPosition.Y - R / 2, R, R)); 

Nov 6, 2012 at 8:16 PM

In normal condition the circle is displayed just right, how can I calculate a new offset correctly? Weird that a minimize of the application or resize of gmap control set is okay.

Coordinator
Nov 6, 2012 at 8:28 PM

the other option is to manually call map.UpdateMarkerLocalPosition after changing the offset

Nov 7, 2012 at 12:18 PM

This seem to work! Thanks alot man.

Nov 30, 2012 at 1:06 PM
Edited Nov 30, 2012 at 1:07 PM

Aaah I spent 1,5 days trying to solving this issue .. And its this simple .. !! I also try to adjust marker size depending on the zoom level so when you zoom out the markers get smaller and you get a nicer overview.

Radioman, perhaps could you make a little adjustment in GMapMarker.cs to have a nice general fix?

Replacing the Offset property with this code works nicely for me when setting the Offset in the OnRender procedure of custom markers. The Position property already contains simular code.

If you'd rather have me make a fork and pull request for these small fixes please let me know I can do that. ;)

 

 

      public Point Offset
      {
         get
         {
            return offset;
         }
         set
         {
            if (offset.Equals(value))
                return; // keep performance up

            offset = value;

            if (IsVisible)
            {
                if (Overlay != null && Overlay.Control != null)
                {
                    Overlay.Control.UpdateMarkerLocalPosition(this);
                }
            }
         }
      }
Coordinator
Nov 30, 2012 at 1:37 PM

done!

Nov 30, 2012 at 1:39 PM

Thanks!