calculateSummary static method
Calculates a summary from a list of locations.
Implementation
static LocationSummary calculateSummary(List<Location> locations) {
if (locations.isEmpty) {
return const LocationSummary.empty();
}
// Sort by timestamp
final sorted = List<Location>.from(locations)
..sort((a, b) => a.timestamp.compareTo(b.timestamp));
double totalDistance = 0;
Duration movingDuration = Duration.zero;
Duration stationaryDuration = Duration.zero;
double totalSpeed = 0;
int speedCount = 0;
double? maxSpeed;
double totalAccuracy = 0;
int accuracyCount = 0;
for (var i = 0; i < sorted.length; i++) {
final loc = sorted[i];
// Accumulate accuracy
totalAccuracy += loc.coords.accuracy;
accuracyCount++;
// Process speed
final speed = loc.coords.speed;
if (speed != null && speed > 0) {
totalSpeed += speed;
speedCount++;
if (maxSpeed == null || speed > maxSpeed) {
maxSpeed = speed;
}
}
// Calculate distance and duration to previous point
if (i > 0) {
final prevLoc = sorted[i - 1];
final distance = _haversineDistance(
prevLoc.coords.latitude,
prevLoc.coords.longitude,
loc.coords.latitude,
loc.coords.longitude,
);
totalDistance += distance;
final duration = loc.timestamp.difference(prevLoc.timestamp);
// Classify as moving or stationary
if (loc.isMoving == true || prevLoc.isMoving == true) {
movingDuration += duration;
} else {
stationaryDuration += duration;
}
}
}
// Calculate frequent locations (simple clustering)
final frequentLocations = _calculateFrequentLocations(sorted);
return LocationSummary(
totalDistanceMeters: totalDistance,
movingDuration: movingDuration,
stationaryDuration: stationaryDuration,
locationCount: locations.length,
averageSpeedMps: speedCount > 0 ? totalSpeed / speedCount : null,
maxSpeedMps: maxSpeed,
periodStart: sorted.first.timestamp,
periodEnd: sorted.last.timestamp,
frequentLocations: frequentLocations,
averageAccuracyMeters:
accuracyCount > 0 ? totalAccuracy / accuracyCount : null,
);
}