Hi folks,
this is not a question, I already worked out this solution. But it made me a lot of headache, so it would be useful for others, too.
Input can look like:
"Brighton Beach" -> get pos of that base
"Brighton Beach 1" -> get pos of base's pad 1
"12.34W 56.78N" -> lon lat (DEG)
"98.76S 54.32E" -> swapped
"12.34 -56.78" -> lon lat (DEG)
Headaches with that:
- Not to use sscanf with "%f" for doubles, use "%lf"!
- Problems to get the "E" because of scientific float notation
- Side effect: You may use "O" as "E" (like on german compass)
You may help me to replace rad=0.0 with the shortest way to get rad of surface level instead.
this is not a question, I already worked out this solution. But it made me a lot of headache, so it would be useful for others, too.
Input can look like:
"Brighton Beach" -> get pos of that base
"Brighton Beach 1" -> get pos of base's pad 1
"12.34W 56.78N" -> lon lat (DEG)
"98.76S 54.32E" -> swapped
"12.34 -56.78" -> lon lat (DEG)
Headaches with that:
- Not to use sscanf with "%f" for doubles, use "%lf"!
- Problems to get the "E" because of scientific float notation
- Side effect: You may use "O" as "E" (like on german compass)
You may help me to replace rad=0.0 with the shortest way to get rad of surface level instead.
PHP:
bool StrToEqu(OBJHANDLE planet, char *str, VECTOR3 &lonradlat, bool strcorrection)
{
// planet: OBJHANDLE to the planet/moon (e.g. planet = vessel->GetSurfaceRef())
// str: the string to scan (from input box)
// output lonradlat (RAD): I always store equ positions in vectors like x=lon, y=rad, z=lat
// That can easily be added by vectors in vessel orientation (horizon level, north facing)
// strcorrection: true converts the input string e.g. "brighton beach" into "Brighton Beach" for later
// returns: true = found sth, false = not found or syntax error
OBJHANDLE base;
std::string s;
int l, pos;
DWORD pad;
double d1, d2, dt;
char c1, c2, ct;
bool ok;
l = strlen(str);
if(l > 0)
{
// if whole string is a base name, get that
base = oapiGetBaseByName(planet, str);
if(base != NULL)
{
oapiGetBaseEquPos(base, &lonradlat.x, &lonradlat.z, &lonradlat.y);
if(strcorrection)
oapiGetObjectName(base, str, l+1);
return true;
}
// input "Brighton Beach 1" would mean Pad1 of that base
s = str;
pos = s.find_last_of(' ');
if(pos > 0)
{
s[pos] = char(0);
if(sscanf(str + pos + 1, "%d", &pad) == 1)
{
base = oapiGetBaseByName(planet, (char *)s.c_str());
if(base != NULL)
{
if((pad > 0) && (pad <= oapiGetBasePadCount(base)))
{
oapiGetBasePadEquPos(base, pad-1, &lonradlat.x, &lonradlat.z, &lonradlat.y);
if(strcorrection)
{
oapiGetObjectName(base, str, l+1);
sprintf(str, "%s %d", str, pad);
}
return true;
}
}
}
}
//input like "12.34E 56.78N"
s = str;
for(unsigned int i=0;i<s.length();i++)
{
// do uppercase and replace E with O
// (E would be interpreted as scientific float notation)
switch(s[i])
{
case 'n':
s[i] = 'N';
break;
case 's':
s[i] = 'S';
break;
case 'w':
s[i] = 'W';
break;
case 'E':
s[i] = 'O';
break;
case 'e':
s[i] = 'O';
break;
case 'o':
s[i] = 'O';
break;
}
}
if(sscanf((char *)s.c_str(), "%lf%c %lf%c", &d1, &c1, &d2, &c2) == 4)
{
if(((c1 == 'N') || (c1 == 'S')) && ((c2 == 'O') || (c2 == 'W')))
{
// swap
ct = c1;
c1 = c2;
c2 = ct;
dt = d1;
d1 = d2;
d2 = dt;
}
ok = false;
if(c1 == 'O')
{
if(c2 == 'N')
{
lonradlat.x = d1 * RAD;
lonradlat.z = d2 * RAD;
ok = true;
}
else if(c2 == 'S')
{
lonradlat.x = d1 * RAD;
lonradlat.z = -d2 * RAD;
ok = true;
}
}
else if (c1 == 'W')
{
if(c2 == 'N')
{
lonradlat.x = -d1 * RAD;
lonradlat.z = d2 * RAD;
ok = true;
}
else if(c2 == 'S')
{
lonradlat.x = -d1 * RAD;
lonradlat.z = -d2 * RAD;
ok = true;
}
}
if(ok)
{
lonradlat.y = 0.0; // surface level would be better
return true;
}
}
//input like "12.34 -56.78"
if(sscanf(str, "%lf %lf", &d1, &d2) == 2)
{
lonradlat.x = d1 * RAD;
lonradlat.z = d2 * RAD;
lonradlat.y = 0.0; // surface level would be better
return true;
}
}
// wrong input or nothing found
return false;
}