This commit is contained in:
meusinfirmary
2025-06-20 14:34:11 +08:00
parent e1c9649c3e
commit c4c1bb90fe

View File

@ -357,23 +357,86 @@ class Tracks extends Model
// Filter loncatan // Filter loncatan
$filtered = self::filterJumps($rawTracks, 1000, 5, 300); $filtered = self::filterJumps($rawTracks, 1000, 5, 300);
// return $filtered; return $filtered;
return array_reverse($filtered); // return array_reverse($filtered);
} }
public static function filterJumps($points, $maxDistance = 1000, $maxTimeGap = 5, $maxSpeed = 300) // public static function filterJumps($points, $maxDistance = 1000, $maxTimeGap = 5, $maxSpeed = 300)
// {
// $filtered = [];
// $last = null;
// foreach ($points as $p) {
// // 🛡️ 1. Validasi data koordinat
// if (!is_numeric($p->latitude) || !is_numeric($p->longitude)) {
// continue;
// }
// if (strlen((string) abs($p->latitude)) < 8 || strlen((string) abs($p->longitude)) < 8) {
// // Buang lat/lon kurang dari 8 digit desimal (umumnya noise)
// continue;
// }
// if (!$last) {
// $filtered[] = $p;
// $last = $p;
// continue;
// }
// // 2. Hitung jarak dan waktu
// $distance = self::haversineDistance(
// $last->latitude,
// $last->longitude,
// $p->latitude,
// $p->longitude
// );
// $timeGap = $p->lst_loc_crt - $last->lst_loc_crt;
// if ($timeGap <= 0) {
// continue;
// }
// $speed = ($distance / $timeGap) * 3.6; // m/s to km/h
// // 🧠 3. Validasi kombinasi logis
// if ($speed <= $maxSpeed && ($distance <= $maxDistance || $timeGap >= $maxTimeGap)) {
// $filtered[] = $p;
// $last = $p;
// } else {
// // Optional debug:
// // Log::info("LONCAT: speed={$speed}, dist={$distance}, timeGap={$timeGap}, pointID={$p->master_id}");
// }
// }
// // ⏳ Tambahkan titik terakhir jika tidak masuk
// if (!empty($points)) {
// $lastPoint = end($points);
// if (empty($filtered) || end($filtered)->lst_loc_crt !== $lastPoint->lst_loc_crt) {
// $filtered[] = $lastPoint;
// }
// }
// return $filtered;
// }
public static function filterJumps($points, $maxDistance = 2000, $maxTimeGap = 5, $maxSpeed = 150)
{ {
$filtered = []; $filtered = [];
$last = null; $last = null;
// Sort dari terbaru ke terlama (pastikan sesuai kebutuhan)
usort($points, fn($a, $b) => $b->lst_loc_crt <=> $a->lst_loc_crt);
foreach ($points as $p) { foreach ($points as $p) {
// 🛡️ 1. Validasi data koordinat // 1. Validasi koordinat
if (!is_numeric($p->latitude) || !is_numeric($p->longitude)) { if (!is_numeric($p->latitude) || !is_numeric($p->longitude)) {
continue; continue;
} }
if (strlen((string) abs($p->latitude)) < 8 || strlen((string) abs($p->longitude)) < 8) { if (
// Buang lat/lon kurang dari 8 digit desimal (umumnya noise) strlen(explode(".", $p->latitude)[1] ?? "") < 6 ||
strlen(explode(".", $p->longitude)[1] ?? "") < 6
) {
continue; continue;
} }
@ -383,14 +446,14 @@ class Tracks extends Model
continue; continue;
} }
// 2. Hitung jarak dan waktu // 2. Jarak & waktu
$distance = self::haversineDistance( $distance = self::haversineDistance(
$last->latitude, $last->latitude,
$last->longitude, $last->longitude,
$p->latitude, $p->latitude,
$p->longitude $p->longitude
); );
$timeGap = $p->lst_loc_crt - $last->lst_loc_crt; $timeGap = $last->lst_loc_crt - $p->lst_loc_crt;
if ($timeGap <= 0) { if ($timeGap <= 0) {
continue; continue;
@ -398,22 +461,16 @@ class Tracks extends Model
$speed = ($distance / $timeGap) * 3.6; // m/s to km/h $speed = ($distance / $timeGap) * 3.6; // m/s to km/h
// 🧠 3. Validasi kombinasi logis // 3. Filter logis
if ($speed <= $maxSpeed && ($distance <= $maxDistance || $timeGap >= $maxTimeGap)) { if ($speed <= $maxSpeed || $distance <= $maxDistance) {
$filtered[] = $p; $filtered[] = $p;
$last = $p; $last = $p;
} else {
// Optional debug:
// Log::info("LONCAT: speed={$speed}, dist={$distance}, timeGap={$timeGap}, pointID={$p->master_id}");
} }
} }
// ⏳ Tambahkan titik terakhir jika tidak masuk // 4. Pastikan hasil minimal N
if (!empty($points)) { if (count($filtered) < 500 && count($points) > 500) {
$lastPoint = end($points); return array_slice($points, 0, 500); // fallback ke raw jika terlalu sedikit
if (empty($filtered) || end($filtered)->lst_loc_crt !== $lastPoint->lst_loc_crt) {
$filtered[] = $lastPoint;
}
} }
return $filtered; return $filtered;