GNSS minőség adatok kijelzése (pod-ok)

This commit is contained in:
torok.istvan 2026-06-09 00:23:28 +02:00
parent b85cdb2596
commit 8b4c25f475
8 changed files with 305 additions and 4 deletions

View File

@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math';
import 'dart:math' as math;
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
@ -65,10 +66,16 @@ class MapSurveyController extends GetxController {
Rx<DateTime> get gpsDateTime => _gnss.gpsDateTime;
bool get gpsIsConnected =>
_gnss.connectionState.value == GnssConnectionState.connected;
double? get horizontalAccuracy => _gnss.horizontalAccuracy;
RxDouble get pdop => _gnss.pdop;
RxDouble get hdop => _gnss.hdop;
RxDouble get vdop => _gnss.vdop;
final wgs84CoordinateFormat = Wgs84CoordinateFormat.decimalDegrees.obs;
final showWgs84Card = true.obs;
final showEovCard = true.obs;
final showGnssQualityCard = true.obs;
// NTRIP állapot
RxBool get ntripIsConnected => _ntrip.isConnected;
@ -799,6 +806,10 @@ class MapSurveyController extends GetxController {
showEovCard.value = !showEovCard.value;
}
void toggleShowGnssQualityCard() {
showGnssQualityCard.value = !showGnssQualityCard.value;
}
String get latitudeText {
return Wgs84CoordinateFormatter.formatLatitude(
gpsLatitude.value, wgs84CoordinateFormat.value);
@ -808,4 +819,28 @@ class MapSurveyController extends GetxController {
return Wgs84CoordinateFormatter.formatLongitude(
gpsLongitude.value, wgs84CoordinateFormat.value);
}
String formatDop(double? value) {
if (value == null || value.isNaN || value.isInfinite) {
return '-';
}
return value.toStringAsFixed(2);
}
String formatMeterCompact(double? value) {
if (value == null || value.isNaN || value.isInfinite) {
return '-';
}
if (value < 1.0) {
return '${value.toStringAsFixed(3)}m';
}
if (value < 10.0) {
return '${value.toStringAsFixed(2)}m';
}
return '${value.toStringAsFixed(1)}m';
}
}

View File

@ -39,7 +39,7 @@ class MapSurveyView extends GetView<MapSurveyController> {
),
Positioned(
top: 300,
top: 390,
right: 60,
left: 8,
child: CoordinatePanel(

View File

@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:math';
import 'dart:typed_data';
import 'package:geolocator/geolocator.dart';
@ -93,6 +94,13 @@ class GnssService extends GetxService {
return activeSatelliteKeys.contains(sat.satelliteKey);
}
double? get horizontalAccuracy {
final lat = latitudeError.value;
final lon = longitudeError.value;
return sqrt(lat * lat + lon * lon);
}
// Belső
final NmeaDecoder _decoder = NmeaDecoder();
StreamSubscription? _nmeaSub;

View File

@ -0,0 +1,204 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:terepi_seged/pages/map_survey/presentations/controllers/map_survey_controller.dart';
import 'map_info_card.dart';
import 'quality_mini_value.dart';
class GnssQualityCard extends StatelessWidget {
final MapSurveyController controller;
const GnssQualityCard({
super.key,
required this.controller,
});
@override
Widget build(BuildContext context) {
return Obx(() {
final hError = controller.horizontalAccuracy;
final vError = controller.gpsAltitudeError.value;
return MapInfoCard(
onClose: controller.toggleShowGnssQualityCard,
title: Row(
children: [
const Icon(Icons.speed, size: 18),
const SizedBox(width: 6),
Text(
'Minőség',
style: Theme.of(context).textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.w700,
),
),
],
),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Row(
children: [
Expanded(
child: QualityMiniValue(
label: 'PDOP',
value: controller.formatDop(controller.pdop.value),
color: qualityColorForDop(
context,
controller.pdop.value,
),
),
),
Expanded(
child: QualityMiniValue(
label: 'HDOP',
value: controller.formatDop(controller.hdop.value),
color: qualityColorForDop(
context,
controller.hdop.value,
),
),
),
Expanded(
child: QualityMiniValue(
label: 'VDOP',
value: controller.formatDop(controller.vdop.value),
color: qualityColorForDop(
context,
controller.vdop.value,
),
),
),
],
),
const SizedBox(height: 3),
Row(
children: [
Expanded(
child: QualityMiniValue(
label: 'Latσ',
value: controller.formatMeterCompact(
controller.gpsLatitudeError.value,
),
color: qualityColorForHorizontalError(
context,
controller.gpsLatitudeError.value,
),
),
),
Expanded(
child: QualityMiniValue(
label: 'Lonσ',
value: controller.formatMeterCompact(
controller.gpsLongitudeError.value,
),
color: qualityColorForHorizontalError(
context,
controller.gpsLongitudeError.value,
),
),
),
Expanded(
child: QualityMiniValue(
label: 'H',
value: controller.formatMeterCompact(hError),
color: qualityColorForHorizontalError(
context,
hError,
),
emphasized: true,
),
),
Expanded(
child: QualityMiniValue(
label: 'V',
value: controller.formatMeterCompact(vError),
color: qualityColorForVerticalError(
context,
vError,
),
emphasized: true,
),
),
],
),
],
),
);
});
}
Color qualityColorForDop(
BuildContext context,
double? value,
) {
final colorScheme = Theme.of(context).colorScheme;
if (value == null || value.isNaN || value.isInfinite) {
return colorScheme.onSurface.withOpacity(0.45);
}
if (value <= 1.0) {
return Colors.green.shade700;
}
if (value <= 2.0) {
return Colors.lightGreen.shade700;
}
if (value <= 5.0) {
return Colors.orange.shade800;
}
return Colors.red.shade700;
}
Color qualityColorForHorizontalError(
BuildContext context,
double? value,
) {
final colorScheme = Theme.of(context).colorScheme;
if (value == null || value.isNaN || value.isInfinite) {
return colorScheme.onSurface.withOpacity(0.45);
}
if (value <= 0.03) {
return Colors.green.shade700;
}
if (value <= 0.10) {
return Colors.lightGreen.shade700;
}
if (value <= 0.50) {
return Colors.orange.shade800;
}
return Colors.red.shade700;
}
Color qualityColorForVerticalError(
BuildContext context,
double? value,
) {
final colorScheme = Theme.of(context).colorScheme;
if (value == null || value.isNaN || value.isInfinite) {
return colorScheme.onSurface.withOpacity(0.45);
}
if (value <= 0.05) {
return Colors.green.shade700;
}
if (value <= 0.15) {
return Colors.lightGreen.shade700;
}
if (value <= 0.75) {
return Colors.orange.shade800;
}
return Colors.red.shade700;
}
}

