GMap.Net开发之自定义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("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();
        }
    }
}

(0)

相关推荐

  • c#调用arcgis地图rest服务示例详解(arcgis地图输出)

    1.使用步骤 1)构建请求网址 A.确定端点:每个GIS服务都有一个端点.例如,ArcGIS Server上Demographics文件夹下名为ESRI_Census_USA的一个地图服务sampleserver1.arcgisonline.com的端点为:http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer. B.确定操作:不同地理信息系统服务支持不同的

  • android实现百度地图自定义弹出窗口功能

    我们使用百度地图的时候,点击地图上的Marker,会弹出一个该地点详细信息的窗口,如下左图所示,有时候,我们希望自己定义这个弹出窗口的内容,或者,干脆用自己的数据来构造这样的弹出窗口,但是,在百度地图最新的Android SDK中,没有方便操作这种弹出窗口的类,虽然有一个PopupOverlay,但是它只支持将弹出内容转化为不多于三个Bitmap,如果这个弹出窗口里想有按钮来响应点击事件,用这个就不能满足要求了,于是,看了一遍百度地图覆盖物的API,我决定用自定义View的方法来实现类似的效果,

  • 基于Arcgis for javascript实现百度地图ABCD marker的效果

    先给大家展示实现后效果: 为直观期间,先贴出来我做的效果 列表展示和地图展示以及联动 显示信息 实现思路: 1.列表与地图的互动 鼠标经过列表时,修改列表图标,并根据列表返回的值在地图上绘蓝色的marker:鼠标移出,修改列表图标为红色,清空地图marker图层. 关键代码: title.on("mouseover",function(){ var attr = $(this).data("attr"); $("#icon"+attr.id).c

  • js 调用百度地图api并在地图上进行打点添加标注

    最近要做一个网页,具体内容是:上边有一个标题,下边分成两块,左边是地图.并且地图上有两个点,点击两个点有相应的提示信息,显示数据库里最新的两条数据信息.右边是一些文字说明.本人刚开始学习,做的也不是很好 总体效果如下所示: 首先新建map.php文件,代码如下 复制代码 代码如下: <!DOCTYPE html> <?php /* 创建与数据库的连接 */ $conn=mysql_connect("","","") or die

  • spring mvc整合freemarker基于注解方式

    基于网络改进为:最正常版本 复制代码 代码如下: <?xml version="1.0" encoding="UTF-8"?> <beans     xmlns="http://www.springframework.org/schema/beans"     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xmlns:p="htt

  • javascript使用百度地图api和html5特性获取浏览器位置

    复制代码 代码如下: <!DOCTYPE html><html><body><p id="demo">点击这个按钮,获得您的位置:</p><button onclick="getLocation()">试一下</button><script src="http://api.map.baidu.com/api?v=1.4" type="text/ja

  • java Spring整合Freemarker的详细步骤

    我的開發環境框架:springmvc開發工具:springsource-tool-suite-2.9.0版本:1.6.0_29tomcat版本:apache-tomcat-7.0.26前言:FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出.FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP.它不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java 等.簡而言之,Freemarker就是在Jave Web開發

  • 百度地图API应用之获取用户的具体位置

    功能的大概:用户通过点击地图上面的位置,在地图上面进行描点,然后再把获取的到的地理位置保存到地图上面的地址栏目中. 主要是百度地图API的使用 复制代码 代码如下: var map = new BMap.Map("allmap"); //实例化一个地图对象var point = new BMap.Point(116.331398,39.897445); //设置地图中心的位置map.centerAndZoom(point,12); //设置地图元素的可视层 map.enableScro

  • freemarker 数字格式化深入理解

    一.使用内建函数c 特点: 不管其表现形式是怎样的(例如"123,456.123,456"."123456.123456"."000123456.123456000"."123,456.123456"."1,2345,6.123456"),只要小数分割符是'.'它就能转化成计算机能够识别的字符串形式,而且都是123456.123456,计算机处理的时候是没有那些所谓的千位分隔符的(空格或逗号),而且计算机支

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

    自定义Marker,可以理解为在地图上自定义图标(Custom Marker),先看看GMap的地图和图标的显示方式: Map控件上可以添加Overlay(图层),可以添加多个图层,先添加的图层在下面显示. 图层上可以添加GMapMarker,当然也可以添加GMapPolygon和GMapRoute,后续介绍. 在地图的使用中常要求的功能就是添加自定义图标,可以点击图标.删除图标.拖动图标.高亮图标等. 下面介绍这些功能的实现(主要是基于WinForm的,WPF的可以参考官方Demo实现): 1

  • iOS开发之自定义UITextField的方法

    UITextField是IOS开发中用户交互中重要的一个控件,常被用来做账号密码框,输入信息框等. 观察效果图 UITextField有以下几种特点: 1.默认占位文字是灰色的 2.当光标点上去时,占位文字变为白色 3.光标是白色的 接下来我们通过不同的方法来解决问题 一.将xib中的UITextField与代码关联 通过NSAttributeString方法来更改占位文字的属性 (void)viewDidLoad { [super viewDidLoad]; // Do any additio

  • Android基于高德地图完全自定义Marker的实现方法

    前言 相信做地图社交类APP开发的大家都知道,一般情况下,为了整体的美观和用户体验度,我们需要定制化Marker的样式.本文中实现的方式都是基于高德地图的,百度地图也类似,大家可以照葫芦画瓢,废话不多说,先来看看最终效果: 实现思路: 先来看看高德官方提供的设置Marker图标的方法: 我们可以看到setIcon()方法,里面的参数BitmapDescriptor就是我们最终需要的东西.那么到底该如何得到这个BitmapDescriptor对象呢,其实很简单,该对象可以通过BitmapDescr

  • Android开发使用自定义View将圆角矩形绘制在Canvas上的方法

    本文实例讲述了Android开发使用自定义View将圆角矩形绘制在Canvas上的方法.分享给大家供大家参考,具体如下: 前几天,公司一个项目中,头像图片需要添加圆角,这样UI效果会更好看,于是写了一个小的demo进行圆角的定义,该处主要是使用BitmapShader进行了渲染(如果要将一张图片裁剪成椭圆或圆形显示在屏幕上,也可以使用BitmapShader来完成). BitmapShader类完成渲染图片的基本步骤如下: 1.创建BitmapShader类的对象 /** * Call this

  • Android开发中自定义ProgressBar控件的方法示例

    本文实例讲述了Android开发中自定义ProgressBar控件的方法.分享给大家供大家参考,具体如下: 很简单,首先加载Drawable,在onMeasure设置好其区域大小, 然后使用canvas.clipRect绘图 public class ProgressView extends ImageView { private Drawable maskDraw; /** * 加载的进度 0-100 */ private int mProcess = 20; public ProgressV

  • php微信开发之自定义菜单完整流程

    一.自定义菜单概述 自定义菜单能够帮助公众号丰富界面,让用户更好更快地理解公众号的功能.开启自定义菜单后,公众号界面如图所示: 二.申请自定义菜单 个人订阅号使用微博认证.企业订阅号通过微信认证:可以申请到自定义菜单资格 服务号默认有菜单权限. 三.获得AppId 和AppSecert AppId和AppSecret在开发者中心-开发者ID中,可以找到. 四.获得Access Token 用appid和appsecert获得access token,接口为 https://api.weixin.

  • AngularJS创建自定义指令的方法详解

    本文实例讲述了AngularJS创建自定义指令的方法.分享给大家供大家参考,具体如下: 这是一篇译文,来自angular开发者说明的指令.主要面向已经熟悉angular开发基础的开发者.这篇文档解释了什么情况下需要创建自己的指令,和如何去创建指令. 什么是指令 从一个高的层面来讲,指令是angular $compile服务的说明,当特定的标签(属性,元素名,或者注释) 出现在DOM中的时候,它让编译器附加指定的行为到DOM上. 这个过程是很简单的.angular内部有很用这样自带的指令,比如说n

  • IOS 开发之自定义按钮实现文字图片位置随意定制

    IOS 开发之自定义按钮实现文字图片位置随意定制 可能有些看到这篇文章的朋友会觉得很不屑:"按钮谁不会自定义?还需要看你的?" 也确实,按钮是我们项目中最常见的控件之一,天天在使用.对于不同类型的按钮,我们是否有更加简便的方法来实现需求是我们需要做的.这里我提出自己的两种方法,您可以对你自己平时自定义按钮的方法做一下对比,看看哪种方法更加简单. 多说一句,千万不要觉得知识简单,觉得自己会了,没必要学习.'往往简单的东西存在大智慧'(这个比给满分),知识都是慢慢积累出来的. 按钮是应用中

  • 使用asp.net mvc,boostrap及knockout.js开发微信自定义菜单编辑工具(推荐)

    前言 微信的接口调试工具可以编辑自定义菜单,不过是提交json格式数据创建菜单,非常的不方便还容易出错.网上的工具不好用,所以就自己写了一个. 正文 先用bootstrap排个页面框架出来,调用自定义菜单接口需要用到AccessToken,放个输入框输入AccessToken.也不排除想直接输入AppId和AppSecret来获取AccessToken的用户,所以还需要下拉菜单来选择是输入AccessToken还是直接获取AccessToken.为了兼顾微信企业号应用创建菜单还需要AgentId

  • wamp安装后自定义配置的方法

    WampServer是目前应用非常广泛的PHP集成开发环境,本文就来讲述Wamp安装后自定义配置的方法.供大家参考借鉴.具体如下: wamp2.5安装完毕后,自己手动重新设置了apache的默认根目录.但是发现本机可以访问,别人不能访问. 提示信息为:Forbidden  you dont hava permission to access * on the server 表示你没有权限访问! 这是比较常见的问题,应该只需修改目录的权限就可以了. 搜索网上讲述的很多方法后发现,都是说把有'den

随机推荐