Base26GPS 标准代码实现
本文档描述了 Base26GPS 标准的代码实现。
引言
Base26GPS 标准用于在不同平台之间共享位置信息,通过将经度和纬度转换为字符串来实现。该字符串由 A 到 Z 的 26 个字符组成,因此在数字系统中是 Base26,也称为二十六进制。 在本文档中,我将描述用于实现它的代码。
更多信息,请访问网站 这里。
背景
位置信息基于经度和纬度。 经度是一个 -180.0 到 180 之间的数字,纬度是一个 -90 到 90 之间的数字。 至今,不同平台的应用程序在彼此之间发送位置信息时没有统一的标准,它们使用各自的内部标准。 这有点类似于 XML 出现之前的情况。
Using the Code
有两个函数:
LocToBase26- 将经度和纬度转换为字符串Base26ToLoc- 将字符串转换为经度和纬度
从经度和纬度转换为字母的步骤如下:
- 前三个字母是“GPS”,接下来的六个字母代表经度,最后六个字母代表纬度。 总共十五个字母。
- 经度和纬度应该始终在小数点后有四位数字。
例如:-180 将变为 -180.0000,12.53 将变为 12.5300,151.45319 将变为 151.4532 - 每个数字都分为小数点左侧的数字和小数点右侧的数字。
- 左侧的数字对于经度来说是从 -180 到 180。 -180 等于 AA,180 等于 NW。 计数从 -180 开始。
对于纬度,左侧的数字是从 -90 到 90。 -90 等于 AA,90 等于 GY。 计数从 -90 开始。 - 右侧的数字分为两组。 每组从 00 到 99。 00 等于 AA,99 等于 DV。 计数从 0 开始。
- 转换后,经度有六个字母,纬度也有六个字母。
例如 – 经度为 12.45,纬度为 -11.54 将生成以下字符串:
“GPSHKBTAADBCCAA”。
从字母转换为经度和纬度使用相同的原理。
这是 LocToBase26.c 的代码
int ConvertLocToBase26(float Longitude,float Latitude, char *Base26GPSString)
{
/* ======================================================================
function name : ConvertLocToBase26
function activity : convert Longitude and Latitude parameter to string
according to Base26GPS standard
input parameters : float Longitude - the Longitude to be translated
float Latitude - the Latitude to be translated
output parameters: char *Base26GPSString - a 15 chars string representing
the Base26GPS standard.
int Return Value - the function success or failure.
"1" = success otherwise fail
========================================================================= */
int PassFail;
int Fail = 0;
char LongitudeString[6];
char LatitudeString[6];
// convert Longitude to string according to Base26GPS standard
PassFail = ConvertLongitude(Longitude,LongitudeString);
if (PassFail== Fail)
{
return 0;
}
//convert Latitude to string according to Base26GPS standard
PassFail = ConvertLatitude(Latitude,LatitudeString);
if (PassFail== Fail)
{
return 0;
}
//combine the strings together along with the GPS header
strcpy(Base26GPSString,"GPS");
strcat(Base26GPSString,LongitudeString);
strcat(Base26GPSString,LatitudeString);
return 1;
}
int ConvertLongitude(float Longitude,char *ReturnString)
{
/* ======================================================================
function name : ConvertLongitude
function activity : convert Longitude parameter to string according to
Base26GPS standard
input parameters : float Longitude - the Longitude to be translated
output parameters: char *ReturnString - a six chars string representing
the translated Longitude
int Return Value - the function success or failure.
"1" = success otherwise fail
========================================================================= */
float TempFloat;
double FractPart;
//char StringFractPart[4];
double TempFractPart;
double IntPart;
int Multiply;
int Add;
//int PassFail;
int Fail = 0;
int Sign;
//check the limits of the Longitude parameter
if (Longitude<-180 || Longitude>180)
{
printf("Longitude parameter out of limits\n");
return 0;
} // round up or down
if (Longitude<0)
{
Longitude-=(float)0.00005;
Sign=-1;
}
else
{
Longitude+=(float)0.00005;
Sign=1;
} // break the Longitude parameter to the integer part
// and the fraction part. the fraction is absolute
FractPart = fabs(modf((double)Longitude,&IntPart) * 10000);
if (FractPart<0)
FractPart-=0.1;
else
FractPart+=0.1;
// integer part activity
// =====================
// extract the multiply part
TempFloat = (float)((((int)(IntPart)+180)/26));
Multiply = (int)TempFloat+65;
if ((int)Longitude==0 && Sign == -1)
Multiply=90;
ReturnString[0] = Multiply;
// extract the add part
TempFloat = (float)((((((IntPart)+180) /26) - (int)(((IntPart)+180)/26) )*26)+0.1);
Add = (int)(TempFloat) + 65;
ReturnString[1] = Add;
//extract the first two fract numbers
TempFractPart = FractPart/100;
// extract the multiply part
TempFloat = (float)(((int)TempFractPart/26));
Multiply = (int)TempFloat+65;
ReturnString[2] = Multiply;
//extract the add part
TempFloat = (float)((((((TempFractPart))/26) - (int)(((TempFractPart))/26))*26));
Add = (int)TempFloat+65;
ReturnString[3] = Add;
// second two numbers in fract part activity
// =========================================
//extract the second two fract numbers
TempFractPart = ((FractPart)/100 - (int)((FractPart)/100))*100;
// extract the multiply part
TempFloat = (float)((TempFractPart/26));
Multiply = (int)TempFloat+65;
ReturnString[4] = Multiply;
//extract the add part
TempFloat = (float)((((((TempFractPart))/26) -
(int)(((TempFractPart))/26))*26)); Add = (int)TempFloat+65;
ReturnString[5] = Add;
// the string is nested in ReturnString and is six chars long.
ReturnString[6] = 0;
return 1;
}
int ConvertLatitude(float Latitude,char *ReturnString)
{
/* ======================================================================
function name : ConvertLatitude
function activity : convert Latitude parameter to string according to
Base26GPS standard
input parameters : float Latitude - the Latitude to be translated
output parameters: char *ReturnString - a six chars string representing
the translated Latitude
int Return Value - the function success or failure.
"1" = success otherwise fail
========================================================================= */
float TempFloat;
double FractPart;
double TempFractPart;
double IntPart;
int Multiply;
int Add;
int Sign;
//check the limits of the Longitude parameter
if (Latitude<-90 || Latitude>90)
{
printf("Latitude parameter out of limits\n");
return 0;
} // round up or down
if (Latitude<0)
{
Latitude-=(float)0.00005;
Sign = -1;
}
else
{
Latitude+=(float)0.00005;
Sign = 1;
}
// break the Longitude parameter to the integer part
// and the fraction part. the fraction is absolute
FractPart = fabs(modf((double)Latitude,&IntPart) * 10000);
// integer part activity
// =====================
// extract the multiply part
TempFloat = (float)(((IntPart+90)/26));
Multiply = (int)TempFloat + 65;
// in case the number is between -0.9999 to -0.0001 the letter Z will be used
// so when translating back we will know about this
if ((int)Latitude==0 && Sign == -1)
Multiply=90;
ReturnString[0] = Multiply;
// extract the add part
TempFloat = (float)(((((IntPart+90) /26) - (int)((IntPart+90)/26) )*26)+0.1);
Add = (int) TempFloat + 65;
ReturnString[1] = Add;
// first two numbers in fract part activity
// ========================================
//extract the first two fract numbers
TempFractPart = FractPart/100;
// extract the multiply part
TempFloat = (float)((TempFractPart/26));
Multiply = (int)TempFloat+65;
ReturnString[2] = Multiply;
//extract the add part
TempFloat = (float)(((((TempFractPart)/26) - (int)((TempFractPart)/26))*26));
Add = (int)TempFloat+65;
ReturnString[3] = Add;
// second two numbers in fract part activity
// =========================================
//extract the second two fract numbers
TempFractPart = (FractPart/100 - (int)(FractPart/100))*100;
// extract the multiply part
TempFloat = (float)((TempFractPart/26));
Multiply = (int)TempFloat + 65;
ReturnString[4] = Multiply;
//extract the add part
TempFloat = (float)(((((TempFractPart)/26) - (int)((TempFractPart)/26))*26));
Add = (int)TempFloat + 65; ReturnString[5] = Add;
ReturnString[6] = 0;
// the string is nested in ReturnString and is six chars long.
return 1;
}
int ConvertStringToSingle(char *StringVar, float *ReturnSingleVar)
{
/* ======================================================================
function name : ConvertStringToSingle
function activity : convert a string value to float value
input parameters : char *StringVar - the string to be translated
output parameters: float *ReturnSingleVar - the translated single variable
(float)
int Return Value - the function success or failure.
"1" = success otherwise fail
========================================================================= */
// convert string input var to float
*ReturnSingleVar = (float)atof(StringVar);
return 1;
}
这是 Base26ToLoc.c 的代码
int ConvertBase26ToLoc
(char *Base26GPSString,float *ReturnLongitude, float *ReturnLatitude)
{
/* ======================================================================
function name : ConvertBase26ToLoc
function activity : convert Base26GPS string to Longitude and Latitude
according to Base26GPS standard
input parameters : char *Base26GPSString - a 15 chars string representing
the Base26GPS standard
output parameters: float Longitude - the Longitude to be translated
float Latitude - the Latitude to be translated
int Return Value - the function success or failure.
"1" = success otherwise fail
========================================================================= */
char LongitudeString[6];
char LatitudeString[6];
char SetString[3];
int RetNum;
int count;
int PassFail;
int Fail = 0;
int Sign;
int SignForZero;
char GPSString[4];
SetString[2] = 0;
// check the validity of the string
if (strlen(Base26GPSString)!=15)
{
printf("the string length does not match\n");
return 0;
}
strncpy(GPSString,Base26GPSString,3);
GPSString[3]=0;
if (strcmp(GPSString,"GPS")!=0)
{
printf("GPS Header is missing\n");
return 0;
}
// extract the longitude text and latitude text from the string
strncpy(LongitudeString,Base26GPSString+3,6);
strncpy(LatitudeString,Base26GPSString+9,6); //check validity of
// alphabetic chars inside the string
//change to capsloc
for (count=0;count<6;count++)
{
if(!(LongitudeString[count]>64 && LongitudeString[count]<91 ||
LongitudeString[count]>96 && LongitudeString[count]<123))
{
printf("string has illegal characters\n");
return 0;
}
if (LongitudeString[count]>96)
LongitudeString[count]-=32;
if(!(LatitudeString[count]>64 && LatitudeString[count]<91 ||
LatitudeString[count]>96 && LatitudeString[count]<123))
{
printf("string has illegal characters\n");
return 0;
}
if (LatitudeString[count]>96)
LatitudeString[count]-=32;
}
// convert Longitude String to Longitude number.
SetString[0] = LongitudeString[0];
SetString[1] = LongitudeString[1];
SignForZero=1;
// in case the number is between -0.9999 to -0.0001 there should be a manipulation
if (SetString[0]==90)
{
SignForZero = -1;
SetString[0]= 71;
}
PassFail = Base26ToNum(SetString,&RetNum);
if (PassFail = Fail)
return 0;
// add the delta for longitude
RetNum-=180;
if (RetNum<0)
Sign=-1;
else
Sign=1;
if (RetNum<-180 || RetNum>180)
{
printf("string parameters out of limits\n");
return 0;
}
*ReturnLongitude = (float)RetNum;
SetString[0] = LongitudeString[2];
SetString[1] = LongitudeString[3];
PassFail = Base26ToNum(SetString,&RetNum);
if (PassFail = Fail)
return 0;
if (RetNum<0 || RetNum>99)
{
printf("string parameters out of limits\n");
return 0;
}
*ReturnLongitude+=((float)RetNum*(float)0.01)*Sign;
SetString[0] = LongitudeString[4];
SetString[1] = LongitudeString[5];
PassFail = Base26ToNum(SetString,&RetNum);
if (PassFail = Fail)
return 0;
if (RetNum<0 || RetNum>99)
{
printf("string parameters out of limits\n");
return 0;
} *ReturnLongitude+=((float)RetNum*(float)0.0001)*Sign;
*ReturnLongitude *= SignForZero;
// convert Latitude string to Latitude number
SetString[0] = LatitudeString[0];
SetString[1] = LatitudeString[1];
// in case the number is between -0.9999 to -0.0001 there should be a manipulation
SignForZero=1;
if (SetString[0]==90)
{
SignForZero = -1;
SetString[0]= 68;
}
PassFail = Base26ToNum(SetString,&RetNum);
if (PassFail = Fail)
return 0;
// add the delta for latitude
RetNum-=90;
if (RetNum<-90 || RetNum>90)
{
printf("string parameters out of limits\n");
return 0;
}
if (RetNum<0)
Sign=-1;
else
Sign=1;
*ReturnLatitude = (float)RetNum;
SetString[0] = LatitudeString[2];
SetString[1] = LatitudeString[3];
PassFail = Base26ToNum(SetString,&RetNum);
if (PassFail = Fail)
return 0; if (RetNum<0 || RetNum>99)
{
printf("string parameters out of limits\n");
return 0;
}
*ReturnLatitude+=((float)RetNum*(float)0.01)*Sign;
SetString[0] = LatitudeString[4];
SetString[1] = LatitudeString[5];
PassFail = Base26ToNum(SetString,&RetNum);
if (PassFail = Fail)
return 0;
if (RetNum<0 || RetNum>99)
{
printf("string parameters out of limits\n");
return 0;
}
*ReturnLatitude+=((float)RetNum*(float)0.0001)*Sign;
*ReturnLatitude*=SignForZero;
return 1;
}
int Base26ToNum(char *SetString, int *RetNum)
{
/* ======================================================================
function name : Base26ToNum
function activity : convert a string value to integer according to
Base26
input parameters : char *SetString - the string to be translated
output parameters: int *RetNum - the translated integer variable
int Return Value - the function success or failure.
"1" = success otherwise fail
========================================================================= */
int Multiply;
int Add;
Multiply = SetString[0]-65;
Add = SetString[1]-65;
*RetNum = Multiply*26+Add;
return 1;
}
关注点
在将数字从 -0.9999 转换为 -0.0001 时存在一个问题,因为没有负零的概念,因此代码中使用了某种操作。
历史
- 这是第一个版本。
