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

WPF在Gmap.net中将Marker动起来

程序员文章站 2022-03-08 12:23:57
前一段时间说过一篇绘制极坐标的,这段时间对它进行了改造已经今非昔比了,功能实现了很多,我目的是让Marker动起来,然后还会绘制Route,上篇也就是简单的绘制了Route,没有关于Marker的相关知识。那个Circle有一定的改造,原来的纯色改成了渐变,这个你可以提前想好,不过在代码中你要做好适... ......

出处来源于博客园 作者张子浩 原文地址https://www.cnblogs.com/zaranet/p/12766143.html,如有转载,请联系我,如无经过作者同意,作者有权申请法律保护。

WPF在Gmap.net中将Marker动起来

   前一段时间说过一篇绘制极坐标的,这段时间对它进行了改造已经今非昔比了,功能实现了很多,我目的是让marker动起来,然后还会绘制route,上篇也就是简单的绘制了route,没有关于marker的相关知识。

  那个circle有一定的改造,原来的纯色改成了渐变,这个你可以提前想好,不过在代码中你要做好适配,将 system.draw.color  转换成了 media.color ,取其中的argb值。

public circle(string name, int radius,string[] vs)
        {
            radius = radius;
            m_viewmodelcircle = new viewmodelcircle();
            m_viewmodelcircle.circledis = name;
            this.datacontext = m_viewmodelcircle;
            initializecomponent();

            //控制circle

            radialgradientbrush radialgradient = new radialgradientbrush();
            var obj = colortranslator.fromhtml(vs[0]);
            var ob2 = colortranslator.fromhtml(vs[1]);
            var ob3 = colortranslator.fromhtml(vs[2]);
            this.circle.stroke= new solidcolorbrush(system.windows.media.color.fromargb(ob3.a, ob3.r, ob3.g, ob3.b)); 
            radialgradient.gradientstops.add(new gradientstop(system.windows.media.color.fromargb(obj.a, obj.r, obj.g, obj.b), 0.75));
            radialgradient.gradientstops.add(new gradientstop(system.windows.media.color.fromargb(ob2.a, ob2.r, ob2.g, ob2.b), 1));
            this.circle.fill = radialgradient;
        }

  我们都知道在wpf的gmap.net中没有了gmapoverlay 概念,所有的东西都在marker中操作,这样其实有一个优点,就是把overlay和marker混合在一起更好管理,你可以通过tag来寻找你对象,非常轻便,但设计者不是这么认为的,可能是某些原理没法走通。

  最基本的右击在map中添加标点可以这么操作。

private void radarmap_mouserightbuttonup(object sender, mousebuttoneventargs e)
        {
            point clickpoint = e.getposition(radarmap);
            pointlatlng point = radarmap.fromlocaltolatlng((int)clickpoint.x, (int)clickpoint.y);
            id += 1;
            gmapmarker currentmarker = new gmapmarker(point);
            {
                currentmarker.shape = new custommarker(id, currentmarker);
                //(currentmarker.shape as custommarker).setcontent(point, "1"); 这种方法可以触发setcontent
                currentmarker.zindex = -1;
                currentmarker.position = point;
                radarmap.markers.add(currentmarker);
                this.focus();
            }
        }

  代码中可以发现我们可以轻松将gmap的marker shape属性 ,随后转换成原来的marker类型,轻松调用属于它的方法,所以它的生命周期是等待它所在gmap中的marker被销毁才会被dispose,至于我的标点数据是从那里接受的,我只是启用两个demo而已,发了个udp通讯,一般来说都是使用结构体来接受,传入的byte值,我们进行逆转。

 public static object bytestostruct(byte[] buf, int len, type type)
        {
            // int len = marshal.sizeof(buf);
            object rtn;
            intptr buffer = marshal.allochglobal(len);
            marshal.copy(buf, 0, buffer, len);
            rtn = marshal.ptrtostructure(buffer, type);
            marshal.freehglobal(buffer);
            return rtn;
        }

  下面的代码是关于绘制,以及判断marker是否存在,如果存在则修改postion,而且还要重新绘制route,每个route是对应着它的marker,所以需要一个字典,每次重新绘制的时候,先将route全部删除,随后重新所有的点,然后进行绘制route,这个代码可能性能上有缺陷,但也是没有办法。

