""); //$ridersArrayLeaderboard = array(); $cpArray = array(); $i = 0; $startTimelog = ''; // riders db data loop if (!$debug) { $debugAmount = 0; } else { $totalWaypoints = array(); $result = $conn->query("SELECT COUNT(id) FROM `" . $eventTable . "`"); $row = $result->fetch_row(); $totalWaypoints = $row[0]; $totalWaypoints = $totalWaypoints * $debugAmount; } for ($x = 0; $x <= $debugAmount; $x++) { $sql = "SELECT ".$eventTable_rc.".*, ".$eventTable.".* FROM ".$eventTable_rc." LEFT JOIN ".$eventTable." ON ".$eventTable_rc.".imei = ".$eventTable.".imei WHERE ".$eventTable_rc.".active=1;"; $res = mysqli_query($conn, $sql); while ($deviceData = mysqli_fetch_array($res)) { if ($deviceData['fixUnix']) { // if there is a fixUnix value then the device is active, otherwise, put it in pre-race loop. $raceData = true; if (!$deviceData['scratched']) { if($grouppedEvent && $groupColors[$deviceData['groupId']]){ $deviceData['color'] = $groupColors[$deviceData['groupId']]; // Groups get same color } } else { if ($deviceData['scratched'] == '4') { $deviceData['color'] = "#ff0000"; // Crew Color } else { $deviceData['color'] = "#000000"; // Scratched color } } $rider = preg_replace("/[^A-Za-z0-9]/", "", $deviceData['nameExt']); // put rider data into php array if (!empty($rider)) { if ($debug) { $rider = $rider . "" . $i; } $lastReportSec = (time() - $deviceData['fixUnix']) - ($viewDelay * 60); $lastReportMins = $lastReportSec / 60; $lastReport = lastReport($lastReportSec); //$lastPingReportSec = (time() - strtotime($deviceData['dateTime'])) - ($viewDelay * 60); //$lastPingReport = lastReport($lastPingReportSec); // check if the last know unixtimestamp is todays otherwise todays data is null $date = date('Y-m-d', $deviceData['fixUnix']); $today = date('Y-m-d'); $attributes = json_decode($deviceData['attributes'], true); // create rider data array for mainpage view if ($debug) { $ridersArray[$rider]['latitude'] = '4.457832'; $ridersArray[$rider]['longitude'] = '52.147147'; } else { $ridersArray[$rider]['latitude'] = floatval($deviceData['latitude']); $ridersArray[$rider]['longitude'] = floatval($deviceData['longitude']); } $ridersArray[$rider]['lastReport'] = $lastReport; $ridersArray[$rider]['lastReportMins'] = round($lastReportMins); $ridersArray[$rider]['teamNumber'] = $deviceData['teamNumber']; $ridersArray[$rider]['startDelay'] = $deviceData['startDelay']; $ridersArray[$rider]['country'] = $deviceData['country']; $ridersArray[$rider]['scratched'] = floatval($deviceData['scratched']); $ridersArray[$rider]['dtf'] = ($deviceData['dtf'] * 1000); $ridersArray[$rider]['dtfKM'] = round($deviceData['dtf']); if(empty($deviceData['groupId']) ) { $deviceData['groupId'] = '1'; } if(!$grouppedEvent){ $deviceData['groupId'] = '1'; } // If no groupped event, force all riders in group 1 to perform ranking and sorting. $ridersArray[$rider]['groupId'] = $deviceData['groupId']; if(isset($groupHeaderLabels)) { $ridersArray[$rider]['groupHeaderLabel'] = $groupHeaderLabels[$deviceData['groupId']]; } $ridersArray[$rider]['groupFinish'] = $deviceData['groupFinish']; // DO WE STILL USE THIS ?? /*if ($date == $today) { $ridersArray[$rider]['avgSpeedToday'] = round($deviceData['speedAvgToday'], 2); if($deviceData['distanceToday']) { $ridersArray[$rider]['todaysDistance'] = round(($deviceData['distanceToday'] * $correctionPercentage), 2); } else { $ridersArray[$rider]['todaysDistance'] = 0; } } else { $ridersArray[$rider]['avgSpeedToday'] = '0'; $ridersArray[$rider]['todaysDistance'] = '0'; }*/ $ridersArray[$rider]['totalDistance'] = round((floatval($deviceData['totalDistance']) * floatval($correctionPercentage)), 2); if(isset($deviceData['speed'])){ $ridersArray[$rider]['currentSpeed'] = round(floatval($deviceData['speed']), 2); // LEGACY ?? } //$ridersArray[$rider]['dbtable'] = $eventTable; $ridersArray[$rider]['riderNameClean'] = $rider; $ridersArray[$rider]['riderColor'] = $deviceData['color']; $ridersArray[$rider]['attributes'] = $deviceData['attributes']; $ridersArray[$rider]['fixTimeUnix'] = $lastReport; $ridersArray[$rider]['fixUnix'] = $deviceData['fixUnix']; $ridersArray[$rider]['firstFixUnix'] = $deviceData['firstFixUnix']; $ridersArray[$rider]['timeIdle'] = $deviceData['timeIdle']; if ( ($deviceData['timeIdle']) && ($deviceData['fixUnix'] != $deviceData['firstFixUnix']) ) { $movingTime = ($deviceData['fixUnix'] - $deviceData['firstFixUnix']) - $deviceData['timeIdle']; $stoppedTime = $deviceData['timeIdle']; $stoppedPercentage = round(($deviceData['timeIdle'] * 100) / ($deviceData['fixUnix'] - $deviceData['firstFixUnix'])); $movingTimePercentage = round(100 - $stoppedPercentage); $ridersArray[$rider]['movingTime'] = $movingTime; $ridersArray[$rider]['movingTimeText'] = sec2elapsed($movingTime); $ridersArray[$rider]['timeIdleText'] = sec2elapsed($deviceData['timeIdle']); $ridersArray[$rider]['stoppedPercentage'] = $stoppedPercentage; $ridersArray[$rider]['movingTimePercentage'] = $movingTimePercentage; } elseif ($deviceData['fixUnix'] != $deviceData['firstFixUnix']) { // No idle time yet so 100% moving time. $movingTime = ($deviceData['fixUnix'] - $deviceData['firstFixUnix']); $stoppedTime = 0; $stoppedPercentage = round(($deviceData['timeIdle'] * 100) / ($deviceData['fixUnix'] - $deviceData['firstFixUnix'])); $movingTimePercentage = round(100 - $stoppedPercentage); $ridersArray[$rider]['movingTime'] = $movingTime; $ridersArray[$rider]['movingTimeText'] = sec2elapsed($movingTime); $ridersArray[$rider]['timeIdleText'] = sec2elapsed($deviceData['timeIdle']); $ridersArray[$rider]['stoppedPercentage'] = $stoppedPercentage; $ridersArray[$rider]['movingTimePercentage'] = $movingTimePercentage; } //$ridersArray[$rider]['dateTimeUnix'] = $lastPingReport; $ridersArray[$rider]['address'] = $deviceData['address']; $ridersArray[$rider]['imei'] = $deviceData['imei']; $ridersArray[$rider]['deviceId'] = $deviceData['deviceId']; $ridersArray[$rider]['course'] = $deviceData['course']; /* Speed the new way */ $ridersArray[$rider]['speedJSON'] = $deviceData['speedJSON']; $speedJSON = json_decode($deviceData['speedJSON'], true); if(isset($speedJSON['rs'])) { $ridersArray[$rider]['routeSpeed'] = $speedJSON['rs']; } if(isset($speedJSON['rsm'])) { $ridersArray[$rider]['routeSpeedMoving'] = $speedJSON['rsm']; } if ($deviceData['finishOverrule']) { $ridersArray[$rider]['finishTime'] = $deviceData['finishOverrule'] + $timezoneCorrection; $finishTime = $deviceData['finishOverrule'] + $timezoneCorrection; } else { $ridersArray[$rider]['finishTime'] = $deviceData['finished']; $finishTime = $deviceData['finished']; } if($ridersArray[$rider]['finishTime']){ if($deviceData['finishCorrection']) { $ridersArray[$rider]['finishTime'] = $ridersArray[$rider]['finishTime'] + intval($deviceData['finishCorrection']*60); $finishTime = $finishTime + intval($deviceData['finishCorrection']*60); } } $ridersArray[$rider]['finishTimeElapsed'] = $deviceData['finished']-$deviceData['firstFixUnix']; $ridersArray[$rider]['altitude'] = $deviceData['altitude']; $ridersArray[$rider]['elevation'] = $deviceData['elevation']; $ridersArray[$rider]['weather'] = $deviceData['weather']; $ridersArray[$rider]['city'] = $deviceData['city']; $ridersArray[$rider]['website'] = $deviceData['website']; // Distance switch depending on data $ridersArray[$rider]['onTrackStatusBoolean'] = false; if ($trackTable || $groupDistanceOnTrack) { if($groupDistanceOnTrack) { if ( isset($totalTrackDistanceGroup[$deviceData['groupId']]) ) { $ridersArray[$rider]['totalTrackDistance'] = $totalTrackDistanceGroup[$deviceData['groupId']]; $totalTrackDistance = $totalTrackDistanceGroup[$deviceData['groupId']]; } else { $ridersArray[$rider]['totalTrackDistance'] = 0; $totalTrackDistance = 0; } } else { $ridersArray[$rider]['totalTrackDistance'] = $totalTrackDistance; } if($startRandomTrackpoint) { if($deviceData['distanceOnTrack'] <= $deviceData['firstDistanceOnTrack']) { if(empty($deviceData['distanceOnTrack'])){ // if the distance on track happends to be zero, he's on the exact start point $deviceData['distanceOnTrack'] = abs( ($deviceData['distanceOnTrack']-$deviceData['firstDistanceOnTrack'])); }else{ $deviceData['distanceOnTrack'] = abs( ($deviceData['distanceOnTrack']-$deviceData['firstDistanceOnTrack']) + $totalTrackDistance ); } } else { $deviceData['distanceOnTrack'] = abs($deviceData['distanceOnTrack']-$deviceData['firstDistanceOnTrack']); } } if (($deviceData['distanceOnTrack'] != "false") && (!empty($deviceData['distanceOnTrack'])) || (!empty($deviceData['distanceOnTrackId']))) { $ridersArray[$rider]['onTrackStatus'] = "On Track"; $ridersArray[$rider]['onTrackStatusBoolean'] = true; $ridersArray[$rider]['onTrackDistance'] = $deviceData['distanceOnTrack']; if(!empty($totalTrackDistance)) { $ridersArray[$rider]['onTrackPercentage'] = round(((floatval($deviceData['distanceOnTrack']) / floatval($totalTrackDistance)) * 100), 2); } else { $ridersArray[$rider]['onTrackPercentage'] = 0; } if($deviceData['finished'] || $deviceData['finishOverrule']) { $deviceData['distanceOnTrack'] = $ridersArray[$rider]['totalTrackDistance']; } if( is_infinite($ridersArray[$rider]['onTrackPercentage']) || is_nan($ridersArray[$rider]['onTrackPercentage']) ) { // JSON Encode fails on INF values. $ridersArray[$rider]['onTrackPercentage'] = 0; } // push distance on track value into the totaldistance value for riders who are on track $ridersArray[$rider]['totalDistance'] = round((floatval($deviceData['distanceOnTrack']) * $correctionPercentage), 3); } else { $ridersArray[$rider]['onTrackStatus'] = "Off Track"; $ridersArray[$rider]['onTrackStatusBoolean'] = false; $ridersArray[$rider]['onTrackDistance'] = ''; // off track - no distance known - fallback on calculated distance } } if($deviceData['finished'] || $deviceData['finishOverrule']) { // rework, why does the view use the $speedjson variable and not the item var from the riders array?? $speedJSON['rs'] = round($totalTrackDistance / (($deviceData['finished']-$deviceData['firstFixUnix'])/3600),2); $ridersArray[$rider]['speedJSON'] = json_encode($speedJSON); $routeSpeed = round($totalTrackDistance / (($deviceData['finished']-$deviceData['firstFixUnix'])/3600),2); if(is_nan($speedJSON['rs'])){ $ridersArray[$rider]['rs'] = 0; } else { $ridersArray[$rider]['rs'] = $routeSpeed; } } if ($finishTime) { $minutes = ($finishTime - $deviceData['firstFixUnix']) / 60; $day = floor($minutes / 1440); $hour = floor(($minutes - $day * 1440) / 60); $min = floor($minutes - ($day * 1440) - ($hour * 60)); $ridersArray[$rider]['finishedInString'] = $day . " d " . $hour . " h " . $min . " m"; } if ($debug) { $ridersArray[$rider]['riderName'] = $rider; } else { $ridersArray[$rider]['riderName'] = $deviceData['nameExt']; } } if ($config_sortActive == 'checkpointCount') { // default values if ($deviceData['scratched']) { $ridersArray[$rider]['cpLastHitUnix'] = $deviceData['teamNumber'] * 100000; // bring down the scratchers } else { $ridersArray[$rider]['cpLastHitUnix'] = $deviceData['teamNumber']; } $ridersArray[$rider]['cpCounter'] = 0; $ridersArray[$rider]['cpLastCP'] = ""; //$cp_sql = "SELECT DISTINCT cpName FROM " . $dataEventTable . " WHERE cpName != 'nocp' AND imei = '" . $data['imei'] . "'"; $cp_sql = "SELECT cpName, MAX(id) FROM " . $dataEventTable . " WHERE cpName != 'nocp' AND imei = '" . $ridersArray[$rider]['imei'] . "' GROUP BY cpName ORDER BY MAX(id)"; $cp_result = mysqli_query($conn, $cp_sql); $cp_checked_rider = array(); while ($data = mysqli_fetch_array($cp_result)) { $cp_checked_rider[] .= $data['cpName']; } $cpCounter = mysqli_num_rows($cp_result); $ridersArray[$rider]['cpCounter'] = $cpCounter; // Get latest CP hit: $last_cp_sql = "SELECT sub.* FROM ( SELECT cpName, cpDistance, fixUnix, fixTime FROM " . $dataEventTable . " WHERE cpName='".end($cp_checked_rider)."' AND imei = '" . $ridersArray[$rider]['imei'] . "' order by fixUnix ASC LIMIT 5) sub ORDER BY CAST(cpDistance as SIGNED INTEGER), fixUnix ASC LIMIT 1"; $last_cp_result = mysqli_query($conn, $last_cp_sql); while ($last_cpDataResult = mysqli_fetch_array($last_cp_result)) { $ridersArray[$rider]['cpLastCP'] = $last_cpDataResult['cpName']; $ridersArray[$rider]['cpLastHitUnix'] = $last_cpDataResult['fixUnix']; } } if ($config_sortActive == 'checkpointScore') { // default values if ($deviceData['scratched']) { $ridersArray[$rider]['cpLastHitUnix'] = $deviceData['teamNumber'] * 100000; // bring down the scratchers } else { $ridersArray[$rider]['cpLastHitUnix'] = $deviceData['teamNumber']; } $ridersArray[$rider]['cpScore'] = 0; $ridersArray[$rider]['cpLastCP'] = ""; // Get all checked checkpoints, no need to dive deep into timestamps, we just need to know which CP for the score. $cp_sql = "SELECT cpName, MAX(id) FROM " . $dataEventTable . " WHERE cpName != 'nocp' AND imei = '" . $ridersArray[$rider]['imei'] . "' GROUP BY cpName ORDER BY MAX(id)"; $cp_result = mysqli_query($conn, $cp_sql); $cp_checked_rider = array(); while ($data = mysqli_fetch_array($cp_result)) { $cp_checked_rider[] .= $data['cpName']; $ridersArray[$rider]['cpScore'] = $ridersArray[$rider]['cpScore'] + $checkpoint_values[$data['cpName']]; } $cpCounter = mysqli_num_rows($cp_result); $ridersArray[$rider]['cpCounter'] = $cpCounter; if(empty($ridersArray[$rider]['cpScore'])){ $ridersArray[$rider]['cpScore'] = 0; } // If empty, set zero points. // Get latest CP hit: $last_cp_sql = "SELECT sub.* FROM ( SELECT cpName, cpDistance, fixUnix, fixTime FROM " . $dataEventTable . " WHERE cpName='".end($cp_checked_rider)."' AND imei = '" . $ridersArray[$rider]['imei'] . "' order by fixUnix ASC LIMIT 5) sub ORDER BY CAST(cpDistance as SIGNED INTEGER), fixUnix ASC LIMIT 1"; $last_cp_result = mysqli_query($conn, $last_cp_sql); while ($last_cpDataResult = mysqli_fetch_array($last_cp_result)) { $ridersArray[$rider]['cpLastCP'] = $last_cpDataResult['cpName']; $ridersArray[$rider]['cpLastHitUnix'] = $last_cpDataResult['fixUnix']; } } $i++; } else { //$sql_name = "SELECT * FROM " . $eventTable . "_rc WHERE imei = '" . $data['imei'] . "'"; //$resultName = mysqli_query($conn, $sql_name); //$deviceData = mysqli_fetch_assoc($resultName); $rider = preg_replace("/[^A-Za-z0-9]/", "", $deviceData['nameExt']); $randomOffset = rand(0, 1000) / 2000; if (!$deviceData['scratched']) { if($grouppedEvent && $groupColors[$deviceData['groupId']]){ $deviceData['color'] = $groupColors[$deviceData['groupId']]; // Groups get same color } } else { if ($deviceData['scratched'] == '4') { $deviceData['color'] = "#ff0000"; // Crew Color } else { $deviceData['color'] = "#000000"; // Scratched color } } if($grouppedEvent){ $startpointLat = $groupStartLocation[$deviceData['groupId']]['latitude']; $startpointLng = $groupStartLocation[$deviceData['groupId']]['longitude']; } $ridersArrayPreRace[$rider]['lastReport'] = 'Start '; $ridersArrayPreRace[$rider]['positionAbbrev'] = '-'; $ridersArrayPreRace[$rider]['teamNumber'] = $deviceData['teamNumber']; $ridersArrayPreRace[$rider]['country'] = $deviceData['country']; $ridersArrayPreRace[$rider]['riderName'] = $deviceData['nameExt']; $ridersArrayPreRace[$rider]['riderNameClean'] = $rider; $ridersArrayPreRace[$rider]['riderColor'] = $deviceData['color']; $ridersArrayPreRace[$rider]['dtf'] = floatval(0); $ridersArrayPreRace[$rider]['dtfKM'] = floatval(0); $ridersArrayPreRace[$rider]['groupId'] = $deviceData['groupId']; $ridersArrayPreRace[$rider]['groupFinish'] = $deviceData['groupFinish']; $ridersArrayPreRace[$rider]['deviceId'] = $deviceData['einsteinDeviceId']; $ridersArrayPreRace[$rider]['preraceCheck'] = $deviceData['preraceCheck']; $ridersArrayPreRace[$rider]['startDelay'] = $deviceData['startDelay']; $ridersArrayPreRace[$rider]['startTimeUnix'] = $groupStartTimes[$deviceData['groupId']] + ($deviceData['startDelay']*60); if(empty($deviceData['groupId']) ) { $deviceData['groupId'] = '1'; } $ridersArrayPreRace[$rider]['groupId'] = $deviceData['groupId']; $ridersArrayPreRace[$rider]['groupFinish'] = $deviceData['groupFinish']; // Make the dot visible x minutes before the start of the participant $timeToStartParticipant = ($ridersArrayPreRace[$rider]['startTimeUnix'] - time()) /60; // in MINUTES if( !empty($config_showDotsPreRace) && ($timeToStartParticipant <= $config_showDotsPreRace) ) { // 24 HRS before the race, show dots. if($timeToStartParticipant <= 1440) { // 24 HRS before the race, show dots. $timeToRequest = $ridersArrayPreRace[$rider]['startTimeUnix']; $timeToRequest = $timeToRequest - (1440*60); // Check if the array is made and filled, if so there is no need to call Traccar again. if( isset($traccar_data_array) && !empty($traccar_data_array) ) { } else { $traccar_data_array = array(); // Request al last known device positions at once from Traccer require_once './config/config.db.einstein.php'; $sql = "SELECT a.id as devices_deviceid, a.*, b.* FROM einstein2.tc_devices a LEFT JOIN einstein2.tc_positions b ON b.id = a.positionid WHERE lastupdate IS NOT NULL AND fixtime >= '".gmdate("Y-m-d\TH:i:s", $timeToRequest)."'"; $result_prerace = mysqli_query($einstein_conn, $sql); while ($device = $result_prerace->fetch_assoc()) { $traccar_data_array[$device['uniqueid']] = $device; } $einstein_conn->close(); } $this_device = $traccar_data_array[$deviceData[1]]; // Why do I need to use 1 and don't I just have the imei field filled like in race mode? ??? $ridersArrayPreRace[$rider]['latitude'] = $this_device['latitude']; $ridersArrayPreRace[$rider]['longitude'] = $this_device['longitude']; } else { $ridersArrayPreRace[$rider]['latitude'] = $startpointLat; $ridersArrayPreRace[$rider]['longitude'] = $startpointLng + ((($randomOffset - 0.5) / 350) * 1.1); } } if(isset($groupHeaderLabels)){ $ridersArrayPreRace[$rider]['groupHeaderLabel'] = $groupHeaderLabels[$deviceData['groupId']]; } } } /************************************************/ /* Overall Ranking */ /************************************************/ $overallRidersArray = []; $overallFinishers = []; $overallNotFinishers = []; // Split finishers and non-finishers foreach ($ridersArray as $rider) { if($rider['scratched'] <= 1 ) { // Only use active riders and DNF in overall ranking, not DNS DSQ & Crew if (!empty($rider['finishTime'])) { $overallFinishers[$rider['riderNameClean']] = $rider; } else { $overallNotFinishers[$rider['riderNameClean']] = $rider; } } } // OVERALL SORTING -> FINISHERS $col = array_column( $overallFinishers, $config_sortFinished ); if($config_sortFinishedOrder == "SORT_DESC") { array_multisort($col, SORT_DESC, $overallFinishers ); } else { array_multisort($col, SORT_ASC, $overallFinishers ); } // OVERALL SORTING -> NON FINISHERS $col = array_column( $overallNotFinishers, $config_sortActive ); if($config_sortActiveOrder == "SORT_DESC") { array_multisort($col, SORT_DESC, $overallNotFinishers ); } else { array_multisort($col, SORT_ASC, $overallNotFinishers ); } // MERGE FINISHERS AND NON FINISHERS BACK TO OVERALL ARRAY $overallRidersArray = array_merge($overallFinishers, $overallNotFinishers); // Add rank and label to each participant and put back in the original ridersarray for further use $i = 1; foreach ($overallRidersArray as $rider) { $ridersArray[$rider['riderNameClean']]['position_overall'] = $i; $ends = array( 'th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'); if (($i % 100) >= 11 && ($i % 100) <= 13) { $ridersArray[$rider['riderNameClean']]['position_overall_abbrev'] = $i . 'th'; } else { $ridersArray[$rider['riderNameClean']]['position_overall_abbrev'] = $i . $ends[$i % 10]; } $i++; } /*************************************************************/ /* Split Riders up in Group Arrays */ /*************************************************************/ $groupRidersArray = array(); foreach ($ridersArray as $key => $item) { $groupRidersArray[$item['groupId']][$key] = $item; } ksort($groupRidersArray, SORT_NUMERIC); // Splits riders into subarrays based on group ID $arr_counter = 1; foreach ($groupRidersArray as $ridersArray) { /************************************************/ /* Prepare Sort Array */ /************************************************/ // Main Arrays $finishers = []; $notFinishers = []; foreach ($ridersArray as $rider) { if (!empty($rider['finishTime'])) { $finishers[$rider['riderNameClean']] = $rider; } else { $notFinishers[$rider['riderNameClean']] = $rider; } } /************************************************/ /* Sort Finishers on time */ /************************************************/ $col = array_column( $finishers, $config_sortFinished ); if($config_sortFinishedOrder == "SORT_DESC") { array_multisort($col, SORT_DESC, $finishers ); } else { array_multisort($col, SORT_ASC, $finishers ); } /***********************************************************/ /* Sort on CP Count (Free Route) */ /***********************************************************/ if ($config_sortActive == 'checkpointCount') { $col_a = array_column( $notFinishers, 'cpCounter' ); $col_b = array_column( $notFinishers, 'cpLastHitUnix' ); array_multisort($col_a, SORT_DESC, $col_b, SORT_ASC, $notFinishers ); } else if ($config_sortActive == 'checkpointScore') { /************************************************/ /* Sortin on CP Score */ /************************************************/ foreach ($notFinishers as $key => $value) { if( empty($value['cpLastHitUnix']) ) { $notFinishers['riderNameClean']['cpLastHitUnix'] = $value['teamNumber']; // If no CP's yet, keep sorting on start number $notFinishers['riderNameClean']['cpScore'] = 0; $notFinishers['riderNameClean']['cpLastCP'] = ""; } } $col_a = array_column( $notFinishers, 'cpScore' ); $col_b = array_column( $notFinishers, 'cpLastHitUnix' ); array_multisort($col_a, SORT_DESC, $col_b, SORT_ASC, $notFinishers ); } else { /************************************************/ /* Default Sorting */ /************************************************/ $col = array_column( $notFinishers, $config_sortActive ); if($config_sortActiveOrder == "SORT_DESC") { array_multisort($col, SORT_DESC, $notFinishers ); } else { array_multisort($col, SORT_ASC, $notFinishers ); } } /************************************************/ /* Merge Sorted Arrays */ /************************************************/ $ridersArray = array_merge($finishers, $notFinishers); /************************************************/ /* Drop DNS & Crew visually */ /************************************************/ foreach ($ridersArray as $rider) { if($rider['scratched'] == '2') { unset($ridersArray[ $rider['riderNameClean']]); // Remove DNS rider $ridersArray[ $rider['riderNameClean']] = $rider; // re-add crew DNS to array to make them drop in position visually } } foreach ($ridersArray as $rider) { if($rider['scratched'] == '4') { unset($ridersArray[ $rider['riderNameClean']]); // Remove crew rider $ridersArray[ $rider['riderNameClean']] = $rider; // re-add crew rider to array to make them drop in position visually } $arr_counter = $rider['groupId']; // HACK RADX } $groupRidersArray[$arr_counter] = $ridersArray; // put updated array back in group array $arr_counter++; } /********************************************/ /* Sort Pre-Race */ /********************************************/ $col = array_column( $ridersArrayPreRace, $config_sortPreRace ); if($config_sortPreRaceOrder == "SORT_DESC") { array_multisort($col, SORT_DESC, $ridersArrayPreRace ); } else { array_multisort($col, SORT_ASC, $ridersArrayPreRace ); } /************************************************/ /* Add ranking and data */ /************************************************/ $firstKey = array_key_first($groupRidersArray); if( isset($groupRidersArray[$firstKey]) ) { $leaderArray = array_shift(array_values($groupRidersArray[$firstKey])); // hack to focus on leader $leaderPosition = "" . $leaderArray['longitude'] . "," . $leaderArray['latitude'] . ""; } foreach ($groupRidersArray as $ridersArray) { $i = 1; $distanceLeader = 0; $distancePreviousParticipant = 0; foreach ($ridersArray as $rider) { // Distance to leader $distanceLeader = $ridersArray[array_key_first($ridersArray)]['totalDistance']; $distanceToLeader = round($distanceLeader-$rider['totalDistance'],2); $ridersArray[$rider['riderNameClean']]['distanceToLeader'] = $distanceToLeader; // Distance to next participant up ahead if($distancePreviousParticipant){ $distanceToNextParticipant = round($distancePreviousParticipant-$rider['totalDistance'],2); $ridersArray[$rider['riderNameClean']]['distanceToNextParticipant'] = $distanceToNextParticipant; } // ETA if(isset($rider['routeSpeedMoving'])) { //if ($rider['lastReportMins'] >= 1440){ $distanceToGo = round($rider['totalTrackDistance']-$rider['totalDistance'],2); $eta_sec = calculate_eta($distanceToGo,$rider['routeSpeedMoving']); $eta = sec2elapsed($eta_sec); $eta = str_replace('0 d ', '', $eta); $eta = str_replace('00 h ', '', $eta); $ridersArray[$rider['riderNameClean']]['eta'] = $eta; $ridersArray[$rider['riderNameClean']]['eta_sec'] = $eta_sec; //} } $ridersArray[$rider['riderNameClean']]['position'] = $i; $ends = array( 'th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'); $arr_counter = $rider['groupId']; // HACK RADX if (($i % 100) >= 11 && ($i % 100) <= 13) { $ridersArray[$rider['riderNameClean']]['positionAbbrev'] = $i . 'th'; } else { $ridersArray[$rider['riderNameClean']]['positionAbbrev'] = $i . $ends[$i % 10]; } $ridersArrayRebuild[] = $ridersArray[$rider['riderNameClean']]; $groupRidersArray[$arr_counter] = $ridersArray; // Put updated array back in the group array. $distancePreviousParticipant = $rider['totalDistance']; unset($eta); $i++; } } } if( isset($ridersArrayRebuild) ) { foreach ($ridersArrayRebuild as $value) { $ridersArrayRebuildNew[$value['riderNameClean']] = $value; } $ridersArray = $ridersArrayRebuildNew; // Rebuild the original riderArray again. } // get the leader array to be used on the replay iframe include $riderKeys = array_keys($ridersArray); $groupPreRaceRidersArray = array(); foreach ($ridersArrayPreRace as $key => $item) { $groupPreRaceRidersArray[$item['groupId']][$key] = $item; } ksort($groupPreRaceRidersArray, SORT_NUMERIC); ?>