128 lines
4.6 KiB
Python
128 lines
4.6 KiB
Python
# ---------------------------------------------------------------------------
|
|
# Sky-Plot Widget
|
|
# ---------------------------------------------------------------------------
|
|
import math
|
|
|
|
from PyQt5.QtCore import Qt
|
|
from PyQt5.QtGui import QPainter, QRadialGradient, QColor, QBrush, QPen, QFont
|
|
from PyQt5.QtWidgets import QWidget
|
|
|
|
from defines import GNSS_NAMES, GNSS_COLORS
|
|
|
|
|
|
class SkyPlotWidget(QWidget):
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self._satellites = []
|
|
self.setMinimumSize(400, 400)
|
|
self.setStyleSheet("background-color: #1a1a2e;")
|
|
|
|
def update_satellites(self, sats: list):
|
|
self._satellites = sats
|
|
self.update()
|
|
|
|
def paintEvent(self, event):
|
|
painter = QPainter(self)
|
|
painter.setRenderHint(QPainter.Antialiasing)
|
|
w, h = self.width(), self.height()
|
|
cx, cy = w / 2, h / 2
|
|
radius = min(w, h) / 2 - 30
|
|
self._draw_background(painter, cx, cy, radius)
|
|
self._draw_grid(painter, cx, cy, radius)
|
|
self._draw_satellites(painter, cx, cy, radius)
|
|
self._draw_legend(painter)
|
|
|
|
def _draw_background(self, painter, cx, cy, radius):
|
|
grad = QRadialGradient(cx, cy, radius)
|
|
grad.setColorAt(0.0, QColor("#0d1b2a"))
|
|
grad.setColorAt(1.0, QColor("#1a1a2e"))
|
|
painter.setBrush(QBrush(grad))
|
|
painter.setPen(Qt.NoPen)
|
|
painter.drawEllipse(
|
|
int(cx - radius), int(cy - radius),
|
|
int(radius * 2), int(radius * 2),
|
|
)
|
|
|
|
def _draw_grid(self, painter, cx, cy, radius):
|
|
pen = QPen(QColor("#2a4a6a"), 1, Qt.DashLine)
|
|
painter.setPen(pen)
|
|
painter.setFont(QFont("Monospace", 8))
|
|
|
|
for elev in (0, 30, 60):
|
|
r = radius * (1 - elev / 90)
|
|
painter.drawEllipse(int(cx - r), int(cy - r), int(r * 2), int(r * 2))
|
|
painter.setPen(QColor("#4a7a9b"))
|
|
painter.drawText(int(cx + 4), int(cy - r), f"{elev}°")
|
|
painter.setPen(pen)
|
|
|
|
for azim in range(0, 360, 45):
|
|
rad = math.radians(azim)
|
|
painter.drawLine(
|
|
int(cx + math.sin(rad) * radius * 0.05),
|
|
int(cy - math.cos(rad) * radius * 0.05),
|
|
int(cx + math.sin(rad) * radius),
|
|
int(cy - math.cos(rad) * radius),
|
|
)
|
|
|
|
painter.setPen(QColor("#7ab7d4"))
|
|
painter.setFont(QFont("Monospace", 10, QFont.Bold))
|
|
for label, azim in (("N", 0), ("O", 90), ("S", 180), ("W", 270)):
|
|
rad = math.radians(azim)
|
|
painter.drawText(
|
|
int(cx + math.sin(rad) * (radius + 15) - 6),
|
|
int(cy - math.cos(rad) * (radius + 15) + 5),
|
|
label,
|
|
)
|
|
|
|
@staticmethod
|
|
def _az_el_to_xy(azim, elev, cx, cy, radius):
|
|
r = radius * (1 - elev / 90)
|
|
rad = math.radians(azim)
|
|
return cx + math.sin(rad) * r, cy - math.cos(rad) * r
|
|
|
|
def _draw_satellites(self, painter, cx, cy, radius):
|
|
for sat in self._satellites:
|
|
if sat["elev"] < 0:
|
|
continue
|
|
color = GNSS_COLORS.get(sat["gnssId"], QColor("#ffffff"))
|
|
x, y = self._az_el_to_xy(sat["azim"], sat["elev"], cx, cy, radius)
|
|
cno = max(0, min(50, sat["cno"]))
|
|
dot_r = 4 + int(cno / 50 * 8)
|
|
|
|
glow = QColor(color)
|
|
glow.setAlpha(60)
|
|
painter.setBrush(QBrush(glow))
|
|
painter.setPen(Qt.NoPen)
|
|
painter.drawEllipse(
|
|
int(x - dot_r * 1.8), int(y - dot_r * 1.8),
|
|
int(dot_r * 3.6), int(dot_r * 3.6),
|
|
)
|
|
|
|
if sat["used"]:
|
|
painter.setBrush(QBrush(color))
|
|
painter.setPen(QPen(QColor("#ffffff"), 1))
|
|
else:
|
|
faded = QColor(color)
|
|
faded.setAlpha(120)
|
|
painter.setBrush(QBrush(faded))
|
|
painter.setPen(QPen(color, 1, Qt.DashLine))
|
|
|
|
painter.drawEllipse(
|
|
int(x - dot_r), int(y - dot_r), dot_r * 2, dot_r * 2
|
|
)
|
|
painter.setPen(QColor("#ffffff"))
|
|
painter.setFont(QFont("Monospace", 7))
|
|
painter.drawText(int(x + dot_r + 2), int(y + 4), str(sat["svId"]))
|
|
|
|
def _draw_legend(self, painter):
|
|
painter.setFont(QFont("Monospace", 8))
|
|
x, y = 10, 20
|
|
for gnss_id, name in GNSS_NAMES.items():
|
|
color = GNSS_COLORS[gnss_id]
|
|
painter.setBrush(QBrush(color))
|
|
painter.setPen(Qt.NoPen)
|
|
painter.drawEllipse(x, y - 8, 10, 10)
|
|
painter.setPen(QColor("#cccccc"))
|
|
painter.drawText(x + 14, y, name)
|
|
y += 16
|