GMap.Net开发之自定义Marker使用方法

  自定义Marker,可以理解为在地图上自定义图标(Custom Marker),先看看GMap的地图和图标的显示方式:

GMap.Net开发之自定义Marker使用方法

  Map控件上可以添加Overlay(图层),可以添加多个图层,先添加的图层在下面显示。

  图层上可以添加GMapMarker,当然也可以添加GMapPolygon和GMapRoute,后续介绍。

  在地图的使用中常要求的功能就是添加自定义图标,可以点击图标、删除图标、拖动图标、高亮图标等。

  下面介绍这些功能的实现(主要是基于WinForm的,WPF的可以参考官方Demo实现):

  1、自定义图标,使用官方的Marker:

  

复制代码 代码如下:

  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,就可以使用自定义的图片来做图标。

  2、继承GMapMarker,自定义Marker:

  

复制代码 代码如下:

  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三个属性的作用:

  Image:保存图标的图片。

  Pen:在图片外围画DrawRectangle的Pen,当其不为null的时候,会在图片的外围画一个矩形,实现高亮(highlight)的效果。

  OutPen:在图片外围画DrawEllipse的Pen,当其不为null的时候,会在图片外围画一个一个椭圆,设置这个值可以实现闪动。

  3、移动图标(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就可以了。

  4、图标闪动的实现:

  需要一个定时器:使用的是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属性来实现自己想要的效果。。。

  效果图如下:

GMap.Net开发之自定义Marker使用方法

  全部代码如下:

  

复制代码 代码如下:

  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("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();

  }

  }

  }