This commit is contained in:
Holy 2024-07-31 23:37:51 +08:00
parent 553bde932c
commit dcfd9c6268
10 changed files with 499 additions and 401 deletions

View File

@ -1,26 +1,30 @@
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import 'package:get/get.dart';
import 'package:gnss/gnss.dart';
class GnssController extends GetxController {
late Gnss gnss;
late final Gnss gnss;
LocationData? locationData;
SignalData? signalData;
var locationUpdate = 0.obs;
var singnalUpdate = 0.obs;
// var _selectedSignal = [];
Map<String, bool> selectedSignal = {};
// List<String> get selectedSignal => _selectedSignal;
// set selectedSignal(Set<String> value) {
// _selectedSignal = value;
// update();
// }
// Map<String, bool> selectedSignal = {
// "GPS": true,
// "GLONASS": true,
// "GALILEO": true,
// "BEIDOU": true,
// "QZSS": true,
// "SBAS": true,
// }.obs;
final selectedSignal = <bool>[true, true, true, true, true, true].obs;
@override
void onInit() async {
super.onInit();
gnss = Gnss(port: "/dev/ttysWK2", baudrate: 115200);
// gnss = Gnss(port: "/dev/ttysWK2", baudrate: 115200);
gnss = Gnss(port: "COM1", baudrate: 115200);
gnss.start();
gnss.locationStream.listen((location) {
locationData = location;
@ -34,7 +38,6 @@ class GnssController extends GetxController {
@override
void dispose() {
// TODO: implement dispose
gnss.dispose();
super.dispose();
}

View File

@ -1,11 +1,10 @@
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:gnss/gnss.dart';
// import 'package:gnss/gnss.dart';
import 'sky/skyplot.dart';
import 'Controller/gnssController.dart'; // Import the correct file location for GnssController
import 'sky/sky_plot.dart';
import 'sky/sky_info.dart';
import 'Controller/gnss_controller.dart'; // Import the correct file location for GnssController
// void main() {
// Get.lazyPut<GnssController>(() => GnssController(), tag: 'gnss');
@ -44,7 +43,7 @@ import 'Controller/gnssController.dart'; // Import the correct file location for
// }
void main() {
Get.lazyPut<GnssController>(() => GnssController(), tag: 'gnss');
Get.put<GnssController>(GnssController());
runApp(MyApp());
}
@ -71,13 +70,13 @@ class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
final con = Get.find<GnssController>(tag: 'gnss');
// final con = Get.find<GnssController>();
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('天空图'),
),
body: SkyPlotPage(),
body: SkyInfo(),
));
}
}

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
class SingleButton extends StatefulWidget {
final controller = Get.find(tag: 'gnss');
// final controller = Get.find(tag: 'gnss');
final List<Color> colors;
final Function(Color) onSelectionChanged;

View File

@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
class MulButton extends StatefulWidget {
final controller = Get.find(tag: 'gnss');
// final controller = Get.find(tag: 'gnss');
final List<Color> colors;
final Function(List<Color>) onSelectionChanged;
final Function(int, bool) onSelectionChanged;
MulButton({
required this.colors,
@ -27,13 +27,13 @@ class _MulButtonState extends State<MulButton> {
void updateSelection(int index, bool value) {
setState(() {
selectedColors[index] = value;
List<Color> selected = [];
for (int i = 0; i < selectedColors.length; i++) {
if (selectedColors[i]) {
selected.add(widget.colors[i]);
}
}
widget.onSelectionChanged(selected); //
// List<Color> selected = [];
// for (int i = 0; i < selectedColors.length; i++) {
// if (selectedColors[i]) {
// selected.add(widget.colors[i]);
// }
// }
widget.onSelectionChanged(index, value); //
});
}

View File

@ -1,120 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:gnssview/sky/device_type.dart';
import '../Controller/gnssController.dart';
import 'mulbutton.dart';
class SkyInfo extends StatelessWidget {
late GnssController controller;
// final String lat; //
// final String lon; //
// final String hdop; //
// final int status; //
// final int view; //
// final int use; // 使
// final String time; //
SkyInfo() {
controller = Get.find<GnssController>(tag: 'gnss');
}
@override
Widget build(BuildContext context) {
final isPortrait =
MediaQuery.of(context).orientation == Orientation.portrait;
return Theme(
data: ThemeData(
textTheme: const TextTheme(
titleLarge: TextStyle(
fontSize: 30,
fontWeight: FontWeight.normal,
),
),
),
child: Container(
margin: const EdgeInsets.only(left: 5),
padding: const EdgeInsets.symmetric(vertical: 20),
alignment: Alignment.centerLeft,
child:
Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
//
rowItem(context, "北纬:", '${controller.locationData?.latitude} '),
rowItem(context, "东经:", '${controller.locationData?.longitude}'),
rowItem(context, "高程:", '${controller.locationData?.altitude}'),
rowItem(context, "水平定位精度:", '${controller.locationData?.hdop}'),
rowItem(context, "垂直定位精度:", '${controller.locationData?.vdop}'),
rowItem(context, "定位状态:", '${controller.locationData?.fixQuality}'),
rowItem(context, "可见卫星数:", '${controller.locationData?.numberSv}'),
rowItem(context, "使用卫星数:", '${controller.locationData?.numberSa}'),
rowItem(context, "时间:", '${controller.locationData?.time}'),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MulButton(
colors: const [
Colors.blue,
Colors.red,
Colors.green,
Colors.orange
],
onSelectionChanged: (selectedColors) {
//
print('选中的颜色: $selectedColors');
},
),
],
),
]),
));
}
Widget rowItem(BuildContext context, String title, String text) => Row(
children: [
FixedWidthTextWidget(
width: 80,
text: title,
style: Theme.of(context).textTheme.titleLarge,
),
Text(
text,
style: Theme.of(context).textTheme.titleLarge,
),
],
);
}
class FixedWidthTextWidget extends StatelessWidget {
final String text;
final double width;
final TextStyle? style;
FixedWidthTextWidget({
super.key,
required this.text,
this.width = 80,
this.style,
});
TextStyle? textStyle;
@override
Widget build(BuildContext context) {
final deviceType = getDeviceType(context);
double dynamicWidth = deviceType == DeviceType.mobile ? 0 : 50;
if (style != null) {
textStyle =
style!.copyWith(fontSize: deviceType == DeviceType.mobile ? 16 : 20);
} else {
textStyle =
TextStyle(fontSize: deviceType == DeviceType.mobile ? 16 : 20);
}
return Container(
margin: const EdgeInsets.symmetric(horizontal: 3),
width: width + dynamicWidth,
child: Text(
text,
style: textStyle,
),
);
}
}

View File

@ -1,250 +0,0 @@
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:get/get.dart';
import 'package:gnss/gnss.dart';
import '../Controller/gnssController.dart';
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<GnssController>(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<String, ui.Image> imageList = {};
@override
SkyPlotPage() {
controller = Get.find<GnssController>(tag: 'gnss');
}
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;
return Obx(() {
controller.singnalUpdate;
return CustomPaint(
painter: DrawSky(controller, context, isDarkMode),
);
});
}
}
class DrawSky extends CustomPainter {
final BuildContext context;
final GnssController controller;
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;
}

