import 'dart:math'; import '../models/user_profile.dart'; /// Approximate determination of age int calcAge(int? birthYear) { if (birthYear != null) { return (DateTime.now().year - birthYear); } return 0; } /// /// Convert decimal coordinate to degrees minutes seconds (DMS). /// String convertDecimalToDMS(double decimalValue, {required bool isLatitude}) { bool isNegative = decimalValue < 0; double absoluteValue = decimalValue.abs(); int degrees = absoluteValue.toInt(); double minutesDecimal = (absoluteValue - degrees) * 60; int minutes = minutesDecimal.toInt(); double secondsDecimal = (minutesDecimal - minutes) * 60; double seconds = double.parse(secondsDecimal.toStringAsFixed(2)); String direction; if (isLatitude) { direction = isNegative ? 'S' : 'N'; } else { direction = isNegative ? 'W' : 'E'; } // return formatted string return '${degrees.abs()}° ${minutes.abs()}\' ${seconds.abs().toStringAsFixed(2)}" $direction'; } /// /// Distance in kilometers between two location coordinates /// double calculateDistance(double lat1, double lon1, double lat2, double lon2) { const R = 6371; // earth radius in kilometers // distance between latitudes and longitudes final dLat = _degreesToRadians(lat2 - lat1); final dLon = _degreesToRadians(lon2 - lon1); final a = sin(dLat / 2) * sin(dLat / 2) + cos(_degreesToRadians(lat1)) * cos(_degreesToRadians(lat2)) * sin(dLon / 2) * sin(dLon / 2); final c = 2 * atan2(sqrt(a), sqrt(1 - a)); return R * c; } double _degreesToRadians(double degrees) { return degrees * pi / 180; } /// /// Shortest distance between two users locations /// double shortestDistanceBetweenUsers( UserProfile currentUser, UserProfile otherUser) { try { if (currentUser.locations.isEmpty || otherUser.locations.isEmpty) { return double.nan; } double shortestDistance = double.nan; // locations currentUser for (var loc1 in currentUser.locations.values) { if (loc1 != null && loc1.latitude != null && loc1.longitude != null) { for (var loc2 in otherUser.locations.values) { if (loc2 != null && loc2.latitude != null && loc2.longitude != null) { double distance = calculateDistance(loc1.latitude!, loc1.longitude!, loc2.latitude!, loc2.longitude!); if (shortestDistance.isNaN || distance < shortestDistance) { shortestDistance = distance; } } } } } return shortestDistance; } catch (e) { return double.nan; } }