Jump to content

Flight Route on Live ACARS Map


stuartpb

Recommended Posts

EDITED ON 20/03/14 - FORGOT ABOUT 3RD FILE AMEND AND ADDED SOME OPTIONAL TWEAKS.

If like me, you want to have the route for each live flight shown on the ACARS map, you can make the amendments to three files in order to do so. I've tested this on a custom KACARS install. This will work for scheduled and charter flights as long as a route is entered either in the schedule, or entered into the ACARS program. If a route doesn't exist in the schedule, or one isn't entered in the ACARS program, a straight point to point line will be shown.

Files to edit:

​​Make backups of these two files before you proceed!!

  1. /core/modules/ACARS/ACARS.php
  2. /common/NavData.class.php
  3. /lib/js/acarsmap.js

Edit Number 1 - ACARS.php

Find the following line:


$flight->route_details = NavData::parseRoute($flight->route);

And replace with:


$flight->route_details = NavData::parseRouteACARS($flight);

Once you've made the change, save the file and upload to your server, overwriting the existing file.

Edit Number 2 - NavData.class.php

Find the line that contains this code:

return $allpoints;
}

AFTER the } on a new line, add the following code:

public static function parseRouteACARS($flight)
{
$routeairport = OperationsData::GetAirportInfo($flight->depicao);
$fromlat = $routeairport->lat;
$fromlng = $routeairport->lng;
$route_string = $flight->route;

if($route_string == '')
{
return array();
}
// Remove any SID/STAR text
$route_string = str_replace('SID', '', $route_string);
$route_string = str_replace('STAR', '', $route_string);

$navpoints = array();
$all_points = explode(' ', $route_string);

foreach($all_points as $key => $value)
{
if(empty($value) === true)
{
continue;
}

$navpoints[] = strtoupper(trim($value));
}

$allpoints = array();
$total = count($navpoints);
$airways = self::getAirways($navpoints);

for($i = 0; $i < $total; $i++)
{
$name = self::cleanName($navpoints[$i]);
/* the current point is an airway, so go through
the airway list and add each corresponding point
between the entry and exit to the list. */
if(isset($airways[$name]))
{
$entry_name = self::cleanName($navpoints[$i-1]);
$exit_name = self::cleanName($navpoints[$i+1]);

$entry = self::getPointIndex($entry_name, $airways[$name]);
$exit = self::getPointIndex($exit_name, $airways[$name]);

if($entry == -1)
{
 $entry = $exit;
}
else
{
 /* Add information abotu the entry point in first,
 if it's valid and exists */
 $allpoints[$entry_name] = $airways[$name][$entry];
}

if($exit == -1)
{
 continue;
}

if($entry < $exit)
{
 # Go forwards through the list adding each one
 for($l=$entry; $l<=$exit; $l++)
 {
 $allpoints[$airways[$name][$l]->name] = $airways[$name][$l];
 }
}
elseif($entry > $exit)
{
 # Go backwards through the list
 for($l=$exit; $l>=$entry; $l--)
 {
 $point_name = self::cleanName($airways[$name][$l]->name);
 $allpoints[$point_name] = $airways[$name][$l];
 }
}
elseif($entry == $exit)
{
 $point_name = self::cleanName($airways[$name][$l]->name);
 $allpoints[$point_name] = $airways[$name][$entry];
}

# Now add the exit point, and increment the main counter by one
if($exit > -1)
{
 $allpoints[$exit_name] = $airways[$name][$exit];
}

continue;
}
else
{
/* This nav point already exists in the list, don't add it
 again */
if(isset($allpoints[$navpoints[$i]]))
{
 continue;
}

/* Means it is a track, so go into processing it
 See if it's something like XXXX/YYYY
 */
if(substr_count($navpoints[$i], '/') > 0)
{
 $name = $navpoints[$i];
 $point_name = explode('/', $name);

 preg_match(self::$nat_pattern, $point_name[0], $matches);

 $coord = $matches[1];
 $lat = $matches[2].$coord[0].$coord[1].'.'.$coord[2].$coord[3];

 /* Match the second set of coordinates */

 # Read the second set
 preg_match(self::$nat_pattern, $point_name[1], $matches);
 if($matches == 0)
 {
 continue;
 }

 $coord = $matches[1];
 $lng = $matches[2].$coord[0].$coord[1].$coord[2].'.'.$coord[3];

 /* Now convert into decimal coordinates */
 $coords = $lat.' '.$lng;
 $coords = Util::get_coordinates($coords);

 if(empty($coords['lat']) || empty($coords['lng']))
 {
 unset($allpoints[$navpoints[$i]]);
 continue;
 }

 $tmp = new stdClass();
 $tmp->id = 0;
 $tmp->type = NAV_TRACK;
 $tmp->name = $name;
 $tmp->title = $name;
 $tmp->lat = $coords['lat'];
 $tmp->lng = $coords['lng'];
 $tmp->airway = '';
 $tmp->sequence = 0;
 $tmp->freq = '';

 $allpoints[$navpoints[$i]] = $tmp;	
 unset($point_name);
 unset($matches);
 unset($tmp);
}
else
{
 $allpoints[$navpoints[$i]] = $navpoints[$i];
 $navpoint_list[] = $navpoints[$i];
}
}
}

$navpoint_list_details = self::getNavDetails($navpoint_list);

foreach($navpoint_list_details as $point => $list)
{
$allpoints[$point] = $list;
}

unset($navpoint_list_details);

/* How will this work - loop through each point, and
decide which one we'll use, determined by the
one which is the shortest distance from the previous

Go in the order of the ones passed in.
*/

foreach($allpoints as $point_name => $point_details)
{
if(is_string($point_details))
{
unset($allpoints[$point_name]);
continue;
}

if(!is_array($point_details))
{
continue;
}

$results_count = count($point_details);

if($results_count == 1)
{
$allpoints[$point_name] = $point_details[0];
}
elseif($results_count > 1)
{
/* There is more than one, so find the one with the shortest
 distance from the previous point out of all the ones */

$index = 0; $dist = 0;

/* Set the inital settings */
$lowest_index = 0;
$lowest = $point_details[$lowest_index];
$lowest_dist = SchedulesData::distanceBetweenPoints($fromlat, $fromlng, $lowest->lat, $lowest->lng);

foreach($point_details as $p)
{
 $dist = SchedulesData::distanceBetweenPoints($fromlat, $fromlng, $p->lat, $p->lng);

 if($dist < $lowest_dist)
 {
 $lowest_index = $index;
 $lowest_dist = $dist;
 }

 $index++;
}

$allpoints[$point_name] = $point_details[$lowest_index];
}

$fromlat = $allpoints[$point_name]->lat;
$fromlng = $allpoints[$point_name]->lng;
}

return $allpoints;
}

