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:그림 외곽 에 Draw Rectangle 의 Pen 을 그립 니 다.null 이 아 닐 때 그림 외곽 에 직사각형 을 그 려 하 이 라이트(highlight)효 과 를 냅 니 다.
OutPen:그림 외곽 에 Draw Ellipe 의 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);
마우스 다운 과 마우스 업 에서 왼쪽 키 를 눌 렀 는 지 여 부 를 판단 합 니 다(왼쪽 키 로 아이콘 이동).OnMarkerEnter 에 선 택 된 Marker 를 설정 하고 Pen 의 값 을 설정 하여 하 이 라 이 트 를 구현 합 니 다.
OnMarkerLeave 에서 선택 한 Marker 를 취소 하고 Pen 의 값 을 취소 하 며 하 이 라 이 트 를 취소 합 니 다.
Mouse Move 에서 선택 한 Marker 의 포지션 을 업데이트 하면 됩 니 다.
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 속성 을 설정 하여 원 하 는 효 과 를 실현 할 수도 있 습 니 다.효과 도 는 다음 과 같다.
모든 코드 는 다음 과 같 습 니 다:
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();
}
}
}