65.9K
CodeProject 正在变化。 阅读更多。
Home

Base26GPS 标准代码实现

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2013年6月15日

CPOL

2分钟阅读

viewsIcon

9610

本文档描述了 Base26GPS 标准的代码实现。

引言

Base26GPS 标准用于在不同平台之间共享位置信息,通过将经度和纬度转换为字符串来实现。该字符串由 A 到 Z 的 26 个字符组成,因此在数字系统中是 Base26,也称为二十六进制。 在本文档中,我将描述用于实现它的代码。

更多信息,请访问网站 这里

背景

位置信息基于经度和纬度。 经度是一个 -180.0 到 180 之间的数字,纬度是一个 -90 到 90 之间的数字。 至今,不同平台的应用程序在彼此之间发送位置信息时没有统一的标准,它们使用各自的内部标准。 这有点类似于 XML 出现之前的情况。

Using the Code

有两个函数:

  • LocToBase26 - 将经度和纬度转换为字符串
  • Base26ToLoc - 将字符串转换为经度和纬度

从经度和纬度转换为字母的步骤如下:

  1. 前三个字母是“GPS”,接下来的六个字母代表经度,最后六个字母代表纬度。 总共十五个字母。
  2. 经度和纬度应该始终在小数点后有四位数字。
    例如:-180 将变为 -180.0000,12.53 将变为 12.5300,151.45319 将变为 151.4532
  3. 每个数字都分为小数点左侧的数字和小数点右侧的数字。
  4. 左侧的数字对于经度来说是从 -180 到 180。 -180 等于 AA,180 等于 NW。 计数从 -180 开始。
    对于纬度,左侧的数字是从 -90 到 90。 -90 等于 AA,90 等于 GY。 计数从 -90 开始。
  5. 右侧的数字分为两组。 每组从 00 到 99。 00 等于 AA,99 等于 DV。 计数从 0 开始。
  6. 转换后,经度有六个字母,纬度也有六个字母。
    例如 – 经度为 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 时存在一个问题,因为没有负零的概念,因此代码中使用了某种操作。

历史

  • 这是第一个版本。
© . All rights reserved.