自定义Marker,可以理解为在地图上自定义图标(Custom Marker),先看看GMap的地图和图标的显示方式:
Map控件上可以添加Overlay(图层),可以添加多个图层,先添加的图层在下面显示。
图层上可以添加GMapMarker,当然也可以添加GMapPolygon和GMapRoute,后续介绍。
在地图的使用中常要求的功能就是添加自定义图标,可以点击图标、删除图标、拖动图标、高亮图标等。
下面介绍这些功能的实现(主要是基于WinForm的,WPF的可以参考官方Demo实现):
1、自定义图标,使用官方的Marker:
直接使用GMap.NET.WindowsForms.Markers中的GMarkerGoogle,传入一个Bitmap,就可以使用自定义的图片来做图标。
2、继承GMapMarker,自定义Marker:
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三个属性的作用:
Image:保存图标的图片。
Pen:在图片外围画DrawRectangle的Pen,当其不为null的时候,会在图片的外围画一个矩形,实现高亮(highlight)的效果。
OutPen:在图片外围画DrawEllipse的Pen,当其不为null的时候,会在图片外围画一个一个椭圆,设置这个值可以实现闪动。
3、移动图标(Move Marker)的实现:
在MapControl中添加如下事件的响应:
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就可以了。
4、图标闪动的实现:
需要一个定时器:使用的是Form下的Timer,定时器响应的事件:
更新所有Marker的OutPen的值(当然你也可以只更新某个Marker),通过在图标上画圈圈来实现闪动,当然你也可以通过设置Marker的IsVisible属性来实现自己想要的效果。。。
效果图如下:
全部代码如下:
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("www.google.com.hk"); } 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(); } }}
原文地址:http://www.poluoluo.com/jzxy/201312/255039.html