效果图

功能

  1. 使用QPainter绘制,雷达图主要包括,同心圆、十字架、刻度、不同颜色的圆圈。
  2. 可以设置卫星的俯仰角,方位角,程序采用系统与卫星的结合,多种系统,n个卫星数据,进行显示,可自行搭配数据结构。
  3. 监测卫星活动状态,定时清理无数据卫星。
  4. 上百目标,界面绘制流畅,无卡顿。

代码

skyMap.h#ifndef SKYMAP_H
#define SKYMAP_H#include <QWidget>
#include <QDateTime>
#include <QTimer>
#include <QMap>#define  PI 3.141592
#define ListSize 1200struct StarSumData
{float elevation;            //仰角float azimuth;              //方位角QDateTime time;             //数据接受时间
};struct StarSum
{int starSum;QColor color;QColor fontColor;QList<StarSumData> starSumDataList;StarSum():fontColor("black"){}bool operator == (const StarSum& s){if (starSum == s.starSum) {return true;}return false;}
};//系统
enum SystemFlag {GPS_SYSTEM = 0,BDS_SYSTEM,GAL_SYSTEM,GLO_SYSTEM
};struct StarPitch {float elevation;    //仰角float azimuth;      //方位角
};QT_BEGIN_NAMESPACE
namespace Ui { class skyMap; }
QT_END_NAMESPACEclass SkyMap : public QWidget
{Q_OBJECTpublic:SkyMap(QWidget *parent = nullptr);~SkyMap();void clearSkyData();//获取所有卫星号void getAllStarSum(QMap<int, QStringList> &onLineStarNumber);void stopDelData();
public slots://接受数据插入图中void insertData(int system, int starSum, float elevation, float azimuth, QDateTime time = QDateTime::currentDateTime());//设置颜色void setColor(QMap<int, QColor> colorList);//卫星超时不运行删除void timeout();//更新画面void timeoutUpdate();
private:void init();void drawCircle(QPainter *painter);void drawLabel(QPainter *painter);void drawAxisLabel(QPainter *painter);void drawStar(QPainter *painter);QColor getStarColor(int system);
protected:void paintEvent(QPaintEvent *e);
private:Ui::skyMap *ui;int m_Angle;int m_CircleSum;QStringList m_LabelList;QStringList m_AxisLabelList;QMap<int, QColor> m_ColorList;int m_Axis_max;int m_Axis_min;int m_CircleSize;int m_FontSize;QTimer* m_Time;QTimer* m_TimeUpdate;int m_UpdateTime;int m_TailSize;QMap<SystemFlag, QList<StarSum>> m_MapStarList; //天空图中的卫星数};
#endif // SKYMAP_H
skyMap.cpp#include "SkyMap.h"
#include "ui_SkyMap.h"
#include "qmath.h"
#include <QPainter>
#include <QPaintEvent>
#include <QPainterPath>
#include <QPen>
#include <QDebug>
#include <QTextOption>
#include <QPainterPath>SkyMap::SkyMap(QWidget *parent): QWidget(parent), ui(new Ui::skyMap)
{ui->setupUi(this);init();
}SkyMap::~SkyMap()
{delete ui;
}void SkyMap::clearSkyData()
{m_MapStarList.clear();
}void SkyMap::getAllStarSum(QMap<int, QStringList> &onLineStarNumber)
{QMap<SystemFlag, QList<StarSum>>::iterator i = m_MapStarList.begin();while (i != m_MapStarList.end()) {QList<StarSum> starSumList = i.value();QStringList starList;for (int index = 0; index < starSumList.size(); ++index) {StarSum starSumTemp = starSumList.at(index);starList << QString::number(starSumTemp.starSum);}onLineStarNumber.insert(int(i.key()), starList);i++;}
}void SkyMap::stopDelData()
{m_Time->stop();
}void SkyMap::insertData(int system, int starSum, float elevation, float azimuth, QDateTime time)
{if (elevation <= 0 || azimuth <= 0) {qDebug() << "天空图方位角俯仰角为0";return;}if (m_MapStarList.contains(SystemFlag(system))) { //判断系统是否存在QMap<SystemFlag, QList<StarSum>>::iterator i = m_MapStarList.begin();while (i != m_MapStarList.end()) {if (i.key() == SystemFlag(system)) {QList<StarSum> starSumList = i.value();//找卫星号StarSum starSumTemp;starSumTemp.starSum = starSum;if (starSumList.contains(starSumTemp)) {int index = starSumList.indexOf(starSumTemp);//吧找到的卫星数据列表给一下QList<StarSumData> starSumDataList = starSumList.at(index).starSumDataList;//判断上一条数据的浮动if (starSumDataList.size() >= 1) {StarSumData starSumDataTemp = starSumDataList.last();int temp = azimuth - starSumDataTemp.azimuth;if (temp > 5 || temp < -5) {return;}temp = elevation - starSumDataTemp.elevation;if (temp > 5 || temp < -5) {return;}}StarSumData starSumDataTemp;starSumDataTemp.azimuth = azimuth;starSumDataTemp.elevation = elevation;starSumDataTemp.time = time;//给卫星数据列表增加新数据starSumDataList.append(starSumDataTemp);//把找到的卫星数据替换一下starSumTemp.starSumDataList = starSumDataList;starSumTemp.color = getStarColor(system);starSumList[index] = starSumTemp;}else {//没有这个卫星增加新数据QList<StarSumData> starSumDataList;StarSumData starSumDataTemp;starSumDataTemp.azimuth = azimuth;starSumDataTemp.elevation = elevation;starSumDataTemp.time = time;starSumDataList.append(starSumDataTemp);starSumTemp.starSumDataList = starSumDataList;starSumTemp.color = getStarColor(system);starSumList.append(starSumTemp);}//更新mapi.value() = starSumList;}++i;}}else {//系统不存在增加新系统QList<StarSum> starSumList;StarSum starSumTemp;starSumTemp.color = getStarColor(system);starSumTemp.starSum = starSum;QList<StarSumData> starSumDataList;StarSumData starSumData;starSumData.azimuth = azimuth;starSumData.elevation = elevation;starSumData.time = time;starSumDataList.append(starSumData);starSumTemp.starSumDataList = starSumDataList;starSumList.append(starSumTemp);m_MapStarList.insert(SystemFlag(system), starSumList);}
}void SkyMap::setColor(QMap<int, QColor> colorList)
{m_ColorList = colorList;
}void SkyMap::timeout()
{if (m_MapStarList.isEmpty()) {return;}QDateTime oldTime = QDateTime::currentDateTime();oldTime.setTime_t(oldTime.toTime_t() - 60 * 60 * 2);//遍历mapQMap<SystemFlag, QList<StarSum>>::iterator i = m_MapStarList.begin();while (i != m_MapStarList.end()) {QList<StarSum> starSumList = i.value();for (int var = 0; var < starSumList.size(); ++var) {StarSum starSum = starSumList.at(var);for (int dataIndex = 0; dataIndex < starSum.starSumDataList.size(); ++dataIndex) {//数据的时间 小于当前时间-2h  删掉if (starSum.starSumDataList.at(dataIndex).time.toTime_t() < oldTime.toTime_t()) {qDebug() << starSum.starSumDataList.at(dataIndex).time << "-------" << oldTime << "删除超时时间" << starSum.starSum  <<"---"<< i.key();starSum.starSumDataList.removeAt(dataIndex);}}starSumList[var] = starSum; //更新卫星列表if (starSum.starSumDataList.isEmpty()) {//卫星数据列表空qDebug() << "删除卫星" << starSum.starSum << "---" << i.key();starSumList.removeAt(var);}}//更新mapi.value() = starSumList;i++;}
}void SkyMap::timeoutUpdate()
{this->update();
}void SkyMap::init()
{m_Angle = 30; //角度m_CircleSum = 5; //圈数m_Axis_max = 90; //最大轴m_Axis_min = 0;m_CircleSize = 10; //圆大小m_FontSize = m_CircleSize - 2;m_UpdateTime = 100; //3s更新界面m_TailSize = m_CircleSize / 3;//尾巴粗细m_Time = new QTimer(this);m_Time->setInterval(60000);connect(m_Time, SIGNAL(timeout()), this, SLOT(timeout()));m_Time->start();m_TimeUpdate = new QTimer(this);m_TimeUpdate->setInterval(m_UpdateTime);connect(m_TimeUpdate, SIGNAL(timeout()), this, SLOT(timeoutUpdate()));m_TimeUpdate->start();//初始外围标签for (int i = 0; i < 360; i += m_Angle) {if (i == 0) {m_LabelList << QString::number(360);}else {m_LabelList << QString::number(i);}}m_AxisLabelList << "90" << "72" << "54" << "36" << "18" << "0";}void SkyMap::drawCircle(QPainter *painter)
{painter->save();QPen pen;pen.setWidthF(1.5);pen.setColor(Qt::black);painter->setPen(pen);QPainterPath looppath;int w = width();int h = height();int radius = qMin(w, h);int step = radius / (m_CircleSum + 1);  //加1是为了四周留出空间,写标签int x = w * 0.2;int y = h * 0.2;// 画圆QRectF outrect;for (int i = 1; i < m_CircleSum + 1; ++i){radius = step * i;x = w / 2 - radius / 2;y = h / 2 - radius / 2;QRectF rect(x, y, radius, radius);looppath.addEllipse(rect);outrect = rect;}painter->drawPath(looppath);//画线int linecount = 360 / m_Angle;int x0 = w / 2 ;int y0 = h / 2;int newradius = outrect.height() / 2;for (int i = 0 ; i < linecount; ++i){int x1 = x0 + newradius*qSin(PI * 2 / linecount * i);int y1 = y0 + newradius*qCos(PI * 2 / linecount * i);painter->drawLine(x0, y0, x1, y1);}painter->restore();
}void SkyMap::drawLabel(QPainter *painter)
{if (m_LabelList.isEmpty()) {return;}painter->save();QPen pen;pen.setWidthF(1.5);pen.setColor(Qt::black);painter->setPen(pen);//QPen pen;//QColor color(Qt::black);//pen.setColor(color/*.lighter(100)*/); //添加线的颜色//painter->setPen(pen);int  laycount = m_CircleSum;  //默认是几层int w = width();int h = height();int count = 360 / m_Angle;int radius = qMin(w, h) / 2;int x0 = w / 2 ;int y0 = h / 2;QFont font;int m_FontSize = 10;if (h > 500) {m_FontSize = 12;}font.setPointSize(m_FontSize);painter->setFont(font);for (int i = 0 ; i < count; ++i){int newradius = radius * laycount / (laycount + 1) + 10;newradius = newradius + 10 * qSin(PI * 2 / count * i);int x1 = x0 + newradius * qSin(PI * 2 / count * i) - 5;int y1 = y0 - newradius * qCos(PI * 2 / count * i) + 5;if (i == 6) { //180x1 -= m_FontSize;y1 += m_FontSize;}if (i == 9) { //270x1 -= (m_FontSize * 2) + 10;}if (i == 7 || i == 8) { //210,240x1 -= (m_FontSize * 2);y1 += m_FontSize;}if (i ==  10 || i == 11) {  //300,330x1 -= (m_FontSize * 2) + 5;y1 -= 5;}if (i < m_LabelList.count()){painter->drawText(x1, y1, m_LabelList.at(i));}}painter->restore();
}void SkyMap::drawAxisLabel(QPainter *painter)
{if (m_AxisLabelList.isEmpty()) {return;}painter->save();QPen pen;pen.setWidthF(1.5);pen.setColor(Qt::black);painter->setPen(pen);//QPen pen;//QColor color(Qt::black);//pen.setColor(color/*.lighter(100)*/); //添加线的颜色//painter->setPen(pen);int  laycount = m_CircleSum;  //默认是几层int w = width();int h = height();int radius = qMin(w, h)/2;int x0 = w / 2 ;int y0 = h / 2;QFont font;int m_FontSize = 10;if (h > 500) {m_FontSize = 12;}font.setPointSize(m_FontSize);painter->setFont(font);for (int j = 0 ; j < laycount + 1; ++j){int newradius = radius * j / (laycount + 1);int x1 = x0 + newradius * qSin(PI);int y1 = y0 + newradius * qCos(PI) - 2;if (j+1 == m_AxisLabelList.size()) { //把0下移painter->drawText(x1 + m_FontSize / 2, y1 + m_FontSize + 6, m_AxisLabelList.at(j));continue;}if (j < m_AxisLabelList.count()){painter->drawText(x1, y1, m_AxisLabelList.at(j));}}painter->restore();
}void SkyMap::drawStar(QPainter *painter)
{painter->save();int w = width();int h = height();int radius = qMin(w, h) / 2 * m_CircleSum / (m_CircleSum + 1);qreal step = 1.0 * radius / (90 - 0);QMap<SystemFlag, QList<StarSum>>::iterator iter = m_MapStarList.begin();while (iter != m_MapStarList.end()) {QList<StarSum> starSumList = iter.value();for (int i = 0; i < starSumList.size(); ++i) {QPainterPath path; //画线路径//某个卫星的数据StarSum starSum = starSumList.at(i);QList<StarSumData> starSumDataList = starSum.starSumDataList;for (int j = 0; j < starSumDataList.size(); ++j) {bool isDrawHead = false;int m_CircleSizeTemp = m_CircleSize;//获取单个卫星的单个数据绘制StarSumData statSumData = starSumDataList.at(j);if (statSumData.azimuth <= 0 && statSumData.elevation <= 0) {continue;}//判断数据量if (starSumDataList.size() == 1 || j >= starSumDataList.size() -1) {//如果只有一条数据或者最后一条数据那么就画头isDrawHead = true;m_CircleSizeTemp = m_CircleSize;}else {//如果数量大于1那么就要画点m_CircleSizeTemp = 10;painter->setBrush(QColor("green"));}qreal length = step * (m_Axis_max - statSumData.elevation);statSumData.azimuth = (m_Axis_max - statSumData.azimuth);QPointF certp(w / 2 + length * qCos(statSumData.azimuth * PI / 180),h / 2 - length * qSin(statSumData.azimuth * PI / 180));//增加线条数据if (j == 0) {path.moveTo(certp);}path.lineTo(certp);path.moveTo(certp);if (isDrawHead) {//画线painter->setPen(QPen(starSum.color, m_TailSize));painter->drawPath(path);//画头painter->setFont(QFont("Arial", m_FontSize));painter->setPen(QPen(starSum.color));painter->setBrush(QBrush(starSum.color));painter->drawEllipse(certp, m_CircleSizeTemp, m_CircleSizeTemp);//画字painter->setPen(QPen(starSum.fontColor));QRect rect;rect.setRect(certp.x() - (m_CircleSize / 2), certp.y() - (m_CircleSize / 2), m_CircleSize, m_CircleSize);painter->drawText(rect, Qt::AlignCenter, QString::number(starSum.starSum));}else {}}}++iter;}painter->restore();painter->end();
}QColor SkyMap::getStarColor(int system)
{QMap<int, QColor>::const_iterator i = m_ColorList.begin();while (i != m_ColorList.end()) {if (i.key() == system) {return i.value();}++i;}return QColor("red");
}void SkyMap::paintEvent(QPaintEvent *e)
{Q_UNUSED(e)QPainter *painter = new QPainter(this);painter->setRenderHint(QPainter::Antialiasing);painter->setRenderHint(QPainter::SmoothPixmapTransform);painter->setRenderHint(QPainter::TextAntialiasing);//画圈drawCircle(painter);//画外围drawLabel(painter);//画俯仰刻度drawAxisLabel(painter);//画圆drawStar(painter);
}

调用方式

初始化调用SkyMap.setColor
通过信号与槽调用SkyMap.insertData

Qt绘制雷达图(卫星轨迹图)相关推荐

  1. 在Matlab中绘制系统的根轨迹图

    在Matlab中绘制系统的根轨迹图 例如某系统的开环传递函数为: 通过上面的开环传递函数可以直接求出2个开环共轭复零点,以及5个开环极点,然后确定根轨迹分支数-自己画根轨迹图的话还是比较麻烦的,这么简 ...

  2. Echarts制作态势图、热点图、轨迹图,使用百度底图,地图下钻

    记录最近使用echarts制作地图的过程及部分代码: 其中在网络上借鉴了不少优秀的源码,在此感谢他们的开源精神. 先看效果: (一)态势图.热点图.轨迹图及全屏功能 全屏效果: (二)改普通地图为百度 ...

  3. Qt绘制旋转的轮播图

    前言 目前见的比较多的轮播图有平移和旋转两种方式.平移类似淘宝那种切换幻灯片一样的效果,旋转一般是近大远小,看起来有点3D的感觉.本文代码实现旋转轮播图效果如下: 完整代码链接: https://gi ...

  4. 使用QT绘制雷达扫描效果

    话不多说直接上代码,代码规范性可能差了点,但是效果得以实现,在这里记录一下. 源码工程在这里下载地址 scan.h的代码如下 #ifndef SCAN_H #define SCAN_H#include ...

  5. Qt绘制雷达图(效果图)

    效果图如下: 原理: 自定义控件,并使用QPainter等绘制. 雷达图主要包括的元素有: 同心圆.十字架.文本标签.不同颜色.不同样式的圆圈.余晖等:可以设置目标显示的方位.距离等,经过我的测试,显 ...

  6. Qt绘制星空图及卫星视图坐标

    绘制卫星视图的圆,标记方位角 void skyViewer::paintEvent(QPaintEvent *event) {Q_UNUSED(event);QPainter painter(this ...

  7. Python绘制卫星星下点轨迹图和卫星星座图

    目录 简介 卫星轨迹图展示 STARLINK-2300 IRIDIUM 180 GPS BIIF-12 BEIDOU 10 星历解算 代码示例 地图绘制 代码示例 卫星星座图绘制展示 starlink ...

  8. matlab系统函数伯德图,利用matlab画出根轨迹图|伯德图bode

    求G(s)=K/s(s+1)(s+3)的根轨迹图形 若开环传递函数不是多项式乘积形式,则不需用conv函数,conv函数可用于多项式乘法以及卷积. num=[1,];%分子上的各项系数 %K=[1:1 ...

  9. Qt总结之七:QPaintEvent绘制雷达图(二)

    前言 这里使用另一套框架写的雷达扫描图 这里PaintEvent事件比上一个版本写的好,但是不喜欢Widget嵌套的方式,后续会把两个版本整合到一起. 一.实现原理 雷达效果包括三个部分:背景.转动的 ...

最新文章

  1. 协作是企业管理的重点和难点
  2. 字节跳动面试官:你离50w年薪就差答对了这个算法题!
  3. 如何打开.npz文件
  4. python与php8-Python比php发展快的十大理由
  5. Cloud Native workshop
  6. 基于java ssm springboot选课推荐交流平台系统设计和实现
  7. VMware9安装Ubuntu 12.10图文详细教程
  8. 用emacs做笔记_3种用于记笔记的Emacs模式
  9. 关于Vue.js去掉#号路由
  10. V4L2Gstreamer媒体控制工具(五)
  11. 自动获取服务器,c#-自动获取服务器IP到客户端
  12. 鸟哥Linux私房菜 第五章 文件权限与目录配置
  13. C++ 面向对象的编程语言有哪些特点?
  14. Andy’s First Dictionary(安迪的第一部词典)
  15. 虚拟服务器伪静态怎么设置,虚拟主机如何设置伪静态
  16. java.lang.RuntimeException: Parcel: unable to marshal value com.
  17. python计算时间
  18. [Unity安卓封装][C#版]Unity使用TextToSpeech
  19. McAfee参与战略合作,i-house.com用区块链整合全球不动产交易市场
  20. Java Regex Pattern Matcher

热门文章

  1. [知了堂学习笔记]_设计模式之工厂模式
  2. 象棋的ai的视线_隐藏在视线中的“未来”技术:人工智能
  3. 如何删除计算机自动更新补丁,教你怎么删除win更新补丁的方法
  4. 分析apache访问日志
  5. zcmu 2100(模拟)
  6. java B2B2C 多级分销多租户电子商城系统-消息队列之 RabbitMQ
  7. 全球市场迅速广泛接受FreeStor飞康SDS转型成功
  8. 二、简单的c++小程序
  9. WampServer 使用详解以及常见问题
  10. 微信公众平台深度开发JAVA版第一季 14.响应被动消息2