Fix route preview acceleration and braking layers

This commit is contained in:
bponders12-cell 2026-09-01 06:24:22 -04:00
parent 5be8a29a4c
commit 63a187e767
1 changed files with 87 additions and 26 deletions

View File

@ -33,8 +33,6 @@ class _MapScreenState extends ConsumerState<MapScreen> {
bool _showHardBraking = true;
bool _showCornering = true;
// These are intentionally derived from the already-persisted telemetry.
// They do not alter the frozen telemetry acquisition/fusion pipeline.
static const double _hardAccelThresholdG = 0.35;
static const double _hardBrakingThresholdG = -0.35;
static const Duration _eventMergeWindow = Duration(milliseconds: 1500);
@ -133,8 +131,6 @@ class _MapScreenState extends ConsumerState<MapScreen> {
return markers;
}
// Build map events directly from persisted longitudinal G when RideEvents are
// absent/incomplete. Existing RideEvents remain untouched and are still shown.
List<AppMapMarker> _buildTelemetryEventMarkers(List<TelemetrySample> samples) {
final gps = samples.where((s) =>
s.latitude != null && s.longitude != null &&
@ -248,32 +244,97 @@ class _MapScreenState extends ConsumerState<MapScreen> {
);
List<AppPolyline> _buildPolylines() {
if (_routePoints.isEmpty || !_showRoute) return [];
if (!_showSpeedHeatmap) {
return [AppPolyline(id: 'history_route', points: _routePoints, color: const Color(0xFF00E5FF), width: 4.5)];
}
if (_routePoints.isEmpty) return [];
final polylines = <AppPolyline>[];
final validSamples = _telemetrySamples.where((t) => t.latitude != null && t.longitude != null).toList();
if (validSamples.isEmpty) return [];
final step = (validSamples.length / 1500).ceil().clamp(1, 10);
List<AppLatLng> currentSegment = [];
Color currentColor = _getSpeedColor(validSamples.first.speed ?? 0.0);
for (int i = 0; i < validSamples.length; i += step) {
final s = validSamples[i];
final pt = AppLatLng(s.latitude!, s.longitude!);
final segColor = _getSpeedColor(s.speed ?? 0.0);
if (segColor != currentColor && currentSegment.isNotEmpty) {
currentSegment.add(pt);
polylines.add(AppPolyline(id: 'speed_seg_${polylines.length}', points: List.from(currentSegment), color: currentColor, width: 5.0));
currentSegment = [pt];
currentColor = segColor;
} else {
currentSegment.add(pt);
if (_showRoute) {
polylines.add(AppPolyline(
id: 'history_route',
points: _routePoints,
color: const Color(0xFF00E5FF),
width: 4.5,
));
}
final validSamples = _telemetrySamples
.where((t) => t.latitude != null && t.longitude != null)
.toList();
if (validSamples.isEmpty) return polylines;
if (_showSpeedHeatmap) {
final step = (validSamples.length / 1500).ceil().clamp(1, 10);
List<AppLatLng> currentSegment = [];
Color currentColor = _getSpeedColor(validSamples.first.speed ?? 0.0);
for (int i = 0; i < validSamples.length; i += step) {
final s = validSamples[i];
final pt = AppLatLng(s.latitude!, s.longitude!);
final segColor = _getSpeedColor(s.speed ?? 0.0);
if (segColor != currentColor && currentSegment.isNotEmpty) {
currentSegment.add(pt);
polylines.add(AppPolyline(id: 'speed_seg_${polylines.length}', points: List.from(currentSegment), color: currentColor, width: 5.0));
currentSegment = [pt];
currentColor = segColor;
} else {
currentSegment.add(pt);
}
}
if (currentSegment.length > 1) {
polylines.add(AppPolyline(id: 'speed_seg_${polylines.length}', points: currentSegment, color: currentColor, width: 5.0));
}
}
if (currentSegment.length > 1) {
polylines.add(AppPolyline(id: 'speed_seg_${polylines.length}', points: currentSegment, color: currentColor, width: 5.0));
if (_showHardAccel) {
polylines.addAll(_buildLongitudinalEventPolylines(
validSamples,
predicate: (g) => g >= _hardAccelThresholdG,
idPrefix: 'accel_layer',
color: const Color(0xFF76FF03),
));
}
if (_showHardBraking) {
polylines.addAll(_buildLongitudinalEventPolylines(
validSamples,
predicate: (g) => g <= _hardBrakingThresholdG,
idPrefix: 'braking_layer',
color: const Color(0xFFFF5252),
));
}
return polylines;
}
List<AppPolyline> _buildLongitudinalEventPolylines(
List<TelemetrySample> samples, {
required bool Function(double g) predicate,
required String idPrefix,
required Color color,
}) {
final polylines = <AppPolyline>[];
List<AppLatLng> segment = [];
var segmentIndex = 0;
void flush() {
if (segment.length >= 2) {
polylines.add(AppPolyline(
id: '${idPrefix}_$segmentIndex',
points: List<AppLatLng>.from(segment),
color: color,
width: 7.0,
));
segmentIndex++;
}
segment = [];
}
for (final sample in samples) {
final g = sample.longitudinalG ?? sample.accelX;
if (g != null && g.isFinite && predicate(g)) {
segment.add(AppLatLng(sample.latitude!, sample.longitude!));
} else {
flush();
}
}
flush();
return polylines;
}