update
This commit is contained in:
@ -305,85 +305,10 @@ class Tracks extends Model
|
|||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public static function lastMoveTracks($vid, $filter = [])
|
|
||||||
// {
|
|
||||||
// $now = time();
|
|
||||||
// $params = [];
|
|
||||||
// $query = "SELECT";
|
|
||||||
// $query .= " v.id as vid,v.device_id,v.nopol1,v.nopol2,v.nopol3";
|
|
||||||
// $query .= " ,tr.id as master_id,tr.latitude,tr.longitude,tr.speed,tr.orientation";
|
|
||||||
// $query .= " ,tr.crt AS lst_loc_crt,tr.crt_d AS lst_loc_crt_d,tr.crt_s AS lst_loc_crt_s";
|
|
||||||
// $query .= " ,tr.ignition,tr.stts_engine";
|
|
||||||
// $query .= " ,tr.pre_milleage,tr.sum_milleage,tr.vhc_milleage,v.sum_milleage AS vhc_sum_milleage_1";
|
|
||||||
// $query .= " ,addr.master_id AS addr_master_id,addr.crt AS addr_loc_crt";
|
|
||||||
// $query .=
|
|
||||||
// " ,addr.country_text,addr.state_text,addr.city_text,addr.district_text,addr.village_text,addr.postcode,addr.streets,addr.postcode,addr.fulladdress";
|
|
||||||
// $query .= " FROM t_vehicles AS v";
|
|
||||||
// // $query .= " INNER JOIN " . self::T_TRACKS . " AS tr ON v.device_id = tr.device_id"; // cara lama berlaku utk gps tracker saja
|
|
||||||
// $query .= " INNER JOIN " . self::T_TRACKS . " AS tr ON v.id = tr.vhc_id"; // support gps tracker dan smartphone / apapun yang mempunyai device_id(IMEI)
|
|
||||||
// $query .= " LEFT JOIN " . self::T_TRACKS_ADDR . " AS addr ON tr.id = addr.master_id";
|
|
||||||
// $query .= " WHERE v.dlt is null";
|
|
||||||
// $query .= " AND v.id = ?";
|
|
||||||
// array_push($params, $vid);
|
|
||||||
// $query .= " AND tr.latitude is not null";
|
|
||||||
// $query .= " AND tr.longitude is not null";
|
|
||||||
|
|
||||||
// // last move based on date
|
|
||||||
// // $query .= " AND tr.crt BETWEEN ? AND ?";
|
|
||||||
// // array_push($params, strtotime('-24 hours', $now), $now);
|
|
||||||
|
|
||||||
// if (isset($filter["start_date"]) && isset($filter["end_date"])) {
|
|
||||||
// $query .= " AND tr.crt_d BETWEEN ? AND ?";
|
|
||||||
// array_push($params, $filter["start_date"], $filter["end_date"]);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (isset($filter["start_at"])) {
|
|
||||||
// $query .= " AND tr.crt > ?";
|
|
||||||
// $params[] = $filter["start_at"];
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // last move based on last count data
|
|
||||||
// $query .= " GROUP BY tr.crt_d";
|
|
||||||
// $query .= " ORDER BY tr.crt_d DESC";
|
|
||||||
// // array_push($params, strtotime('-24 hours', $now), $now);
|
|
||||||
|
|
||||||
// // if (isset($filter["limit"])) {
|
|
||||||
// // $query .= " LIMIT ?";
|
|
||||||
// // $params[] = $filter["limit"] ?? 500;
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// $query .= " ;";
|
|
||||||
|
|
||||||
// // return DB::select($query, $params);
|
|
||||||
// $rawTracks = DB::select($query, $params);
|
|
||||||
// $cleanTracks = self::filterJumps($rawTracks);
|
|
||||||
|
|
||||||
// if (isset($filter["limit"])) {
|
|
||||||
// return array_slice($cleanTracks, 0, $filter["limit"]);
|
|
||||||
// }
|
|
||||||
// return $cleanTracks;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public static function lastMoveTracks($vid, $filter = [])
|
public static function lastMoveTracks($vid, $filter = [])
|
||||||
{
|
{
|
||||||
$now = time();
|
$now = time();
|
||||||
$params = [];
|
$params = [];
|
||||||
|
|
||||||
/**
|
|
||||||
* bikin lemot 30s timeout karena ada 2 join di rows yang banyak
|
|
||||||
* solution: indexing column
|
|
||||||
* show index from t_gps_tracks_address;
|
|
||||||
* create index addr_device_id on t_gps_tracks_address (device_id);
|
|
||||||
* create index addr_master_id on t_gps_tracks_address (master_id);
|
|
||||||
* show index from t_gps_tracks;
|
|
||||||
* create index tracks_device_id on t_gps_tracks (device_id);
|
|
||||||
* show index from t_vehicles;
|
|
||||||
* create index vhc_device_id on t_vehicles (device_id);
|
|
||||||
*
|
|
||||||
* solution not working. Don't reinvent the wheel
|
|
||||||
* create view. not working
|
|
||||||
*/
|
|
||||||
|
|
||||||
$query = "SELECT";
|
$query = "SELECT";
|
||||||
$query .= " v.id as vid,v.device_id,v.nopol1,v.nopol2,v.nopol3";
|
$query .= " v.id as vid,v.device_id,v.nopol1,v.nopol2,v.nopol3";
|
||||||
$query .= " ,tr.id as master_id,tr.latitude,tr.longitude,tr.speed,tr.orientation";
|
$query .= " ,tr.id as master_id,tr.latitude,tr.longitude,tr.speed,tr.orientation";
|
||||||
@ -394,22 +319,18 @@ class Tracks extends Model
|
|||||||
$query .=
|
$query .=
|
||||||
" ,addr.country_text,addr.state_text,addr.city_text,addr.district_text,addr.village_text,addr.postcode,addr.streets,addr.postcode,addr.fulladdress";
|
" ,addr.country_text,addr.state_text,addr.city_text,addr.district_text,addr.village_text,addr.postcode,addr.streets,addr.postcode,addr.fulladdress";
|
||||||
$query .= " FROM t_vehicles AS v";
|
$query .= " FROM t_vehicles AS v";
|
||||||
// $query .= " INNER JOIN " . self::T_TRACKS . " AS tr ON v.device_id = tr.device_id"; // cara lama berlaku utk gps tracker saja
|
$query .= " INNER JOIN " . self::T_TRACKS . " AS tr ON v.id = tr.vhc_id";
|
||||||
$query .= " INNER JOIN " . self::T_TRACKS . " AS tr ON v.id = tr.vhc_id"; // support gps tracker dan smartphone / apapun yang mempunyai device_id(IMEI)
|
|
||||||
$query .= " LEFT JOIN " . self::T_TRACKS_ADDR . " AS addr ON tr.id = addr.master_id";
|
$query .= " LEFT JOIN " . self::T_TRACKS_ADDR . " AS addr ON tr.id = addr.master_id";
|
||||||
$query .= " WHERE v.dlt is null";
|
$query .= " WHERE v.dlt IS NULL";
|
||||||
$query .= " AND v.id = ?";
|
$query .= " AND v.id = ?";
|
||||||
array_push($params, $vid);
|
$params[] = $vid;
|
||||||
$query .= " AND tr.latitude is not null";
|
$query .= " AND tr.latitude IS NOT NULL";
|
||||||
$query .= " AND tr.longitude is not null";
|
$query .= " AND tr.longitude IS NOT NULL";
|
||||||
|
|
||||||
// last move based on date
|
|
||||||
// $query .= " AND tr.crt BETWEEN ? AND ?";
|
|
||||||
// array_push($params, strtotime('-24 hours', $now), $now);
|
|
||||||
|
|
||||||
if (isset($filter["start_date"]) && isset($filter["end_date"])) {
|
if (isset($filter["start_date"]) && isset($filter["end_date"])) {
|
||||||
$query .= " AND tr.crt_d BETWEEN ? AND ?";
|
$query .= " AND tr.crt_d BETWEEN ? AND ?";
|
||||||
array_push($params, $filter["start_date"], $filter["end_date"]);
|
$params[] = $filter["start_date"];
|
||||||
|
$params[] = $filter["end_date"];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($filter["start_at"])) {
|
if (isset($filter["start_at"])) {
|
||||||
@ -417,19 +338,39 @@ class Tracks extends Model
|
|||||||
$params[] = $filter["start_at"];
|
$params[] = $filter["start_at"];
|
||||||
}
|
}
|
||||||
|
|
||||||
// last move based on last count data
|
// $query .= " GROUP BY tr.crt_d";
|
||||||
$query .= " GROUP BY tr.crt_d";
|
|
||||||
$query .= " ORDER BY tr.crt_d DESC";
|
$query .= " ORDER BY tr.crt_d DESC";
|
||||||
// array_push($params, strtotime('-24 hours', $now), $now);
|
|
||||||
|
|
||||||
if (isset($filter["limit"])) {
|
if (!isset($filter["limit"]) || $filter["limit"] < 3000) {
|
||||||
|
$filter["limit"] = 3000;
|
||||||
|
}
|
||||||
$query .= " LIMIT ?";
|
$query .= " LIMIT ?";
|
||||||
$params[] = $filter["limit"] ?? 500;
|
$params[] = $filter["limit"];
|
||||||
|
|
||||||
|
$raw = DB::select($query, $params);
|
||||||
|
|
||||||
|
usort($raw, function ($a, $b) {
|
||||||
|
$aTime = strtotime($a->lst_loc_crt ?? "1970-01-01 00:00:00");
|
||||||
|
$bTime = strtotime($b->lst_loc_crt ?? "1970-01-01 00:00:00");
|
||||||
|
return $aTime <=> $bTime;
|
||||||
|
});
|
||||||
|
|
||||||
|
$filtered = self::filterJumps($raw);
|
||||||
|
|
||||||
|
$minData = 500;
|
||||||
|
if (count($filtered) < $minData) {
|
||||||
|
$needed = $minData - count($filtered);
|
||||||
|
$lastRaw = array_slice($raw, -$needed);
|
||||||
|
$filtered = array_merge($filtered, $lastRaw);
|
||||||
}
|
}
|
||||||
|
|
||||||
$query .= " ;";
|
usort($filtered, function ($a, $b) {
|
||||||
|
$aTime = strtotime($a->lst_loc_crt ?? "1970-01-01 00:00:00");
|
||||||
|
$bTime = strtotime($b->lst_loc_crt ?? "1970-01-01 00:00:00");
|
||||||
|
return $bTime <=> $aTime;
|
||||||
|
});
|
||||||
|
|
||||||
return DB::select($query, $params);
|
return $filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function haversineDistance($lat1, $lon1, $lat2, $lon2)
|
public static function haversineDistance($lat1, $lon1, $lat2, $lon2)
|
||||||
@ -450,8 +391,14 @@ class Tracks extends Model
|
|||||||
return $earthRadius * $c;
|
return $earthRadius * $c;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function filterJumps($points, $maxDistance = 50, $maxTimeGap = 10)
|
public static function filterJumps(
|
||||||
{
|
$points,
|
||||||
|
$maxDistance = 150,
|
||||||
|
$maxTimeGap = 20,
|
||||||
|
$maxSpeed = 40,
|
||||||
|
$maxHardJump = 800,
|
||||||
|
$maxIdleJump = 1000
|
||||||
|
) {
|
||||||
$filtered = [];
|
$filtered = [];
|
||||||
$last = null;
|
$last = null;
|
||||||
|
|
||||||
@ -468,13 +415,25 @@ class Tracks extends Model
|
|||||||
$p->latitude,
|
$p->latitude,
|
||||||
$p->longitude
|
$p->longitude
|
||||||
);
|
);
|
||||||
$timeGap = $p->lst_loc_crt - $last->lst_loc_crt;
|
|
||||||
|
|
||||||
if ($distance <= $maxDistance || $timeGap > $maxTimeGap) {
|
$timeGap = $p->lst_loc_crt - $last->lst_loc_crt;
|
||||||
|
$speed = $timeGap > 0 ? $distance / $timeGap : 0;
|
||||||
|
|
||||||
|
if ($distance > $maxHardJump) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($distance > $maxIdleJump && $p->speed == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($timeGap <= $maxTimeGap && $speed > $maxSpeed) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($distance > $maxDistance) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$filtered[] = $p;
|
$filtered[] = $p;
|
||||||
$last = $p;
|
$last = $p;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return $filtered;
|
return $filtered;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user