1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Unpacking ICAO Codes etc from BGL File

Discussion in 'Tools programming' started by scruffyduck, 22 Nov 2006.

  1. scruffyduck

    scruffyduck Administrator Staff Member FSDevConf team Resource contributor

    17 Sep 2005
    My head hurts :)

    I am trying to understand how the packing of ICAO codes works in the bgl file format.

    Reading Winfried's documentation each letter or number has a value between 0...37 With:
    blank 00
    digits 0 .. 9 02 .. 11
    letters A .. Z 12 .. 37

    I am to take the leftmost letter/number coded as above and multiply it by 38. I then add the next letter/number code to the result and multiply that by 38. Keep going until all the letters/numbers have been consumed. Multiply the result by 0x20 to left shift it by 5 bytes and hey presto that is the packed number!

    Well not here it ain't!! So I must be doing something wrong - consistently.

    Take MXA3 - M=24, X=35, A=12 and 3=5. The result in the bgl file for this is 43773729 but if I use the above calculation (WITHOUT the shift) I get 51981302. Compare the two numbers and mine is 1.187499973 times the number stored in the bgl.

    I tried 6 other ICAOs and in each case got a value 1.18749973 times the value in the BGL file. Clearly I don't understand how this works so any help would be much appreciated.
    Last edited: 22 Nov 2006
  2. Manuel Ambulo

    Manuel Ambulo

    29 Sep 2006
    Hi, scruffyduck,

    In my FS2004's program, for get an airport's ICAO_ID, i use the structure (below) for airport, where i get the "dwICAO_ID" member, and pass it to the "Get_ICAO_ID" subroutine (and also, i pass an empty string which will be filled with the decoded ICAO_ID of the airport). Note, that i just get the lastest 27 bits of the DWORD containing the ICAO_ID....the first 5 bits is unused for me.

    // FS2004's Airport
    struct FS2004_Airport
    unsigned short wType; // (0x0003 = Airport)
    unsigned long dwSize;
    unsigned char Total_runways;
    unsigned char Total_com_freqs;
    unsigned char Total_startlocations;
    unsigned char unknown1;
    unsigned char unknown2;
    unsigned char Total_helipads;
    unsigned long Lon;
    unsigned long Lat;
    unsigned long Alt;
    unsigned long Tower_Lon;
    unsigned long Tower_Lat;
    unsigned long Tower_Alt;
    float mag_var;
    unsigned long dw1 :5; // (5 bits)--> Unknown
    unsigned long dwICAO_ID :27; // (27 bits)--> Airport's ICAO_ID
    unsigned long unknown3;
    unsigned long unknown4;

    void Get_ICAO_ID(char szId[6], unsigned long dwId)
    static char szIdChar[] = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    szId[0] = '\0';

    for (int nIndex = 0; nIndex < 5 && dwId > 0; nIndex++)
    memmove(szId + 1, szId, 5);
    szId[0] = szIdChar[dwId % 38];
    dwId /= 38;

    24 * 38 = 912
    912 + 35 * 38 = 35986
    35986 + 12 * 38 = 1367924
    1367924 + 5 * 38 = 51981302 <--- Here is the value you get, BUT!..the problem is...

    The lastest multiplied "38"...see...if i dont multiply the last digit by "38", you will get -->
    1367924 + 5 = **1367929**.........instead of 51981302.

    If i convert the result "1367929" from decimal to binary i will get:


    And if i get the value in the *.bgl file, "43773729", and convert it to binary:


    Compare both values and you will see they are the SAME, except for the first 5 bits in the "43773729" value, See:

    101001101111101111001-------------> 1367929
    101001101111101111001---00001----> 43773729
    --------------------------(5 bits)----

    In others words, to the result you get from your calculations will be "1367929", if you do a Left shift (<<) of 5 bits:

    1367929 << 5 = 43773728; // For add the 5 bits to your value...

    You will get ---> 43773728 (pretty much closer to the value you get in the *.bgl file).

    101001101111101111001----00000----> 43773728 (calculations results..)
    101001101111101111001----00001----> 43773729 (value from *.bgl file.)
    ---------------------------(5 bits)-----------

    Hope this help you :)

    Best Regards,

    Manuel Ambulo
    Last edited: 23 Nov 2006
  3. scruffyduck

    scruffyduck Administrator Staff Member FSDevConf team Resource contributor

    17 Sep 2005
    Hi Manuel and many many thanks - that is the conclusion I came to at 2am this morning when I could not sleep! I was multiplying the last letter/number by 38 when I should not. 38/32 is 1.1875 and that is the error I found :)

    Update: Ok that is working fine now - thanks again!
    Last edited: 23 Nov 2006
  4. VADS


    12 Dec 2006
    Unpacking ICAO Codes

    I need to query when they say shift to the left 5 bytes - how does one convert the result to get what you're looking for?

    as i had the idea somehow that if i have 51981302 that i'd convert
    the last three by multiplying by 0.20

    302 x 0.20 = 60.4 is this calculation correct or have i misunderstood something along the way?

    Gareth - Vads
    Virtual Aerospace Design South Africa
  5. berendt


    27 Feb 2007
    Unpacking ICAO Codes ...


    presumably, your question is completely answered by now; however, if you feel so, you might have a look at my tool <Find_ICAO.zip> which I uploaded to the Avsim Library last week.

    Regards, Gerhard.
    Last edited: 3 Mar 2007
  6. scruffyduck

    scruffyduck Administrator Staff Member FSDevConf team Resource contributor

    17 Sep 2005
    Thanks Gerhard

    Yes SDE can now pack and unpack ICAO codes, both those that are shifted and those that are not. :)

Share This Page