上一篇文章介紹瞭如何在WinForm和WPF中使用GMap控件,這篇介紹下GMap中Marker的使用。html
自定義Marker,能夠理解爲在地圖上自定義圖標(Custom Marker),先看看GMap的地圖和圖標的顯示方式:緩存
Map控件上能夠添加Overlay(圖層),能夠添加多個圖層,先添加的圖層在下面顯示。ide
圖層上能夠添加GMapMarker,固然也能夠添加GMapPolygon和GMapRoute,後續介紹。this
在地圖的使用中常要求的功能就是添加自定義圖標,能夠點擊圖標、刪除圖標、拖動圖標、高亮圖標等。google
下面介紹這些功能的實現(主要是基於WinForm的,WPF的能夠參考官方Demo實現):spa
一、自定義圖標,使用官方的Marker:code
Bitmap bitmap = Bitmap.FromFile("F:\\Projects\\GMapDemo\\GMapDemo\\Image\\A.png") as Bitmap; GMapMarker marker = new GMarkerGoogle(point, bitmap);
直接使用GMap.NET.WindowsForms.Markers中的GMarkerGoogle,傳入一個Bitmap,就能夠使用自定義的圖片來作圖標。orm
二、繼承GMapMarker,自定義Marker:htm
using System; using System.Collections.Generic; using System.Linq; using System.Text; using GMap.NET; using GMap.NET.WindowsForms; using System.Drawing; namespace GMapWinFormDemo { class GMapMarkerImage : GMapMarker { private Image image; public Image Image { get { return image; } set { image = value; if (image != null) { this.Size = new Size(image.Width, image.Height); } } } public Pen Pen { get; set; } public Pen OutPen { get; set; } public GMapMarkerImage(GMap.NET.PointLatLng p, Image image) : base(p) { Size = new System.Drawing.Size(image.Width, image.Height); Offset = new System.Drawing.Point(-Size.Width / 2, -Size.Height / 2); this.image = image; Pen = null; OutPen = null; } public override void OnRender(Graphics g) { if (image == null) return; Rectangle rect = new Rectangle(LocalPosition.X, LocalPosition.Y, Size.Width, Size.Height); g.DrawImage(image, rect); if (Pen != null) { g.DrawRectangle(Pen, rect); } if (OutPen != null) { g.DrawEllipse(OutPen, rect); } } public override void Dispose() { if (Pen != null) { Pen.Dispose(); Pen = null; } if (OutPen != null) { OutPen.Dispose(); OutPen = null; } base.Dispose(); } } }
介紹下GMapMarkerImage三個屬性的做用:blog
Image:保存圖標的圖片。
Pen:在圖片外圍畫DrawRectangle的Pen,當其不爲null的時候,會在圖片的外圍畫一個矩形,實現高亮(highlight)的效果。
OutPen:在圖片外圍畫DrawEllipse的Pen,當其不爲null的時候,會在圖片外圍畫一個一個橢圓,設置這個值能夠實現閃動。
三、移動圖標(Move Marker)的實現:
在MapControl中添加以下事件的響應:
mapControl.MouseDown += new MouseEventHandler(mapControl_MouseDown); mapControl.MouseUp += new MouseEventHandler(mapControl_MouseUp); mapControl.MouseMove += new MouseEventHandler(mapControl_MouseMove); mapControl.OnMarkerClick += new MarkerClick(mapControl_OnMarkerClick); mapControl.OnMarkerEnter += new MarkerEnter(mapControl_OnMarkerEnter); mapControl.OnMarkerLeave += new MarkerLeave(mapControl_OnMarkerLeave);
MouseDown和MouseUp中判斷左鍵是否按下(用左鍵來移動圖標)。
OnMarkerEnter中設置選中的Marker,同時設置Pen的值,實現高亮。
OnMarkerLeave中取消選中的Marker,取消Pen的值,取消高亮。
MouseMove中更新選中選中Marker的Position就能夠了。
四、圖標閃動的實現:
須要一個定時器:使用的是Form下的Timer,定時器響應的事件:
void blinkTimer_Tick(object sender, EventArgs e) { foreach (GMapMarker m in objects.Markers) { if (m is GMapMarkerImage) { GMapMarkerImage marker = m as GMapMarkerImage; if (marker.OutPen == null) marker.OutPen = new Pen(Brushes.Red, 2); else { marker.OutPen.Dispose(); marker.OutPen = null; } } } mapControl.Refresh(); }
更新全部Marker的OutPen的值(固然你也能夠只更新某個Marker),經過在圖標上畫圈圈來實現閃動,固然你也能夠經過設置Marker的IsVisible屬性來實現本身想要的效果。。。
效果圖以下:
所有代碼以下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using GMap.NET; using GMap.NET.WindowsForms; using GMap.NET.MapProviders; using GMap.NET.WindowsForms.Markers; namespace GMapWinFormDemo { public partial class MainForm : Form { private GMapOverlay objects = new GMapOverlay("objects"); //放置marker的圖層 private GMapMarkerImage currentMarker; private bool isLeftButtonDown = false; private Timer blinkTimer = new Timer(); public MainForm() { InitializeComponent(); try { System.Net.IPHostEntry e = System.Net.Dns.GetHostEntry("ditu.google.cn"); } catch { mapControl.Manager.Mode = AccessMode.CacheOnly; MessageBox.Show("No internet connection avaible, going to CacheOnly mode.", "GMap.NET Demo", MessageBoxButtons.OK, MessageBoxIcon.Warning); } mapControl.CacheLocation = Environment.CurrentDirectory + "\\GMapCache\\"; //緩存位置 mapControl.MapProvider = GMapProviders.GoogleChinaMap; //google china 地圖 mapControl.MinZoom = 2; //最小比例 mapControl.MaxZoom = 17; //最大比例 mapControl.Zoom = 5; //當前比例 mapControl.ShowCenter = false; //不顯示中心十字點 mapControl.DragButton = System.Windows.Forms.MouseButtons.Left; //左鍵拖拽地圖 mapControl.Position = new PointLatLng(32.064,118.704); //地圖中心位置:南京 mapControl.OnMapZoomChanged += new MapZoomChanged(mapControl_OnMapZoomChanged); mapControl.MouseClick += new MouseEventHandler(mapControl_MouseClick); mapControl.MouseDown += new MouseEventHandler(mapControl_MouseDown); mapControl.MouseUp += new MouseEventHandler(mapControl_MouseUp); mapControl.MouseMove += new MouseEventHandler(mapControl_MouseMove); mapControl.OnMarkerClick += new MarkerClick(mapControl_OnMarkerClick); mapControl.OnMarkerEnter += new MarkerEnter(mapControl_OnMarkerEnter); mapControl.OnMarkerLeave += new MarkerLeave(mapControl_OnMarkerLeave); mapControl.Overlays.Add(objects); } void mapControl_MouseMove(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left && isLeftButtonDown) { if (currentMarker != null) { PointLatLng point = mapControl.FromLocalToLatLng(e.X, e.Y); currentMarker.Position = point; currentMarker.ToolTipText = string.Format("{0},{1}", point.Lat, point.Lng); } } } void mapControl_MouseUp(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { isLeftButtonDown = false; } } void mapControl_MouseDown(object sender, MouseEventArgs e) { if (e.Button == System.Windows.Forms.MouseButtons.Left) { isLeftButtonDown = true; } } void mapControl_OnMarkerLeave(GMapMarker item) { if (item is GMapMarkerImage) { currentMarker = null; GMapMarkerImage m = item as GMapMarkerImage; m.Pen.Dispose(); m.Pen = null; } } void mapControl_OnMarkerEnter(GMapMarker item) { if (item is GMapMarkerImage) { currentMarker = item as GMapMarkerImage; currentMarker.Pen = new Pen(Brushes.Red, 2); } } void mapControl_OnMarkerClick(GMapMarker item, MouseEventArgs e) { } void mapControl_MouseClick(object sender, MouseEventArgs e) { if(e.Button == System.Windows.Forms.MouseButtons.Right) { //objects.Markers.Clear(); PointLatLng point = mapControl.FromLocalToLatLng(e.X,e.Y); //GMapMarker marker = new GMarkerGoogle(point, GMarkerGoogleType.green); Bitmap bitmap = Bitmap.FromFile("F:\\Projects\\GMapDemo\\GMapDemo\\Image\\A.png") as Bitmap; //GMapMarker marker = new GMarkerGoogle(point, bitmap); GMapMarker marker = new GMapMarkerImage(point, bitmap); marker.ToolTipMode = MarkerTooltipMode.OnMouseOver; marker.ToolTipText = string.Format("{0},{1}", point.Lat, point.Lng); objects.Markers.Add(marker); } } void mapControl_OnMapZoomChanged() { } private void buttonBeginBlink_Click(object sender, EventArgs e) { blinkTimer.Interval = 1000; blinkTimer.Tick += new EventHandler(blinkTimer_Tick); blinkTimer.Start(); } void blinkTimer_Tick(object sender, EventArgs e) { foreach (GMapMarker m in objects.Markers) { if (m is GMapMarkerImage) { GMapMarkerImage marker = m as GMapMarkerImage; if (marker.OutPen == null) marker.OutPen = new Pen(Brushes.Red, 2); else { marker.OutPen.Dispose(); marker.OutPen = null; } } } mapControl.Refresh(); } private void buttonStopBlink_Click(object sender, EventArgs e) { blinkTimer.Stop(); foreach (GMapMarker m in objects.Markers) { if (m is GMapMarkerImage) { GMapMarkerImage marker = m as GMapMarkerImage; marker.OutPen.Dispose(); marker.OutPen = null; } } mapControl.Refresh(); } } }