Advertisement
layr

fix data reformatter

Apr 24th, 2012
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 15.48 KB | None | 0 0
  1. #!/bin/bash
  2. # Simple script for calculating and reformatting fixes' coordinates for the FlightGear/X-Plane fix database (fix.dat).
  3. # Note the script is very sensitive about the source format. Current version supports (to an extent) basic web- and PDF based FIX-lists.
  4. # Examples can be seen here: http://eaip.eans.ee/2012-03-08/html/eAIP/EE-ENR-4.4-en-GB.html#ENR-4.4 and http://www.lfv.se/AIP/ENR/ENR%204/ES_ENR_4_4_en.pdf
  5. #
  6. # If you encounter any kind of incorrect functionality, please contact me.
  7. #
  8. # Simply copy the data from the web or PDF file into the source file (defined below) and run the script. Result is a destination file (also defined below).
  9. #
  10. # The online web-based FIX list assumes the designators and coordinates are all on a separate lines (it should copy that way from the web browser by default).
  11. # The PDF-based FIX list on the other hand assumes the designator is followed by coordinates on the same line. Same line may also contain other designators and coordinates.
  12. #
  13. #
  14. # The source file contents from web-based fix list should look something like this (without the #-signs at the beginning of course):
  15. #------------------------------------------------------------------------------------
  16.     #ABSAK  <<----- the source file shall begin with the first FIX designator.
  17.     #
  18.     #581843N
  19.     #
  20.     #0270210E
  21.     #       EETU IFR PROC <<----- note the lines in between the designators and coordinates can contain anything.
  22.     #ANAMA 
  23.     #
  24.     #582459N
  25.     #
  26.     #0242842E
  27.     #   M857, P607, UM857, UP607 (and so on)
  28. #------------------------------------------------------------------------------------
  29. # ... and from a PDF list something like this:
  30. #------------------------------------------------------------------------------------
  31.     #ABDOB 49°54.00′N 006°34.90′E IAP ETAD ABGAS 48°35.62′N 010°23.50′E TB6 ADAMS 49°47.89′N 011°56.00′E IAP ETIC <<----- still the fist line has to start with a FIX designator
  32.     #ALOPO 50°16.82′N 011°46.08′E TL10
  33.     #BADLI 49°03.82′N 008°26.85′E SID ETAD
  34.     #BADOB 54°06.10′N 011°56.93′E IAP ETNL
  35.     #BADSU 53°59.22′N 012°39.17′E IAP ETNL
  36.     #BANIM 49°43.10′N 008°36.53′E TB6, TL8
  37.     #AMT FÜR FLUGSICHERUNG DER BUNDESWEHR  <<----- These random lines inbetween are not a problem
  38.     #AMDT 02/12
  39.     #ENR 4.4 - 2
  40.     #28 JUL 2011
  41.     #MILITÄRISCHES LUFTFAHRTHANDBUCH DEUTSCHLAND
  42.     #MILITARY AERONAUTICAL INFORMATION PUBLICATION GERMANY
  43.     #Name Koordinaten Zweck
  44.     #Name Coordinates Purpose
  45.     #1 2 3
  46.     #LAGIP 53°49.48′N 011°53.88′E IAP ETNL
  47. #------------------------------------------------------------------------------------
  48. # Note the script may make mistakes, since it assumes the fix name could consist of two separate words (not mentioning the fact it's not well written by no means :) ).
  49. # It also might not identify the coordinates or even misinterpret them.
  50. #
  51. # Don't forget to make this file executable!
  52. #
  53. # PS the FIX tables are located in AIPs under ENROUTE submenu (paragraph 4.4)
  54. #
  55. # Written by Laur Aliste <laur.aliste ät gmail>
  56. #------------------------------------------------------------------------------------
  57. #------------------------------------------------------------------------------------
  58. # Define the name and location of the source file:
  59. source_to_copy_FIX_data_to="$HOME/Downloads/FG_data/fix_source"
  60. # Define the name and location of the destination file:
  61. dest="$HOME/Downloads/FG_data/fix_final"
  62.  
  63. #######################################################################################
  64. ######## Don't edit anything from here on if you're not sure what you're doing ########
  65. #######################################################################################
  66. source="/tmp/.fix_reformatter_source"
  67. source_intermediate="/tmp/.fix_reformatter_intermediate"
  68. clear
  69. count=0
  70. cp $source_to_copy_FIX_data_to $source
  71. echo "DUMMY" >> $source
  72. # Delete empty lines:
  73. sed '/^$/d' $source > $source_intermediate
  74. # Delete lines starting with space or a tab:
  75. sed  '/^[ \t]\+/d' $source_intermediate > $source
  76.  
  77. # Define the source format:
  78. set $(cat $source | sed -n 1p)
  79. third_arg_digits=$(echo $3 | sed "s/[^0-9]//g")
  80. if [[ "$1" =~ ^[A-Z\ ]+$ ]] && [[ "${#1}" =~ ^[4-9]+$ ]] && [[ -z "$third_arg_digits" ]]; then
  81.     file_format="online_AIP"
  82.     echo "Assuming we're dealing here with a FIX list taken from a an online AIP having a classic web-based AIP format."
  83.     # Delete lines containing "," or ":"
  84.     sed -e '/'[:,]'/d' < $source > $source_intermediate
  85.     mv $source_intermediate $source
  86. elif [[ "$1" =~ ^[A-Z\ ]+$ ]] && [[ "${#third_arg_digits}" =~ ^[6-9]+$ ]]; then
  87.     file_format="PDF_source"
  88.     echo "Assuming we're dealing here with a FIX list taken from a PDF file (or similar)."
  89. else
  90.     echo "========================================================"
  91.     echo "  It seems the source format provided isn't supported"
  92.     echo "  by this script. Read the script header for more info."
  93.     echo "========================================================"; exit 1
  94. fi
  95. > $source_intermediate
  96. # Organise the source file for the calculation script:
  97. if [[ "$file_format" == "online_AIP" ]]; then
  98.     while [ $count -lt 40 ] ;do
  99.         count=0
  100.         designator=$(echo $(cat $source | sed -n 1p))
  101.         until [[ "$designator" =~ ^[A-Z\ ]+$ ]] && [[ "${#designator}" =~ ^[4-9]+$ ]]; do
  102.             if [ $count -le 40 ]; then
  103.                 sed -i 1d $source
  104.                 designator=$(echo $(cat $source | sed -n 1p))
  105.                 let count=$count+1
  106.             else
  107.                 if [ -z "$(cat $source | sed -n 1p)" ]; then
  108.                 designator="DUMMY"
  109.                 fi
  110.             fi
  111.         done
  112.         sed -i 1d $source
  113.         latitude=$(cat $source | sed -n 1p)
  114.         latitude_digits=$(echo $latitude | sed "s/[^0-9]//g")
  115.         until [[ "$latitude_digits" =~ ^[0-9]+$ ]] && [[ "${#latitude_digits}" =~ ^[6-8]+$ ]] ; do
  116.             if [ $count -le 40 ]; then
  117.                 sed -i 1d $source
  118.                 latitude=$(cat $source | sed -n 1p)
  119.                 latitude_digits=$(echo $latitude | sed "s/[^0-9]//g")
  120.                 let count=$count+1
  121.             else
  122.                 if [ -z "$(cat $source | sed -n 1p)" ]; then
  123.                 latitude_digits="0000000"
  124.                 fi
  125.             fi
  126.         done
  127.         sed -i 1d $source
  128.         longitude=$(cat $source | sed -n 1p)
  129.         longitude_digits=$(echo $longitude | sed "s/[^0-9]//g")
  130.         until [[ $longitude_digits =~ ^[0-9]+$ ]] && [[ ${#longitude_digits} =~ ^[7-9]+$ ]]; do
  131.             if [ $count -le 40 ]; then
  132.                 sed -i 1d $source
  133.                 longitude=$(cat $source | sed -n 1p)
  134.                 longitude_digits=$(echo $longitude | sed "s/[^0-9]//g")
  135.                 let count=$count+1
  136.             else
  137.                 if [ -z "$(cat $source | sed -n 1p)" ]; then
  138.                 longitude_digits="00000000"
  139.                 fi
  140.             fi
  141.         done
  142.         sed -i 1d $source
  143.         echo "$designator" >> $source_intermediate
  144.         echo "$latitude" >> $source_intermediate
  145.         echo "$longitude" >> $source_intermediate
  146.     done
  147. elif [[ "$file_format" == "PDF_source" ]]; then
  148.     set $(cat $source | sed -n 1p)
  149.     str="$@"
  150.     until [[ "$str" == "DUMMY" ]]; do
  151.         until [[ "${#str}" == "1" ]]; do
  152.             set $str
  153.             third_variable_digits=$(echo $3 | sed "s/[^0-9]//g")
  154.             if [[ "$1" =~ ^[A-Z]+$ ]] && [[ "$third_variable_digits" =~ ^[0-9]+$ ]] && [ ${#third_variable_digits} -ge 6 ]; then
  155.                 second_variable_digits=$(echo $2 | sed "s/[^0-9]//g")
  156.                 if [[ "$2" =~ ^[A-Z]+$ ]]; then
  157.                     designator=$(echo "$1 $2")
  158.                     latitude=$3
  159.                     longitude=$4
  160.                     remove="$1 $2"
  161.                 elif ! [[ "${#third_variable_digits}" =~ ^[6-9]+$ ]]; then
  162.                     echo "======================================================"
  163.                     echo "            An error has occurred. Sorry."
  164.                     echo "======================================================"; exit 1
  165.                 else
  166.                     designator=$1
  167.                     latitude=$2
  168.                     longitude=$3
  169.                     remove="$1"
  170.                 fi
  171.  
  172.                 echo "$designator" >> $source_intermediate
  173.                 echo "$latitude" >> $source_intermediate
  174.                 echo "$longitude" >> $source_intermediate
  175.             else
  176.                 remove="$1"
  177.             fi
  178.             str=" $@ "
  179.  
  180.             for remove_designators_from_the_beginning in $remove ; do
  181.               str=${str/ $remove_designators_from_the_beginning / }
  182.             done
  183.  
  184.         done
  185.         sed -i 1d $source
  186.         set $(cat $source | sed -n 1p)
  187.         str="$@"
  188.     done
  189. # Write 'DUMMY' to the end of the source. It'll mark the end of the math loop:
  190. echo "DUMMY" >> $source_intermediate
  191. fi
  192.  
  193. mv $source_intermediate $source
  194. # Wipe the old destination file:
  195. > $dest
  196.     designator=$(cat $source | sed -n 1p)
  197. # Start the math loop:
  198. while : ;do
  199.     latitude_line=$(cat $source | sed -n 2p)
  200.     # Trim preceeding and succeeding tabs:
  201.     trim() { echo $latitude_line; }
  202.     latitude_line="$(trim '$latitude_line')"
  203.     # Extract the number of items and number of digits in coordinate value in order to identify it:
  204.     latitude_digits=$(echo "$latitude_line" | sed "s/[^0-9]//g")
  205.     nr_of_latitude_digits=${#latitude_digits}
  206.     nr_of_latitude_items=${#latitude_line}
  207.  
  208.     longitude_line=$(cat $source | sed -n 3p)
  209.     trim2() { echo $longitude_line; }
  210.     longitude_line="$(trim2 '$longitude_line')"
  211.     longitude_digits=$(echo "$longitude_line" | sed "s/[^0-9]//g")
  212.  
  213.     # Identify coordinate system by examining the latitude coordinate:
  214.     if [[ "$nr_of_latitude_items" == "7" ]] && [[ "$nr_of_latitude_digits" == "6" ]]; then
  215.         format="HHMMSS"
  216.     elif [[ "$nr_of_latitude_items" == "9" ]] && [[ "$nr_of_latitude_digits" == "7" ]] && [[ "$(echo $latitude_line | cut -c7)" == "." ]]; then
  217.         format="HHMMSS.S"
  218.     elif [[ "$nr_of_latitude_items" == "10" ]] && [[ "$nr_of_latitude_digits" == "8" ]] && [[ "$(echo $latitude_line | cut -c7)" == "." ]]; then
  219.         format="HHMMSS.SS"
  220.     elif [[ "$nr_of_latitude_items" == "10" ]] && [[ "$nr_of_latitude_digits" == "6" ]] && [[ "$(echo $latitude_line | cut -c7)" == "." ]]; then
  221.         format="HH°MM.MM′"
  222.     elif [[ "$nr_of_latitude_items" == "13" ]] && [[ "$nr_of_latitude_digits" == "8" ]]; then
  223.         format="HH°MM'SS.SS′′"
  224.     elif [[ "$nr_of_latitude_items" == "10" ]] && [[ "$nr_of_latitude_digits" == "6" ]]; then
  225.         format="HH°MM'SS′′"
  226.     else
  227.         echo "======================================================"
  228.         echo "The coordinate system could not be identified or isn't"
  229.         echo "supported by this script. Sorry."
  230.         echo -e "Unidentified coordinate is: $latitude_line\n"
  231.         echo -e "If the coordinate above doesn't look anything like"
  232.         echo -e "a coordinate should, then the script has misinterpreted"
  233.         echo -e "the source-file. I'd reccommend you removing  or editing"
  234.         echo -e "corresponding line from the source file and try again."
  235.         echo "======================================================"; exit 1
  236.     fi
  237.     count=0
  238.     # Define latitude values (hr, min):
  239.     hr_lat="$(( 10#$(echo $latitude_digits | cut -c1-2) ))"
  240.     min_lat=$(echo $latitude_digits | cut -c3-4)
  241.     # Define longitude values (hr, min):
  242.     hr_lon="$(( 10#$(echo $longitude_digits | cut -c1-3) ))"
  243.     min_lon=$(echo $longitude_digits | cut -c4-5)
  244.     # Define hemispheres:
  245.     lat_hemisphere=$(echo "$latitude_line" | sed "s/[^NS]//g")
  246.     lon_hemisphere=$(echo "$longitude_line" | sed "s/[^WE]//g")
  247.     case "$format" in
  248.         "HHMMSS")   # Define latitude values (sec):
  249.                 sec_lat=$(echo $latitude_digits | cut -c5-6)
  250.                 # Define longitude values (sec):
  251.                 sec_lon=$(echo $longitude_digits | cut -c6-7)
  252.             ;;
  253.         "HHMMSS.SS")    # Define latitude values (sec):
  254.                 sec_lat=$(echo $latitude_digits | cut -c5-6).$(echo $latitude_digits | cut -c7-8)
  255.                 # Define longitude values (sec):
  256.                 sec_lon=$(echo $longitude_digits | cut -c6-7).$(echo $longitude_digits | cut -c8-9)
  257.             ;;
  258.         "HHMMSS.S") # Define latitude values (sec):
  259.                 sec_lat=$(echo $latitude_digits | cut -c5-6).$(echo $latitude_digits | cut -c7)
  260.                 # Define longitude values (sec):
  261.                 sec_lon=$(echo $longitude_digits | cut -c6-7).$(echo $longitude_digits | cut -c8)
  262.             ;;
  263.         "HH°MM.MM′") # Define latitude values (min, sec):
  264.                 min_lat=$(echo $latitude_digits | cut -c3-4).$(echo $latitude_digits | cut -c5-6)
  265.                 sec_lat="0"
  266.                 # Define longitude values (min, sec):
  267.                 min_lon=$(echo $longitude_digits | cut -c4-5).$(echo $latitude_digits | cut -c6-7)
  268.                 sec_lon="0"
  269.             ;;
  270.         "HH°MM'SS.SS′′") # Define latitude values (sec):
  271.                 sec_lat=$(echo $latitude_digits | cut -c5-6).$(echo $latitude_digits | cut -c7-8)
  272.                 # Define longitude values (sec):
  273.                 sec_lon=$(echo $longitude_digits | cut -c6-7).$(echo $longitude_digits | cut -c8-9)
  274.             ;;
  275.         "HH°MM'SS′′") # Define latitude values (sec):
  276.                 sec_lat=$(echo $latitude_digits | cut -c5-6)
  277.                 # Define longitude values (sec):
  278.                 sec_lon=$(echo $longitude_digits | cut -c6-7)
  279.             ;;
  280.         *)      echo "========================================================"
  281.                 echo "  It looks like the coordinates provided aren't supported"
  282.                 echo -e "  by this script :(\n"
  283.                 echo " The coordinates in the source file can't be read by the"
  284.                 echo " script. Check the destination file and look what is the"
  285.                 echo " last fix finished. Then find it in the source file and"
  286.                 echo " see whether the problem can be fixed manually."
  287.                 echo "========================================================"; exit 1
  288.             ;;
  289.     esac
  290.     # Define the number of digits in the hour value of coordinate (if it originally contained 0 or 00 in the beginning, it gets removed in the calculations. This variable is later used for restoring these zeroes:
  291.     nr_of_digits_in_long=${#hr_lon}
  292.     nr_of_digits_in_lat=${#hr_lat}
  293.     # Calculate and define the latitude coordinate:
  294.     lat_value=$(echo "scale=6; ($sec_lat/60 + $min_lat)/60 + $hr_lat" | bc )
  295.     # If the latitude coordinate had initially 0 or 00 as a first digit, restore them in front of the result (the 0 was previously removed in calculations):
  296.     if [[ "$nr_of_digits_in_lat" == "1" ]] && [[ "$hr_lat" == "0" ]]; then
  297.         lat_value="00$lat_value"
  298.     elif [[ "$nr_of_digits_in_lat" == "1" ]]; then
  299.         lat_value="0$lat_value"
  300.     fi
  301.     # Make the latitude value negative, if it's located on southern hemisphere:
  302.     if [[ "$lat_hemisphere" == "S" ]]; then
  303.         lat_value="-$lat_value"
  304.     else
  305.         lat_value=" $lat_value"
  306.     fi
  307.     # Calculate and define the longitude coordinate:
  308.     long_value=$(echo "scale=6; ($sec_lon/60 + $min_lon)/60 + $hr_lon" | bc )
  309.     # If the longitude coordinate had initially 0, 00 or 000 as a first digit, restore them in front of the result (the 0 was previously removed in calculations):
  310.     if [[ "$nr_of_digits_in_long" == "1" ]] && [[ "$hr_lon" == "0" ]]; then
  311.         long_value="000$long_value"
  312.     elif [[ "$nr_of_digits_in_long" == "1" ]]; then
  313.         long_value="00$long_value"
  314.     elif [[ "$nr_of_digits_in_long" == "2" ]]; then
  315.         long_value="0$long_value"
  316.     fi
  317.     # Make the longitude value negative, if it's western longitude:
  318.     if [[ "$lon_hemisphere" == "W" ]]; then
  319.         long_value=" -$long_value"
  320.     else
  321.         long_value="  $long_value"
  322.     fi
  323.     # Write the final result into destination file:
  324.     echo "$lat_value$long_value $designator" >> $dest
  325.  
  326.     sed -i 1d $source
  327.     designator=$(cat $source | sed -n 1p)
  328.     # Start deleting loop (it deletes first lines until new FIX is encountered; then it'll be processed again and so on...):
  329.     until [[ "$designator" =~ ^[A-Z\ ]+$ ]] && [[ "${#designator}" =~ ^[4-9]+$ ]] && [[ "$designator" != "DUMMY" ]]; do
  330.         # If 'DUMMY' is encountered in the source file, the loop gets closed:
  331.         if [[ "$designator" == "DUMMY" ]]; then
  332.             rm $source
  333.             echo "======================================================"
  334.             echo " List has been successfully finished :)"
  335.             echo -e " (or at least it looks that way)\n"
  336.             echo "  Result was saved into $dest"
  337.             echo "==============================================================="; exit 0
  338.         elif [ $count -lt 5 ]; then
  339.             sed -i 1d $source
  340.             designator=$(cat $source | sed -n 1p)
  341.             let count=$count+1
  342.         else
  343.             echo "======================================================"
  344.             echo " An error has occurred :("
  345.             echo "    Look into source and/or destination file and see"
  346.             echo "    whether the problem can be fixed manually."
  347.             echo "======================================================"; exit 1
  348.         fi
  349.     done
  350.  
  351. done
  352. exit
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement