• WPF在Gmap.net中将Marker动起来


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

       前一段时间说过一篇绘制极坐标的,这段时间对它进行了改造已经今非昔比了,功能实现了很多,我目的是让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 给搞的。也只能见谅了.

  • 相关阅读:
    第三章函数
    基本数据类型
    gulp压缩js
    read/load
    jQuery的类数组对象结构
    立即调用表达式
    npm
    cocos2d.js
    图片上传后压缩 Thinkphp
    判断用户是否在微信中
  • 原文地址:https://www.cnblogs.com/ZaraNet/p/12766143.html
Copyright © 2020-2023  润新知