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

Java Implementation of the Base26GPS Standard

4.00/5 (1 vote)
22 Jul 2013CPOL4 min read 13K  
This tip describes the Java implementation of Base26GPS.

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. This code can be used as the driver for an Android based application that uses Base26GPS.

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 resemblance to the time before XML and after XML.

Using the Code

There are two classes:

  • LocToBase26GPS - converts Longitude and Latitude to a string
  • Base26GPSToLoc - 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 LocToBase26GPS class:

Java
public class LocToBase26GPS { 
 /* ====================================================================
  * Class Name : LocToBase26GPS
  * Class Activity : Convert Location to Base26GPS
  =====================================================================*/
 private String base26GPSString; 
 private float longitude;
 private float latitude;
 private String faultMessage;
 private boolean isFault;

Return the translated string:

Java
 public String Base26GPSString() {
  return base26GPSString;  
}

Return the fault message:

Java
public String FaultMessage() {
  return faultMessage;
}

Return the fault flag:

Java
public boolean IsFault() {
  return isFault;
}

Constructor:

Java
public LocToBase26GPS() {}

Send the longitude and latitude to be translated to string:

Java
public void LocToBase26GPSTranslate(float Longitude,float Latitude) {
  /* ====================================================================== 
  * public function
  * function name : LocToBase26GPSTranslate                                  
  * 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 
  *  ======================================================================= */
   
  longitude = Longitude;
  latitude = Latitude;
  String LongitudeString = "";
  String LatitudeString = "";
 
  base26GPSString = "";
  faultMessage = "";
  isFault = false;

Generate the Longitude part string:

Java
LongitudeString = LongitudeToBase26GPS(longitude);
if (isFault)
 return;

Generate the Latitude part string:

Java
LatitudeString = LatitudeToBase26GPS(latitude);
if (isFault)
 return;

Attach the "GPS" header:

Java
base26GPSString = "GPS" + LongitudeString + LatitudeString;  
         
    }

Convert Longitude to string:

Java
private String LongitudeToBase26GPS(float longitude) {
  /* ====================================================================== 
  * private function
  * function name : LongitudeToBase26GPS                                  
  * function activity : convert Longitude parameter to string 
  *                    according to Base26GPS standard
  * input parameters : float Longitude - the Longitude to be translated                      
  *  ======================================================================= */
  
     float TempFloat;
     double FractPart;
     double TempFractPart;
     double IntPart;
     int Multiply;
     int Add;
     int Sign;
     String ReturnString = "";

Check the limits of the longitude:

Java
if (longitude < -180 || longitude > 180)
{
 faultMessage = "Longitude Parameter out of limits";
 isFault = true;
 return ReturnString;
}
if (longitude < 0)
{
 longitude -= (float)0.00005;
 Sign = -1;
}
else
{
 longitude += (float)0.00005;
 Sign = 1;
}

Get the integral part:

Java
IntPart = ((double)Math.floor(Math.abs(longitude)))*Sign;

Get the fract part:

Java
FractPart = Math.abs(((double)longitude - IntPart)*10000);

Get the base26 multiply part of the int part. the start is from -180:

Java
TempFloat = (float)((((int)(IntPart) + 180) / 26));
      Multiply = (int)TempFloat + 65;

If the Longitude is between -0.9999 to -0.0001, use the letter Z:

Java
if ((int)longitude == 0 && Sign == -1)
             Multiply = 90;

Add the result to the string:

Java
ReturnString += (char)(Multiply);
         
TempFloat = (float)((((((IntPart) + 180) / 26) - 
(int)(((IntPart) + 180) / 26)) * 26) + 0.1);

Get the base26 add part of the int part:

Java
Add = (int)(TempFloat) + 65;

Add the result to the string:

Java
ReturnString += (char)(Add);

Get the base26 multiply part of the first couple fract part:

Java
TempFractPart = FractPart / 100;
TempFloat = (float)(((int)TempFractPart / 26));
Multiply = (int)TempFloat + 65;

Add the result to the string:

Java
ReturnString += (char)(Multiply);
TempFloat = (float)((((((TempFractPart)) / 26) - 
(int)(((TempFractPart)) / 26)) * 26));

Get the base26 add part of the first couple fract part:

Java
Add = (int)TempFloat + 65;

Add the result to the string:

Java
ReturnString += (char)(Add);

Get the base26 multiply part of the second couple fract part:

Java
TempFractPart = ((FractPart) / 100 - 
(int)((FractPart) / 100)) * 100;
TempFloat = (float)((TempFractPart / 26));
Multiply = (int)TempFloat + 65;

Add the result to the string:

Java
ReturnString += (char)(Multiply);

Get the base26 add part of the second couple fract part:

Java
TempFloat = (float)((((((TempFractPart)) / 26) - 
(int)(((TempFractPart)) / 26)) * 26));
Add = (int)TempFloat + 65;

Add the result to the string:

Java
ReturnString += (char)(Add);
return ReturnString;

Convert Latitude to string. it has the same principle as the Longitude:

Java
private String LatitudeToBase26GPS(float latitude)  {
/* ====================================================================== 
* private function
* function name : LatitudeToBase26GPS                                  
* function activity : convert Latitude parameter to string 
*                    according to Base26GPS standard
* input parameters : float Latitude - the Longitude to be translated
*  ======================================================================= */
   
     float TempFloat;
     double FractPart;
     double TempFractPart;
     double IntPart;
     int Multiply;
     int Add;
     int Sign;
     String ReturnString = "";
     // check the limits of the longitude
     if (latitude < -90 || latitude > 90)
     {
         faultMessage = "Langitude Parameter out of limits";
         isFault = true;
         return ReturnString;
     }
     if (latitude < 0)
     {
         latitude -= (float)0.00005;
         Sign = -1;
     }
     else
     {
         latitude += (float)0.00005;
         Sign = 1;
     }
     // get the integral part
     IntPart = ((double)Math.floor(Math.abs(latitude))) * Sign;
     // get the fract part
     FractPart = Math.abs((double)latitude - IntPart) * 10000;
     // get the base26 multiply part of the 
     // integral part. the start is from -180
     TempFloat = (float)((((int)(IntPart) + 90) / 26));
     Multiply = (int)TempFloat + 65;         
     // if the Latitude is between -0.9999 to -0.0001 use the letter Z
     if ((int)latitude == 0 && Sign == -1)
         Multiply = 90;
     // add the result to the string
     ReturnString += (char)(Multiply);
     // get the base26 add part of the integral part.
     TempFloat = (float)((((((IntPart) + 90) / 26) - 
     (int)(((IntPart) + 90) / 26)) * 26) + 0.1);
     Add = (int)(TempFloat) + 65;
     // add the result to the string
     ReturnString += (char)(Add);
     // get the base26 multiply part of the first couple of fract part.
     TempFractPart = FractPart / 100;
     TempFloat = (float)(((int)TempFractPart / 26));
     Multiply = (int)TempFloat + 65;
     ReturnString += (char)(Multiply);
     // get the base26 add part of the first couple of fract part.
     TempFloat = (float)((((((TempFractPart)) / 26) - 
     (int)(((TempFractPart)) / 26)) * 26));
     Add = (int)TempFloat + 65;
     // add the result to the string
     ReturnString += (char)(Add);         
     // get the base26 multiply part of the first couple of fract part.
     TempFractPart = ((FractPart) / 100 - 
     (int)((FractPart) / 100)) * 100;
     TempFloat = (float)((TempFractPart / 26));
     Multiply = (int)TempFloat + 65;
     // add the result to the string
     ReturnString += (char)(Multiply);
     // get the base26 add part of the second couple of fract part.
     TempFloat = (float)((((((TempFractPart)) / 26) - 
     (int)(((TempFractPart)) / 26)) * 26));
     Add = (int)TempFloat + 65;
     // add the result to the string
    ReturnString += (char)(Add);
     return ReturnString;     
}

Here is the code for the Base26GPSToLoc class:

Java
public class Base26GPSToLoc {
 /* ====================================================================
  * Class Name : Base26GPSToLoc
  * Class Activity : Convert Location to Base26GPS
  =====================================================================*/
    private float longitude = 0;
    private float latitude = 0;   
    private String faultMessage;
    private boolean isFault;

Return the fault message:

Java
  public String FaultMessage()  {
  return faultMessage;
}

Return the fault flag:

Java
    public boolean IsFault()    {
     return isFault;     
}

Return the translated Longitude:

Java
    public float Longitude()    {     
      return longitude;    
}

Return the translated Latitude:

Java
public float Latitude()    {
     return latitude;
}

Constructor:

Java
public Base26GPSToLoc()    {}

Send the String to be translated to Longitude and Latitude:

Java
public void Base26GPSToLocTranslate(String Base26GPSString)   {
 /* ====================================================================== 
* public function
* function name : Base26GPSToLocTranslate                                  
* function activity : convert Base26GPS String to Longitude and Latitude
*                     parameters according to Base26GPS standard
* input parameters : String Base26GPSString - the String to be translated                      
*  ======================================================================= */
 
    String LongitudeString = "";
    String LatitudeString = "";
    String SetString = "";
    int RetNum;
    int Count;
    int Sign;
    int SignForZero = 1;
    faultMessage = "";
    isFault = false;
    
    try
    {

Check the length of the string:

Java
if (Base26GPSString.length() != 15)
{
    faultMessage = "the string length does not match";
    isFault = true;
    return;
}

Check if the header of the string is GPS:

Java
if ( !((Base26GPSString.substring(0, 3)).toUpperCase()).equals("GPS"))
{
    faultMessage = "GPS Header is missing";
    isFault = true;
    return;
}

Extract the longitude part of the string:

Java
LongitudeString = Base26GPSString.substring(3, 9).toUpperCase();

Extract the latitude part of the string:

Java
LatitudeString = Base26GPSString.substring(9, 15).toUpperCase();

Check that all characters are legal (A..Z):

Java
for (Count = 0; Count < 6; Count++)
{
 
     if (!(((int)((LongitudeString.substring(
       Count, Count+1)).toCharArray()[0])) > 64 &&
        ((int)((LongitudeString.substring
        (Count, Count+1)).toCharArray()[0])) < 91))
    {
        faultMessage = "Longitude string has illegal characters";
        isFault = true;
        return;
    }             
    if (!(((int)((LatitudeString.substring
    (Count, Count+1)).toCharArray()[0])) > 64 &&
        ((int)((LatitudeString.substring
        (Count, Count+1)).toCharArray()[0])) < 91))
    {
        faultMessage = "Latitude string has illegal characters";
        isFault = true;
        return;
    }                
}

Longitude activity:

Check if the letter Z is in the integral part. If so, it means there is a negative zero.

Java
if ((int)(LongitudeString.substring(0, 1).toCharArray()[0]) == 90)
{
    SetString = "";
    SetString += (char)71;
    SignForZero = -1;
}
else
{
    // get the multiply letter of the integral part
    SetString = LongitudeString.substring(0, 1);
    SignForZero = 1;
}

Get the add letter from the integral part:

Java
SetString += LongitudeString.substring(1, 2);

Convert to number from base26:

Java
RetNum = Base26ToNum(SetString);
if (isFault == true)
    return;

The longitude integral part starts from -180:

Java
RetNum -= 180;
if (RetNum < 0)
    Sign = -1;
else
    Sign = 1;

Check the outcome limits:

Java
if (RetNum < -180 || RetNum > 180)
{
    faultMessage = "Longitude string parameter out of limits";
    isFault = true;
    return;
}

Add the result to longitude:

Java
longitude = (float)RetNum;

Get the two letters of the first couple of the fract part:

Java
SetString = LongitudeString.substring(2, 4);

Convert to number from base26:

Java
RetNum = Base26ToNum(SetString);
if (isFault == true)
    return;

Check the outcome limits:

Java
if (RetNum < 0 || RetNum > 99)
{
    faultMessage = "Longitude string parameter out of limits";
    isFault = true;
    return;
}

Add the result to longitude:

Java
longitude += ((float)RetNum * (float)0.01) * Sign;

Get the two letters of the second couple of the fract part:

Java
SetString = LongitudeString.substring(4, 6);
RetNum = Base26ToNum(SetString);
if (isFault == true)
    return;

Check the outcome limits:

Java
if (RetNum < 0 || RetNum > 99)
{
    faultMessage = "Longitude string parameter out of limits";
    isFault = true;
    return;
}

Add the result to longitude:

Java
longitude += ((float)RetNum * (float)0.0001) * Sign;

If negative zero, then add minus to the result:

Java
longitude *= SignForZero;

Latitude activity (same principle as latitude activity):

Java
    // check if the letter Z is in the integral part        
    // if so it means there is a negative zero
    if ((int)(LatitudeString.substring(0, 1).toCharArray()[0]) == 90)
    {
        SetString = "";
        SetString += (char)68;
        SignForZero = -1;
    }
    else
    {
    // get the multiply letter of the integral part
     SetString = LatitudeString.substring(0, 1);
        SignForZero = 1;
    }
    // get the add letter of the integral part
    SetString += LatitudeString.substring(1, 2);
    // convert to number from base26
    RetNum = Base26ToNum(SetString);
    if (isFault == true)
        return;
    
    // the latitude integral part starts from -180
    RetNum -= 90;
    if (RetNum < 0)
        Sign = -1;
    else
        Sign = 1;
    // check the outcome limits
    if (RetNum < -90 || RetNum > 90)
    {
        faultMessage = "Latitude string parameter out of limits";
        isFault = true;
        return;
    }
            
    // add the result to latitude
    latitude = (float)RetNum;
    //get the two letters of the first couple of the fract part
    SetString = LatitudeString.substring(2, 4);            
    RetNum = Base26ToNum(SetString);
    if (isFault == true)
        return;            // check the outcome limits
    if (RetNum < 0 || RetNum > 99)
    {
        faultMessage = "Latitude string parameter out of limits";
        isFault = true;
        return;
    }
    // add the result to latitude
    latitude += ((float)RetNum * (float)0.01) * Sign;
    //get the two letters of the second couple of the fract part
    SetString = LatitudeString.substring(4, 6);            
    RetNum = Base26ToNum(SetString);
    if (isFault == true)
        return;            // check the outcome limits
    if (RetNum < 0 || RetNum > 99)
    {
        faultMessage = "Latitude string parameter out of limits";
        isFault = true;
        return;
    }
    // add the result to longitude
    latitude += ((float)RetNum * (float)0.0001) * Sign;
    // if negative zero then add minus to the result
    latitude *= SignForZero;
}

Handle an exception if there is...

Java
    catch (Exception e)
    {
        faultMessage = "string parameters illegal";
        isFault = true;
        return;
    }
}

Convert Base26 to number function:

Java
private int Base26ToNum(String SetString)    {
     /* ====================================================================== 
  * private function
  * function name : Base26ToNum                                  
  * function activity : convert two chars string to Base26 
  *                    according to Base26GPS standard
  * input parameters :String SetString - the String to be translated
  * output parameters : int - the base26 value                      
  *  ======================================================================= */
     
        int Multiply;
        int Add;
        int RetNum;
        try
        {

Get the multiply part:

Java
Multiply = (SetString.substring(0, 1).toCharArray()[0]) - 65;

Get the add part:

Java
Add = (SetString.substring(1, 2).toCharArray()[0]) - 65;

the result from base26:

Java
    RetNum = Multiply * 26 + Add;
    return RetNum;
}
catch (Exception e)
{
    faultMessage = "Base26ToNum Fault";
    isFault = true;
    return 0;
}

Points of Interest

I used Eclipse for this. Actually, this is my first project in Java. I have a lot of knowledge in C# and object oriented. converting to Java is quite easy.

History

There is an ANSI C and JavaScript version of this code also. I published them both here.

License

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