list<radartargetinfo> dislist = new list<radartargetinfo>();
        //已经添加的集合
        public list<radartargetinfo> addlist = new list<radartargetinfo>();
        //用于画线
        dictionary<string,list<pointlatlng>> pointlatlngsdic = new dictionary<string,list<pointlatlng>>();
        //标点和数据id的关系
        list<markerdatarole> rolelist = new list<markerdatarole>();
        /// <summary>
        /// 检查数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkdata(object sender, eventargs e)
        {
            if (currentmarkercontext.list.count == 0)
            {
                return;
            }
            //应该添加的数据
            var list = currentmarkercontext.list.except(addlist).tolist();
            addlist.addrange(list);
            dislist.clear();
            foreach (var group in list.groupby(u => u.id))
            {
                int flyid = group.key;
                radartargetinfo radartarget = new radartargetinfo();
                pointlatlng currentpoint = new pointlatlng();
                foreach (var item in group)
                {
                    pointlatlng point = new pointlatlng(item.latitude, item.longitude);
                    currentpoint = point;
                    //代表没有
                    if (rolelist.firstordefault(u => u.dataid == flyid) == null)
                    {
                        gmapmarker currentmarker = new gmapmarker(point);
                        {
                            currentmarker.shape = new custommarker(flyid, currentmarker);
                            currentmarker.zindex = -1;
                            currentmarker.tag = flyid;
                            currentmarker.position = point;
                            radarmap.markers.add(currentmarker);
                        }
                        rolelist.add(new markerdatarole(){dataid = flyid,markerid = flyid});
                    }
                    else
                    {
                        radarmap.markers.where(u => u.tag != null).where(u => convert.toint32(u.tag) == flyid).firstordefault().position = point;
                    }
                    var str = flyid.tostring();
                    if (pointlatlngsdic.containskey(str))
                    {
                        pointlatlngsdic[str].add(point);
                    }
                    else
                    {
                        var value = new list<pointlatlng>();
                        value.add(point);
                        pointlatlngsdic.add(str, value);
                    }
                    radartarget = item;
                }
                dislist.add(radartarget);
                //这里找到flyid
                (radarmap.markers.where(u => convert.toint32(u.tag) == flyid).firstordefault().shape as custommarker).setcontent(currentpoint, flyid);
            }
            this.雷达目标数据.itemssource = dislist;
            foreach (var item in radarmap.markers.where(u => u.tag != null).where(u => u.tag.tostring() == "line").tolist())
            {
                radarmap.markers.remove(item);
            }
            foreach (var item in pointlatlngsdic)
            {
                gmaproute gmroute = new gmaproute(pointlatlngsdic[item.key])
                {
                    shape = new line()
                    {
                        strokethickness = 4
                    },tag = "line"
                };
                radarmap.markers.add(gmroute);
            }
        }

  还有一个需要强调的是,上面说过可以通过shape找到本身调用其方法,那个marker上面的文本就是这么改的。

 public void setcontent(pointlatlng point, int pihao)
        {
            this.批号.content = pihao.tostring();
            this.纬度.content = "纬度:" + ((int)(point.lat * 1000) / 1000.0).tostring();
            this.经度.content = "纬度:" + ((int)(point.lng * 1000) / 1000.0).tostring();
        }

  (radarmap.markers.where(u => convert.toint32(u.tag) == flyid).firstordefault().shape as custommarker).setcontent(currentpoint, flyid);

   还有就是至于我的wpf程序自适应问题,我都是用viewbox做的,因为前端ui他老是玩margin,so...你懂的!人家都是blend for visual studio 给搞的。也只能见谅了.