MobilApp/lib/widgets/map/measure_bottom_panel.dart

267 lines
11 KiB
Dart
Raw Normal View History

// Bemérés mód alsó panel:
// - Aktuális koordináták (WGS84 + EOV)
// - GPS minőség + pontosság
// - Rögzített pontok száma
// - Nagy "Pont rögzítése" gomb
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:terepi_seged/services/gnss/gnss_connection.dart';
import 'package:terepi_seged/services/gnss/gnss_service.dart';
import '../../pages/map_survey/presentations/controllers/map_survey_controller.dart';
class MeasureBottomPanel extends StatelessWidget {
final MapSurveyController ctrl;
const MeasureBottomPanel({super.key, required this.ctrl});
@override
Widget build(BuildContext context) {
final cs = Theme.of(context).colorScheme;
return Container(
decoration: BoxDecoration(
color: cs.surface,
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.12),
blurRadius: 12,
offset: const Offset(0, -3),
),
],
),
child: SafeArea(
top: false,
child: Padding(
padding: const EdgeInsets.fromLTRB(16, 10, 16, 8),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
// ── Koordináta sor ─────────────────────────────────────
Obx(() {
final lat = ctrl.gpsLatitude.value;
final lon = ctrl.gpsLongitude.value;
final eovY = ctrl.eovY.value;
final eovX = ctrl.eovX.value;
final hasGps = GnssService.to.connectionState.value ==
GnssConnectionState.connected;
if (!hasGps) {
return Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Text(
'GPS pozíció nem elérhető',
style:
TextStyle(color: cs.onSurfaceVariant, fontSize: 12),
),
);
}
return Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Row(
children: [
// WGS84
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('WGS84',
style: TextStyle(
fontSize: 10,
color: cs.onSurfaceVariant,
fontWeight: FontWeight.w500)),
Text(
'${lat.toStringAsFixed(7)}°',
style: const TextStyle(
fontSize: 12,
fontFeatures: [FontFeature.tabularFigures()]),
),
Text(
'${lon.toStringAsFixed(7)}°',
style: const TextStyle(
fontSize: 12,
fontFeatures: [FontFeature.tabularFigures()]),
),
],
),
),
Container(
width: 1,
height: 36,
color: cs.outlineVariant,
margin: const EdgeInsets.symmetric(horizontal: 10)),
// EOV
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('EOV',
style: TextStyle(
fontSize: 10,
color: cs.onSurfaceVariant,
fontWeight: FontWeight.w500)),
Text(
'Y: ${eovY == 0 ? "" : eovY.toStringAsFixed(1)}',
style: const TextStyle(
fontSize: 12,
fontFeatures: [FontFeature.tabularFigures()]),
),
Text(
'X: ${eovX == 0 ? "" : eovX.toStringAsFixed(1)}',
style: const TextStyle(
fontSize: 12,
fontFeatures: [FontFeature.tabularFigures()]),
),
],
),
),
Container(
width: 1,
height: 36,
color: cs.outlineVariant,
margin: const EdgeInsets.symmetric(horizontal: 10)),
// Pontosság
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('Pontosság',
style: TextStyle(
fontSize: 10,
color: cs.onSurfaceVariant,
fontWeight: FontWeight.w500)),
Obx(() => Text(
'H: ${ctrl.horizontalAccuracyText}',
style: TextStyle(
fontSize: 12,
color: _accuracyColor(
ctrl.gpsLatitudeError.value,
ctrl.gpsLongitudeError.value),
fontWeight: FontWeight.w600,
fontFeatures: const [
FontFeature.tabularFigures()
],
),
)),
Obx(() => Text(
'V: ${ctrl.verticalAccuracyText}',
style: TextStyle(
fontSize: 12,
color: _accuracyColor(
ctrl.gpsAltitudeError.value,
ctrl.gpsAltitudeError.value),
fontWeight: FontWeight.w600,
fontFeatures: const [
FontFeature.tabularFigures()
],
),
)),
],
),
],
),
);
}),
const Divider(height: 1),
const SizedBox(height: 8),
// ── Minőség chip + rögzített pontok + gomb ─────────────
Row(
children: [
// GPS minőség chip
Obx(() {
final q = ctrl.gpsQuality.value;
final color = ctrl.getCurrentLocationMarkerColor(q);
final label = ctrl.getGpsQualityIndicator(quality: q);
return Container(
padding: const EdgeInsets.symmetric(
horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: color.withOpacity(0.15),
borderRadius: BorderRadius.circular(6),
border: Border.all(color: color.withOpacity(0.5)),
),
child: Row(mainAxisSize: MainAxisSize.min, children: [
Container(
width: 7,
height: 7,
decoration: BoxDecoration(
color: color, shape: BoxShape.circle),
),
const SizedBox(width: 5),
Text(label,
style: TextStyle(
fontSize: 11,
color: color,
fontWeight: FontWeight.w600)),
]),
);
}),
const SizedBox(width: 8),
// Rögzített pontok száma
Obx(() {
final count = ctrl.pointWithDescriptionList.length;
return Container(
padding: const EdgeInsets.symmetric(
horizontal: 8, vertical: 4),
decoration: BoxDecoration(
color: cs.surfaceContainerHighest,
borderRadius: BorderRadius.circular(6),
),
child: Row(mainAxisSize: MainAxisSize.min, children: [
Icon(Icons.location_on,
size: 13, color: Colors.amber.shade700),
const SizedBox(width: 4),
Text('$count pont',
style: const TextStyle(
fontSize: 11, fontWeight: FontWeight.w500)),
]),
);
}),
const Spacer(),
IconButton(
onPressed: ctrl.openMeasuredPointsList,
icon: const Icon(Icons.list_alt_outlined),
tooltip: 'Bemért pontok'),
const SizedBox(width: 4),
// Pont rögzítése gomb
Obx(() {
final hasGps = GnssService.to.connectionState.value ==
GnssConnectionState.connected;
return FilledButton.icon(
onPressed: hasGps ? ctrl.showAddPointDialog : null,
icon: const Icon(Icons.add_location_alt, size: 18),
label: const Text('Rögzítés'),
style: FilledButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 16, vertical: 10),
),
);
})
],
),
],
),
),
),
);
}
Color _accuracyColor(double e1, double e2) {
final e = e1 > e2 ? e1 : e2;
if (e <= 0.05) return Colors.green;
if (e <= 0.20) return Colors.lightGreen;
if (e <= 1.00) return Colors.orange;
return Colors.red;
}
}