calculateSummary static method

LocationSummary calculateSummary(
  1. List<Location> locations
)

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,
  );
}