Chris1165 Posted January 24, 2012 Report Posted January 24, 2012 There's an excellent post on this forum for calculating percentage complete. After scratching my head figuring out why this wouldn't work for me, I realized that xacars, and subsequently kacars as well, does not calculate distance remaining. Which explains why this data never shows up on my map. I modifed ACARS.PHP to manually calculate the distance remaining no matter what client you're using. I've only tested this with xacars client. I'll also post the percentage complete code here as well as I've modified that slightly. ASCARS.PHP located in core/modules/ACARS <?php /** * phpVMS - Virtual Airline Administration Software * Copyright (c) 2008 Nabeel Shahzad * For more information, visit www.phpvms.net * Forums: http://www.phpvms.net/forum * Documentation: http://www.phpvms.net/docs * * phpVMS is licenced under the following license: * Creative Commons Attribution Non-commercial Share Alike (by-nc-sa) * View license.txt in the root, or visit http://creativecommons.org/licenses/by-nc-sa/3.0/ * * @author Nabeel Shahzad * @copyright Copyright (c) 2008, Nabeel Shahzad * @link http://www.phpvms.net * @license http://creativecommons.org/licenses/by-nc-sa/3.0/ */ class ACARS extends CodonModule { public $title = 'ACARS'; public $acarsflights; public function index() { $this->viewmap(); } public function viewmap() { $this->title = 'ACARS Map'; $this->set('acarsdata', ACARSData::GetACARSData()); $this->render('acarsmap.tpl'); } /** * We didn't list a function for each ACARS client, * so call this, which will include the acars peice in */ public function __call($name, $args) { $acars_action = $args[0]; // clean the name... $name = preg_replace("/[^a-z0-9-]/", "", strtolower($name)); if(dirname(__FILE__).DS.$name.'.php') { include_once dirname(__FILE__).DS.$name.'.php'; return; } } public function data() { $flights = ACARSData::GetACARSData(); if(!$flights) $flights = array(); $this->acarsflights = array(); foreach($flights as $flight) { if($flight->route == '') { $flight->route_details = array(); } else { //$flight->route_details = NavData::parseRoute($flight->route); # Jeff's fix for ACARS $params->deplat = $flight->deplat; $params->deplng = $flight->deplng; $params->route = $flight->route; $flight->route_details = NavData::parseRoute($params); } $c = (array) $flight; // Convert the object to an array $c['pilotid'] = PilotData::GetPilotCode($c['code'], $c['pilotid']); $totaldistance = round(SchedulesData::distanceBetweenPoints($flight->deplat, $flight->deplng, $flight->arrlat, $flight->arrlng)); $percomplete = ABS(number_format(((($totaldistance - $flight->distremain) / $totaldistance) * 100), 2)); $c['percomplete'] = $percomplete; $totaldistance = round(SchedulesData::distanceBetweenPoints($flight->deplat, $flight->deplng, $flight->arrlat, $flight->arrlng)); /* ----------------------------------------------------------------------------------------- $flight->distremain is not valid when using xacar so, automatically calculate distance remaining by current lat/long and arrival lat/long.. ----------------------------------------------------------------------------------------- */ $radius = 6371.0090667; // earth mean radius defined by IUGG $dlon = $flight->lng- $flight->arrlng; $tempd = acos( sin(deg2rad($flight->lat)) * sin(deg2rad($flight->arrlat)) + cos(deg2rad($flight->lat)) * cos(deg2rad($flight->arrlat)) * cos(deg2rad($dlon))) * $radius; $mydis = $tempd * 0.539956803; // convert to nm $percomplete = ABS(number_format(((($totaldistance - $mydis) / $totaldistance) * 100), 2)); $c['distremain'] = ABS(number_format($mydis,1)); //$percomplete = ABS(number_format(((($totaldistance - $flight->distremain) / $totaldistance) * 100), 2)); $c['percomplete'] = $percomplete; // Normalize the data if($c['timeremaining'] == '') { $c['timeremaining'] == '-'; } if(trim($c['phasedetail']) == '') { $c['phasedetail'] = 'Enroute'; } /* If no heading was passed via ACARS app then calculate it This should probably move to inside the ACARSData function, so then the heading is always there for no matter what the calcuation is */ if($flight->heading == '') { /* Calculate an angle based on current coords and the destination coordinates */ $flight->heading = intval(atan2(($flight->lat - $flight->arrlat), ($flight->lng - $flight->arrlng)) * 180 / 3.14); //$flight->heading *= intval(180/3.14159); if(($flight->lng - $flight->arrlng) < 0) { $flight->heading += 180; } if($flight->heading < 0) { $flight->heading += 360; } } // Little one-off fixes to normalize data $c['pilotname'] = $c['firstname'] . ' ' . $c['lastname']; unset($c['messagelog']); $this->acarsflights[] = $c; continue; } CodonEvent::Dispatch('refresh_acars', 'ACARS'); echo json_encode($this->acarsflights); } public function routeinfo() { if($this->get->depicao == '' || $this->get->arricao == '') return; $depinfo = OperationsData::GetAirportInfo($this->get->depicao); if(!$depinfo) { $depinfo = OperationsData::RetrieveAirportInfo($this->get->depicao); } $arrinfo = OperationsData::GetAirportInfo($this->get->arricao); if(!$arrinfo) { $arrinfo = OperationsData::RetrieveAirportInfo($this->get->arricao); } // Convert to json format $c = array(); $c['depapt'] = (array) $depinfo; $c['arrapt'] = (array) $arrinfo; echo json_encode($c); } public function fsacarsconfig() { $this->write_config('fsacars_config.tpl', Auth::$userinfo->code.'.ini'); } public function fspaxconfig() { $this->write_config('fspax_config.tpl', Auth::$userinfo->code.'_config.cfg'); } public function xacarsconfig() { $this->write_config('xacars_config.tpl', 'xacars.ini'); } /** * Write out a config file to the user, give the template name and * the filename to save the template as to the user * * @param mixed $template_name Template to use for config (fspax_config.tpl) * @param mixed $save_as File to save as (xacars.ini) * @return mixed Nothing, sends the file to the user * */ public function write_config($template_name, $save_as) { if(!Auth::LoggedIn()) { echo 'You are not logged in!'; break; } $this->set('pilotcode', PilotData::GetPilotCode(Auth::$userinfo->code, Auth::$userinfo->pilotid)); $this->set('userinfo', Auth::$userinfo); $acars_config = Template::GetTemplate($template_name, true); $acars_config = str_replace("\n", "\r\n", $acars_config); Util::downloadFile($acars_config, $save_as); } } Add the following to your style.css style.css located in your lib/skins/theme directory dl, dt, dd{margin:0;padding:0;} dd{ width:216px; height:41px; background:url(/lib/images/bg_bar.gif) no-repeat 0 0; position:relative; } dd span{ position:absolute; display:block; width:200px; height:25px; background:url(/lib/images/bar.gif) no-repeat 0 0; top:8px; left:8px; overflow:hidden; text-indent:-8000px; } dd em{ position:absolute; display:block; width:200px; height:25px; background:url(/lib/images/bg_cover.gif) repeat-x; top:0; } acarsmap.tpl located in core/templates <?php /** * These are some options for the ACARS map, you can change here * * By default, the zoom level and center are ignored, and the map * will try to fit the all the flights in. If you want to manually set * the zoom level and center, set "autozoom" to false. * * You can use these MapTypeId's: * http://code.google.com/apis/maps/documentation/v3/reference.html#MapTypeId * * Change the "TERRAIN" to the "Constant" listed there - they are case-sensitive * * Also, how to style the acars pilot list table. You can use these style selectors: * * table.acarsmap { } * table.acarsmap thead { } * table.acarsmap tbody { } * table.acarsmap tbody tr.even { } * table.acarsmap tbody tr.odd { } */ ?> <script type="text/javascript"> <?php /* These are the settings for the Google map. You can see the Google API reference if you want to add more options. There's two options I've added: autozoom: This will automatically center in on/zoom so all your current flights are visible. If false, then the zoom and center you specify will be used instead refreshTime: Time, in seconds * 1000 to refresh the map. The default is 10000 (10 seconds) */ ?> var acars_map_defaults = { autozoom: true, zoom: 4, center: new google.maps.LatLng("<?php echo Config::Get('MAP_CENTER_LAT'); ?>", "<?php echo Config::Get('MAP_CENTER_LNG'); ?>"), mapTypeId: google.maps.MapTypeId.TERRAIN, refreshTime: 10000 }; </script> <div class="mapcenter" align="center"> <div id="acarsmap" style="width:<?php echo Config::Get('MAP_WIDTH');?>; height: <?php echo Config::Get('MAP_HEIGHT')?>"></div> </div> <?php /* See below for details and columns you can use in this table */ ?> </div> <table border = "0" width="100%" class="acarsmap"> <thead> <tr> <td><b>Pilot</b></td> <td><b>Flight Number</b></td> <td><b>Departure</b></td> <td><b>Arrival</b></td> <td><b>Status</b></td> <td><b>Altitude</b></td> <td><b>Speed</b></td> <td><b>Distance/Time Remain</b></td> <td><b>Percent Complete</b></td> </tr> </thead> <tbody id="pilotlist"></tbody> </table> <script type="text/javascript" src="<?php echo fileurl('/lib/js/acarsmap.js');?>"></script> <?php /* This is the template which is used in the table above, for each row. Be careful modifying it. You can simply add/remove columns, combine columns too. Keep each "section" (<%=...%>) intact Variables you can use (what they are is pretty obvious) Variable: Notes: <%=flight.pilotid%> <%=flight.firstname%> <%=flight.lastname%> <%=flight.pilotname%> First and last combined <%=flight.flightnum%> <%=flight.depapt%> Gives the airport name <%=flight.depicao%> <%=flight.arrapt%> Gives the airport name <%=flight.arricao%> <%=flight.phasedetail%> <%=flight.heading%> <%=flight.alt%> <%=flight.gs%> <%=flight.disremaining%> <%=flight.timeremaning%> <%=flight.aircraft%> Gives the registration <%=flight.aircraftname%> Gives the full name <%=flight.client%> FSACARS/Xacars/FSFK, etc <%=flight.trclass%> "even" or "odd" <%=flight.percomplete%> You can also use logic in the templating, if you so choose: http://ejohn.org/blog/javascript-micro-templating/ */ ?> <script type="text/html" id="acars_map_row"> <tr class="<%=flight.trclass%>"> <td><a href="<?php echo url('/profile/view');?>/<%=flight.pilotid%>"><%=flight.pilotid%> - <%=flight.pilotname%></a></td> <td><%=flight.flightnum%></td> <td><%=flight.depicao%></td> <td><%=flight.arricao%></td> <td><%=flight.phasedetail%></td> <td><%=flight.alt%></td> <td><%=flight.gs%></td> <td><%=flight.distremain%> <?php echo Config::Get('UNITS');?> / <%=flight.timeremaining%></td> <td> <dd> <span><%=flight.percomplete%>%<em style="left:<%=flight.percomplete * 2%>px"><%=flight.percomplete%>%"></em><%=flight.percomplete%>%</span> </dd> <!-- deleted --> </td> </tr> </script> <?php /* This is the template for the little map bubble which pops up when you click on a flight Same principle as above, keep the <%=...%> tags intact. The same variables are available to use here as are available above. */ ?> <script type="text/html" id="acars_map_bubble"> <span style="font-size: 10px; text-align:left; width: 100%" align="left"> <a href="<?php echo url('/profile/view');?>/<%=flight.pilotid%>"><%=flight.pilotid%> - <%=flight.pilotname%></a><br /> <strong>Flight <%=flight.flightnum%></strong> (<%=flight.depicao%> to <%=flight.arricao%>)<br /> <strong>Status: </strong><%=flight.phasedetail%><br /> <strong>Dist/Time Remain: </strong><%=flight.distremain%> <?php echo Config::Get('UNITS');?> / <%=flight.timeremaining%><br /> </span> </script> <?php /* This is a small template for information about a navpoint popup Variables available: <%=nav.title%> <%=nav.name%> <%=nav.freq%> <%=nav.lat%> <%=nav.lng%> <%=nav.type%> 2=NDB 3=VOR 4=DME 5=FIX 6=TRACK */ ?> <script type="text/html" id="navpoint_bubble"> <span style="font-size: 10px; text-align:left; width: 100%" align="left"> <strong>Name: </strong><%=nav.title%> (<%=nav.name%>)<br /> <strong>Type: </strong> <?php /* Show the type of point */ ?> <% if(nav.type == 2) { %> NDB <% } %> <% if(nav.type == 3) { %> VOR <% } %> <% if(nav.type == 4) { %> DME <% } %> <% if(nav.type == 5) { %> FIX <% } %> <% if(nav.type == 6) { %> TRACK <% } %> <br /> <?php /* Only show frequency if it's not a 0*/ ?> <% if(nav.freq != 0) { %> <strong>Frequency: </strong><%=nav.freq%> <% } %> </span> </script> For the animated percentage bar, place the three gif's (bar.gif, bg_cover.gif and bg_bar.gif) in your lib/images directory. Also, keep in mind I'm not using the variable flight.distremaining on the TPL's (templates). I'm using <%=flight.distremain%>. If anyone finds this information useful, let me know. Quote
Jeff Posted January 25, 2012 Report Posted January 25, 2012 Very nice, and works extremely well. Quote
Jeff Posted January 25, 2012 Report Posted January 25, 2012 I have a slight problem when using this. I already use dd, dt and dl in my css, and it is interfering with my registration and log-in pages. The forms on those pages are showing the images from your css code. Your code in css dl, dt, dd { margin:0;padding:0;}dd { width:216px; height:41px; background:url(/lib/images/bg_bar.gif) no-repeat 0 0; position:relative;}dd span{ position:absolute; display:block; width:200px; height:25px; background:url(/lib/images/bar.gif) no-repeat 0 0; top:8px; left:8px; overflow:hidden; text-indent:-8000px; } dd em { position:absolute; display:block; width:200px; height:25px; background:url(/lib/images/bg_cover.gif) repeat-x; top:0; } My css that controls the forms on registration and log-in dl { position: relative; width: 730px; z-index: 100; clear: both; } dt { clear: both; float: left; width: 180px; padding: 0px 0 2px 0; text-align: left; font-size: 12px; font-weight: bold; } dd { float: left; width: 520px; margin: 0 0 8px 0; padding-left: 6px; font-size: 12px; } dd button { } dd p { margin-top: 0px; } dd input { width: 300px; padding: 3px; margin-bottom: 3px; z-index: 500; } How can I solve this so they aren't conflicting each other? Quote
Chris1165 Posted January 26, 2012 Author Report Posted January 26, 2012 I have a slight problem when using this. I already use dd, dt and dl in my css, and it is interfering with my registration and log-in pages. The forms on those pages are showing the images from your css code. [ My css that controls the forms on registration and log-in [ How can I solve this so they aren't conflicting each other? You can rename them in the css and your template file.. Try this: percentdd{ width:216px; height:41px; background:url(/lib/images/bg_bar.gif) no-repeat 0 0; position:relative; } percentdd span{ position:absolute; display:block; width:200px; height:25px; background:url(/lib/images/bar.gif) no-repeat 0 0; top:8px; left:8px; overflow:hidden; text-indent:-8000px; } percentdd em{ position:absolute; display:block; width:200px; height:25px; background:url(/lib/images/bg_cover.gif) repeat-x; top:0; } And change your ascars.map file to: <percentdd> <span><%=flight.percomplete%>%<em style="left:<%=flight.percomplete * 2%>px"><%=flight.percomplete%>%"></em><%=flight.percomplete%>%</span> </percentdd> That should solve any conflict. I believe you can name the css tag to just about anything you want. I should have realized that someone might be using those tags and made something more generic. Quote
Jeff Posted January 26, 2012 Report Posted January 26, 2012 Thanks. Worked, and I knew it was a simple fix. Quote
Chris1165 Posted January 27, 2012 Author Report Posted January 27, 2012 Thanks. Worked, and I knew it was a simple fix. Fantastic! Quote
Moderators mark1million Posted January 27, 2012 Moderators Report Posted January 27, 2012 This does work for xacars but for displaying distance remaining in kACARS it removes the variable and you get a blank distance remaining for other clients. Quote
CarlosGarcia Posted February 6, 2012 Report Posted February 6, 2012 Using XAcars with X-plane 9.70 Dont work for me I can get the Time remaining <%=flight.timeremaining%> and Bar Graphics to work. The Distance Reaming works good. I replace core/modules/ACARS acars.php (In your post says ASCARS.PHP but i think is not the right file name) file with the code you post, Add the css to my liv/skyns/CGA ( the name of my Skyn is CGA)css and add the Gif files to lib/images directory.. and acarsmap.tpl to the core/templates. Any idea, Carlos Garcia Acevedo SKBQ Barranquilla Colombia Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.