Once you've made the change, save the file and upload to your server, overwriting the existing file.

Edit Number 3 - acarsmap.js

Open the acarsmap.js file, and find the following code. If you are using the default file, it should be on lines 148 & 149

if(this.flightdetails.route_details.length > 0)
{

Remove this code

Then remove the closing bracket for the if statement, which again if you are using the default file will be on line 182.

Once you've made the change, save the file and upload to your server, overwriting the existing file.

TEST

Now when you visit your live flights ACARS map, when you click on an ongoing flight, the route should be displayed in red. I'm going to work on plotting the flown route alongside the planned route next.

Cheers,

Stuart

EXAMPLE:

Capture.PNG

Optional Amend To acarsmap.js

I found that when I made the following amends, the plotted line for the flight route stayed on the map. If you want to remove the line when a user clicks the map, you can make the following amend:

On this block of code, you will see that the clearPreviousMarkers function call is commented out for the map click event.

// They clicked the map
google.maps.event.addListener(map, 'click', function()
{
//clearPreviousMarkers();
});

Just uncomment the function call, so the block of code looks like this:

// They clicked the map
google.maps.event.addListener(map, 'click', function()
{
clearPreviousMarkers();
});

Another Optional Edit - acarsmap.js

In the example image above you can see that the fix, vor and aircraft icons are sitting above the flight path. This was annoying me, as I think it would be much neater if the icons are centred on the flight path. The reason they are sitting above is because you have to specify an offset for icons when using Google Maps. The offset would be half the icon height, and half the icon width.

Please note: If you have changed the default icons, you need to amend the second offset point to half the width and half the height of the icons.

So I've made a mod to the acarsmap.js file to include the offset.

Step 1: The in-flight directional icon:

Find the following code:

var pos = new google.maps.LatLng(lat, lng);
flightMarkers[flightMarkers.length] = new google.maps.Marker({
position: pos,
map: map,
icon: url+"/lib/images/inair/"+data[i].heading+".png",
flightdetails: data[i],
infowindow_content: detailed_bubble
});

Replace with this code:

var pos = new google.maps.LatLng(lat, lng);
var flightpos = new google.maps.MarkerImage("/lib/images/inair/"+data[i].heading+".png",
null,
new google.maps.Point(0,0),
new google.maps.Point(17, 17)
);
flightMarkers[flightMarkers.length] = new google.maps.Marker({
position: pos,
map: map,
icon: flightpos,
flightdetails: data[i],
infowindow_content: detailed_bubble,
zIndex:200
});

This takes care of the in-flight directional icon.

Step 2: VOR & FIX Icons

Find the following code:

var loc = new google.maps.LatLng(nav.lat, nav.lng);

		 if(nav.type == 3)
			 icon = "icon_vor.png";
		 else
			 icon = "icon_fix.png";

		 var navpoint_info = tmpl("navpoint_bubble", {nav: nav});
		 routeMarkers[routeMarkers.length] = new google.maps.Marker({
		 position: loc,
		 map: map,
		 icon: url + "/lib/images/"+icon,
		 title: nav.title,
		 zIndex: 100,
		 infowindow_content: navpoint_info
		 });

Replace with:

var loc = new google.maps.LatLng(nav.lat, nav.lng);

		 if(nav.type == 3)
			 var image = new google.maps.MarkerImage("/lib/images/icon_vor.png",
 null,
 new google.maps.Point(0,0),
 new google.maps.Point(10, 10)
 );
		 else
 var image = new google.maps.MarkerImage("/lib/images/icon_fix.png",
 null,
 new google.maps.Point(0,0),
 new google.maps.Point(10, 10)
 );

		 var navpoint_info = tmpl("navpoint_bubble", {nav: nav});
		 routeMarkers[routeMarkers.length] = new google.maps.Marker({
		 position: loc,
		 map: map,
		 icon: image,
		 title: nav.title,
		 zIndex: 100,
		 infowindow_content: navpoint_info
		 });

Then save the file and upload to your server. You should now have centred icons along your flight path, as shown below:

newcapt.PNG

I think this looks much neater :-)

