WPF使用 Gmap.NET 繪製極座標運動軌跡
阿新 • • 發佈:2020-04-09
大家好,已經很久沒有更新了,今天寫一篇關於WPF 使用 Gmap.NET 相關的,網上很多Winform的很**,所以我給Wpf進行一些補充。雖然它已經很久沒有更新了,但是也只能用這個了。沒別的好選擇的,畢竟它也沒啥可更新的,也可以理解。
使用它之前請Nuget安裝一下GMap.NET.Core、GMap.NET.WindowsPresentation 的庫。ok 我們直接開始。
我們在MainWindows中寫上一個WrapPanel 用於存放Gmap的容器。
<WrapPanel Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" x:Name="mapPanel">
隨後我們在MainWindows建構函式中進行配置,然後給mapPanel中添加了radarMap控制元件。還有滑鼠右擊的
public MainWindow() { m_viewModel = new ViewModelMain(); InitializeComponent(); radarMap = new GMap.NET.WindowsPresentation.GMapControl(); InitMapControl(radarMap); this.mapPanel.Children.Add(radarMap); radarMap.MouseRightButtonUp += RadarMap_MouseRightButtonUp; this.videoWindows.Child = pictureBox; DrawWarningArea(); }
隨後在初始化容器中配置一些地圖的設定,這裡面有一個靜態檔案,裡面也沒啥。自己也可以寫,我就不把Config寫出來了。
private void InitMapControl(GMap.NET.WindowsPresentation.GMapControl radarMap) { //radarMap.Name = "radarMap"; radarMap.Manager.Mode = AccessMode.ServerAndCache; radarMap.Position = Config.CenterPoint; radarMap.ShowCenter = false; radarMap.DragButton = System.Windows.Input.MouseButton.Left; radarMap.MinZoom = Config.MINZOOM; radarMap.MaxZoom = Config.MAXZOOM; radarMap.Zoom = Config.INITZOOM; radarMap.OnMapZoomChanged += radarMap_OnMapZoomChanged; }
這個是滑鼠右擊新增Marker的,這個就比較噁心了,由於Wpf中沒有overlays的概念,所以你就直接新增marker就行。具體看程式碼,這個裡面有個自定義控制元件。
List<PointLatLng> pointLatlngs = new List<PointLatLng>(); private void RadarMap_MouseRightButtonUp(object sender, MouseButtonEventArgs e) { Point clickPoint = e.GetPosition(radarMap); PointLatLng point = radarMap.FromLocalToLatLng((int)clickPoint.X, (int)clickPoint.Y); pointLatlngs.Add(point); GMapMarker currentMarker = new GMapMarker(point); { currentMarker.Shape = new CustomMarker(1,currentMarker, "custom position marker"); currentMarker.Offset = new System.Windows.Point(-15, -15); currentMarker.ZIndex = int.MaxValue; radarMap.Markers.Add(currentMarker); } }
具體是寫了個控制元件,要不Wpf沒辦法渲染上。
<UserControl x:Class="DisplayControlTerminal.Map.CustomMarker" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:DisplayControlTerminal.Map" mc:Ignorable="d" d:DesignHeight="5.75" d:DesignWidth="6"> <Image Name="icon" Source="/Resources/bigMarkerGreen.png" VerticalAlignment="Center" HorizontalAlignment="Center" Height="4" Margin="1,0,3,3" Width="2"/> </UserControl>
還有那個Circle是在DrawWarningArea裡畫出來的,呼叫了裡面帶參的建構函式,然後裡面就不用管了。
private void DrawWarningArea() { for (int i = 0; i < Config.SCOPE_DIS; i++) { GMapMarker it = new GMapMarker(Config.CenterPoint); it.ZIndex = -1; Circle c = new Circle((i + 1).ToString() + "km", (i + 1) * 1000); c.Tag = it; c.IsHitTestVisible = false; c.UpdateCircle(radarMap); it.Shape = c; radarMap.Markers.Add(it); Circles.Add(it); } GMapMarker crossCenter = new GMapMarker(Config.CenterPoint); Cross cross = new Cross(); cross.Tag = crossCenter; cross.SetOffset(); crossCenter.Shape = cross; //crossCenter.ZIndex = 55; radarMap.Markers.Add(crossCenter); //m.Shape = new CustomMarker(this, m, "ceshi"); //m.ZIndex = 55; //radarMap.Markers.Add(m); }
最重要的是如何畫軌跡,我第一時間就想到了Pen類,然後根據pointlatlng這個集合我們想辦法去搞事情,果不其然,我們只需要讓你的硬體裝置給你的那 pointLatlngs 集合中新增就行,但如何將經緯度轉換成本地座標 就比較複雜了。
List<PointLatLng> pointLatlngs = new List<PointLatLng>();
private void Button_Click(object sender, RoutedEventArgs e) { for (int i = 0; i < pointLatlngs.Count; i++) { GMapRoute gmRoute = new GMapRoute(new List<PointLatLng>() { pointLatlngs[i] , pointLatlngs.Count-1 == i ? pointLatlngs[i] : pointLatlngs[i + 1]}) { Shape = new Line() { StrokeThickness = 4, Stroke = System.Windows.Media.Brushes.BlueViolet } }; radarMap.Markers.Add(gmRoute); } }
最後效果圖