68 lines
2.3 KiB
Dart
68 lines
2.3 KiB
Dart
import 'dart:math' as math;
|
|
import 'package:latlong2/latlong.dart';
|
|
|
|
class NavigationHelper {
|
|
static const Distance _distanceCalculator = Distance();
|
|
|
|
/// Menghitung jarak antara dua titik dalam meter
|
|
static double calculateDistance(LatLng p1, LatLng p2) {
|
|
return _distanceCalculator.as(LengthUnit.Meter, p1, p2);
|
|
}
|
|
|
|
/// Menghitung bearing (sudut) antara dua titik (0-360 derajat)
|
|
static double calculateBearing(LatLng p1, LatLng p2) {
|
|
double lat1 = p1.latitude * math.pi / 180;
|
|
double lon1 = p1.longitude * math.pi / 180;
|
|
double lat2 = p2.latitude * math.pi / 180;
|
|
double lon2 = p2.longitude * math.pi / 180;
|
|
|
|
double dLon = lon2 - lon1;
|
|
double y = math.sin(dLon) * math.cos(lat2);
|
|
double x = math.cos(lat1) * math.sin(lat2) -
|
|
math.sin(lat1) * math.cos(lat2) * math.cos(dLon);
|
|
double radians = math.atan2(y, x);
|
|
return (radians * 180 / math.pi + 360) % 360;
|
|
}
|
|
|
|
/// Menghitung jarak terdekat dari titik ke sebuah segmen garis (Cross Track Distance)
|
|
static double getDistanceToSegment(LatLng p, LatLng s1, LatLng s2) {
|
|
final double l2 = math.pow(calculateDistance(s1, s2), 2).toDouble();
|
|
if (l2 == 0) return calculateDistance(p, s1);
|
|
|
|
// Proyeksi titik ke garis
|
|
double t = ((p.latitude - s1.latitude) * (s2.latitude - s1.latitude) +
|
|
(p.longitude - s1.longitude) * (s2.longitude - s1.longitude)) /
|
|
(math.pow(s2.latitude - s1.latitude, 2) +
|
|
math.pow(s2.longitude - s1.longitude, 2));
|
|
|
|
t = math.max(0, math.min(1, t));
|
|
|
|
LatLng projection = LatLng(
|
|
s1.latitude + t * (s2.latitude - s1.latitude),
|
|
s1.longitude + t * (s2.longitude - s1.longitude),
|
|
);
|
|
|
|
return calculateDistance(p, projection);
|
|
}
|
|
|
|
/// Menentukan apakah ada belokan tajam di titik tertentu pada rute
|
|
static String? detectManeuver(List<LatLng> points, int index) {
|
|
if (index <= 0 || index >= points.length - 1) return null;
|
|
|
|
double bearing1 = calculateBearing(points[index - 1], points[index]);
|
|
double bearing2 = calculateBearing(points[index], points[index + 1]);
|
|
|
|
double diff = (bearing2 - bearing1 + 360) % 360;
|
|
|
|
if (diff > 180) diff -= 360;
|
|
|
|
if (diff > 25 && diff < 160) {
|
|
return "Belok Kanan";
|
|
} else if (diff < -25 && diff > -160) {
|
|
return "Belok Kiri";
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|