1. 程式人生 > >GMap.Net開發之自定義Marker

GMap.Net開發之自定義Marker

上一篇文章介紹瞭如何在WinForm和WPF中使用GMap控制元件,這篇介紹下GMap中Marker的使用。

自定義Marker,可以理解為在地圖上自定義圖示(Custom Marker),先看看GMap的地圖和圖示的顯示方式:

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屬性來實現自己想要的效果。。。

效果圖如下:

全部程式碼如下:

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();
        }
    }
}
View Code

相關推薦

GMap.Net開發定義Marker

上一篇文章介紹瞭如何在WinForm和WPF中使用GMap控制元件,這篇介紹下GMap中Marker的使用。 自定義Marker,可以理解為在地圖上自定義圖示(Custom Marker),先看看GMap的地圖和圖示的顯示方式: Map控制元件上可以新增Overlay(圖層),可以新增多個圖層,先新增

Revit二次開發 定義選項卡排在最前端

引用AdWindows.dll類庫  Autodesk.Windows.RibbonControl ribbon = AutodeskWindows.ComponentManager.Ribbon;        

Android 開發定義控制元件開發-01

最近一直在忙於公司的專案,因為要去現場測試正式使用,專案不大但是經手了三個人,到我這裡只能去填坑了,不說這個了,說一下今天得主題,自定義控制元件之基本圖形繪製。 我們平時畫圖需要兩種工具:紙和筆。在Android中 Paint 就是畫筆,而Canvas類就是紙,在這裡叫做畫布。 所以

Java微信公眾平臺開發定義選單

一、自定義選單的說明和按鈕型別 1、選單說明 1)自定義選單最多包括3個一級選單,每個一級選單最多包含5個二級選單。 2)一級選單最多4個漢字,二級選單最多7個漢字,多出來的部分將會以“...”代替。 3)建立自定義選單後,選單的重新整理策略是,在使用者進入公

Android 開發定義控制元件開發-02

1.畫筆的基本設定 : 1.setColor() 該函式的作用是設定畫筆顏色,完整的函式宣告如下: void setColor(int color) 我們知道,一種顏色是由紅、綠、藍三色合成出來的,所以引數 color 只能取8位的0xAARRGGBB樣式顏色值。 其中:

iOS開發定義圓環式Slider

#pragma mark - UIControl functions //開始跟蹤觸控 -(BOOL) beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event { [super beginTrackingWithTouch:

Android軟體開發 定義控制元件

Android軟體開發之 自定義控制元件 雖然Android系統提供了各種各樣的控制元件供我們開發使用,但在實際的開發中,系統提供的控制元件有時候不能滿足我們的需求,這時我們就需要自定義一個控制元件。 下面的例子就來自定義一個簡單的Button: 首先是佈局,image_btn.xml: <?xml

Android開發定義可清空內容的EditText

在開發過程中不可避免的總會遇到比如登入註冊、使用者資訊修改等,這時候又是不可避免的會用到EditText控制元件。這個控制元件的使用頻率雖然幾乎類似我們吃飯用“筷子”的頻率,but能不能用出花樣

Android開發定義控制元件--ViewPager

package com.itheima18.viewpager; import java.util.ArrayList; import java.util.Timer; import java.util.concurrent.Executors; import java.util.concurrent.Sc

Android開發定義圓角矩形圖片ImageView

android中的ImageView只能顯示矩形的圖片,這樣一來不能滿足我們其他的需求,比如要顯示圓角矩形的圖片,這個時候,我們就需要自定義ImageView了,其原理就是首先獲取到圖片的Bitmap,然後進行裁剪對應的圓角矩形的bitmap,然後在onDraw()進行繪製

GMap.Net開發在WinForm和WPF中使用GMap.Net地圖外掛

GMap.NET是什麼? 來看看它的官方說明:GMap.NET is great and Powerful, Free, cross platform, open source .NET control. Enable use routing, geocoding, directions and maps

GMap.Net開發在地圖上新增多邊形

上一篇介紹了在GMap上新增自定義標籤(GMapMarker),這篇介紹在GMap上新增多邊形(GMapPolyogn),並且介紹如何在地圖上畫任意的多邊形。 如果已經知道了多邊形的各個點的位置,就可以通過如下方式在地圖上新增多邊形: GMapOverlay polyOverlay = new GMa

GMap.Net開發地址解析與路徑查詢

上一篇介紹瞭如何在GMap地圖上新增多邊形,這篇介紹下如何使用線上的地圖服務進行“地址解析”和“路徑查詢”。 先看地址解析,GMap中的地址解析主要用到GeocodingProvider中的如下方法: //根據關鍵字得到一組座標 GeoCoderStatusCode GetPoints(string

android開發定義屬性、View和使用

“自定義”這三字聽起來就像是一個高階程式設計師所擁有的一樣!太不接地氣了!come on,baby,讓我們成為高階程式設計師吧!哈哈! 第一步:首先建立一個工程專案,在專案中的res/values/下建立atts.xml檔案,在該檔案中: <?xml version

iOS開發定義鍵盤(數字,字母型別等隨意切換)

專案開發很多時候用系統給的鍵盤不是很滿足自身實際需求,那就自定義一個吧: 方法其實很簡單,重新定義一個view,繼承UItextfield,把UI設計好的需求鍵盤加入新的otherKeyboardView,然後執行程式碼:  self.inputView =self.oth

iOS開發定義導航欄返回按鈕右滑返回手勢失效的解決---親測是有效的。

問題一:怎麼自定義leftItem問題二:為什麼系統自帶的右滑返回手勢失效問題三:怎麼解決這個失效問題3.怎麼解決這個失效問題 其實很簡單很簡單~只需要新增下面這一句程式碼即可self.navigationController.interactivePopGestureRe

Android開發定義控制元件(一)---onMeasure詳解

         話說一個有十年的程式設計經驗的老漢,決定改行書法,在一個熱火炎炎的中午,老漢拿著毛筆,在一張白紙上寫了個“Hello World!”,從此開啟了他的書法旅程。那麼問題來了請問自定義一個控制元件需要怎樣的流程?我們經常說自定義控制元件,那麼究竟怎樣去自定義一

java版微信公眾號開發定義選單的建立

廢話(不過還是必須得看):在微信公眾號啟動開發者模式之後,微信公眾號後臺的自定義選單便無法再使用!需要自己在伺服器上進行自定義選單的開發。自定義選單介面地址:https://api.weixin.qq.com/cgi-bin/menu/create?access_token

iOS開發定義載入等待框(MBProgressHUD)

原文地址:http://blog.csdn.net/ryantang03/article/details/7877120 MBProgressHUD是一個開源專案,實現了很多種樣式的提示框,使用上簡單、方便,並且可以對顯示的內容進行自定義,功能很強大,很多專案中都有

iOS開發定義導航欄返回按鈕右滑返回手勢失效的解決

我相信針對每一個iOS開發者來說~除了根檢視控制器外~所有的介面通過導航欄push過去的介面都是可以通過右滑來返回上一個介面~其實~在很多應用和APP中~使用者已經習慣了這個功能~然而~作為開發者的我們~也並沒有為此做些什麼~因為我們在建立專案時~蘋果公司已經為我們都做好了~那麼~我們這期就來聊一聊這系統