feat: 초기 프로젝트 설정 및 LunchPick 앱 구현
LunchPick(오늘 뭐 먹Z?) Flutter 앱의 초기 구현입니다. 주요 기능: - 네이버 지도 연동 맛집 추가 - 랜덤 메뉴 추천 시스템 - 날씨 기반 거리 조정 - 방문 기록 관리 - Bluetooth 맛집 공유 - 다크모드 지원 기술 스택: - Flutter 3.8.1+ - Riverpod 상태 관리 - Hive 로컬 DB - Clean Architecture 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
110
lib/core/utils/distance_calculator.dart
Normal file
110
lib/core/utils/distance_calculator.dart
Normal file
@@ -0,0 +1,110 @@
|
||||
import 'dart:math' as math;
|
||||
|
||||
class DistanceCalculator {
|
||||
static const double earthRadiusKm = 6371.0;
|
||||
|
||||
static double calculateDistance({
|
||||
required double lat1,
|
||||
required double lon1,
|
||||
required double lat2,
|
||||
required double lon2,
|
||||
}) {
|
||||
final double dLat = _toRadians(lat2 - lat1);
|
||||
final double dLon = _toRadians(lon2 - lon1);
|
||||
|
||||
final double a = math.sin(dLat / 2) * math.sin(dLat / 2) +
|
||||
math.cos(_toRadians(lat1)) *
|
||||
math.cos(_toRadians(lat2)) *
|
||||
math.sin(dLon / 2) *
|
||||
math.sin(dLon / 2);
|
||||
|
||||
final double c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a));
|
||||
|
||||
return earthRadiusKm * c;
|
||||
}
|
||||
|
||||
static double _toRadians(double degree) {
|
||||
return degree * (math.pi / 180);
|
||||
}
|
||||
|
||||
static String formatDistance(double distanceInKm) {
|
||||
if (distanceInKm < 1) {
|
||||
return '${(distanceInKm * 1000).round()}m';
|
||||
} else if (distanceInKm < 10) {
|
||||
return '${distanceInKm.toStringAsFixed(1)}km';
|
||||
} else {
|
||||
return '${distanceInKm.round()}km';
|
||||
}
|
||||
}
|
||||
|
||||
static bool isWithinDistance({
|
||||
required double lat1,
|
||||
required double lon1,
|
||||
required double lat2,
|
||||
required double lon2,
|
||||
required double maxDistanceKm,
|
||||
}) {
|
||||
final distance = calculateDistance(
|
||||
lat1: lat1,
|
||||
lon1: lon1,
|
||||
lat2: lat2,
|
||||
lon2: lon2,
|
||||
);
|
||||
return distance <= maxDistanceKm;
|
||||
}
|
||||
|
||||
static double? calculateDistanceFromCurrentLocation({
|
||||
required double targetLat,
|
||||
required double targetLon,
|
||||
double? currentLat,
|
||||
double? currentLon,
|
||||
}) {
|
||||
if (currentLat == null || currentLon == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return calculateDistance(
|
||||
lat1: currentLat,
|
||||
lon1: currentLon,
|
||||
lat2: targetLat,
|
||||
lon2: targetLon,
|
||||
);
|
||||
}
|
||||
|
||||
static List<T> sortByDistance<T>({
|
||||
required List<T> items,
|
||||
required double Function(T) getLat,
|
||||
required double Function(T) getLon,
|
||||
required double currentLat,
|
||||
required double currentLon,
|
||||
}) {
|
||||
final List<T> sortedItems = List<T>.from(items);
|
||||
|
||||
sortedItems.sort((a, b) {
|
||||
final distanceA = calculateDistance(
|
||||
lat1: currentLat,
|
||||
lon1: currentLon,
|
||||
lat2: getLat(a),
|
||||
lon2: getLon(a),
|
||||
);
|
||||
|
||||
final distanceB = calculateDistance(
|
||||
lat1: currentLat,
|
||||
lon1: currentLon,
|
||||
lat2: getLat(b),
|
||||
lon2: getLon(b),
|
||||
);
|
||||
|
||||
return distanceA.compareTo(distanceB);
|
||||
});
|
||||
|
||||
return sortedItems;
|
||||
}
|
||||
|
||||
static Map<String, double> getDefaultLocationForKorea() {
|
||||
return {
|
||||
'latitude': 37.5665,
|
||||
'longitude': 126.9780,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user