效果图
功能
- 使用QPainter绘制,雷达图主要包括,同心圆、十字架、刻度、不同颜色的圆圈。
- 可以设置卫星的俯仰角,方位角,程序采用系统与卫星的结合,多种系统,n个卫星数据,进行显示,可自行搭配数据结构。
- 监测卫星活动状态,定时清理无数据卫星。
- 上百目标,界面绘制流畅,无卡顿。
代码
skyMap.h
#ifndef SKYMAP_H
#define SKYMAP_H
#include
#include
#include
#include
#define PI 3.141592
#define ListSize 1200
struct 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_NAMESPACE
class SkyMap : public QWidget
{
Q_OBJECT
public:
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.cpp
#include "SkyMap.h"
#include "ui_SkyMap.h"
#include "qmath.h"
#include
#include
#include
#include
#include
#include
#include
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);
}
i.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);
QMap<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) {
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);
}
}
i.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;
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);
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);
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) {
x1 -= m_FontSize;
y1 += m_FontSize;
}
if (i == 9) {
x1 -= (m_FontSize * 2) + 10;
}
if (i == 7 || i == 8) {
x1 -= (m_FontSize * 2);
y1 += m_FontSize;
}
if (i == 10 || i == 11) {
x1 -= (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);
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()) {
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 {
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