WPF在Gmap.net中將Marker動起來

出處來源於博客園 做者張子浩 原文地址http://www.javashuo.com/article/p-hvbopqlo-dp.html,若有轉載,請聯繫我,如無通過做者贊成,做者有權申請法律保護。html

   前一段時間說過一篇繪製極座標的,這段時間對它進行了改造已經今非昔比了,功能實現了不少,我目的是讓Marker動起來,而後還會繪製Route,上篇也就是簡單的繪製了Route,沒有關於Marker的相關知識。前端

  那個Circle有必定的改造,原來的純色改爲了漸變,這個你能夠提早想好,不過在代碼中你要作好適配,將 System.draw.color  轉換成了 Media.Color ,取其中的ARGB值。git

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中添加標點能夠這麼操做。this

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值,咱們進行逆轉。spa

 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,這個代碼可能性能上有缺陷,但也是沒有辦法。.net

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);code

   還有就是至於個人Wpf程序自適應問題,我都是用Viewbox作的,由於前端UI他總是玩Margin,so...你懂的!人家都是Blend for visual Studio 給搞的。也只能見諒了.htm

相關文章
相關標籤/搜索