Initial import of version 0.3
[gpsdata] / src / satelliteview.cpp
diff --git a/src/satelliteview.cpp b/src/satelliteview.cpp
new file mode 100644 (file)
index 0000000..b90822f
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ *  GPSData for Maemo.
+ *  Copyright (C) 2011 Roman Moravcik
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <QtGui>
+
+#include "satelliteview.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+void SatelliteView::updateWidget(const QList<QGeoSatelliteInfo> &satellites, bool inUseList)
+{
+    if (inUseList)
+        m_satellitesInUse = satellites;
+    else
+        m_satellitesInView = satellites;
+
+    update();
+}
+
+void SatelliteView::paintEvent(QPaintEvent * /* event */)
+{
+    QPainter painter(this);
+    painter.setRenderHint(QPainter::Antialiasing);
+
+    double widget_width = 0;
+    double widget_height = 0;
+    double widget_x = 0;
+    double widget_y = 0;
+
+    if (rect().width() < rect().height()) {
+        /* Portrait orientation */
+        widget_width = rect().width() - (2 * m_margin);
+        widget_height = widget_width;
+        widget_x = rect().x() + m_margin;
+        widget_y = rect().y() + (rect().height() - widget_height) / 2.0;
+    } else {
+        /* Landscape orientation */
+        widget_height = rect().height() - (2 * m_margin);
+        widget_width = widget_height;
+        widget_x = rect().x() + (rect().width() - widget_width) / 2.0;
+        widget_y = rect().y() + m_margin;
+    }
+    QRectF widgetArea(widget_x, widget_y, widget_width, widget_height);
+
+    /* Draw N/E/S/W labels */
+    paintLabels(painter, widgetArea);
+
+    int label_height = painter.fontMetrics().height();
+    int label_width = label_height;
+    double grid_x = widget_x + m_margin + label_width;
+    double grid_y =  widget_y + m_margin + label_height;
+    double grid_width = widget_width - (2 * m_margin) - (2 * label_width);
+    double grid_height = widget_height - (2 * m_margin) - (2 * label_height);
+    QRectF gridArea(grid_x, grid_y, grid_width, grid_height);
+
+    /* Draw grid */
+    paintGrid(painter, gridArea);
+
+    /* Draw satellites in view */
+    for (int index = 1; index <= m_numOfSatellites; ++index) {
+        paintSatellite(painter, gridArea, index);
+    }
+}
+
+void SatelliteView::paintLabels(QPainter &painter, const QRectF &area)
+{
+    int label_height = painter.fontMetrics().height();
+    int label_width = label_height;
+
+    painter.setPen(QApplication::palette().color(QPalette::Text));
+
+    /* "North" label */
+    QRect northLabel(area.x(), area.y(), area.width(), label_height);
+    painter.drawText(northLabel, Qt::AlignCenter, tr("N"));
+
+    /* "South" label */
+    QRect southLabel(area.x(), area.y() + area.height() - label_height, area.width(), label_height);
+    painter.drawText(southLabel, Qt::AlignCenter, tr("S"));
+
+    /* "West" label */
+    QRect westLabel(area.x(), area.y(), label_width, area.height());
+    painter.drawText(westLabel, Qt::AlignCenter, tr("W"));
+
+    /* "East" label */
+    QRect eastLabel(area.x() + area.width() - label_width, area.y(), label_width, area.height());
+    painter.drawText(eastLabel, Qt::AlignCenter, tr("E"));
+}
+
+void SatelliteView::paintGrid(QPainter &painter, const QRectF &area)
+{
+    painter.setPen(m_graphGridColor);
+    for (int i = 0; i < 3; i++) {
+        double grid_width =  area.width() * (3.0 - i) / 3.0;
+        double grid_height = area.height() * (3.0 - i) / 3.0;
+        double grid_x = area.x() + (area.width() * i / 6.0);
+        double grid_y = area.y() + (area.height() * i / 6.0);
+
+        QRectF gridArea(grid_x, grid_y, grid_width, grid_height);
+        painter.drawArc(gridArea, 0, 5760);
+    }
+
+    /* Grid */
+    painter.drawLine(area.x(), area.y() + area.height() / 2.0, area.x() + area.width(), area.y() + area.height() / 2.0);
+    painter.drawLine(area.x() + area.width() / 2.0, area.y(), area.x() + area.width() / 2.0, area.y() + area.height());
+
+}
+
+void SatelliteView::paintSatellite(QPainter &painter, const QRectF &area, int index)
+{
+    double center_x = area.x() + (double) area.width() / 2.0;
+    double center_y = area.y() + (double) area.height() / 2.0;
+
+    bool inUse = false;
+    int satelliteElevation = -1;
+    int satelliteAzimuth = 0;
+    for (int iter = 0; iter < m_satellitesInView.count(); iter++) {
+        if (m_satellitesInView.at(iter).prnNumber() == index) {
+            if (m_satellitesInView.at(iter).hasAttribute(QGeoSatelliteInfo::Elevation))
+                satelliteElevation = m_satellitesInView.at(iter).attribute(QGeoSatelliteInfo::Elevation);
+
+            if (m_satellitesInView.at(iter).hasAttribute(QGeoSatelliteInfo::Azimuth))
+                satelliteAzimuth = m_satellitesInView.at(iter).attribute(QGeoSatelliteInfo::Azimuth);
+            break;
+        }
+    }
+    for (int iter = 0; iter < m_satellitesInUse.count(); iter++) {
+        if (m_satellitesInUse.at(iter).prnNumber() == index) {
+            inUse = true;
+            break;
+        }
+    }
+
+    /* Display only visible satellites */
+    if (satelliteElevation >= 0) {
+        int satellite_width = 30;
+        int satellite_height = 30;
+        double temp = (180 - satelliteElevation) * (double) area.width() / 360.0;
+        double satellite_x = temp * qCos((satelliteAzimuth - 90) * M_PI / 180.0) +
+                             center_x - (double) (satellite_width / 2.0);
+        double satellite_y = temp * qSin((satelliteAzimuth - 90) * M_PI / 180.0) +
+                             center_y - (double) (satellite_height / 2.0);
+        QRectF satelliteArea(satellite_x, satellite_y, satellite_width, satellite_height);
+
+        /* Draw a small circle with PRN number inside */
+        painter.setPen(m_satelliteBorderColor);
+        if (inUse)
+            painter.setBrush(m_satelliteInUseColor);
+        else
+            painter.setBrush(m_satellitehInViewColor);
+        painter.drawChord(satelliteArea, 0, 5760);
+
+        int panel_width = 10;
+        painter.setBrush(m_satelliteSolarPanelColor);
+        QRectF solarPanelLArea(satellite_x - panel_width, satellite_y,
+                               panel_width, satellite_height);
+        painter.drawRect(solarPanelLArea);
+
+        QRectF solarPanelRArea(satellite_x + satellite_width, satellite_y,
+                               panel_width, satellite_height);
+        painter.drawRect(solarPanelRArea);
+
+        /* Satellite's PRN must be painter over the satellite circle */
+        QFont font = QApplication::font();
+        font.setPixelSize(12);
+        painter.setFont(font);
+        painter.setPen(m_satelliteBorderColor);
+        painter.drawText(satelliteArea, Qt::AlignCenter, QString::number(index));
+    }
+}
+
+SatelliteView::SatelliteView(QWidget *parent) : QWidget(parent)
+{
+    m_graphGridColor = QColor(74, 69, 66);
+    m_satelliteBorderColor = QColor(0, 0, 0);
+    m_satelliteSolarPanelColor = QColor(0, 75, 255);
+    m_satellitehInViewColor = QColor(153, 153, 153);
+    m_satelliteInUseColor = QColor(51, 191, 51);
+}