WPF 使用 Gmap.NET 绘制极坐标运动轨迹

367 阅读3分钟

前言

尽管网上已有不少关于WinForms平台下GMap.NET的教程,但对于WPF开发者来说,相关信息相对匮乏。因此,本文在填补这一空白,为WPF用户提供详尽的指导和实用技巧。

虽然GMap.NET项目本身已经很久没有更新,但其稳定性和功能性依然使其成为许多开发者在.NET平台上处理地图显示和交互时的首选工具。

考虑到当前市场上缺乏更好的替代方案,继续使用并优化GMap.NET仍然是一个合理的选择。事实上,由于其核心功能已经非常成熟,进一步的重大更新需求并不强烈。

正文

使用它之前请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);
    }
}

最后效果图

总结

通过本次分享,我们希望为WPF开发者提供了宝贵的参考资料,帮助在项目中更高效地集成GMap.NET。

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

优秀是一种习惯,欢迎大家留言学习!

作者:ZaraNet

出处:cnblogs.com/ZaraNet/p/12661384.html

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!