import 'dart:convert'; import 'dart:math'; import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter/widgets.dart'; import 'package:get/get.dart'; import 'package:gnss/gnss.dart'; import '../Controller/gnss_controller.dart'; const signalNameList = ["GPS", "GLONASS", "GALILEO", "BEIDOU", "QZSS"]; const List signalColorList = [ Color.fromARGB(255, 255, 0, 0), Color.fromARGB(255, 0, 255, 0), Color.fromARGB(255, 0, 0, 255), Color.fromARGB(255, 255, 255, 0), Color.fromARGB(255, 0, 255, 255) ]; // class DrawSkyPlot { // double width = 500; // double height = 500; // late Canvas ctx; // Map legend = {}; // final Paint _paint = Paint(); // Path path = Path(); // bool isPortrait = false; // late LocationData locationData; // late SignalData signalData; // late GnssController controller; // // final GnssController controller; // final bool isDarkMode; // Color color = Colors.black; // DrawSkyPlot(op, this.isDarkMode, this.controller) { // // controller = Get.find(tag: 'gnss'); // ctx = op['ctx']; // canvas dom 对象 // height = op['height']; // 画布高 // width = op['width']; // 画布宽 // if (isDarkMode) { // color = Colors.white; // } else { // color = Colors.black; // } // _paint // ..color = color // ..strokeWidth = 3 // ..style = PaintingStyle.stroke; // MediaQueryData mediaQueryData = // MediaQueryData.fromView(WidgetsBinding.instance.window); // final orientation = mediaQueryData.orientation; // // 横屏竖屏宽高重新设置 // if (orientation == Orientation.portrait) { // height = op['width']; // isPortrait = true; // } else { // width = op['height']; // isPortrait = false; // } // } // //外圈 // drawSkyPlotCircle() { // double x = (width / 2) + 50; // double y = (height / 2) - 15; // double r = height / 2.5; // ctx.drawCircle(Offset(x, y), r, _paint); // ctx.drawCircle(Offset(x, y), r * 2 / 3, _paint); // ctx.drawCircle(Offset(x, y), r / 3, _paint); // path.moveTo(x - r, y); // path.lineTo(x + r, y); // path.moveTo(x, y - r); // path.lineTo(x, y + r); // path.moveTo(x + cos(30 * (pi / 180)) * r, y + sin(30 * (pi / 180)) * r); // path.lineTo(x - cos(30 * (pi / 180)) * r, y - sin(30 * (pi / 180)) * r); // path.moveTo(x + cos(60 * (pi / 180)) * r, y + sin(60 * (pi / 180)) * r); // path.lineTo(x - cos(60 * (pi / 180)) * r, y - sin(60 * (pi / 180)) * r); // path.moveTo(x + cos(60 * (pi / 180)) * r, y - sin(60 * (pi / 180)) * r); // path.lineTo(x - cos(60 * (pi / 180)) * r, y + sin(60 * (pi / 180)) * r); // path.moveTo(x - cos(60 * (pi / 180)) * r, y + sin(60 * (pi / 180)) * r); // path.lineTo(x + cos(60 * (pi / 180)) * r, y - sin(60 * (pi / 180)) * r); // path.moveTo(x + cos(30 * (pi / 180)) * r, y - sin(30 * (pi / 180)) * r); // path.lineTo(x - cos(30 * (pi / 180)) * r, y + sin(30 * (pi / 180)) * r); // path.moveTo(x - cos(30 * (pi / 180)) * r, y + sin(30 * (pi / 180)) * r); // path.lineTo(x + cos(30 * (pi / 180)) * r, y - sin(30 * (pi / 180)) * r); // ctx.drawPath(path, _paint); // Map textList = { // '0': Offset(x, y - r - 25), // '30': Offset( // x + cos(60 * (pi / 180)) * r, y - sin(60 * (pi / 180)) * r - 25), // '60': Offset( // x + cos(30 * (pi / 180)) * r + 10, y - sin(30 * (pi / 180)) * r - 10), // '90': Offset(x + r + 10, y - 5), // '120': Offset( // x + cos(30 * (pi / 180)) * r, y + sin(30 * (pi / 180)) * r + 5), // '150': Offset( // x + cos(60 * (pi / 180)) * r, y + sin(60 * (pi / 180)) * r + 5), // '180': Offset(x - 10, y + r), // '210': Offset( // x - cos(60 * (pi / 180)) * r - 20, y + sin(60 * (pi / 180)) * r + 10), // '240': Offset( // x - cos(30 * (pi / 180)) * r - 30, y + sin(30 * (pi / 180)) * r + 5), // '270': Offset(x - r - 35, y - 5), // '300': Offset( // x - cos(30 * (pi / 180)) * r - 37, y - sin(30 * (pi / 180)) * r - 20), // '330': Offset( // x - cos(60 * (pi / 180)) * r - 30, y - sin(60 * (pi / 180)) * r - 25) // }; // textList.forEach((key, offset) { // TextPainter( // text: TextSpan(text: key, style: TextStyle(color: color, fontSize: 20)), // textDirection: TextDirection.ltr, // ) // ..layout() // ..paint(ctx, offset); // }); // } // getCircles() { // legend = {}; // double radius = height / 2.5; // double r = 15; // if (controller.signalData == null) { // return; // } // var signalData = controller.signalData!; // if (controller.selectedSignal['GPS'] == true) { // for (int i = 0; i < signalData.GPS.length; i++) { // SignalGPS item = controller.signalData.GPS[i]; // double elev = item.elevation * pi / 180; // 将仰角转换为弧度 // double maxr = radius * cos(elev); // 计算该点到圆心的距离 // double azi = (90 - item.azimuth) * pi / 180; // 将方位角转换为弧度 // double cx = (maxr) * cos(azi); // 计算 x 坐标 // double cy = -(maxr) * sin(azi); // 计算 y // _paint.color = Colors.blue; // _paint.style = PaintingStyle.fill; // // 绘制卫星位置 // ctx.drawCircle(Offset(cx, cy), r, _paint); // } // } else if (controller.selectedSignal['BDS'] == true) { // for (int i = 0; i < signalData.BDS.length; i++) { // SignalBDS item = controller.signalData!.BDS![i]; // double elev = item.elevation * pi / 180; // 将仰角转换为弧度 // double maxr = radius * cos(elev); // 计算该点到圆心的距离 // double azi = (90 - item.azimuth) * pi / 180; // 将方位角转换为弧度 // double cx = (maxr) * cos(azi); // 计算 x 坐标 // double cy = -(maxr) * sin(azi); // 计算 y // _paint.color = Colors.red; // _paint.style = PaintingStyle.fill; // // 绘制卫星位置 // ctx.drawCircle(Offset(cx, cy), r, _paint); // } // } else if (controller.selectedSignal['GLO'] == true) { // for (int i = 0; i < signalData.GLO.length; i++) { // SignalGLO item = controller.signalData!.GLO![i]; // double elev = item.elevation * pi / 180; // 将仰角转换为弧度 // double maxr = radius * cos(elev); // 计算该点到圆心的距离 // double azi = (90 - item.azimuth) * pi / 180; // 将方位角转换为弧度 // double cx = (maxr) * cos(azi); // 计算 x 坐标 // double cy = -(maxr) * sin(azi); // 计算 y // _paint.color = Colors.green; // _paint.style = PaintingStyle.fill; // // 绘制卫星位置 // ctx.drawCircle(Offset(cx, cy), r, _paint); // } // } else if (controller.selectedSignal['ALS'] == true) { // for (int i = 0; i < signalData.GAL.length; i++) { // SignalGAL item = controller.signalData!.GAL![i]; // double elev = item.elevation * pi / 180; // 将仰角转换为弧度 // double maxr = radius * cos(elev); // 计算该点到圆心的距离 // double azi = (90 - item.azimuth) * pi / 180; // 将方位角转换为弧度 // double cx = (maxr) * cos(azi); // 计算 x 坐标 // double cy = -(maxr) * sin(azi); // 计算 y // _paint.color = Colors.orange; // _paint.style = PaintingStyle.fill; // // 绘制卫星位置 // ctx.drawCircle(Offset(cx, cy), r, _paint); // } // } // } // } 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; return Obx(() { controller.singnalUpdate; final signalGNSS = [ controller.signalData?.GPS, controller.signalData?.GLO, controller.signalData?.GAL, controller.signalData?.BDS, controller.signalData?.QZSS, ]; return CustomPaint( painter: SkyPlotPainter(signalGNSS, controller.selectedSignal), ); }); } } // class DrawSky extends CustomPainter { // final BuildContext context; // final GnssController controller; // final radius = 20.0; // final bool isDarkMode; // // late SignalData signalData; // DrawSky(this.controller, this.context, this.isDarkMode); // @override // void paint(Canvas canvas, Size size) { // canvas.translate(0, -15); // final bool isPortrait = // MediaQuery.of(context).orientation == Orientation.portrait; // DrawSkyPlot skyPlot = DrawSkyPlot({ // 'ctx': canvas, // 'height': size.height, // 'width': size.width, // }, isDarkMode, controller); // if (!isPortrait) { // canvas.translate(-30, 0); // } // skyPlot.drawSkyPlotCircle(); // // if (controller.chartData.value.time != 0) { // if (isPortrait) { // canvas.translate(size.width / 2, size.height / 2); // } else { // canvas.translate(size.width / 2, size.height / 2); // } // skyPlot.getCircles(); // if (isPortrait) { // canvas.translate(-size.width / 2, -size.height / 2); // } else { // canvas.translate(-size.width / 2, -size.height / 2); // } // // } // } // @override // bool shouldRepaint(covariant CustomPainter oldDelegate) => true; // } class SkyPlotPainter extends CustomPainter { final List?> signalGNSS; final List selectedSignal; final satelliteRadius = 20.0; SkyPlotPainter(this.signalGNSS, this.selectedSignal); @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = Colors.blue ..style = PaintingStyle.stroke; final double radius = min(size.width / 2, size.height / 2); final Offset center = Offset(size.width / 2, size.height / 2); // 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); } // Draw satellite positions final satellitePaint = Paint()..style = PaintingStyle.fill; for (int i = 0; i < signalGNSS.length; i++) { final signalData = signalGNSS[i]; if (!selectedSignal[i] || signalData == null) { continue; } satellitePaint.color = signalColorList[i]; drawGnssSignal(canvas, center, radius, signalData, satellitePaint); } } void drawGnssSignal( Canvas canvas, Offset center, double radius, List signals, Paint paint, ) { for (final signal in signals) { final int el = signal.elevation; final double az = signal.azimuth * 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); } } @override bool shouldRepaint(covariant CustomPainter oldDelegate) { return false; } }