欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-02-28 18:14:22
自定义marker,可以理解为在地图上自定义图标(custom marker),先看看gmap的地图和图标的显示方式: map控件上可以添加overlay(图层),可...

自定义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();
        }
    }
}