Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / GPS

Base26GPS Standard Code Implementation

5.00/5 (1 vote)
15 Jun 2013CPOL2 min read 9.4K  
This tip describes the code for the Base26GPS standard.

Introduction

The Base26GPS standard is used for sharing location between platforms by converting the longitude and latitude to a string. The string is from A to Z, having 26 characters all together thus making it a Base26 in the numeral system which is also known as Hexavigesimal. In this tip, I will describe the code that is used to implement it.

For more information, you can visit the website here.

Background

Location is based on Longitude and Latitude. Longitude is a number between -180.0 to 180 and latitude is a number between -90 to 90. Until now, applications from different platforms did not have a standard to send the location between one another, they used their own internal standards. It has a small ressemblance to the time before XML and after XML

Using the Code

There are two functions:

  • LocToBase26 - converts Longitude and Latitude to a string
  • Base26ToLoc - converts a string to Longitude and Latitude

Converting from Longitude and Latitude to Alphabetic letters is done using the following steps:

  1. The first three letters are "GPS", next six letters represent Longitude and last six letters represent Latitude. All together fifteen letters. 
  2. The Longitude and Latitude should always have 4 numbers after the dot.
    For example: -180 will be -180.0000, 12.53 will be 12.5300 and 151.45319 will be 151.4532
  3. Each one is separated to the number located at the left side of the decimal point and the number located at the right of the decimal point.
  4. The left number is from -180 to 180 for Longitude. -180 equals to AA and 180 equals to NW. Here the counting begins from -180.
    For Latitude, the left number is from -90 to 90. -90 equals to AA and 90 equals to GY. Here the counting begins from -90.
  5. The right number is divided into two groups. Each group is from 00 to 99. 00 equals to AA and 99 equals to DV. Here the counting begins from 0.
  6. After conversion, there are six letters for Longitude and six letters for Latitude.
    For example – Longitude of 12.45 and Latitude of -11.54 will generate the string
    "GPSHKBTAADBCCAA".

Converting from alphabetic letters to Longitude and Latitude is done using the same principle.

Here is the code for the LocToBase26.c :

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;
}
C++
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;
}
C++
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;
 
}
C++
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;
}

Here is the code for the Base26ToLoc.c:

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;
 }
C++
 // 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;
 
}
C++
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;
}

Points of Interest

There is an issue with translating numbers from -0.9999 to -0.0001 because there is no such thing as a negative zero, therefore a manipulation in the code was used.

History

  • This is the first version.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)