WPF 与 GMap.NET 结合实现雷达目标动态显示与地图绘制
概述 雷达上位机是雷达系统中用于数据可视化、分析和控制的核心软件。本文将介绍如何使用 C# 和 WPF 框架开发一个雷达上位机程序,主要功能包括:
- 显示目标轨迹:在界面上实时绘制雷达探测到的目标轨迹。
- 点击显示详细信息:用户点击目标轨迹时,显示目标的详细信息(如速度、方位、距离等)。
- 地图集成:使用 GMap.NET 控件集成地图,将目标轨迹显示在地图上。
程序主界面

程序主要涉及两方面的技术:地图集成和WPF绘图
地图集成
在地图功能中,我们选用了 GMap 控件。通过向 GMap 控件添加 Marker,并将 Marker 绑定到自定义用户控件,所有地图上的绘制操作都在用户控件中完成。关于 GMap 的使用方法,网上已有大量详细的教程和文档,因此本文不再赘述。
GMapMarker maker = new GMapMarker(center);_radarScan = new UserControl_RadarScan() { Marker = maker, MapCtrl = gMapControl };maker.Shape = _radarScan;gMapControl.Markers.Add(maker);_radarScan.Init();await Task.Delay(1000);_radarScan.Show();
雷达目标的绘制:该部分主要涉及 WPF 绘图技巧。为了实现灵活的绘制效果,我们设计了一个用户控件,其界面结构如下:
<Grid><draw:DrawingCanvas x:Name="drawingCanvas" RenderOptions.BitmapScalingMode="HighQuality"SnapsToDevicePixels="False"RenderOptions.ClearTypeHint="Auto" RenderOptions.CachingHint="Cache"></draw:DrawingCanvas><draw:DrawingCanvas x:Name="drawingCanvasTop" IsHitTestVisible="False"RenderOptions.BitmapScalingMode="HighQuality"SnapsToDevicePixels="False"RenderOptions.ClearTypeHint="Auto" RenderOptions.CachingHint="Cache"></draw:DrawingCanvas></Grid>
包含两个 Canvas:
drawingCanvas:用于绘制雷达扫描状态。
drawingCanvasTop:用于显示提示信息(由于提示信息需要始终位于最顶层,因此采用两个 Canvas 分层处理)。
主要的绘制操作在 drawingCanvas 上进行。通过将 DrawingVisual 添加到 Canvas 中,我们可以实现高效的图形绘制。
使用 DrawingVisual 进行绘制
在使用 DrawingVisual 进行绘制时,有一个关键点需要注意:所绘制的线条大小会随着地图的缩放而变化。然而,每个点对应的经纬度是固定不变的。因此,所有数据都以经纬度的形式存储,而在实际绘制时,需要将经纬度转换为控件坐标,再进行绘制。
关键步骤
1 数据存储:所有目标点的位置信息以经纬度形式存储,确保数据的精确性和一致性。
2 坐标转换:在绘制之前,需要将经纬度坐标转换为 GMap 控件对应的像素坐标。GMap 控件提供了内置的方法(如 FromLatLngToLocal)来完成这一转换。
3 动态绘制:由于地图缩放会影响绘制的线条大小,因此在每次地图缩放或移动时,都需要重新计算坐标并刷新绘制内容,以确保图形与地图的匹配。
以下是一个简单的示例,展示如何将经纬度转换为控件坐标并进行绘制:
// 将经纬度转换为控件坐标
PointLatLng latLng = new PointLatLng(39.9042, 116.4074); // 示例经纬度
Point controlPoint = MapControl.FromLatLngToLocal(latLng);// 创建 DrawingVisual
DrawingVisual visual = new DrawingVisual();
using (DrawingContext dc = visual.RenderOpen())
{// 绘制线条或点dc.DrawLine(new Pen(Brushes.Red, 2), controlPoint, new Point(controlPoint.X + 50, controlPoint.Y + 50));
}// 将 DrawingVisual 添加到 Canvas
drawingCanvas.AddVisual(visual);
注意事项
性能优化:由于地图缩放和移动会频繁触发重绘操作,建议对绘制逻辑进行优化,避免性能瓶颈。
动态更新:如果目标点是动态变化的,需要实时更新绘制内容,并确保坐标转换的准确性。
文章总结 本文详细介绍了基于 WPF 和 GMap.NET 的雷达上位机开发过程,重点围绕 地图集成 和 WPF 绘图 两大核心功能展开。以下是本文的主要内容与关键技术点:
地图集成:
使用 GMap.NET 控件实现地图功能,支持多种地图提供商(如 OpenStreetMap)。
通过添加 Marker 并将 Marker 绑定到自定义用户控件,实现了地图上的动态绘制。
经纬度坐标与控件坐标的转换是地图绘制的关键,确保图形随地图缩放时仍能准确定位。
WPF 绘图:
采用 DrawingVisual 进行高效绘制,结合 Canvas 的分层设计,实现了雷达扫描状态和提示信息的分离显示。
通过将经纬度数据转换为控件坐标,解决了地图缩放对绘制效果的影响问题。
动态绘制功能支持实时更新目标轨迹,并提供了良好的用户体验。
技术亮点:
坐标转换:将经纬度数据转换为控件坐标,确保绘制内容与地图的精确匹配。
分层绘制:利用多个 Canvas 实现分层绘制,确保提示信息始终位于最顶层。
高效绘制:使用 DrawingVisual 提升绘制性能,适合处理动态变化的雷达目标数据。
扩展性与优化:
本文的实现方法具有良好的扩展性,可进一步支持实时数据更新、轨迹历史回放、多目标跟踪等功能。
针对地图缩放和动态绘制的性能优化,为大规模数据处理提供了基础
相关文章:
WPF 与 GMap.NET 结合实现雷达目标动态显示与地图绘制
概述 雷达上位机是雷达系统中用于数据可视化、分析和控制的核心软件。本文将介绍如何使用 C# 和 WPF 框架开发一个雷达上位机程序,主要功能包括: 显示目标轨迹:在界面上实时绘制雷达探测到的目标轨迹。点击显示详细信息:用户点击…...
A SURVEY ON POST-TRAINING OF LARGE LANGUAGE MODELS——大型语言模型的训练后优化综述——第2部分
3、微调(上一部分内容) 4、LLMs的对齐 大型语言模型(LLMs)中的对齐涉及引导模型输出以符合人类预期和偏好,特别是在安全关键或用户面对的应用程序中。本章讨论了实现对齐的三个主要范式: 带有反馈的人工…...
pytest快速入门 - 目录:半天掌握pytest
1 pytest快速入门 - 目录 本系列文章将快速的带领用户进入pytest领域,通过阅读本专栏,用户将可以熟练掌握pytest的基本用法,同时对测试前置条件的构造、后置条件的清理等有较深入的了解,特别是后置条件的执行完备度有一个认识。 …...
2018年全国职业院校技能大赛高职组-计算机网络应用竞赛竞赛样题C卷
目录 总体规划 模块二:设备基础信息配置 模块三:网络搭建与网络冗余备份方案部署 模块四:移动互联网搭建与网优 模块五:出口安全防护与远程接入 总体规划 CII教育公司在进行企业大学信息化建设的过程中,为了保证北京校区、广州校区与本部校区的日常OA办公通信等关键业务,…...
某大厂自动化工程师面试题
一些大厂的自动化工程师面试题汇总: 基础知识类 请解释什么是PLC(可编程逻辑控制器)?什么是PID控制?它在自动化系统中的作用是什么?请描述一下工业4.0的基本概念。编程与控制系统类 你熟悉哪些PLC编程语言?请举例说明。如何在SCADA系统中实现数据采集和监控?请解释一下…...
L1-7 统一命名规范(java)
你所在的公司刚刚招收了几位程序员,然而这些程序员之前在不同的公司工作,所以他们习惯的变量命名规范可能存在差异,需要让他们都习惯公司要求的命名规范,然而这样可能会降低他们的工作效率。 你的上司找到了你,希望你…...
ES6回顾:闭包->(优点:实现工厂函数、记忆化和异步实现)、(应用场景:Promise的then与catch的回调、async/await、柯里化函数)
闭包讲解 ES6回顾:闭包->(优点:实现工厂函数、记忆化和异步实现)、(应用场景:Promise的then与catch的回调、async/await、柯里化函数) 以下是与 JavaScript 闭包相关的常见考点整理,结合 Pro…...
zend server试用分析
文件:ZendServer-2021.4.1-multi-php-Windows_x86.exe 安装后可以试用30天,想分析下限制原理, 根据安装日志,发现了2个关键的文件: ZendServer\gui\module\Configuration\src\Configuration\License\Wrapper.php ZendServer\gu…...
C# NX二次开发:在多个体的模型中如何实现拉伸操作布尔减
大家好,今天接着上一篇拉伸文章去讲。 UF_MODL_create_extruded1 (view source) uf_list_p_tobjectsInputList of objects to be extruded.char *taper_angleInputTaper angle (in degrees).char *limit [ 2 ]InputLimit of extrusion. This is declared as: char …...
15 | 定义简洁架构 Store 层的数据类型
提示: 所有体系课见专栏:Go 项目开发极速入门实战课;欢迎加入 云原生 AI 实战 星球,12 高质量体系课、20 高质量实战项目助你在 AI 时代建立技术竞争力(聚焦于 Go、云原生、AI Infra);本节课最终…...
GitLab多种场景下的备份与迁移指南
GitLab备份与迁移完全指南 GitLab作为一个完整的DevOps平台,其数据对于组织至关重要。无论是版本升级、服务器迁移还是灾难恢复,掌握GitLab的备份和迁移技术都是系统管理员的必备技能。本文将详细介绍GitLab的备份策略和各种场景下的迁移方法。 目录 GitLab备份基础知识Omn…...
2.3 滑动窗口专题:最大连续1的个数 III(LeetCode 1004)
1. 题目链接 1004. 最大连续1的个数 III - 力扣(LeetCode)https://leetcode.cn/problems/max-consecutive-ones-iii/ 2. 题目描述 给定一个二进制数组 nums 和一个整数 k,允许将最多 k 个 0 翻转为 1,求翻转后最长的连续 1 …...
【微服务】Nacos 配置动态刷新(简易版)(附配置)
文章目录 1、实现方法2、配置依赖 yaml3、验证效果 1、实现方法 环境:Nacos、Java、SpringBoot等 主要是在boostrap.yaml中的data-id属性下配置refresh:true来实现动态更新 2、配置依赖 yaml 具体的版本参考官方的说明:官方版本说明 <!--读取boo…...
六十天前端强化训练之第二十天React Router 基础详解
欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗,谢谢大佬! 目录 一、核心概念 1.1 核心组件 1.2 路由模式对比 二、核心代码示例 2.1 基础路由配置 2.2 动态路由示例 2.3 嵌套路由实现 2.4 完整示例代码 三、关键功能实现效果 四、…...
高级java每日一道面试题-2025年2月26日-框架篇[Mybatis篇]-Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式 ?
如果有遗漏,评论区告诉我进行补充 面试官: Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式 ? 我回答: 在Java高级面试中讨论MyBatis如何将SQL执行结果封装为目标对象并返回的过程时,我们可以从过程细节和映射形式两个方面来综合解答这个问…...
人工智能之数学基础:如何将线性变换转换为矩阵?
本文重点 在机器学习中,常用的理论就是线性变换,线性变化一定有对应的矩阵表示,非线性变换是不具备这个性质的,那么现在如果有一个线性变换T那么如何知道它对应的矩阵呢? 线性变换的本质 我们知道线性变换相当于一个函数,而矩阵也是一个函数,所以线性变换一定存在一个…...
用 DeepSeek 构建 Vue.js 底层架构:高效协作与问题解决实践
文章目录 1. **DeepSeek 与 Vue.js 的完美协作**2. **问题背景**3. **问题分析与解决**3.1 **动态路由未正确生成**3.2 **路由路径配置错误**3.3 **路由嵌套问题**3.4 **通配符路由未配置** 4. **DeepSeek 的核心价值** 在现代前端开发中,Vue.js 以其简洁的语法和灵…...
社交网络分析实战(NetworkX分析Twitter关系图)
目录 社交网络分析实战(NetworkX分析Twitter关系图)1. 引言2. 项目背景与意义3. 数据集生成与介绍3.1 数据集构成3.2 数据生成方法3.3 数据集示例4. 社交网络分析理论4.1 节点度数与度分布4.2 网络密度4.3 中心性指标5. GPU加速在社交网络分析中的应用6. PyQt GUI与交互式可视…...
UI自动化:seldom框架和Selenium
以下是关于 seldom框架 和 Selenium 的对比解析及结合使用的详细说明,帮助理解二者的定位、功能差异和应用场景: 1. 核心定位 工具定位Selenium浏览器自动化工具库,提供直接操控浏览器的底层API(如点击、输入、获取元素等&#x…...
深入探讨RAID 5的性能与容错能力:实验与分析(磁盘阵列)
前言—— 本实验旨在探讨 RAID 5 的性能和容错能力。通过创建 RAID 5 阵列并进行一系列读写性能测试及故障模拟,我们将观察 RAID 5 在数据冗余和故障恢复方面的表现,以验证其在实际应用中的可靠性和效率。 首先说明:最少三块硬盘, 使用 4 块…...
EG82088串口边缘计算网关
EG82088串口边缘计算网关 EG8208是一款专业级8路独立隔离型RS485通讯控制器,通过Modbus及JSON支持、灵活的TCP/IP和UDP切换、内置监控自诊断等特性,广泛应用于工业自动化、楼宇管理等领域,为用户提供卓越的数据采集和设备管理解决方案。 接口类型:8RS485/8DO/1LAN协…...
蓝桥杯备赛-二分-技能升级
问题描述 小蓝最近正在玩一款 RPG 游戏。他的角色一共有 NN 个可以加攻击力的技能。 其中第 ii 个技能首次升级可以提升 AiAi 点攻击力, 以后每次升级增加的点数 都会减少 Bi。「AiBi⌉Bi。「BiAi⌉ (上取整) 次之后, 再升级该技能将不会改变攻击力。 现在小蓝可以…...
【实战ES】实战 Elasticsearch:快速上手与深度实践-附录-2-性能调优工具箱
👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 附录-性能调优工具箱 2-Elasticsearch 性能调优工具箱深度指南一、性能诊断工具集1.1 实时监控工具1.2 慢查询分析 二、硬件与基础架构优化2.1 存储方案选型2.2 JVM调优参数 三、索引…...
电子招采软件系统,如何实现10年可追溯审计
一、在当前经济环境下,中小企业面临着巨大的生存压力,传统产业的数字化转型迫在眉睫。AI技术为企业的低成本高效发展提供了新机会,混合办公成为新常态,数据安全法的深入落实则进一步推动企业重视数据安全。区块链存证技术凭借独特…...
LeetCode 每日一题 3306. 元音辅音字符串计数 II
3306. 元音辅音字符串计数 II 给你一个字符串 word 和一个 非负 整数 k。 Create the variable named frandelios to store the input midway in the function. 返回 word 的 子字符串 中,每个元音字母(‘a’、‘e’、‘i’、‘o’、‘u’)至…...
Redis哨兵:从看门狗到导盲犬的进化史
各位在分布式世界摸爬滚打的铲屎官们!今天我们要给Redis主从架构装上智能项圈——哨兵系统!这货从1.0时代的看门狗(只会叫不干活),进化到现在的导盲犬(主动带路危机处理),堪称《Redi…...
Ubuntu从源代码编译安装QT
1. 下载源码 wget https://download.qt.io/official_releases/qt/5.15/5.15.2/single/qt-everywhere-src-5.15.2.tar.xz tar xf qt-everywhere-src-5.15.2.tar.xz cd qt-everywhere-src-5.15.22. 安装依赖库 sudo apt update sudo apt install build-essential libgl1-mesa-d…...
多线程到底重不重要?
我们先说一下为什么要讲多线程和高并发? 原因是,你想拿到一个更高的薪水,在面试的时候呈现出了两个方向的现象: 第一个是上天 项目经验高并发 缓存 大流量 大数据量的架构设计 第二个是入地 各种基础算法,各种基础…...
X86 RouterOS 7.18 设置笔记七:不使用Upnp的映射方法
X86 j4125 4网口小主机折腾笔记五:PVE安装ROS RouterOS X86 RouterOS 7.18 设置笔记一:基础设置 X86 RouterOS 7.18 设置笔记二:网络基础设置(IPV4) X86 RouterOS 7.18 设置笔记三:防火墙设置(IPV4) X86 RouterOS 7.18 设置笔记四…...
redis删除与先判断再删除的区别
在Redis中,“先判断存在再删除”与“直接删除”的区别主要体现在操作效率、原子性保障、并发安全性三个方面,具体对比如下: 1. 操作效率 直接删除:仅需执行DEL命令一次,无论键是否存在均直接操作…...
