Ither Posted October 9, 2020 Report Share Posted October 9, 2020 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. Quote Link to comment Share on other sites More sharing options...
web541 Posted October 9, 2020 Report Share Posted October 9, 2020 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. Quote Link to comment Share on other sites More sharing options...
Ither Posted October 28, 2020 Author Report Share Posted October 28, 2020 (edited) 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 October 28, 2020 by Ither Quote Link to comment Share on other sites More sharing options...
web541 Posted October 29, 2020 Report Share Posted October 29, 2020 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). Quote Link to comment Share on other sites More sharing options...
Ither Posted October 29, 2020 Author Report Share Posted October 29, 2020 (edited) 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 October 29, 2020 by Ither Quote Link to comment Share on other sites More sharing options...
web541 Posted October 29, 2020 Report Share Posted October 29, 2020 2 hours ago, Ither said: This will not go backwards no matter what I try. By this do you mean it's running but not going backwards, or not running at all? Quote Link to comment Share on other sites More sharing options...
Ither Posted October 29, 2020 Author Report Share Posted October 29, 2020 (edited) 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 October 30, 2020 by Ither Quote Link to comment Share on other sites More sharing options...
Ither Posted October 30, 2020 Author Report Share Posted October 30, 2020 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. Quote Link to comment Share on other sites More sharing options...
web541 Posted October 30, 2020 Report Share Posted October 30, 2020 Nice job! I was going to suggest checking the $entry and $exit variables as they were the last things that could possibly be changed. Quote Link to comment Share on other sites More sharing options...
Administrators ProAvia Posted October 30, 2020 Administrators Report Share Posted October 30, 2020 Good job! Quote Link to comment Share on other sites More sharing options...
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.