Navigáció javítása, fejlesztése

This commit is contained in:
2026-07-15 03:13:52 +02:00
parent 0810c528ec
commit 204d848ba4
4 changed files with 143 additions and 62 deletions
@@ -1,7 +1,9 @@
import 'dart:async';
import 'dart:math' as math;
import 'package:flutter_map/flutter_map.dart';
import 'package:get/get.dart';
import 'package:latlong2/latlong.dart';
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';
@@ -50,12 +52,17 @@ class VibroNavController extends GetxController {
// ── Periodikus napló ───────────────────────────────────────────────
final isLogging = false.obs;
final logIntervalSec = 60.obs; // felhasználó által állítható
final logs = <VehiclePositionLog>[].obs;
Timer? _logTimer;
// ── Térkép — a MapController itt él, nem a View State-jében ────────
final mapController = MapController();
@override
void onInit() {
super.onInit();
load();
refreshLogs();
if (Get.isRegistered<GnssService>()) {
ever(GnssService.to.lastGgaLine, (_) => _onPosition());
}
@@ -67,6 +74,10 @@ class VibroNavController extends GetxController {
super.onClose();
}
Future<void> refreshLogs() async {
logs.value = await loadLogs();
}
Future<void> load() async {
final projectId = ProjectService.to.activeProjectId;
if (projectId == null) {
@@ -212,5 +223,6 @@ class VibroNavController extends GetxController {
: null,
);
await _db.insertVehiclePositionLog(entry);
logs.add(entry);
}
}
@@ -13,6 +13,7 @@ import 'package:terepi_seged/services/gnss/gnss_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';
import 'package:terepi_seged/widgets/map/animated_map_follow.dart';
import 'package:terepi_seged/widgets/map/imported_layer_overlay.dart';
import '../controllers/vibro_nav_controller.dart';
@@ -20,59 +21,9 @@ import '../controllers/vibro_nav_controller.dart';
/// Egyszerű navigációs oldal a vibrátor-járműhöz. ÖNÁLLÓ oldal, nem
/// MapSurveyMode — saját MapController kell a forgó (track-up)
/// térképhez, hogy ez semmilyen más módot ne érintsen.
class VibroNavView extends StatefulWidget {
class VibroNavView extends GetView<VibroNavController> {
const VibroNavView({super.key});
@override
State<VibroNavView> createState() => _VibroNavViewState();
}
class _VibroNavViewState extends State<VibroNavView> {
late final VibroNavController controller;
final _mapController = MapController();
List<VehiclePositionLog> _logs = [];
@override
void initState() {
super.initState();
controller = Get.put(VibroNavController());
_refreshLogs();
// Forgatás + a naplók frissítése a pozíció-változásokra.
ever(controller.travelHeading, (_) => _applyRotation());
ever(controller.hasPosition, (_) => _followPosition());
}
@override
void dispose() {
Get.delete<VibroNavController>();
super.dispose();
}
Future<void> _refreshLogs() async {
_logs = await controller.loadLogs();
if (mounted) setState(() {});
}
void _applyRotation() {
final h = controller.travelHeading.value;
if (h == null) return;
try {
_mapController.rotate(-h);
} catch (_) {}
}
void _followPosition() {
if (!controller.hasPosition.value ||
!Get.isRegistered<CoordConverterService>()) {
return;
}
final gnss = GnssService.to;
try {
_mapController.move(LatLng(gnss.latitude.value, gnss.longitude.value),
_mapController.camera.zoom);
} catch (_) {}
}
@override
Widget build(BuildContext context) {
return Scaffold(
@@ -94,6 +45,17 @@ class _VibroNavViewState extends State<VibroNavView> {
body: Stack(
children: [
_buildMap(),
Obx(() {
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,
@@ -104,8 +66,7 @@ class _VibroNavViewState extends State<VibroNavView> {
left: 8,
right: 8,
bottom: 8,
child: _NavPanel(
controller: controller, onLoggingToggled: _refreshLogs),
child: _NavPanel(controller: controller),
),
],
),
@@ -118,16 +79,22 @@ class _VibroNavViewState extends State<VibroNavView> {
final nearest = controller.nearestPoint.value;
return FlutterMap(
mapController: _mapController,
mapController: controller.mapController,
options: const MapOptions(
initialCenter: LatLng(47.5, 19.05),
initialZoom: 15,
),
children: [
// TileLayer(
// urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
// userAgentPackageName: 'hu.app_dev.terepi_seged',
// ),
TileLayer(
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
userAgentPackageName: 'hu.app_dev.terepi_seged',
urlTemplate: 'http://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}',
subdomains: const ['mt0', 'mt1', 'mt2', 'mt3'],
maxNativeZoom: 18,
),
// Tervezett útvonal + minden más importált háttérréteg — a
// MEGLÉVŐ rétegimport-mechanizmus, nincs hozzá új kód.
const ImportedLayerOverlay(),
@@ -140,7 +107,7 @@ class _VibroNavViewState extends State<VibroNavView> {
child: _SourcePointMarker(
point: sp,
isNearest: sp.uuid == nearest?.uuid,
isVerified: controller.isVerified(sp, _logs),
isVerified: controller.isVerified(sp, controller.logs),
),
),
if (controller.hasPosition.value)
@@ -237,6 +204,7 @@ class _VibroNavViewState extends State<VibroNavView> {
}
final inserted = await AppDatabase.instance.insertSourcePoints(saved);
await controller.load();
await controller.refreshLogs();
Get.snackbar('Import kész', '$inserted forráspont importálva',
snackPosition: SnackPosition.BOTTOM);
} catch (e) {
@@ -252,8 +220,7 @@ class _VibroNavViewState extends State<VibroNavView> {
class _NavPanel extends StatelessWidget {
final VibroNavController controller;
final VoidCallback onLoggingToggled;
const _NavPanel({required this.controller, required this.onLoggingToggled});
const _NavPanel({required this.controller});
@override
Widget build(BuildContext context) {
@@ -298,7 +265,6 @@ class _NavPanel extends StatelessWidget {
'(${controller.logIntervalSec.value} mp)'),
onPressed: () {
controller.stopLogging();
onLoggingToggled();
},
)
: FilledButton.icon(
@@ -308,7 +274,6 @@ class _NavPanel extends StatelessWidget {
'(${controller.logIntervalSec.value} mp-enként)'),
onPressed: () {
controller.startLogging();
onLoggingToggled();
},
),
),