no signal, 2=>extremely weak signal 3=>very weak signal, 4=>good signal, 5=>strong signal const STTS_GSM_DFT = 0; // default const STTS_GSM_NO_SIGNAL = 1; const STTS_GSM_BAD_SIGNAL = 2; const STTS_GSM_WEAK_SIGNAL = 3; const STTS_GSM_GOOD_SIGNAL = 4; const STTS_GSM_STRONG_SIGNAL = 5; // type source const SOURCE_GPS_TRACKER = 1; const SOURCE_SMARTPHONE = 2; /** * perlu tambahin filter untuk melihat tracking yang sesuai dengan vehiclenya aja * karena ada case: * device sudah sampai dilokasi pengantaran dan dimatikan, ketika dipakai lagi data tracking yang lama kelihatan dan loncat * untuk mengatasi itu di service_tracking juga perlu validasi tambahan, entah seperti apa caranya */ public static function listCurrentTracks($filter = []) { $now = time(); $params = []; $query = "SELECT"; $query .= " v.id as vid,v.device_id,v.name as vhc_name,c.name as vhc_cat_name,t.name as vhc_type_name"; $query .= " ,v.nopol1,v.nopol2,v.nopol3,vd.fvhc_img"; $query .= " ,v.is_track_holiday,v.track_sch_d,v.track_sch_h,vd.speed_limit,v.crt as vhc_crt"; $query .= " ,client.id as client_group_id,client.c_name as client_group_name"; $query .= " ,tr.ignition,tr.stts_engine,tr.stts_gps,tr.stts_gsm"; $query .= " ,tr.pre_milleage,tr.sum_milleage,tr.vhc_milleage,v.sum_milleage AS vhc_sum_milleage_1"; // FRO // $query .= " ,(SELECT SUM(pre_milleage) FROM " . self::T_TRACKS . " WHERE vhc_id = v.id LIMIT 1) as vhc_sum_milleage"; // $query .= " ,(SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine = " . self::STTS_EN_IDLING . " AND vhc_id = v.id AND crt_s >= ( // SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine IN (" . self::STTS_EN_STOPING . "," . self::STTS_EN_MOVING . ") AND vhc_id = v.id AND crt_s <= tr.crt_s ORDER BY id DESC LIMIT 1 // ) ORDER BY id ASC LIMIT 1) as lst_idle_at"; // $query .= " ,(SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine = " . self::STTS_EN_STOPING . " AND vhc_id = v.id AND crt_s >= ( // SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine IN (" . self::STTS_EN_IDLING . "," . self::STTS_EN_MOVING . ") AND vhc_id = v.id AND crt_s <= tr.crt_s ORDER BY id DESC LIMIT 1 // ) ORDER BY id ASC LIMIT 1) as lst_stop_at"; $query .= " ,tr.id AS lst_master_id,tr.latitude AS lst_lat,tr.longitude AS lst_lng,tr.speed AS lst_speed,tr.orientation AS lst_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_addr.master_id AS lst_addr_master_id,tr_addr.country_text AS lst_country_text,tr_addr.state_text AS lst_state_text,tr_addr.city_text AS lst_city_text"; $query .= " ,tr_addr.district_text AS lst_district_text,tr_addr.village_text AS lst_village_text,tr_addr.postcode AS lst_postcode"; $query .= " ,tr_addr.streets AS lst_streets,tr_addr.fulladdress AS lst_fulladdress"; // FRO // $query .= " ,(SELECT COUNT(id) FROM " . self::T_TRACKS . " WHERE vhc_id = v.id AND action = 'heartbeat' AND crt BETWEEN ".($now-(10*60))." AND ".$now." LIMIT 1) as lst_heartbeat"; // heartbeat last data on further 10 minutes if (isset($filter["active_rates"])) { $query .= ",rate.vdr_id as rate_vdr_id,rate.vhc_type as rate_vhc_type,rate.origin_prov as rate_origin_prov,rate.dest_city as rate_dest_city,rate.dest_district as rate_dest_district"; $query .= ",rate.fast_time as rate_fast_time,rate.long_time as rate_long_time,rate.sell_kg as rate_sell_kg,rate.sell_cbm as rate_sell_cbm,rate.sell_ftl as rate_sell_ftl"; } if (isset($filter["get_order_data"])) { $query .= ",ord.id as ord_id,ord.code as ord_code,ord.status as ord_stts,ord.crt as ord_crt,ord_pck.pck_name as ord_pck_name,ord_pck.pck_addr as ord_pck_addr,ord_drop.drop_name as ord_drop_name,ord_drop.drop_addr as ord_drop_addr"; $query .= ",(SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_pck.pck_ktid LIMIT 1) ord_pck_ktname, (SELECT nmKotamadyaKel FROM t_region WHERE kodeKab = ord_drop.drop_ktid LIMIT 1) ord_drop_ktname"; $query .= ",ord_drv.drv_name as ord_drv_name,ord_drv.drv_phone_val as ord_drv_phone_val,ord_drv.drv_phone2_val as ord_drv_phone2_val,ord_drv.drv_addr as ord_drv_addr"; $query .= ",ord_c.c_name as ord_c_name,ord_c.c_pt_name as ord_c_pt_name"; } $query .= " FROM t_vehicles AS v"; $query .= " INNER JOIN t_vehicles_detail AS vd ON v.id = vd.vid"; $query .= " INNER JOIN t_vehicles_types AS t ON v.type_id = t.id"; $query .= " INNER JOIN t_vehicles_cats AS c ON v.cat_id = c.id"; $query .= " LEFT JOIN t_users AS vendor ON v.vendor_id = vendor.id"; $query .= " LEFT JOIN t_clients AS client ON vendor.client_group_id = client.id"; // get last updated row from many rows // $query .= " LEFT JOIN ( SELECT MAX(crt) max_crt, device_id FROM " . self::T_TRACKS . " WHERE latitude is not null AND longitude is not null GROUP BY device_id ORDER BY crt DESC ) AS tr1 ON (v.device_id = tr1.device_id)"; // cara lama berlaku utk gps tracker saja // // $query .= " LEFT JOIN ( SELECT MAX(crt) max_crt, device_id, vhc_id FROM " . self::T_TRACKS . " WHERE latitude is not null AND longitude is not null GROUP BY vhc_id ORDER BY crt DESC ) AS tr1 ON (v.id = tr1.vhc_id)"; // support gps tracker dan smartphone / apapun yang mempunyai device_id(IMEI) // $query .= " LEFT JOIN " . self::T_TRACKS . " AS tr ON (tr.crt = tr1.max_crt)"; // get last updated tracking from updated table realtime // $query .= " LEFT JOIN db_trucking.t_gps_tracks_rltm AS tr ON tr.vhc_id = v.id"; $query .= " LEFT JOIN t_gps_tracks_rltm AS tr ON tr.vhc_id = v.id"; // $query .= " LEFT JOIN " . self::T_TRACKS_ADDR . " AS tr_addr ON tr.id = tr_addr.master_id"; //FRO $query .= " LEFT JOIN " . self::T_TRACKS_ADDR . " AS tr_addr ON tr.latitude = tr_addr.lat and tr.longitude = tr_addr.lng"; if (isset($filter["active_rates"])) { // $query .= " INNER JOIN t_conf_rates as rate ON v.type_id = rate.vhc_type"; $query .= " INNER JOIN t_conf_rates as rate ON v.vendor_id = rate.vdr_id"; } if (isset($filter["get_order_data"])) { // the old way => only 1 order 1 vehicle $query .= " LEFT JOIN t_orders as ord ON v.ord_id = ord.id"; $query .= " LEFT JOIN t_orders_pickups as ord_pck ON v.ord_id = ord_pck.ord_id"; $query .= " LEFT JOIN t_orders_drops as ord_drop ON v.ord_id = ord_drop.ord_id"; $query .= " LEFT JOIN t_orders_drivers as ord_drv ON v.ord_id = ord_drv.ord_id"; $query .= " LEFT JOIN t_orders_clients as ord_c ON v.ord_id = ord_c.ord_id"; // the new way => can handle 2 order in 1 vehicle // $query .= " LEFT JOIN t_orders_vehicles as ord_vhc ON v.id = ord_vhc.vhc_id"; // $query .= " LEFT JOIN t_orders as ord ON ord_vhc.ord_id = ord.id"; // $query .= " LEFT JOIN t_orders_pickups as ord_pck ON ord_vhc.ord_id = ord_pck.ord_id"; // $query .= " LEFT JOIN t_orders_drops as ord_drop ON ord_vhc.ord_id = ord_drop.ord_id"; // $query .= " LEFT JOIN t_orders_drivers as ord_drv ON ord_vhc.ord_id = ord_drv.ord_id"; // $query .= " LEFT JOIN t_orders_clients as ord_c ON ord_vhc.ord_id = ord_c.ord_id"; } $query .= " WHERE v.dlt is null"; // $query .= " AND tr.action IN ('location','alarm')"; // kalo gamau ngambil data heartbeat(idling) // $query .= " AND tr.device_id = v.device_id"; // cara lama berlaku utk gps tracker saja // $query .= " AND tr.vhc_id = v.id"; // support gps tracker dan smartphone / apapun yang mempunyai device_id(IMEI) // bikin lemot $query .= " AND tr.latitude != 0 AND tr.latitude is not null"; if (isset($filter["status"])) { $query .= " AND v.status = ?"; $params[] = $filter["status"]; } if (isset($filter["is_in_ord"])) { $query .= " AND v.is_in_ord = ?"; $params[] = $filter["is_in_ord"]; } if (isset($filter["nopol1"]) && isset($filter["nopol2"]) && isset($filter["nopol3"])) { $query .= " AND v.nopol1 = ? AND v.nopol2 = ? AND v.nopol3 = ?"; array_push($params, $filter["nopol1"], $filter["nopol2"], $filter["nopol3"]); } if (isset($filter["vid"])) { $query .= " AND v.id = ?"; $params[] = $filter["vid"]; } if (isset($filter["vids"])) { if ($filter["vids"] && count($filter["vids"]) > 0) { $binds_vids = ""; foreach ($filter["vids"] as $k => $v) { $binds_vids .= "?,"; $params[] = $v; } if (substr($binds_vids, -1) === ",") { $binds_vids = substr($binds_vids, 0, -1); } $query .= " AND v.id IN ($binds_vids)"; } else { $query .= " AND v.id = ?"; $params[] = 0; } } if (isset($filter["own_by_vdr_id"])) { $query .= " AND v.vendor_id = ?"; $params[] = $filter["own_by_vdr_id"]; } if (isset($filter["active_rates"])) { // v1 // $query .= " AND rate.vdr_id != 0 AND rate.dest_city != 0 AND rate.dest_district != 0"; // $query .= " AND rate.origin_prov = ? AND (rate.dest_city = ? OR rate.dest_district = ?) AND rate.sell_kg = ? AND rate.sell_cbm = ? AND rate.long_time = ?"; // array_push($params, $filter['active_rates']->origin_prov, $filter['active_rates']->dest_city, $filter['active_rates']->dest_district, $filter['active_rates']->sell_kg, $filter['active_rates']->sell_cbm, $filter['active_rates']->long_time); // v2 $query .= " AND rate.vdr_id != 0 AND rate.dest_city != 0 AND rate.is_active = " . ConfRates::IS_ACTIVE; $query .= " AND rate.origin_prov = ? AND (rate.dest_city = ? OR rate.dest_district = ?) AND rate.sell_ftl = ? AND rate.long_time = ?"; array_push( $params, $filter["active_rates"]->origin_prov, $filter["active_rates"]->dest_city, $filter["active_rates"]->dest_district, $filter["active_rates"]->sell_ftl, $filter["active_rates"]->long_time ); } if (isset($filter["prefer_truck_type"])) { $query .= " AND v.type_id = ?"; $params[] = $filter["prefer_truck_type"]; } if (isset($filter["get_order_data"])) { if (isset($filter["client_id"])) { $query .= " AND ord_c.c_id = ?"; $params[] = $filter["client_id"]; } // $query .= " AND ord.status IN (22,4)"; } if (isset($filter["company"])) { $query .= " AND client.id = ?"; $params[] = $filter["company"]; } // $query .= " AND v.id = 70"; $query .= " GROUP BY v.id"; $query .= " ORDER BY tr.crt_d DESC"; $query .= " LIMIT 500;"; // dd($query); $list = DB::select($query, $params); foreach ($list as $_list) { $_query = " SELECT SUM(pre_milleage) as vhc_sum_milleage FROM " . self::T_TRACKS . " WHERE vhc_id = ?"; $_query = DB::select($_query, [$_list->vid]); $_list->vhc_sum_milleage = $_query[0]->vhc_sum_milleage; $_query = " SELECT crt_s as lst_idle_at FROM " . self::T_TRACKS . " WHERE stts_engine = " . self::STTS_EN_IDLING . " AND vhc_id = ? AND crt_s >= ( SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine IN ( " . self::STTS_EN_STOPING . ", " . self::STTS_EN_MOVING . ") AND vhc_id = ? AND crt_s <= ? ORDER BY id DESC LIMIT 1 ) ORDER BY id ASC LIMIT 1"; $_query = DB::select($_query, [$_list->vid, $_list->vid, $_list->lst_loc_crt_s]); $_list->lst_idle_at = count($_query) == 0 ? "" : $_query[0]->lst_idle_at; $_query = "SELECT crt_s as lst_stop_at FROM " . self::T_TRACKS . " WHERE stts_engine = " . self::STTS_EN_STOPING . " AND vhc_id = ? AND crt_s >= ( SELECT crt_s FROM " . self::T_TRACKS . " WHERE stts_engine IN (" . self::STTS_EN_IDLING . "," . self::STTS_EN_MOVING . ") AND vhc_id = ? AND crt_s <= ? ORDER BY id DESC LIMIT 1 ) ORDER BY id ASC LIMIT 1 "; $_query = DB::select($_query, [$_list->vid, $_list->vid, $_list->lst_loc_crt_s]); $_list->lst_stop_at = count($_query) == 0 ? "" : $_query[0]->lst_stop_at; $_query = " SELECT COUNT(id) as lst_heartbeat FROM " . self::T_TRACKS . " WHERE vhc_id = ? AND action = 'heartbeat' AND crt BETWEEN " . ($now - 10 * 60) . " AND " . $now . " LIMIT 1"; $_query = DB::select($_query, [$_list->vid]); $_list->lst_heartbeat = count($_query) == 0 ? "" : $_query[0]->lst_heartbeat; } // em return $list; } public static function lastMoveTracks($vid, $filter = []) { $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, tr.crt_d_format"; $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.id = tr.vhc_id"; $query .= " LEFT JOIN " . self::T_TRACKS_ADDR . " AS addr ON tr.id = addr.master_id"; $query .= " WHERE v.dlt IS NULL AND v.id = ?"; $params[] = $vid; $query .= " AND tr.latitude IS NOT NULL AND tr.longitude IS NOT NULL"; if (isset($filter["start_date"], $filter["end_date"])) { $query .= " AND tr.crt_d BETWEEN ? AND ?"; $params[] = $filter["start_date"]; $params[] = $filter["end_date"]; } if (isset($filter["start_at"])) { $query .= " AND tr.crt > ?"; $params[] = $filter["start_at"]; } $query .= " ORDER BY tr.crt_d DESC"; $limit = isset($filter["limit"]) && $filter["limit"] > 500 ? $filter["limit"] : 50000; $query .= " LIMIT ?"; $params[] = $limit; $raw = DB::select($query, $params); $rawAscCleaned = self::removeSpeedSandwich($raw); $filtered = self::filterJumps($rawAscCleaned); $combined = $filtered; // usort($combined, fn($a, $b) => $b->lst_loc_crt_d <=> $a->lst_loc_crt_d); $final = array_slice($combined, 0, 500); return $final; } public static function haversineDistance($lat1, $lon1, $lat2, $lon2) { $earthRadius = 6371000; // meters $lat1 = deg2rad($lat1); $lon1 = deg2rad($lon1); $lat2 = deg2rad($lat2); $lon2 = deg2rad($lon2); $dlat = $lat2 - $lat1; $dlon = $lon2 - $lon1; $a = sin($dlat / 2) ** 2 + cos($lat1) * cos($lat2) * sin($dlon / 2) ** 2; $c = 2 * atan2(sqrt($a), sqrt(1 - $a)); return $earthRadius * $c; } private static function removeSpeedSandwich($data) { $cleaned = []; for ($i = 0; $i < count($data); $i++) { $next = $data[$i + 1] ?? null; // lebih lama $curr = $data[$i]; $prev = $data[$i - 1] ?? null; // lebih baru // Logika dibalik: prev = lebih baru, next = lebih lama if ($prev && $next && $prev->speed > 5 && $curr->speed < 5 && $next->speed > 5) { continue; } $cleaned[] = $curr; } return $cleaned; } public static function filterJumps( $points, $maxDistance = 150, $maxTimeGap = 20, $maxSpeed = 100, $maxHardJump = 100, $maxIdleJump = 100, $maxRealSpeed = 100 ) { $filtered = []; $last = null; $start = null; foreach ($points as $p) { if (!$last) { $filtered[] = $p; $last = $p; $start = $p; continue; } $distance = self::haversineDistance( $last->latitude, $last->longitude, $p->latitude, $p->longitude ); $t1 = strtotime($last->lst_loc_crt); $t2 = strtotime($p->lst_loc_crt); $timeGap = $t2 - $t1; $speed = $timeGap > 0 ? $distance / $timeGap : 0; $realSpeedKmh = $speed * 3.6; $jumpFromStart = self::haversineDistance( $start->latitude, $start->longitude, $p->latitude, $p->longitude ); if ($distance > $maxHardJump) { continue; } if ($distance > $maxIdleJump && $p->speed < 5 && $last->speed < 5) { continue; } if ($timeGap <= $maxTimeGap && $speed > $maxSpeed) { continue; } if ($realSpeedKmh > $maxRealSpeed) { continue; } if ($jumpFromStart > 500 && $p->speed < 5) { continue; } // >10 km dari area awal tapi status idle $filtered[] = $p; $last = $p; } return $filtered; } public static function nearestInCircle($lat, $lng, $rad, $filter = []) { $earth_rad = Helper::EARTH_RADIUS_M; $t_gps_tracks = self::T_TRACKS; $select_select = ""; $join_join = ""; $where_where = ""; $params = [ "lat1" => $lat, "lat2" => $lat, "lng" => $lng, "v_status" => Vehicles::STTS_ACTIVE, "v_is_in_ord" => Vehicles::IN_ORD_NO, "rad" => $rad, ]; if (isset($filter["active_rates"])) { $select_select .= ",rate.vdr_id as rate_vdr_id,rate.vhc_type as rate_vhc_type,rate.origin_prov as rate_origin_prov,rate.dest_city as rate_dest_city,rate.dest_district as rate_dest_district"; $select_select .= ",rate.fast_time as rate_fast_time,rate.long_time as rate_long_time,rate.sell_kg as rate_sell_kg,rate.sell_cbm"; } if (isset($filter["active_rates"])) { // $join_join .= " INNER JOIN t_conf_rates as rate ON v.type_id = rate.vhc_type"; $join_join .= " INNER JOIN t_conf_rates as rate ON v.vendor_id = rate.vdr_id"; } if (isset($filter["active_rates"])) { // v1 // $where_where .= " AND rate.vdr_id != 0 AND rate.dest_city != 0 AND rate.dest_district != 0"; // $where_where .= " AND rate.origin_prov = :origin_prov AND (rate.dest_city = :dest_city OR rate.dest_district = :dest_district) AND rate.sell_kg = :sell_kg AND rate.sell_cbm = :sell_cbm AND rate.long_time = :long_time"; // v2 $where_where .= " AND rate.vdr_id != 0 AND rate.dest_city != 0 AND rate.is_active = " . ConfRates::IS_ACTIVE; $where_where .= " AND rate.origin_prov = :origin_prov AND (rate.dest_city = :dest_city OR rate.dest_district = :dest_district) AND rate.sell_ftl = :sell_ftl AND rate.long_time = :long_time"; $params["origin_prov"] = $filter["active_rates"]->origin_prov; $params["dest_city"] = $filter["active_rates"]->dest_city; $params["dest_district"] = $filter["active_rates"]->dest_district; // v1 // $params['sell_kg'] = $filter['active_rates']->sell_kg; // $params['sell_cbm'] = $filter['active_rates']->sell_cbm; // v2 $params["sell_ftl"] = $filter["active_rates"]->sell_ftl; $params["long_time"] = $filter["active_rates"]->long_time; } if (isset($filter["prefer_truck_type"])) { $where_where .= " AND v.type_id = :prefer_truck_type"; $params["prefer_truck_type"] = $filter["prefer_truck_type"]; } $query = "SELECT v.*,tr.latitude,tr.longitude,tr.id as master_id ,u.first_name as vendor_name,u.phone as vendor_phone,u.phone_code as vendor_phone_code,u.email as vendor_mail,u.fulladdress as vendor_addr ,( $earth_rad * acos( cos( radians( :lat1 ) ) * cos( radians( tr.latitude ) ) * cos( radians( tr.longitude ) - radians( :lng ) ) + sin( radians( :lat2 ) ) * sin(radians( tr.latitude )) ) ) AS distance $select_select FROM $t_gps_tracks as tr INNER JOIN t_vehicles as v ON tr.vhc_id = v.id INNER JOIN t_users as u ON v.vendor_id = u.id -- get last updated row from many rows LEFT JOIN ( SELECT MAX(crt) max_crt, vhc_id FROM $t_gps_tracks WHERE latitude is not null AND longitude is not null GROUP BY vhc_id ORDER BY crt DESC ) AS tr1 ON (v.id = tr1.vhc_id) $join_join WHERE v.dlt is null AND v.status = :v_status AND v.is_in_ord = :v_is_in_ord AND tr.latitude is not null AND tr.longitude != 0 -- get last updated row from many rows AND tr.crt = tr1.max_crt $where_where GROUP BY tr.vhc_id HAVING distance <= :rad -- ORDER BY distance ASC ORDER BY tr.crt DESC ;"; return DB::select($query, $params); } public static function addTracks($data) { $id = DB::table(self::T_TRACKS)->insertGetId($data); return $id; } public static function addTracksAddr($data) { $id = DB::table(self::T_TRACKS_ADDR)->insertGetId($data); return $id; } public static function listLogsGps($filter = []) { $params = []; $where_where = ""; $limit = ""; if (isset($filter["crt_greater_than"])) { $where_where .= " AND crt > ?"; $params[] = $filter["crt_greater_than"]; } if (isset($filter["limit"])) { $limit .= " LIMIT ?"; $params[] = $filter["limit"]; } return DB::select( "SELECT * FROM " . self::T_TRACKS . " as tr WHERE device_id is not null AND device_id != 0 " . $where_where . " ORDER BY tr.crt DESC " . $limit . " ", $params ); } public static function gpsLocsAddr($filter = []) { $params = []; $select = ""; $join = ""; $where = ""; $order_by = ""; $group_by = ""; $limit = ""; if (isset($filter["source"])) { $where .= " AND tr.source = ?"; $params[] = $filter["source"]; } if (isset($filter["vhc_id"])) { $where .= " AND tr.vhc_id = ?"; $params[] = $filter["vhc_id"]; } if (isset($filter["drv_id"])) { $where .= " AND tr.drv_id = ?"; $params[] = $filter["drv_id"]; } if (isset($filter["group_by"])) { $group_by .= " GROUP BY " . $filter["group_by"]; } if (isset($filter["order_by"])) { $order_by .= " ORDER BY " . $filter["order_by"]; } if (isset($filter["limit"])) { $limit .= " LIMIT " . $filter["limit"]; } return DB::select( "SELECT tr.* ,tr_addr.country_id,tr_addr.country_text,tr_addr.state_id,tr_addr.state_text,tr_addr.city_id,tr_addr.city_text ,tr_addr.district_id,tr_addr.district_text,tr_addr.village_id,tr_addr.village_text,tr_addr.postcode,tr_addr.streets,tr_addr.fulladdress ,tr_addr.stts_reverse_geo $select FROM t_gps_tracks as tr LEFT JOIN t_gps_tracks_address as tr_addr ON tr.id = tr_addr.master_id $join WHERE tr.latitude is not null AND tr.longitude != 0 $where $group_by $order_by $limit ;", $params ); } }