Base26GPS Standard Code Implementation
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
- convertsLongitude
andLatitude
to astring
Base26ToLoc
- converts astring
toLongitude
andLatitude
Converting from Longitude
and Latitude
to Alphabetic letters is done using the following steps:
-
The first three letters are "GPS", next six letters represent
Longitude
and last six letters representLatitude
. All together fifteen letters. - The
Longitude
andLatitude
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 - 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.
- 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.
ForLatitude
, the left number is from -90 to 90. -90 equals to AA and 90 equals to GY. Here the counting begins from -90. - 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.
- After conversion, there are six letters for
Longitude
and six letters forLatitude
.
For example –Longitude
of 12.45 andLatitude
of -11.54 will generate thestring
"GPSHKBTAADBCCAA
".
Converting from alphabetic letters to Longitude
and Latitude
is done using the same principle.
Here is the code for the 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;
}
Here is the code for the 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;
}
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.