2 ******************************************************************************
4 * @file gpsconstellationwidget.cpp
5 * @author Edouard Lafargue Copyright (C) 2010.
6 * @addtogroup GCSPlugins GCS Plugins
8 * @addtogroup GPSGadgetPlugin GPS Gadget Plugin
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
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"
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 // |--------------------|
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());
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
++) {
74 satIcons
[i
] = new QGraphicsSvgItem(world
);
75 satIcons
[i
]->setSharedRenderer(renderer
);
76 satIcons
[i
]->setElementId("sat-notSeen");
79 satTexts
[i
] = new QGraphicsSimpleTextItem("##", satIcons
[i
]);
80 satTexts
[i
]->setBrush(QColor("Black"));
81 satTexts
[i
]->setFont(QFont("Digital-7"));
85 GpsConstellationWidget::~GpsConstellationWidget()
94 void GpsConstellationWidget::showEvent(QShowEvent
*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
)
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.
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)) {
135 satIcons
[index
]->setElementId("satellite-sbas");
137 satIcons
[index
]->setElementId("sat-sbas-notSeen");
139 } else if ((prn
> 64 && prn
< 97) || 255 == prn
) {
141 satIcons
[index
]->setElementId("satellite-glonass");
143 satIcons
[index
]->setElementId("sat-glonass-notSeen");
145 } else if ((prn
> 32 && prn
< 65) || (prn
> 158 && prn
< 164)) {
147 satIcons
[index
]->setElementId("satellite-beidou");
149 satIcons
[index
]->setElementId("sat-beidou-notSeen");
153 satIcons
[index
]->setElementId("satellite");
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...
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);
177 satIcons
[index
]->hide();
182 Converts the elevation/azimuth to X/Y coordinates on the map
185 QPointF
GpsConstellationWidget::polarToCoord(int elevation
, int azimuth
)
189 double vect_elevation
;
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
);
201 x
= (world
->boundingRect().width() / 2) + x
;
202 y
= (world
->boundingRect().height() / 2) + y
;
204 return QPointF(x
, y
);