Further edit:

I just found that the in-flight directional icon was sitting under the nav and fix icons when they were close together. This is because there is a Z-Index value set for the nav and fix icons but not one set for the other icon. This is an easy fix and I've amended the code on step one of this amend to include it. I just added a Z-Index value for the in-flight icon that is higher than that of the other two icons.

  • Like 3
Link to comment
Share on other sites

Thank you also for this "mod" script. So have you an idea howto put SID/STAR in the phpvms_navdata tavle or other to give all the route in the LiveMap

I see that :

// Remove any SID/STAR text
$route_string = str_replace('SID', '', $route_string);
$route_string = str_replace('STAR', '', $route_string);

But I have no idea to parse all points include SID/STAR to the route...

Maybe some one can help us?

@

Ademar I have ssen you have make a script with Fernando via PM to have an IVAO table, Can you please share with us? or not

Regards Fred

Link to comment
Share on other sites

I am stuck on step one. In ACARS.php. I dont have the line that I need to replace. Here is what I have.

# Jeff's fix for ACARS
$params->deplat = $flight->deplat;
$params->deplng = $flight->deplng;
$params->route = $flight->route;
$flight->route_details = NavData::parseRoute($params); 

I am assuming Jeff made an edit for my Custom ACARS

Link to comment
Share on other sites

I am stuck on step one. In ACARS.php. I dont have the line that I need to replace. Here is what I have.

# Jeff's fix for ACARS
$params->deplat = $flight->deplat;
$params->deplng = $flight->deplng;
$params->route = $flight->route;
$flight->route_details = NavData::parseRoute($params); 

I am assuming Jeff made an edit for my Custom ACARS

Just make that

# Jeff's fix for ACARS
$params->deplat = $flight->deplat;
$params->deplng = $flight->deplng;
$params->route = $flight->route;
//$flight->route_details = NavData::parseRoute($params);
$flight->route_details = NavData::parseRouteACARS($params);

Link to comment
Share on other sites

  • 4 weeks later...
  • 2 weeks later...

Hi

I'm going to work on plotting the flown route alongside the planned route next.

Are you able to do something like that?

I use kAcars free (as we know it is not possible to buy custom version). kAcars is simple to use but has some limitations. The most important for me is the fact, that kAcars doesn't check how the flight was flown. Let's say, a pilot declares, that he will fly from point A to B but in fact his flown route was from A to D. In the pirep I'll see A to B route and I won't know, that he did a different flight.

So, it would be great to see on flight map the planned and flown route. Or maybe there is some other way, to check the actual route?

Best Regards

Bartek

Link to comment
Share on other sites

  • 4 weeks later...
  • Members

indeed i had it first with airplain icon but i didnt like it so i put it just a line with an arrow the solution was to take the coordinated from the acars and save it in a temp table and after flight completion it is transfered to the pireps table

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...