122
lib/sky/sky_info.dart Normal file
View File

@ -0,0 +1,122 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:gnssview/sky/device_type.dart';
import '../Controller/gnss_controller.dart';
import 'mulbutton.dart';
class SkyInfo extends StatelessWidget {
late final GnssController controller;
SkyInfo({super.key}) {
controller = Get.find<GnssController>();
}
@override
Widget build(BuildContext context) {
final isPortrait =
MediaQuery.of(context).orientation == Orientation.portrait;
return Theme(
data: ThemeData(
textTheme: const TextTheme(
titleLarge: TextStyle(
fontSize: 30,
fontWeight: FontWeight.normal,
),
),
),
child: Container(
margin: const EdgeInsets.only(left: 5),
padding: const EdgeInsets.symmetric(vertical: 20),
alignment: Alignment.centerLeft,
child: Obx(() {
controller.locationUpdate.value;
final location = controller.locationData;
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
//
rowItem(context, "纬度:", '${location?.latitude}'),
rowItem(context, "经度:", '${location?.longitude}'),
rowItem(context, "高程:", '${location?.altitude}'),
rowItem(context, "水平精度:", '${location?.hdop}'),
rowItem(context, "垂直精度:", '${location?.vdop}'),
rowItem(context, "定位状态:", '${location?.fixQuality}'),
rowItem(context, "可见卫星数:", '${location?.numberSv}'),
rowItem(context, "使用卫星数:", '${location?.numberSa}'),
rowItem(
context,
"时间:",
location == null
? 'null'
: DateFormat('yyyy-MM-dd HH:mm:ss')
.format(location.time)),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MulButton(
colors: const [
Colors.blue,
Colors.red,
Colors.green,
Colors.orange
],
onSelectionChanged: (int index, bool value) {
controller.selectedSignal[index] = value;
},
),
],
),
]);
})));
}
Widget rowItem(BuildContext context, String title, String text) => Row(
children: [
FixedWidthText(
width: 80,
text: title,
style: Theme.of(context).textTheme.titleLarge,
),
Text(
text,
style: Theme.of(context).textTheme.titleLarge,
),
],
);
}
class FixedWidthText extends StatelessWidget {
final String text;
final double width;
final TextStyle? style;
const FixedWidthText({
super.key,
required this.text,
this.width = 80,
this.style,
});
@override
Widget build(BuildContext context) {
final deviceType = getDeviceType(context);
double dynamicWidth = deviceType == DeviceType.mobile ? 0 : 50;
TextStyle textStyle;
if (style != null) {
textStyle =
style!.copyWith(fontSize: deviceType == DeviceType.mobile ? 16 : 20);
} else {
textStyle =
TextStyle(fontSize: deviceType == DeviceType.mobile ? 16 : 20);
}
return Container(
margin: const EdgeInsets.symmetric(horizontal: 3),
width: width + dynamicWidth,
child: Text(
text,
style: textStyle,
),
);
}
}

336
lib/sky/sky_plot.dart Normal file
View File

@ -0,0 +1,336 @@
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 = <String>["GPS", "GLONASS", "GALILEO", "BEIDOU", "QZSS"];
const List<Color> 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<GnssController>(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<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;
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<List<SignalGNSS>?> signalGNSS;
final List<bool> 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<SignalGNSS> 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;
}
}

View File

@ -120,10 +120,18 @@ packages:
description:
path: "."
ref: main
resolved-ref: "6e4c9b35dc86d027a0f0bfbc65747a4813d92a2c"
resolved-ref: "05b6cd1985ad7f13a487820f4cfa1e9622e2daae"
url: "https://git.mcxa.cn:89/flutter/gnss.git"
source: git
version: "0.0.1"
intl:
dependency: "direct main"
description:
name: intl
sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91"
url: "https://pub.dev"
source: hosted
version: "0.17.0"
leak_tracker:
dependency: transitive
description:

View File

@ -34,7 +34,7 @@ dependencies:
git:
url: https://git.mcxa.cn:89/flutter/gnss.git
ref: main
intl: ^0.17.0
# libserialport:
# path: plugins/libserialport