Jump to content

NavData Airways Reverse Count Problem


Ither

Recommended Posts

Long time no talk all.

Hope everyone is well!

 

I've been fighting the navdata point display on the maps and have finally gotten it to point where I am happy, however I discovered an issue I can't quite figure out.

When you run the parseRoute to generate the waypoints on the live map; it goes through airways and finds the entry/exit and everything in between. This works fine when the entry to exit is position (going forward) but when it's backwards it doesn't pull anything.

 

I have this particular airway where I'm entering at sequence 36 - KULIS and exiting at sequence 20 - SIDAK. It will not pull the values for sequence 35 to 21.

 

Here is a JSON dump of the data after parsing;
 

route_details:
ANSOK: {id: "70025", name: "ANSOK", title: "", airway: "UZ42", airway_type: "H", …}
ASEGI: {id: "70035", name: "ASEGI", title: "", airway: "UZ42", airway_type: "H", …}
ASODA: {id: "70020", name: "ASODA", title: "", airway: "UZ42", airway_type: "H", …}
BCO: {id: "70037", name: "BCO", title: "", airway: "UZ42", airway_type: "H", …}
CLIZA: {id: "70033", name: "CLIZA", title: "", airway: "UZ42", airway_type: "H", …}
CPN: {id: "70030", name: "CPN", title: "", airway: "UZ42", airway_type: "H", …}
DANLI: {id: "70036", name: "DANLI", title: "", airway: "UZ42", airway_type: "H", …}
DUBDU: {id: "70031", name: "DUBDU", title: "", airway: "UZ42", airway_type: "H", …}
EKIDI: {id: "70040", name: "EKIDI", title: "", airway: "UZ42", airway_type: "H", …}
ENROD: {id: "70016", name: "ENROD", title: "", airway: "UZ42", airway_type: "H", …}
ENRUB: {id: "70015", name: "ENRUB", title: "", airway: "UZ42", airway_type: "H", …}
ESORU: {id: "70042", name: "ESORU", title: "", airway: "UZ42", airway_type: "H", …}
EVMIM: {id: "70027", name: "EVMIM", title: "", airway: "UZ42", airway_type: "H", …}
GEKEM: {id: "70019", name: "GEKEM", title: "", airway: "UZ42", airway_type: "H", …}
GENKO: {id: "70039", name: "GENKO", title: "", airway: "UZ42", airway_type: "H", …}
GRD: {id: "70014", name: "GRD", title: "", airway: "UZ42", airway_type: "H", …}
ILSAN: {id: "70029", name: "ILSAN", title: "", airway: "UZ42", airway_type: "H", …}
KULIS: {id: "57176", name: "KULIS", title: "KULIS", airway: "UM415", airway_type: "H", …}
LOKAM: {id: "70032", name: "LOKAM", title: "", airway: "UZ42", airway_type: "H", …}
MUPAG: {id: "70034", name: "MUPAG", title: "", airway: "UZ42", airway_type: "H", …}
NEKOP: {id: "70038", name: "NEKOP", title: "", airway: "UZ42", airway_type: "H", …}
NEVKU: {id: "70022", name: "NEVKU", title: "", airway: "UZ42", airway_type: "H", …}
OBLUG: {id: "70026", name: "OBLUG", title: "", airway: "UZ42", airway_type: "H", …}
OPLEM: {id: "70021", name: "OPLEM", title: "", airway: "UZ42", airway_type: "H", …}
PUMRO: {id: "70018", name: "PUMRO", title: "", airway: "UZ42", airway_type: "H", …}
SIDAK: {id: "69160", name: "SIDAK", title: "", airway: "UZ22", airway_type: "H", …}
UGOVU: {id: "70028", name: "UGOVU", title: "", airway: "UZ42", airway_type: "H", …}
UGPOP: {id: "70041", name: "UGPOP", title: "", airway: "UZ42", airway_type: "H", …}
UKLIM: {id: "70023", name: "UKLIM", title: "", airway: "UZ42", airway_type: "H", …}
UMSIL: {id: "69161", name: "UMSIL", title: "", airway: "UZ22", airway_type: "H", …}
UTLUP: {id: "70024", name: "UTLUP", title: "", airway: "UZ42", airway_type: "H", …}
VAGOR: {id: "69162", name: "VAGOR", title: "", airway: "UZ22", airway_type: "H", …}
VALEV: {id: "70017", name: "VALEV", title: "", airway: "UZ42", airway_type: "H", …}

 

Here is my entry waypoint

 

KULIS:
airway: "UM415"
airway_type: "H"
freq: ""
id: "57176"
lat: "-13.477331"
lng: "-74.951080"
loc: "SAM"
name: "KULIS"
seq: "36"
title: "KULIS"
type: "5"

 

