ama*_*nda 4 c c++ geolocation latitude-longitude
我正在寻找最好的C或C++代码来编码和解码从/到double/char的十进制纬度和经度值.我更喜欢将代码从double转换为char [],反之亦然而不是c ++字符串.
如果你有一个很棒的代码片段.
澄清一下:我需要将字符串Degrees/Minutes/Seconds转换为double并返回字符串.我有3亿条记录,所以速度是一个很大的问题.
请参阅:http://en.wikipedia.org/wiki/Geographic_coordinate_conversion
通过电子邮件与OP(amanda)合作,我们开发了一个基于大型switch-case语句的快速功能.
amanda报告说它的运行速度比它们使用的代码快15倍左右.
考虑到这是超过3亿条记录,这应该是相当可观的时间节省.
我发现问题非常有趣.
这是代码:
/* WARNING: These values are very important, as used under the "default" case. */
#define INT_PART 3
#define DEC_PART 2
double Str2LatLong(char* coord)
//double LLStr::Str2LL(char* coord)
{
int sign = +1;
double val;
int i = 0; /* an index into coord, the text-input string, indicating the character currently being parsed */
int p[9] = {0,0,1, /* degrees */
0,0,1, /* minutes */
0,0,1 /* seconds */
};
int* ptr = p; /* p starts at Degrees.
It will advance to the Decimal part when a decimal-point is encountered,
and advance to minutes & seconds when a separator is encountered */
int flag = INT_PART; /* Flips back and forth from INT_PART and DEC_PART */
while(1)
{
switch (coord[i])
{
/* Any digit contributes to either degrees,minutes, or seconds */
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
*ptr = 10* (*ptr) + (coord[i] - '0');
if (flag == DEC_PART) /* it'd be nice if I could find a clever way to avoid this test */
{
ptr[1] *= 10;
}
break;
case '.': /* A decimal point implies ptr is on an integer-part; advance to decimal part */
flag = DEC_PART; /* after encountering a decimal point, we are now processing the Decimal Part */
ptr++; /* ptr[0] is now the Decimal piece; ptr[1] is the Denominator piece (powers of 10) */
break;
/* A Null terminator triggers return (no break necessary) */
case '\0':
val = p[0]*3600 + p[3]*60 + p[6]; /* All Integer math */
if (p[1]) val += ((double)p[1]/p[2]) * 3600; /* Floating-point operations only if needed */
if (p[4]) val += ((double)p[4]/p[5]) * 60; /* (ditto) */
if (p[7]) val += ((double)p[7]/p[8]); /* (ditto) */
return sign * val / 3600.0; /* Only one floating-point division! */
case 'W':
case 'S':
sign = -1;
break;
/* Any other symbol is a separator, and moves ptr from degrees to minutes, or minutes to seconds */
default:
/* Note, by setting DEC_PART=2 and INT_PART=3, I avoid an if-test. (testing and branching is slow) */
ptr += flag;
flag = INT_PART; /* reset to Integer part, we're now starting a new "piece" (degrees, min, or sec). */
}
i++;
}
return -1.0; /* Should never reach here! */
}
Run Code Online (Sandbox Code Playgroud)