import 'dart:math'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:gnss/gnss.dart'; import '../Controller/gnss_controller.dart'; const signalNameList = ["GPS", "GLO", "GAL", "BDS", "QZS"]; const Map signalPrefixList = { "GPS": "G", "GLO": "N", "GAL": "E", "BDS": "B", "QZS": "Q" }; const Map signalColorMap = { "GPS": Color.fromARGB(255, 255, 0, 0), "GLO": Color.fromARGB(255, 0, 255, 0), "GAL": Color.fromARGB(255, 0, 0, 255), "BDS": Color.fromARGB(255, 146, 73, 206), "QZS": Color.fromARGB(255, 13, 179, 179), }; class SkyPlotPage extends StatelessWidget { late final GnssController controller; // Map imageList = {}; @override SkyPlotPage({super.key}) { controller = Get.find(); } Future loadImage(String path) async { ByteData data = await rootBundle.load(path); ui.Codec codec = await ui.instantiateImageCodec(data.buffer.asUint8List()); ui.FrameInfo fi = await codec.getNextFrame(); return fi.image; } @override Widget build(BuildContext context) { bool isDarkMode = Theme.of(context).brightness == Brightness.dark; final size = MediaQuery.of(context).size; return Obx(() { controller.signalUpdate.value; return SizedBox( width: size.width, height: size.height, child: CustomPaint( painter: SkyPlotPainter(controller.signalData, controller.selectedSignal), ), ); }); } } class SkyPlotPainter extends CustomPainter { final SignalData? signalData; final Map selectedSignal; final satelliteRadius = 12.0; SkyPlotPainter(this.signalData, this.selectedSignal); @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = const ui.Color.fromARGB(255, 0, 0, 0) ..style = PaintingStyle.stroke ..strokeWidth = 2.0; // 设置线条的粗细,这里设置为2.0 final double radius = min(size.width / 2.4, size.height / 2); final Offset center = Offset(size.width / 2, size.height / 2 - 5); // Draw concentric circles for different elevation angles for (int i = 0; i <= 90; i += 30) { double r = radius * (90 - i) / 90; canvas.drawCircle(center, r, paint); } // Draw lines for different azimuth angles for (int i = 0; i < 360; i += 30) { double radians = i * pi / 180; double x = center.dx + radius * cos(radians); double y = center.dy + radius * sin(radians); canvas.drawLine(center, Offset(x, y), paint); String text; if (i == 0) { text = ' N'; } else if (i == 180) { text = 'S'; } else { text = '${(i + 90) % 360}'; } TextPainter textPainter = TextPainter( text: TextSpan( text: text, style: const TextStyle(color: Colors.black, fontSize: 15)), textDirection: TextDirection.ltr, ); textPainter.layout(); // 布局文本 // 计算文本的位置并绘制 double textX = x + 14 * cos(radians); // 向外偏移 double textY = y + 14 * sin(radians); // 向外偏移 textPainter.paint(canvas, Offset(textX - 12, textY - 8)); } if (signalData == null) { return; } // Draw satellite positions final satellitePaint = Paint()..style = PaintingStyle.fill; signalData!.forEach((key, value) { if (selectedSignal[key] == true) { satellitePaint.color = signalColorMap[key] ?? Colors.yellow; drawGnssSignal(canvas, center, radius, value, satellitePaint, key); } }); } void drawGnssSignal( Canvas canvas, Offset center, double radius, List signals, Paint paint, String neme, ) { for (final signal in signals) { final int el = signal.elevation; final double az = (360 - signal.azimuth + 90) * pi / 180; final double r = radius * (90 - el) / 90; final double x = center.dx + r * cos(az); final double y = center.dy + r * sin(az); canvas.drawCircle(Offset(x, y), satelliteRadius, paint); TextPainter( text: TextSpan( text: signalPrefixList[neme]! + signal.prn.toString().padLeft(2, '0'), style: const TextStyle(color: Colors.white, fontSize: 12), ), textDirection: TextDirection.ltr, ) ..layout() ..paint(canvas, Offset(x - 9, y - 7)); } } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return true; } }