diff --git a/lib/pages/map_survey/presentations/controllers/map_survey_controller.dart b/lib/pages/map_survey/presentations/controllers/map_survey_controller.dart index bd54c81..29b0c03 100644 --- a/lib/pages/map_survey/presentations/controllers/map_survey_controller.dart +++ b/lib/pages/map_survey/presentations/controllers/map_survey_controller.dart @@ -42,6 +42,7 @@ import 'package:terepi_seged/services/gnss/gnss_service.dart'; import 'package:terepi_seged/services/ntrip_service.dart'; import 'package:terepi_seged/services/project_service.dart'; import 'package:terepi_seged/widgets/map_edit_tools/map_feature_save_sheet.dart'; +import 'package:terepi_seged/widgets/shared_map_widgets.dart'; class MapSurveyController extends GetxController { static MapSurveyController get to => Get.find(); @@ -123,6 +124,7 @@ class MapSurveyController extends GetxController { RxBool mapIsInitialized = false.obs; final MapController mapController = MapController(); + bool _isMapProgrammaticMove = false; final polylineHitNotifier = ValueNotifier?>(null); final polygonHitNotifier = ValueNotifier?>(null); @@ -232,6 +234,7 @@ class MapSurveyController extends GetxController { polygonEditorController.addListener(() { editorPointCount.value = polygonEditorController.points.length; }); + await _setInitialPositionFromPhone(); mapIsInitialized.value = true; } @@ -266,6 +269,46 @@ class MapSurveyController extends GetxController { super.onClose(); } + Future _setInitialPositionFromPhone() async { + try { + // Engedély ellenőrzés + final permission = await Geolocator.checkPermission(); + if (permission == LocationPermission.denied || + permission == LocationPermission.deniedForever) { + await Geolocator.requestPermission(); + } + + // getLastKnownPosition → azonnal visszatér (cache) + // Nem vár új GPS fixre → nem lassítja az indulást + Position? pos = await Geolocator.getLastKnownPosition(); + + // Ha nincs cache → gyors egyszeri lekérés (max 3 mp) + pos ??= await Geolocator.getCurrentPosition( + locationSettings: const LocationSettings( + accuracy: LocationAccuracy.low, // gyors, kevésbé pontos + timeLimit: Duration(seconds: 3), + ), + ).timeout( + const Duration(seconds: 3), + onTimeout: () => throw Exception('GPS timeout'), + ); + + currentLatitude.value = pos.latitude; + currentLongitude.value = pos.longitude; + + // Térkép mozgatása — csak ha már inicializálva van a widget + // mapIsInitialized előtt hívjuk, de a controller már kész + // A move() biztonságos ha a mapController már csatolt + mapController.move( + LatLng(pos.latitude, pos.longitude), + currentZoom.value, + ); + } catch (e) { + // Hiba esetén marad a default pozíció — nem kritikus + debugPrint('Kezdő pozíció lekérés sikertelen: $e'); + } + } + // ───────────────────────────────────────────────────────────────── // GnssService frissítés kezelése // ───────────────────────────────────────────────────────────────── @@ -395,19 +438,38 @@ class MapSurveyController extends GetxController { // ───────────────────────────────────────────────────────────────── void mapZoomIn() { - if (currentZoom.value >= maxZoomValue) return; - currentZoom.value++; + final newZoom = (mapController.camera.zoom + 1).clamp(0.0, maxZoomValue); + // if (currentZoom.value >= maxZoomValue) return; + // currentZoom.value++; + currentZoom.value = newZoom; + _isMapProgrammaticMove = true; _moveMap(); } void mapZoomOut() { - if (currentZoom.value <= 0) return; - currentZoom.value--; + final newZoom = (mapController.camera.zoom - 1).clamp(0.0, maxZoomValue); + // if (currentZoom.value <= 0) return; + // currentZoom.value--; + currentZoom.value = newZoom; + _isMapProgrammaticMove = true; _moveMap(); } - void setIsMapMoveToCenter() => - isMapMoveToCenter.value = !isMapMoveToCenter.value; + void setIsMapMoveToCenter() { + isMapMoveToCenter.value = !isMapMoveToCenter.value; + + // Bekapcsoláskor azonnal ugrik az aktuális pozícióra + if (isMapMoveToCenter.value && + currentLatitude.value != 0.0 && + currentLongitude.value != 0.0) { + _isMapProgrammaticMove = true; + mapController.move( + LatLng(currentLatitude.value, currentLongitude.value), + currentZoom.value, + ); + // Ez MapEventSource.mapController → NEM kapcsolja ki a követést ✓ + } + } void _moveMap() { final lat = isMapMoveToCenter.value @@ -419,25 +481,64 @@ class MapSurveyController extends GetxController { mapController.move(LatLng(lat, lon), currentZoom.value); } + void onMapPositionChanged(MapCamera camera, bool hasGesture) { + if (hasGesture) { + currentZoom.value = camera.zoom; + } + if (_isMapProgrammaticMove) { + _isMapProgrammaticMove = false; + return; + } + + if (hasGesture && isMapMoveToCenter.value) { + isMapMoveToCenter.value = false; + } + // if (isMapMoveToCenter.value) { + // isMapMoveToCenter.value = false; + // } + } + void _updateCurrentLocationMarker() { + // Koordináta validáció — 0,0 = nincs fix + final lat = currentLatitude.value; + final lon = currentLongitude.value; + if (lat == 0.0 && lon == 0.0) { + currentLocationMarker.clear(); + return; + } + + final color = _gnss.hasValidData + ? getCurrentLocationMarkerColor(_gnss.gpsQuality.value) + : Colors.blue; // telefon GPS: kék + currentLocationMarker.assignAll([ Marker( - point: LatLng(currentLatitude.value, currentLongitude.value), - width: 15.0, - height: 15.0, - child: Container( - width: 15.0, - height: 15.0, - decoration: BoxDecoration( - color: getCurrentLocationMarkerColor(_gnss.gpsQuality.value), - shape: BoxShape.circle, - border: Border.all(width: 1.5, color: Colors.white), - ), - ), - ) + point: LatLng(lat, lon), + width: 16, + height: 16, + child: PulsingDot(color: color), // ← shared_map_widgets.dart-ból + ), ]); + // currentLocationMarker.assignAll([ + // Marker( + // point: LatLng(currentLatitude.value, currentLongitude.value), + // width: 15.0, + // height: 15.0, + // child: Container( + // width: 15.0, + // height: 15.0, + // decoration: BoxDecoration( + // color: getCurrentLocationMarkerColor(_gnss.gpsQuality.value), + // shape: BoxShape.circle, + // border: Border.all(width: 1.5, color: Colors.white), + // ), + // ), + // ) + // ]); + if (isMapMoveToCenter.value) { + _isMapProgrammaticMove = true; mapController.move( LatLng(currentLatitude.value, currentLongitude.value), currentZoom.value, @@ -1150,6 +1251,7 @@ class MapSurveyController extends GetxController { await updateNoteItem(updated); _editingNoteItemId = null; + activeEditTool.value = MapEditTool.none; } Future deleteEditingItem() async { diff --git a/lib/pages/map_survey/presentations/views/map_survey_view.dart b/lib/pages/map_survey/presentations/views/map_survey_view.dart index cb8c587..62fc2d1 100644 --- a/lib/pages/map_survey/presentations/views/map_survey_view.dart +++ b/lib/pages/map_survey/presentations/views/map_survey_view.dart @@ -9,6 +9,8 @@ import 'package:terepi_seged/enums/map_survey_mode.dart'; import 'package:terepi_seged/pages/map_survey/presentations/controllers/map_survey_controller.dart'; import 'package:terepi_seged/pages/map_survey/presentations/views/settings_dialog.dart'; import 'package:terepi_seged/pages/tracking/presentation/controllers/tracking_controller.dart'; +import 'package:terepi_seged/services/gnss/gnss_device_service.dart'; +import 'package:terepi_seged/services/gnss/gnss_service.dart'; import 'package:terepi_seged/utils/rive_utils.dart'; import 'package:terepi_seged/widgets/coordinate_panel.dart'; import 'package:terepi_seged/widgets/map_bottom_panel.dart'; @@ -27,11 +29,24 @@ class MapSurveyView extends GetView { Widget build(BuildContext context) { return Stack(children: [ SharedMapWidget( + controls: const MapControls(), mapController: controller.mapController, + isFollowing: controller.isMapMoveToCenter, + initialCenter: LatLng( + // ← nem fix érték + controller.currentLatitude.value != 0.0 + ? controller.currentLatitude.value + : 47.5, + controller.currentLongitude.value != 0.0 + ? controller.currentLongitude.value + : 19.0, + ), + initialZoom: controller.currentZoom.value, currentZoom: controller.currentZoom, onZoomIn: controller.mapZoomIn, onZoomOut: controller.mapZoomOut, - onCenterOnGps: controller.isMapMoveToCenter, + onPositionChanged: controller.onMapPositionChanged, + onCenterOnGps: controller.setIsMapMoveToCenter, onLongPress: (tapPosition, point) { if (controller.activeEditTool.value == MapEditTool.point) { controller.saveEditedPoint(point: point); @@ -59,8 +74,15 @@ class MapSurveyView extends GetView { controller.clearNoteItemSelection(); }, layers: [ - Obx(() => - MarkerLayer(markers: controller.currentLocationMarker.toList())), + Obx(() { + final isGpsActive = GnssService.to.activeConnectionType.value != + GnssConnectionType.none; + if (isGpsActive) { + return MarkerLayer( + markers: controller.currentLocationMarker.toList()); + } + return const SizedBox.shrink(); + }), // Track polyline Obx(() {