From 04d8d34a776485fb2816a7e42fc82e99bd3faa3e Mon Sep 17 00:00:00 2001 From: 240403 <240403@epvc.pt> Date: Wed, 4 Mar 2026 17:16:04 +0000 Subject: [PATCH] correcao de erros no codigo do mapa --- lib/screens/google_map_screen.dart | 104 ++++++++++++++++------------- 1 file changed, 59 insertions(+), 45 deletions(-) diff --git a/lib/screens/google_map_screen.dart b/lib/screens/google_map_screen.dart index 1082d89..506adc5 100644 --- a/lib/screens/google_map_screen.dart +++ b/lib/screens/google_map_screen.dart @@ -18,11 +18,14 @@ class _GoogleMapScreenState extends State { GoogleMapController? _mapController; StreamSubscription? _positionStreamSubscription; Timer? _simulationTimer; - + + // Controle de frequência de atualização para evitar sobrecarga e crashes + DateTime? _lastUpdate; + final List _routePoints = []; final Set _polylines = {}; final Set _markers = {}; - + LatLng? _plannedStart; LatLng? _plannedEnd; bool _isPlanningMode = false; @@ -44,6 +47,7 @@ class _GoogleMapScreenState extends State { } Future _setupIconsAndTracking() async { + // Marcadores premium: tamanho ideal para visibilidade e estética _startIcon = await _createPremiumMarker(Colors.greenAccent, Icons.play_arrow_rounded, 85); _finishIcon = await _createPremiumMarker(AppColors.coral, Icons.flag_rounded, 85); _arrowIcon = await _createArrowMarker(Colors.black, Colors.white, 95); @@ -87,6 +91,7 @@ class _GoogleMapScreenState extends State { void dispose() { _positionStreamSubscription?.cancel(); _simulationTimer?.cancel(); + _mapController?.dispose(); super.dispose(); } @@ -98,45 +103,48 @@ class _GoogleMapScreenState extends State { permission = await Geolocator.requestPermission(); if (permission == LocationPermission.denied) return; } - Position position = await Geolocator.getCurrentPosition(); + Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.bestForNavigation); _currentPosition = LatLng(position.latitude, position.longitude); setState(() => _isLoading = false); _startLocationStream(); } void _startLocationStream() { - _positionStreamSubscription = Geolocator.getPositionStream(locationSettings: const LocationSettings(accuracy: LocationAccuracy.high, distanceFilter: 5)).listen((Position position) { - if (!_isSimulating) _updatePosition(LatLng(position.latitude, position.longitude), position.speed); + _positionStreamSubscription = Geolocator.getPositionStream( + locationSettings: const LocationSettings( + accuracy: LocationAccuracy.bestForNavigation, + distanceFilter: 0 + ) + ).listen((Position position) { + if (!_isSimulating) { + final now = DateTime.now(); + if (_lastUpdate == null || now.difference(_lastUpdate!).inMilliseconds > 500) { + _lastUpdate = now; + _updatePosition(LatLng(position.latitude, position.longitude), position.speed); + } + } + }, onError: (error) { + debugPrint("Erro no GPS: $error"); }); } void _updatePosition(LatLng newPoint, double speed) { + if (!mounted) return; setState(() { if (_routePoints.isNotEmpty) { _totalDistance += Geolocator.distanceBetween(_currentPosition.latitude, _currentPosition.longitude, newPoint.latitude, newPoint.longitude); } - _currentSpeed = speed; + _currentSpeed = speed >= 0 ? speed : 0; _routePoints.add(newPoint); _currentPosition = newPoint; - - // Update only the dynamic follower arrow - _markers.removeWhere((m) => m.markerId.value == 'follower'); - _markers.add(Marker( - markerId: const MarkerId('follower'), - position: _currentPosition, - rotation: _calculateRotation(_routePoints), - flat: true, - anchor: const Offset(0.5, 0.5), - icon: _arrowIcon ?? BitmapDescriptor.defaultMarker, - zIndex: 12, - )); + _updateMarkers(); // Agora só atualiza a seta seguidora if (_routePoints.length > 1) { _polylines.removeWhere((p) => p.polylineId.value == 'route' || p.polylineId.value == 'route_glow'); _polylines.add(Polyline( polylineId: const PolylineId('route_glow'), points: List.from(_routePoints), - color: Colors.lightBlueAccent.withOpacity(0.3), + color: Colors.cyanAccent.withOpacity(0.3), width: 14, zIndex: 9, )); @@ -151,7 +159,25 @@ class _GoogleMapScreenState extends State { )); } }); - _mapController?.animateCamera(CameraUpdate.newLatLng(newPoint)); + + if (_mapController != null) { + _mapController!.animateCamera(CameraUpdate.newLatLng(newPoint)); + } + } + + void _updateMarkers() { + // Remove APENAS o marcador da seta seguidora para evitar duplicidade com o ponto de partida fixo + _markers.removeWhere((m) => m.markerId.value == 'follower'); + + _markers.add(Marker( + markerId: const MarkerId('follower'), + position: _currentPosition, + rotation: _calculateRotation(_routePoints), + flat: true, + anchor: const Offset(0.5, 0.5), + icon: _arrowIcon ?? BitmapDescriptor.defaultMarker, + zIndex: 12, + )); } double _calculateRotation(List points) { @@ -192,40 +218,28 @@ class _GoogleMapScreenState extends State { _routePoints.clear(); _polylines.removeWhere((p) => p.polylineId.value == 'route' || p.polylineId.value == 'route_glow'); _totalDistance = 0.0; - - // Start from planned start OR current real location _currentPosition = _plannedStart ?? _currentPosition; - - // Initialize routePoints with the start so the arrow appears immediately at the start point _routePoints.add(_currentPosition); - - // Update only the follower arrow. Planned markers are already in the set. - _markers.removeWhere((m) => m.markerId.value == 'follower'); - _markers.add(Marker( - markerId: const MarkerId('follower'), - position: _currentPosition, - flat: true, - anchor: const Offset(0.5, 0.5), - icon: _arrowIcon ?? BitmapDescriptor.defaultMarker, - zIndex: 12, - )); + _updateMarkers(); // Reposiciona a seta no início }); - _simulationTimer = Timer.periodic(const Duration(seconds: 1), (timer) { - double latStep = 0.00025; - double lngStep = 0.00025; + _simulationTimer = Timer.periodic(const Duration(milliseconds: 100), (timer) { + double latStep = 0.000025; + double lngStep = 0.000025; + if (_plannedEnd != null) { double dist = Geolocator.distanceBetween(_currentPosition.latitude, _currentPosition.longitude, _plannedEnd!.latitude, _plannedEnd!.longitude); - if (dist < 12) { - _updatePosition(_plannedEnd!, 0.0); - _toggleSimulation(); - return; + if (dist < 2) { + _updatePosition(_plannedEnd!, 0.0); + _toggleSimulation(); + return; } - latStep = (_plannedEnd!.latitude - _currentPosition.latitude) / (max(dist / 8, 1)); - lngStep = (_plannedEnd!.longitude - _currentPosition.longitude) / (max(dist / 8, 1)); + latStep = (_plannedEnd!.latitude - _currentPosition.latitude) / (max(dist / 0.8, 1)); + lngStep = (_plannedEnd!.longitude - _currentPosition.longitude) / (max(dist / 0.8, 1)); } + LatLng nextPoint = LatLng(_currentPosition.latitude + latStep, _currentPosition.longitude + lngStep); - _updatePosition(nextPoint, 3.5 + Random().nextDouble()); + _updatePosition(nextPoint, 3.5 + Random().nextDouble() * 0.5); }); } }