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:
- The first three letters are "GPS", next six letters represent
Longitude
and last six letters represent Latitude
. All together fifteen letters. - 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 - 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.
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. - 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 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 :
int ConvertLocToBase26(float Longitude,float Latitude, char *Base26GPSString)
{
int PassFail;
int Fail = 0;
char LongitudeString[6];
char LatitudeString[6];
PassFail = ConvertLongitude(Longitude,LongitudeString);
if (PassFail== Fail)
{
return 0;
}
PassFail = ConvertLatitude(Latitude,LatitudeString);
if (PassFail== Fail)
{
return 0;
}
strcpy(Base26GPSString,"GPS");
strcat(Base26GPSString,LongitudeString);
strcat(Base26GPSString,LatitudeString);
return 1;
}
int ConvertLongitude(float Longitude,char *ReturnString)
{
float TempFloat;
double FractPart;
double TempFractPart;
double IntPart;
int Multiply;
int Add;
int Fail = 0;
int Sign;
if (Longitude<-180 || Longitude>180)
{
printf("Longitude parameter out of limits\n");
return 0;
} if (Longitude<0)
{
Longitude-=(float)0.00005;
Sign=-1;
}
else
{
Longitude+=(float)0.00005;
Sign=1;
} FractPart = fabs(modf((double)Longitude,&IntPart) * 10000);
if (FractPart<0)
FractPart-=0.1;
else
FractPart+=0.1;
TempFloat = (float)((((int)(IntPart)+180)/26));
Multiply = (int)TempFloat+65;
if ((int)Longitude==0 && Sign == -1)
Multiply=90;
ReturnString[0] = Multiply;
TempFloat = (float)((((((IntPart)+180) /26) - (int)(((IntPart)+180)/26) )*26)+0.1);
Add = (int)(TempFloat) + 65;
ReturnString[1] = Add;
TempFractPart = FractPart/100;
TempFloat = (float)(((int)TempFractPart/26));
Multiply = (int)TempFloat+65;
ReturnString[2] = Multiply;
TempFloat = (float)((((((TempFractPart))/26) - (int)(((TempFractPart))/26))*26));
Add = (int)TempFloat+65;
ReturnString[3] = Add;
TempFractPart = ((FractPart)/100 - (int)((FractPart)/100))*100;
TempFloat = (float)((TempFractPart/26));
Multiply = (int)TempFloat+65;
ReturnString[4] = Multiply;
TempFloat = (float)((((((TempFractPart))/26) -
(int)(((TempFractPart))/26))*26)); Add = (int)TempFloat+65;
ReturnString[5] = Add;
ReturnString[6] = 0;
return 1;
}
int ConvertLatitude(float Latitude,char *ReturnString)
{
float TempFloat;
double FractPart;
double TempFractPart;
double IntPart;
int Multiply;
int Add;
int Sign;
if (Latitude<-90 || Latitude>90)
{
printf("Latitude parameter out of limits\n");
return 0;
} if (Latitude<0)
{
Latitude-=(float)0.00005;
Sign = -1;
}
else
{
Latitude+=(float)0.00005;
Sign = 1;
}
FractPart = fabs(modf((double)Latitude,&IntPart) * 10000);
TempFloat = (float)(((IntPart+90)/26));
Multiply = (int)TempFloat + 65;
if ((int)Latitude==0 && Sign == -1)
Multiply=90;
ReturnString[0] = Multiply;
TempFloat = (float)(((((IntPart+90) /26) - (int)((IntPart+90)/26) )*26)+0.1);
Add = (int) TempFloat + 65;
ReturnString[1] = Add;
TempFractPart = FractPart/100;
TempFloat = (float)((TempFractPart/26));
Multiply = (int)TempFloat+65;
ReturnString[2] = Multiply;
TempFloat = (float)(((((TempFractPart)/26) - (int)((TempFractPart)/26))*26));
Add = (int)TempFloat+65;
ReturnString[3] = Add;
TempFractPart = (FractPart/100 - (int)(FractPart/100))*100;
TempFloat = (float)((TempFractPart/26));
Multiply = (int)TempFloat + 65;
ReturnString[4] = Multiply;
TempFloat = (float)(((((TempFractPart)/26) - (int)((TempFractPart)/26))*26));
Add = (int)TempFloat + 65; ReturnString[5] = Add;
ReturnString[6] = 0;
return 1;
}
int ConvertStringToSingle(char *StringVar, float *ReturnSingleVar)
{
*ReturnSingleVar = (float)atof(StringVar);
return 1;
}
Here is the code for the Base26ToLoc.c:
int ConvertBase26ToLoc
(char *Base26GPSString,float *ReturnLongitude, float *ReturnLatitude)
{
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;
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;
}
strncpy(LongitudeString,Base26GPSString+3,6);
strncpy(LatitudeString,Base26GPSString+9,6); 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;
}
SetString[0] = LongitudeString[0];
SetString[1] = LongitudeString[1];
SignForZero=1;
if (SetString[0]==90)
{
SignForZero = -1;
SetString[0]= 71;
}
PassFail = Base26ToNum(SetString,&RetNum);
if (PassFail = Fail)
return 0;
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;
SetString[0] = LatitudeString[0];
SetString[1] = LatitudeString[1];
SignForZero=1;
if (SetString[0]==90)
{
SignForZero = -1;
SetString[0]= 68;
}
PassFail = Base26ToNum(SetString,&RetNum);
if (PassFail = Fail)
return 0;
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)
{
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.