You can see seq = 36, my exit waypoint for this is seq = 20.

 

SIDAK
AIRAWAY: UM415
SEQ: 20

 

Here's the function in NavData.class.php

 

public static function parseRoute($schedule) {
        $fromlat = $schedule->deplat;
        $fromlng = $schedule->deplng;
        $route_string = $schedule->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);
        $route_string = str_replace('DCT', '', $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;
    }

 

If anyone has any ideas I'm all ears--been plugging at this for about a week now.

 

Every single airway that is punched into route works without issue if the entry sequence number is less than exit sequence number so that it's moving forward in gathering the waypoint info.

Link to comment
Share on other sites

4 hours ago, Ither said:

Every single airway that is punched into route works without issue if the entry sequence number is less than exit sequence number so that it's moving forward in gathering the waypoint info.

Sounds like some sort of logic error to me.

 

 

Here's a couple of guesses:

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];
    }

 

there could be something going on with the name here as going backwards, the point name isn't 'cleaned' (through the cleanName function), so I would try changing these lines:

$point_name = self::cleanName($airways[$name][$l]->name);
$allpoints[$point_name] = $airways[$name][$l];

// TO THIS:

$allpoints[$airways[$name][$l]->name] = $airways[$name][$l];

and seeing if that does anything.

 

 

For these lines here:

if (isset($airways[$name])) {
    $entry_name = self::cleanName($navpoints[$i - 1]);
    $exit_name = self::cleanName($navpoints[$i + 1]);

because there's a bunch of looping happening afterwards, this could be something, so I would temporarily change it to this:

if (isset($airways[$name])) {
    $entry_name = self::cleanName($navpoints[$i + 1]);
    $exit_name = self::cleanName($navpoints[$i - 1]);

and see if it does the reverse (so the route is parsed correctly backwards instead of forwards). Just a hunch so I could be totally wrong.

 

 

5 hours ago, Ither said:

where I'm entering at sequence 36 - KULIS and exiting at sequence 20 - SIDAK. It will not pull the values for sequence 35 to 21.

Does this mean it's not in the output at all?

 

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

I would want to know if the $allpoints variable contains the correct airways/points at this stage before any of the parsing occurs. So before this line, you might want to dump it and see if the results are the same:

return $allpoints;

but phpVMS might not like the format of that, so you might have to return json_encode($allpoints) if you're logging it in the console or print_r($allpoints) if you have a url.

Link to comment
Share on other sites

  • 3 weeks later...
On 10/9/2020 at 5:40 PM, web541 said:

For these lines here:




if (isset($airways[$name])) {
    $entry_name = self::cleanName($navpoints[$i - 1]);
    $exit_name = self::cleanName($navpoints[$i + 1]);

because there's a bunch of looping happening afterwards, this could be something, so I would temporarily change it to this:




if (isset($airways[$name])) {
    $entry_name = self::cleanName($navpoints[$i + 1]);
    $exit_name = self::cleanName($navpoints[$i - 1]);

and see if it does the reverse (so the route is parsed correctly backwards instead of forwards). Just a hunch so I could be totally wrong.

So doing this above shows the waypoints that are missing, but they're in the wrong order (scrambled) but it at least found them.

 

I did dump the $allpoints before everything else and it doesn't include missing waypoints.

 

Here is route of flight I'm doing.

DCT GEG J153 REO DCT MYBAD MYBAD2

 

$allpoints before any processing.

{GEG: {…}, REO: {…}, MYBAD: "MYBAD", MYBAD2: "MYBAD2"}
GEG: {id: "17370", name: "GEG", title: "", airway: "J153", airway_type: "H", …}
MYBAD: "MYBAD"
MYBAD2: "MYBAD2"
REO: {id: "17365", name: "REO", title: "", airway: "J153", airway_type: "H", …}
__proto__: Object

 

What it's currently pulling.

{GEG: {…}, REO: {…}, MYBAD: {…}}
GEG: {id: "17017", name: "GEG", title: "GEG", airway: "J136", airway_type: "H", …}
MYBAD: {id: "36434", name: "MYBAD", title: "MYBAD", airway: "Q132", airway_type: "H", …}
REO: {id: "17365", name: "REO", title: "", airway: "J153", airway_type: "H", …}
__proto__: Object

 

What it's missing

BLUNT - J153 - SEQUENCE 5
CHASS - J153 - SEQUENCE 4
BEAMO - J153 - SEQUENCE 3
BKE - J153 - SEQUENCE 2
REO - J153 - SEQUENCE 1

 

Edited by Ither
Link to comment
Share on other sites

On 10/28/2020 at 11:12 AM, Ither said:

So doing this above shows the waypoints that are missing, but they're in the wrong order (scrambled) but it at least found them.

Hmm, that could be a start. Is there a pattern to it or is it truely random? And does the order stay the same if you run the same function twice or do the waypoints keep jumbling up?

 

 

On 10/28/2020 at 11:12 AM, Ither said:

I did dump the $allpoints before everything else and it doesn't include missing waypoints.

Was the first dump taken before this line:

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

or earlier in the function?

 

If that's the case then it's probably an issue within the loops somewhere as anything further than this line is just pulling waypoint info from your DB and ordering it (which seems to be working from your dumps).

Link to comment
Share on other sites

It's always -- if the entry to the airway is higher sequence number than the exit, thus it has to go backwards, it never pulls/adds the waypoints. If the entry is lower than exit sequence number it works fine.

 

I've done some more debugging. You can dig through full function above to piece in -- here's what I can tell.

 

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;
			}
                
            }
		
        return $allpoints;

 

The return $allpoints above gives me the entry (GEG) and exit (REO)

 

{GEG: {…}, REO: {…}}
GEG: {id: "17370", name: "GEG", title: "", airway: "J153", airway_type: "H", …}
REO: {id: "17365", name: "REO", title: "", airway: "J153", airway_type: "H", …}
__proto__: Object

 

Now when I return $airways instead I do get entire J153 airway including waypoints that are missing -- they are in order: BLUNT - CHASS - BEAMO - BKE

 

{J153: Array(8)}
J153: Array(8)
0: {id: "17365", name: "REO", title: "", airway: "J153", airway_type: "H", …}
1: {id: "17366", name: "BKE", title: "", airway: "J153", airway_type: "H", …}
2: {id: "17367", name: "BEAMO", title: "", airway: "J153", airway_type: "H", …}
3: {id: "17368", name: "CHASS", title: "", airway: "J153", airway_type: "H", …}
4: {id: "17369", name: "BLUNT", title: "", airway: "J153", airway_type: "H", …}
5: {id: "17370", name: "GEG", title: "", airway: "J153", airway_type: "H", …}
6: {id: "17371", name: "ZB", title: "", airway: "J153", airway_type: "B", …}
7: {id: "17372", name: "DI", title: "", airway: "J153", airway_type: "B", …}
length: 8
__proto__: Array(0)
__proto__: Object

 

I've dug into this more -- it's all around this:

 

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];
                    }

 