View File

@ -45,7 +45,7 @@ class MapInfoCard extends StatelessWidget {
),
],
),
const SizedBox(height: 6),
const SizedBox(height: 1),
child,
],
),

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:terepi_seged/pages/map_survey/presentations/controllers/map_survey_controller.dart';
import 'package:terepi_seged/widgets/gnss_quality_card.dart';
import 'package:terepi_seged/widgets/wgs84_coordinate_card.dart';
import 'eov_coordinate_card.dart';
@ -27,6 +28,9 @@ class MapInfoCardColumn extends StatelessWidget {
if (controller.showEovCard.value) {
cards.add(EovCoordinateCard(controller: controller));
}
if (controller.showGnssQualityCard.value) {
cards.add(GnssQualityCard(controller: controller));
}
if (cards.isEmpty) {
return const SizedBox.shrink();
@ -41,7 +45,7 @@ class MapInfoCardColumn extends StatelessWidget {
children: [
for (var i = 0; i < cards.length; i++) ...[
cards[i],
if (i != cards.length - 1) const SizedBox(height: 8)
if (i != cards.length - 1) const SizedBox(height: 4)
]
],
),

View File

@ -0,0 +1,50 @@
import 'package:flutter/material.dart';
class QualityMiniValue extends StatelessWidget {
final String label;
final String value;
final Color color;
final bool emphasized;
const QualityMiniValue({
required this.label,
required this.value,
required this.color,
this.emphasized = false,
});
@override
Widget build(BuildContext context) {
final colorScheme = Theme.of(context).colorScheme;
return Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(
label,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.labelSmall?.copyWith(
color: colorScheme.onSurface.withOpacity(0.65),
fontWeight: FontWeight.w600,
height: 1.0,
),
),
const SizedBox(height: 2),
Text(
value,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: color,
fontWeight: emphasized ? FontWeight.w800 : FontWeight.w700,
height: 1.05,
fontFeatures: const [
FontFeature.tabularFigures(),
],
),
),
],
);
}
}

View File

@ -39,7 +39,7 @@ class Wgs84CoordinateCard extends StatelessWidget {
label: 'Lat',
value: controller.latitudeText,
),
const SizedBox(height: 4),
const SizedBox(height: 1),
CoordinateRow(
label: 'Lon',
value: controller.longitudeText,