correcao de erros no codigo do mapa
This commit is contained in:
@@ -19,6 +19,9 @@ class _GoogleMapScreenState extends State<GoogleMapScreen> {
|
|||||||
StreamSubscription<Position>? _positionStreamSubscription;
|
StreamSubscription<Position>? _positionStreamSubscription;
|
||||||
Timer? _simulationTimer;
|
Timer? _simulationTimer;
|
||||||
|
|
||||||
|
// Controle de frequência de atualização para evitar sobrecarga e crashes
|
||||||
|
DateTime? _lastUpdate;
|
||||||
|
|
||||||
final List<LatLng> _routePoints = [];
|
final List<LatLng> _routePoints = [];
|
||||||
final Set<Polyline> _polylines = {};
|
final Set<Polyline> _polylines = {};
|
||||||
final Set<Marker> _markers = {};
|
final Set<Marker> _markers = {};
|
||||||
@@ -44,6 +47,7 @@ class _GoogleMapScreenState extends State<GoogleMapScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _setupIconsAndTracking() async {
|
Future<void> _setupIconsAndTracking() async {
|
||||||
|
// Marcadores premium: tamanho ideal para visibilidade e estética
|
||||||
_startIcon = await _createPremiumMarker(Colors.greenAccent, Icons.play_arrow_rounded, 85);
|
_startIcon = await _createPremiumMarker(Colors.greenAccent, Icons.play_arrow_rounded, 85);
|
||||||
_finishIcon = await _createPremiumMarker(AppColors.coral, Icons.flag_rounded, 85);
|
_finishIcon = await _createPremiumMarker(AppColors.coral, Icons.flag_rounded, 85);
|
||||||
_arrowIcon = await _createArrowMarker(Colors.black, Colors.white, 95);
|
_arrowIcon = await _createArrowMarker(Colors.black, Colors.white, 95);
|
||||||
@@ -87,6 +91,7 @@ class _GoogleMapScreenState extends State<GoogleMapScreen> {
|
|||||||
void dispose() {
|
void dispose() {
|
||||||
_positionStreamSubscription?.cancel();
|
_positionStreamSubscription?.cancel();
|
||||||
_simulationTimer?.cancel();
|
_simulationTimer?.cancel();
|
||||||
|
_mapController?.dispose();
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,45 +103,48 @@ class _GoogleMapScreenState extends State<GoogleMapScreen> {
|
|||||||
permission = await Geolocator.requestPermission();
|
permission = await Geolocator.requestPermission();
|
||||||
if (permission == LocationPermission.denied) return;
|
if (permission == LocationPermission.denied) return;
|
||||||
}
|
}
|
||||||
Position position = await Geolocator.getCurrentPosition();
|
Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.bestForNavigation);
|
||||||
_currentPosition = LatLng(position.latitude, position.longitude);
|
_currentPosition = LatLng(position.latitude, position.longitude);
|
||||||
setState(() => _isLoading = false);
|
setState(() => _isLoading = false);
|
||||||
_startLocationStream();
|
_startLocationStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _startLocationStream() {
|
void _startLocationStream() {
|
||||||
_positionStreamSubscription = Geolocator.getPositionStream(locationSettings: const LocationSettings(accuracy: LocationAccuracy.high, distanceFilter: 5)).listen((Position position) {
|
_positionStreamSubscription = Geolocator.getPositionStream(
|
||||||
if (!_isSimulating) _updatePosition(LatLng(position.latitude, position.longitude), position.speed);
|
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) {
|
void _updatePosition(LatLng newPoint, double speed) {
|
||||||
|
if (!mounted) return;
|
||||||
setState(() {
|
setState(() {
|
||||||
if (_routePoints.isNotEmpty) {
|
if (_routePoints.isNotEmpty) {
|
||||||
_totalDistance += Geolocator.distanceBetween(_currentPosition.latitude, _currentPosition.longitude, newPoint.latitude, newPoint.longitude);
|
_totalDistance += Geolocator.distanceBetween(_currentPosition.latitude, _currentPosition.longitude, newPoint.latitude, newPoint.longitude);
|
||||||
}
|
}
|
||||||
_currentSpeed = speed;
|
_currentSpeed = speed >= 0 ? speed : 0;
|
||||||
_routePoints.add(newPoint);
|
_routePoints.add(newPoint);
|
||||||
_currentPosition = newPoint;
|
_currentPosition = newPoint;
|
||||||
|
_updateMarkers(); // Agora só atualiza a seta seguidora
|
||||||
// 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,
|
|
||||||
));
|
|
||||||
|
|
||||||
if (_routePoints.length > 1) {
|
if (_routePoints.length > 1) {
|
||||||
_polylines.removeWhere((p) => p.polylineId.value == 'route' || p.polylineId.value == 'route_glow');
|
_polylines.removeWhere((p) => p.polylineId.value == 'route' || p.polylineId.value == 'route_glow');
|
||||||
_polylines.add(Polyline(
|
_polylines.add(Polyline(
|
||||||
polylineId: const PolylineId('route_glow'),
|
polylineId: const PolylineId('route_glow'),
|
||||||
points: List.from(_routePoints),
|
points: List.from(_routePoints),
|
||||||
color: Colors.lightBlueAccent.withOpacity(0.3),
|
color: Colors.cyanAccent.withOpacity(0.3),
|
||||||
width: 14,
|
width: 14,
|
||||||
zIndex: 9,
|
zIndex: 9,
|
||||||
));
|
));
|
||||||
@@ -151,7 +159,25 @@ class _GoogleMapScreenState extends State<GoogleMapScreen> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
_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<LatLng> points) {
|
double _calculateRotation(List<LatLng> points) {
|
||||||
@@ -192,40 +218,28 @@ class _GoogleMapScreenState extends State<GoogleMapScreen> {
|
|||||||
_routePoints.clear();
|
_routePoints.clear();
|
||||||
_polylines.removeWhere((p) => p.polylineId.value == 'route' || p.polylineId.value == 'route_glow');
|
_polylines.removeWhere((p) => p.polylineId.value == 'route' || p.polylineId.value == 'route_glow');
|
||||||
_totalDistance = 0.0;
|
_totalDistance = 0.0;
|
||||||
|
|
||||||
// Start from planned start OR current real location
|
|
||||||
_currentPosition = _plannedStart ?? _currentPosition;
|
_currentPosition = _plannedStart ?? _currentPosition;
|
||||||
|
|
||||||
// Initialize routePoints with the start so the arrow appears immediately at the start point
|
|
||||||
_routePoints.add(_currentPosition);
|
_routePoints.add(_currentPosition);
|
||||||
|
_updateMarkers(); // Reposiciona a seta no início
|
||||||
// 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,
|
|
||||||
));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
_simulationTimer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
_simulationTimer = Timer.periodic(const Duration(milliseconds: 100), (timer) {
|
||||||
double latStep = 0.00025;
|
double latStep = 0.000025;
|
||||||
double lngStep = 0.00025;
|
double lngStep = 0.000025;
|
||||||
|
|
||||||
if (_plannedEnd != null) {
|
if (_plannedEnd != null) {
|
||||||
double dist = Geolocator.distanceBetween(_currentPosition.latitude, _currentPosition.longitude, _plannedEnd!.latitude, _plannedEnd!.longitude);
|
double dist = Geolocator.distanceBetween(_currentPosition.latitude, _currentPosition.longitude, _plannedEnd!.latitude, _plannedEnd!.longitude);
|
||||||
if (dist < 12) {
|
if (dist < 2) {
|
||||||
_updatePosition(_plannedEnd!, 0.0);
|
_updatePosition(_plannedEnd!, 0.0);
|
||||||
_toggleSimulation();
|
_toggleSimulation();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
latStep = (_plannedEnd!.latitude - _currentPosition.latitude) / (max(dist / 8, 1));
|
latStep = (_plannedEnd!.latitude - _currentPosition.latitude) / (max(dist / 0.8, 1));
|
||||||
lngStep = (_plannedEnd!.longitude - _currentPosition.longitude) / (max(dist / 8, 1));
|
lngStep = (_plannedEnd!.longitude - _currentPosition.longitude) / (max(dist / 0.8, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
LatLng nextPoint = LatLng(_currentPosition.latitude + latStep, _currentPosition.longitude + lngStep);
|
LatLng nextPoint = LatLng(_currentPosition.latitude + latStep, _currentPosition.longitude + lngStep);
|
||||||
_updatePosition(nextPoint, 3.5 + Random().nextDouble());
|
_updatePosition(nextPoint, 3.5 + Random().nextDouble() * 0.5);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user