Navigációs térkép és útvoanlrögzítés hibáinak javítása
This commit is contained in:
@@ -9,7 +9,10 @@ import 'package:terepi_seged/models/source_point.dart';
|
||||
import 'package:terepi_seged/models/vechicle_position_log.dart';
|
||||
import 'package:terepi_seged/services/app_database.dart';
|
||||
import 'package:terepi_seged/services/coord_converter_service.dart';
|
||||
import 'package:terepi_seged/services/gnss/gnss_connection.dart';
|
||||
import 'package:terepi_seged/services/gnss/gnss_device_service.dart';
|
||||
import 'package:terepi_seged/services/gnss/gnss_service.dart';
|
||||
import 'package:terepi_seged/services/layer_import_service.dart';
|
||||
import 'package:terepi_seged/services/project_service.dart';
|
||||
import 'package:terepi_seged/services/sps_import_service.dart';
|
||||
import 'package:terepi_seged/services/vechicle_identity_service.dart';
|
||||
@@ -27,50 +30,80 @@ class VibroNavView extends GetView<VibroNavController> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Vibrátor navigáció'),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.upload_file),
|
||||
tooltip: 'Forráspontok importja (SPS S-fájl)',
|
||||
onPressed: _importSourcePoints,
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.local_shipping_outlined),
|
||||
tooltip: 'Jármű kiválasztása',
|
||||
onPressed: _pickVehicle,
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Stack(
|
||||
children: [
|
||||
_buildMap(),
|
||||
Obx(() {
|
||||
final target =
|
||||
controller.hasPosition.value && Get.isRegistered<GnssService>()
|
||||
appBar: AppBar(
|
||||
title: const Text('Navigáció'),
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.bluetooth_connected),
|
||||
tooltip: "Gyors újracsatlakozás a GNSS vevőhöz",
|
||||
onPressed: _quickReconnectGnss,
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.layers_outlined),
|
||||
tooltip: 'Réteg importja (GeoJSON/KML/KMZ)',
|
||||
onPressed: _importLayer,
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.upload_file),
|
||||
tooltip: 'Forráspontok importja (SPS S-fájl)',
|
||||
onPressed: _importSourcePoints,
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.local_shipping_outlined),
|
||||
tooltip: 'Jármű kiválasztása',
|
||||
onPressed: _pickVehicle,
|
||||
),
|
||||
],
|
||||
),
|
||||
body: Obx(() {
|
||||
if (!controller.mapReady.value) {
|
||||
return const Center(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CircularProgressIndicator(),
|
||||
SizedBox(height: 12),
|
||||
Text('Pozíció lekérése…'),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
return Stack(
|
||||
children: [
|
||||
_buildMap(),
|
||||
Builder(builder: (context) {
|
||||
final target = controller.hasPosition.value &&
|
||||
Get.isRegistered<GnssService>()
|
||||
? LatLng(GnssService.to.latitude.value,
|
||||
GnssService.to.longitude.value)
|
||||
: null;
|
||||
return AnimatedMapFollow(
|
||||
mapController: controller.mapController,
|
||||
target: target,
|
||||
heading: controller.travelHeading.value);
|
||||
}),
|
||||
Positioned(
|
||||
left: 8,
|
||||
right: 8,
|
||||
top: 8,
|
||||
child: _VehicleBadge(),
|
||||
),
|
||||
Positioned(
|
||||
left: 8,
|
||||
right: 8,
|
||||
bottom: 8,
|
||||
child: _NavPanel(controller: controller),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
return AnimatedMapFollow(
|
||||
mapController: controller.mapController,
|
||||
target: target,
|
||||
heading: controller.travelHeading.value,
|
||||
);
|
||||
}),
|
||||
Positioned(
|
||||
left: 8,
|
||||
right: 8,
|
||||
top: 8,
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(child: _VehicleBadge()),
|
||||
const SizedBox(width: 8),
|
||||
const _GnssStatusBadge(),
|
||||
],
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 8,
|
||||
right: 8,
|
||||
bottom: 8,
|
||||
child: _NavPanel(controller: controller),
|
||||
),
|
||||
],
|
||||
);
|
||||
}));
|
||||
}
|
||||
|
||||
Widget _buildMap() {
|
||||
@@ -78,10 +111,17 @@ class VibroNavView extends GetView<VibroNavController> {
|
||||
final points = controller.sourcePoints;
|
||||
final nearest = controller.nearestPoint.value;
|
||||
|
||||
final gnssPos =
|
||||
Get.isRegistered<GnssService>() && GnssService.to.latitude.value != 0
|
||||
? LatLng(
|
||||
GnssService.to.latitude.value, GnssService.to.longitude.value)
|
||||
: null;
|
||||
final center = gnssPos ?? const LatLng(47.5, 19.05);
|
||||
|
||||
return FlutterMap(
|
||||
mapController: controller.mapController,
|
||||
options: const MapOptions(
|
||||
initialCenter: LatLng(47.5, 19.05),
|
||||
options: MapOptions(
|
||||
initialCenter: center,
|
||||
initialZoom: 15,
|
||||
),
|
||||
children: [
|
||||
@@ -147,6 +187,38 @@ class VibroNavView extends GetView<VibroNavController> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _quickReconnectGnss() async {
|
||||
final device = GnssDeviceService.to.selectedDevice.value;
|
||||
if (device == null) {
|
||||
Get.snackbar(
|
||||
'Nincs korábbi GNSS-eszköz',
|
||||
'Előbb válassz ki egyet a Kitűzés/Mérés beállításaiban.',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
return;
|
||||
}
|
||||
Get.snackbar(
|
||||
'Újracsatlakozás',
|
||||
'„${device.name}" (${device.typeLabel}) — folyamatban…',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
duration: const Duration(seconds: 2),
|
||||
);
|
||||
await GnssService.to.reconnect();
|
||||
}
|
||||
|
||||
Future<void> _importLayer() async {
|
||||
try {
|
||||
final layer = await LayerImportService.to.importFile();
|
||||
if (layer != null) {
|
||||
Get.snackbar('Réteg importálva', layer.name,
|
||||
snackPosition: SnackPosition.BOTTOM);
|
||||
}
|
||||
} catch (e) {
|
||||
Get.snackbar('Import hiba', e.toString(),
|
||||
snackPosition: SnackPosition.BOTTOM);
|
||||
}
|
||||
}
|
||||
|
||||
// ── SPS S-fájl (forráspont) import — kompakt, egyetlen dialógus ────
|
||||
|
||||
Future<void> _importSourcePoints() async {
|
||||
@@ -419,3 +491,59 @@ class _VehicleMarker extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _GnssStatusBadge extends StatelessWidget {
|
||||
const _GnssStatusBadge();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!Get.isRegistered<GnssService>()) return const SizedBox.shrink();
|
||||
|
||||
return Obx(() {
|
||||
final gnss = GnssService.to;
|
||||
final state = gnss.connectionState.value;
|
||||
final quality = gnss.gpsQuality.value;
|
||||
|
||||
Color color;
|
||||
IconData icon;
|
||||
String label;
|
||||
|
||||
if (state == GnssConnectionState.connected && quality > 0) {
|
||||
color = Colors.green;
|
||||
icon = Icons.gps_fixed;
|
||||
label = quality >= 4 ? 'RTK fix' : (quality == 2 ? 'RTK float' : 'GPS');
|
||||
} else if (state == GnssConnectionState.connected) {
|
||||
color = Colors.orange;
|
||||
icon = Icons.gps_not_fixed;
|
||||
label = 'Nincs fix';
|
||||
} else if (state == GnssConnectionState.connecting) {
|
||||
color = Colors.orange;
|
||||
icon = Icons.gps_not_fixed;
|
||||
label = 'Csatlakozás…';
|
||||
} else {
|
||||
color = Colors.red;
|
||||
icon = Icons.gps_off;
|
||||
label = 'Nincs GNSS';
|
||||
}
|
||||
|
||||
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, width: 1),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(icon, size: 14, color: color),
|
||||
const SizedBox(width: 4),
|
||||
Text(label,
|
||||
style: TextStyle(
|
||||
fontSize: 11, fontWeight: FontWeight.w600, color: color)),
|
||||
],
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user