Improve GPS performance and heading display

- Reduce GPS distanceFilter to 0 for faster updates
- Add timeLimit to ensure regular position updates
- Implement cached heading to avoid showing N/A when GPS heading unavailable
- Add speed display logic: show "--" when stationary with no heading data
- Add rotating navigation icon that points in heading direction
- Fix degree symbol in heading format display

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Mikkeli Matlock
2025-08-25 07:26:20 +09:00
parent 56327c00ec
commit 89ce53bb1b
2 changed files with 32 additions and 10 deletions
+16 -5
View File
@@ -3,11 +3,14 @@ import 'package:geolocator/geolocator.dart';
import 'package:permission_handler/permission_handler.dart';
class GpsService {
static double? _lastValidHeading;
static Stream<Position> get positionStream {
return Geolocator.getPositionStream(
locationSettings: const LocationSettings(
accuracy: LocationAccuracy.bestForNavigation,
distanceFilter: 1,
distanceFilter: 0,
timeLimit: Duration(seconds: 10),
),
);
}
@@ -21,16 +24,24 @@ class GpsService {
return await Geolocator.isLocationServiceEnabled();
}
static double getCachedHeading(double heading) {
if (heading >= 0 && heading <= 360) {
_lastValidHeading = heading;
return heading;
}
return _lastValidHeading ?? 0.0;
}
static String getCompassDirection(double heading) {
if (heading < 0) return 'N/A';
final cachedHeading = getCachedHeading(heading);
const directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW'];
final index = ((heading + 22.5) / 45).floor() % 8;
final index = ((cachedHeading + 22.5) / 45).floor() % 8;
return directions[index];
}
static String formatHeading(double heading) {
if (heading < 0) return 'N/A';
return '${heading.round()} ${getCompassDirection(heading)}';
final cachedHeading = getCachedHeading(heading);
return '${cachedHeading.round()}° ${getCompassDirection(heading)}';
}
}
+12 -1
View File
@@ -5,6 +5,7 @@ import 'package:wakelock_plus/wakelock_plus.dart';
import 'speed_units.dart';
import 'gps_service.dart';
import 'color_themes.dart';
import 'dart:math' as math; // Import for math.pi
void main() {
runApp(const SpeedoApp());
@@ -118,10 +119,17 @@ class _SpeedometerScreenState extends State<SpeedometerScreen> {
});
}
String _getSpeedDisplayText(double displaySpeed) {
if (_speed == 0.0 && _heading == -1.0) {
return '--';
}
return displaySpeed.toStringAsFixed(0);
}
@override
Widget build(BuildContext context) {
final displaySpeed = _currentUnit.convert(_speed);
final speedText = displaySpeed.toStringAsFixed(0);
final speedText = _getSpeedDisplayText(displaySpeed);
final currentTheme = ColorThemes.getTheme(_currentThemeIndex);
return Scaffold(
@@ -222,12 +230,15 @@ class _SpeedometerScreenState extends State<SpeedometerScreen> {
children: [
Flexible(
flex: 2,
child: Transform.rotate(
angle: (_heading >= 0 && _heading < 360) ? (_heading * math.pi / 180.0) : 0,
child: Icon(
Icons.navigation,
size: 100,
color: currentTheme.headingText,
),
),
),
Flexible(
flex: 1,
child: FittedBox(