FarisaRahmaSari_E31222327/BBS/lib/models/location_config.dart

95 lines
3.6 KiB
Dart

import 'package:shared_preferences/shared_preferences.dart';
import 'package:qyuota/config/api_config.dart';
import 'dart:math' show asin, cos, pow, sin, sqrt;
class LocationConfig {
// Singleton pattern
static final LocationConfig _instance = LocationConfig._internal();
factory LocationConfig() => _instance;
LocationConfig._internal();
// Mendapatkan latitude kantor dari SharedPreferences atau default
Future<double> getOfficeLatitude() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getDouble(ApiConfig.officeLatitudeKey) ?? ApiConfig.defaultOfficeLatitude;
}
// Mendapatkan longitude kantor dari SharedPreferences atau default
Future<double> getOfficeLongitude() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getDouble(ApiConfig.officeLongitudeKey) ?? ApiConfig.defaultOfficeLongitude;
}
// Mendapatkan radius presensi dari SharedPreferences atau default
Future<double> getRadiusInMeters() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getDouble(ApiConfig.radiusInMetersKey) ?? ApiConfig.defaultRadiusInMeters;
}
// Menyimpan konfigurasi lokasi kantor baru
Future<bool> saveOfficeLocation(double latitude, double longitude) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setDouble(ApiConfig.officeLatitudeKey, latitude);
return await prefs.setDouble(ApiConfig.officeLongitudeKey, longitude);
}
// Menyimpan radius presensi baru
Future<bool> saveRadius(double radius) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
return await prefs.setDouble(ApiConfig.radiusInMetersKey, radius);
}
// Menghitung jarak antara dua koordinat (Haversine formula)
double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
const double earthRadius = 6371000; // Radius bumi dalam meter
const double tolerance = 50.0; // Toleransi 50 meter untuk akurasi GPS
// Konversi derajat ke radian
final double dLat = _toRadians(lat2 - lat1);
final double dLon = _toRadians(lon2 - lon1);
// Rumus haversine
final double a = pow(sin(dLat / 2), 2) +
cos(_toRadians(lat1)) *
cos(_toRadians(lat2)) *
pow(sin(dLon / 2), 2);
final double c = 2 * asin(sqrt(a));
// Jarak dalam meter dengan toleransi
double distance = (earthRadius * c) - tolerance;
print('\n=== DETAIL PERHITUNGAN JARAK ===');
print('Koordinat 1: ($lat1, $lon1)');
print('Koordinat 2: ($lat2, $lon2)');
print('dLat (radian): ${dLat.toStringAsFixed(6)}');
print('dLon (radian): ${dLon.toStringAsFixed(6)}');
print('a: ${a.toStringAsFixed(6)}');
print('c: ${c.toStringAsFixed(6)}');
print('Jarak akhir: ${distance.toStringAsFixed(2)} meter');
print('Toleransi: ${tolerance.toStringAsFixed(2)} meter');
return distance > 0 ? distance : 0; // Pastikan jarak tidak negatif
}
// Konversi derajat ke radian
double _toRadians(double degree) {
return degree * (3.141592653589793 / 180);
}
// Memeriksa apakah lokasi berada dalam radius yang ditentukan
Future<bool> isLocationInRadius(double latitude, double longitude) async {
double officeLatitude = await getOfficeLatitude();
double officeLongitude = await getOfficeLongitude();
double radiusInMeters = await getRadiusInMeters();
double distance = calculateDistance(
latitude,
longitude,
officeLatitude,
officeLongitude
);
return distance <= radiusInMeters;
}
}