LP-56 - Better txpid option namings, fix tabs-spaces, tooltips. headers, variable...
[librepilot.git] / ground / openpilotgcs / src / plugins / gpsdisplay / gpsconstellationwidget.cpp
blob9fde211c0218819189172a462d43480401e844d9
1 /**
2 ******************************************************************************
4 * @file gpsconstellationwidget.cpp
5 * @author Edouard Lafargue Copyright (C) 2010.
6 * @addtogroup GCSPlugins GCS Plugins
7 * @{
8 * @addtogroup GPSGadgetPlugin GPS Gadget Plugin
9 * @{
10 * @brief A widget which displays the GPS constellation
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "gpsconstellationwidget.h"
30 #include <QtGui>
31 #include <QDebug>
34 * Initialize the widget
36 GpsConstellationWidget::GpsConstellationWidget(QWidget *parent) : QGraphicsView(parent)
38 // Create a layout, add a QGraphicsView and put the SVG inside.
39 // The constellation widget looks like this:
40 // |--------------------|
41 // | |
42 // | |
43 // | Constellation |
44 // | |
45 // | |
46 // | |
47 // |--------------------|
50 setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
51 setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
53 QSvgRenderer *renderer = new QSvgRenderer();
54 renderer->load(QString(":/gpsgadget/images/gpsEarth.svg"));
56 world = new QGraphicsSvgItem();
57 world->setSharedRenderer(renderer);
58 world->setElementId("map");
60 scene = new QGraphicsScene(this);
61 scene->addItem(world);
62 scene->setSceneRect(world->boundingRect());
63 setScene(scene);
65 QFontDatabase::addApplicationFont(":/gpsgadget/font/digital-7.ttf");
67 // Now create 'maxSatellites' satellite icons which we will move around on the map:
68 for (int i = 0; i < MAX_SATTELITES; i++) {
69 satellites[i][0] = 0;
70 satellites[i][1] = 0;
71 satellites[i][2] = 0;
72 satellites[i][3] = 0;
74 satIcons[i] = new QGraphicsSvgItem(world);
75 satIcons[i]->setSharedRenderer(renderer);
76 satIcons[i]->setElementId("sat-notSeen");
77 satIcons[i]->hide();
79 satTexts[i] = new QGraphicsSimpleTextItem("##", satIcons[i]);
80 satTexts[i]->setBrush(QColor("Black"));
81 satTexts[i]->setFont(QFont("Digital-7"));
85 GpsConstellationWidget::~GpsConstellationWidget()
87 delete scene;
88 scene = 0;
90 // delete renderer;
91 // renderer = 0;
94 void GpsConstellationWidget::showEvent(QShowEvent *event)
96 Q_UNUSED(event)
97 // Thit fitInView method should only be called now, once the
98 // widget is shown, otherwise it cannot compute its values and
99 // the result is usually a ahrsbargraph that is way too small.
100 fitInView(world, Qt::KeepAspectRatio);
101 // Scale, can't use fitInView since that doesn't work until we're shown.
102 // qreal factor = height()/world->boundingRect().height();
103 // world->setScale(factor);
104 // setSceneRect(world->boundingRect());
107 void GpsConstellationWidget::resizeEvent(QResizeEvent *event)
109 Q_UNUSED(event);
110 fitInView(world, Qt::KeepAspectRatio);
113 void GpsConstellationWidget::updateSat(int index, int prn, int elevation, int azimuth, int snr)
115 if (index >= MAX_SATTELITES) {
116 // A bit of error checking never hurts.
117 return;
120 // TODO: add range checking
121 satellites[index][0] = prn;
122 satellites[index][1] = elevation;
123 satellites[index][2] = azimuth;
124 satellites[index][3] = snr;
126 if (prn && elevation >= 0) {
127 QPointF opd = polarToCoord(elevation, azimuth);
128 opd += QPointF(-satIcons[index]->boundingRect().center().x(),
129 -satIcons[index]->boundingRect().center().y());
130 satIcons[index]->setTransform(QTransform::fromTranslate(opd.x(), opd.y()), false);
132 // Show normal GPS, SBAS/QZSS (120-158,193-197 range), BeiDou (33-64, 159-163) or GLONASS (65-96, 255 if unidentified)
133 if ((prn > 119 && prn < 159) || (prn > 192 && prn < 198)) {
134 if (snr) {
135 satIcons[index]->setElementId("satellite-sbas");
136 } else {
137 satIcons[index]->setElementId("sat-sbas-notSeen");
139 } else if ((prn > 64 && prn < 97) || 255 == prn) {
140 if (snr) {
141 satIcons[index]->setElementId("satellite-glonass");
142 } else {
143 satIcons[index]->setElementId("sat-glonass-notSeen");
145 } else if ((prn > 32 && prn < 65) || (prn > 158 && prn < 164)) {
146 if (snr) {
147 satIcons[index]->setElementId("satellite-beidou");
148 } else {
149 satIcons[index]->setElementId("sat-beidou-notSeen");
151 } else {
152 if (snr) {
153 satIcons[index]->setElementId("satellite");
154 } else {
155 satIcons[index]->setElementId("sat-notSeen");
158 satIcons[index]->show();
160 QRectF iconRect = satIcons[index]->boundingRect();
161 QString prnString = QString().number(prn);
162 if (prnString.length() == 1) {
163 prnString = "0" + prnString;
165 satTexts[index]->setText(prnString);
166 QRectF textRect = satTexts[index]->boundingRect();
168 // Fixed scale, looks better for numbers 01,11,126...
169 qreal scale = 1.40;
171 QTransform matrix;
172 matrix.translate(iconRect.width() / 2, iconRect.height() / 2);
173 matrix.scale(scale, scale);
174 matrix.translate(-textRect.width() / 2, -textRect.height() / 2);
175 satTexts[index]->setTransform(matrix, false);
176 } else {
177 satIcons[index]->hide();
182 Converts the elevation/azimuth to X/Y coordinates on the map
185 QPointF GpsConstellationWidget::polarToCoord(int elevation, int azimuth)
187 double x;
188 double y;
189 double vect_elevation;
190 double rad_azimuth;
192 // Vector modulus scaled to circle and angle (azimut)
193 vect_elevation = 0.79 - (elevation / 90.00f) * 0.79;
194 rad_azimuth = M_PI * azimuth / 180;
196 // Cartesian coordinates
197 x = ((world->boundingRect().width() * vect_elevation) / 2) * sin(rad_azimuth);
198 y = ((world->boundingRect().height() * vect_elevation) / 2) * -cos(rad_azimuth);
200 // Start from center
201 x = (world->boundingRect().width() / 2) + x;
202 y = (world->boundingRect().height() / 2) + y;
204 return QPointF(x, y);