fix: render isolated route acceleration and braking events

This commit is contained in:
github-actions[bot] 2026-09-01 14:49:44 +00:00
parent 2f1b9ad024
commit df83274bed
1 changed files with 42 additions and 11 deletions

View File

@ -309,32 +309,63 @@ class _MapScreenState extends ConsumerState<MapScreen> {
required String idPrefix,
required Color color,
}) {
if (samples.isEmpty) return [];
// A threshold crossing is often only one telemetry sample wide. Requiring
// two consecutive qualifying samples made isolated acceleration/braking
// events disappear from the map. Build event runs, then include one GPS
// sample on each side so every event renders as a visible route segment.
final polylines = <AppPolyline>[];
List<AppLatLng> segment = [];
final eventIndices = <int>[];
for (var i = 0; i < samples.length; i++) {
final g = samples[i].longitudinalG ?? samples[i].accelX;
if (g != null && g.isFinite && predicate(g)) {
eventIndices.add(i);
}
}
if (eventIndices.isEmpty) return polylines;
var runStart = eventIndices.first;
var runEnd = eventIndices.first;
var segmentIndex = 0;
void flush() {
if (segment.length >= 2) {
void emitRun(int start, int end) {
final expandedStart = start > 0 ? start - 1 : start;
final expandedEnd = end < samples.length - 1 ? end + 1 : end;
final points = <AppLatLng>[];
for (var i = expandedStart; i <= expandedEnd; i++) {
final sample = samples[i];
points.add(AppLatLng(sample.latitude!, sample.longitude!));
}
// The surrounding point guarantees two points for an isolated event
// while preserving a single continuous segment for adjacent events.
if (points.length >= 2) {
polylines.add(AppPolyline(
id: '${idPrefix}_$segmentIndex',
points: List<AppLatLng>.from(segment),
points: points,
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!));
for (var i = 1; i < eventIndices.length; i++) {
final index = eventIndices[i];
// Keep nearby threshold samples in one event run. A gap of more than
// two samples starts a new visual event while allowing brief sensor
// dropouts inside a hard maneuver.
if (index - runEnd <= 2) {
runEnd = index;
} else {
flush();
emitRun(runStart, runEnd);
runStart = runEnd = index;
}
}
flush();
emitRun(runStart, runEnd);
return polylines;
}