This will not go backwards no matter what I try.

 

I pulled the $airways array before this if statement and it all exists.

 

{J153: Array(8)}
J153: Array(8)
0: {id: "17365", name: "REO", title: "", airway: "J153", airway_type: "H", …}
1: {id: "17366", name: "BKE", title: "", airway: "J153", airway_type: "H", …}
2: {id: "17367", name: "BEAMO", title: "", airway: "J153", airway_type: "H", …}
3: {id: "17368", name: "CHASS", title: "", airway: "J153", airway_type: "H", …}
4: {id: "17369", name: "BLUNT", title: "", airway: "J153", airway_type: "H", …}
5: {id: "17370", name: "GEG", title: "", airway: "J153", airway_type: "H", …}
6: {id: "17371", name: "ZB", title: "", airway: "J153", airway_type: "B", …}
7: {id: "17372", name: "DI", title: "", airway: "J153", airway_type: "B", …}
length: 8
__proto__: Array(0)
__proto__: Object

 

Edited by Ither
Link to comment
Share on other sites

3 hours ago, web541 said:

By this do you mean it's running but not going backwards, or not running at all?


Correct.

 

The function runs fine in all statements except when it needs to count waypoints backwards. 

 

I built a sandbox that lets me push that navdata function without needing live flights.

 

Here are 2 images (they are large but should help understand.) It has preset validation (what I put into parser), Raw Results that the function dumped out, and then Airway Results (this is from the $airways variable when the function pulls all waypoints for the airway it detected in route string.)

 

Preface: This image is a flight that has an Airway (J153) where the entry waypoint sequence is higher number then it's exit waypoint. This type of route does not parse and therefore all I get is the entry/exit waypoint--nothing in the middle.

 

Link: https://imgur.com/a/zfAxXUx

 

Preface: This image is a flight that has an Airway (N864) where the entry waypoint sequence is the lowest number and the exit is the highest number. This type of route always works and never has issue.

 

Link: https://imgur.com/a/EIimLYm

 

I'm at my ends of figuring it out -- I cannot find the problem in why it will not go backwards.

 

If you want to tinker with it let me know -- I can give you access to my dev VM that has prod copy of site -- you can do whatever you want in it without impacting my live site. I really want to get this fixed because it is one last thing on my map that is not working right.

 

Edited by Ither
Link to comment
Share on other sites

FIXED

 

After setting up the sandbox it finally dawned on me.

 

This here:

} 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];
                    }

 

Needs to change to:

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

 

Now I have it working forwards and backwards now. :)

 

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...