James Turner wrote:
> Is there any code in Sim/FlightGear to do generic conversion of a lat /
> lon string into a decimal degree value?
>
> And, if it doesn't exist, any suggestions how do a vaguely elegant
> implementation?

Heh, that actually sounded kinda fun, so I tried it.  Here's the
smallest parser for your syntax that I could come up with, in good old
obfuscatorial C style.  It sits pleasingly close to the line between
elegance and perversity.

Like all small parsers, it accepts a superset of the desired syntax.
Basically, it looks for a list of decimal numbers embedded in the
string and uses the first three as degree, minutes and seconds.  The
presence of a "S" or "W character indicates that the result is in a
hemisphere where the final answer must be negated.  Non-number
characters are treated as whitespace separating numbers.

So there are lots of bogus strings you can feed it to get a bogus
answer, but that's not surprising.  It does, however, correctly parse
all the well-formed strings I can thing of to feed it.  I've tried all
the following:

37�54.204' N
N37 54 12
37�54'12"
37.9034
122�18.621' W
122w 18 37
-122.31035

Andy

-- 
Andrew J. Ross                NextBus Information Systems
Senior Software Engineer      Emeryville, CA
[EMAIL PROTECTED]              http://www.nextbus.com
"Men go crazy in conflagrations.  They only get better one by one."
 - Sting (misquoted)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

double parseLatLon(char* s)
{
    char buf[64];
    int i, len, top=0;
    double stk[32], sign=1;

    strncpy(buf, s, 64);
    len = strlen(buf);

    for(i=0; i<len; i++) {
        char c = buf[i];
        if((c>='0' && c<='9') || c=='-' || c=='.' || c=='+')
            continue;  /* Digit characters are cool as is */
        if((c|32) == 'w' || (c|32) == 's')
            sign = -1; /* These mean "negate" (note case insensitivity) */
        buf[i] = 0;    /* Replace everything else with nuls */
    }

    /* Build a stack of doubles */
    stk[0] = stk[1] = stk[2] = 0;
    for(i=0; i<len; i++) {
        while(i<len && buf[i] == 0) i++;
        if(i != len) {
            stk[top++] = atof(buf+i);
            i += strlen(buf+i);
        }
    }

    return sign * (stk[0] + (stk[1] + stk[2] / 60) / 60);
}

int main(int argc, char** argv)
{
    printf("%f\n", parseLatLon(argv[1]));
    return 1;
}

Reply via email to