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