gnssview/lib/sky/sky_plot.dart

155 lines
4.5 KiB
Dart
Raw Permalink Normal View History

2024-08-06 17:41:15 +08:00
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 = <String>["GPS", "GLO", "GAL", "BDS", "QZS"];
const Map<String, String> signalPrefixList = {
"GPS": "G",
"GLO": "N",
"GAL": "E",
"BDS": "B",
"QZS": "Q"
};
const Map<String, Color> 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<String, ui.Image> imageList = {};
@override
SkyPlotPage({super.key}) {
controller = Get.find<GnssController>();
}
Future<ui.Image> 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<String, bool> 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<SignalGNSS> 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;
}
}