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

JavaScript Implementation of Base26GPS Standard

5.00/5 (1 vote)
29 Jun 2013CPOL4 min read 7.4K  
This is the JavaScript implementation of Base26GPS Standard

Introduction

I am continuing the tip about the implementation in ANSI C.

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.

Using the Code

There are two functions:

  • ConcertLocToBase26 - converts Longitude and Latitude to a string
  • ConvertBase26ToLoc - 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.

Below are the JavaScript functions that convert from Longitude, Latitude to Base26GPS and vise versa.

I learned some things while writing this code.

For example, I noticed the Google Chrome does not support in a transparant manner the 'GetElementById' which searches the name of the form box. Instead, I had to dig into the path of the form.
Another thing I studied is how to manipulate inside a string and how to convert it to decimal value and I also learned how to return more than one variable from a function.
What amazes me in JavaScript is that there is no need to declare the variable's type.

The thing I enjoyed the most is using my own browser to debug and run the script. There is no need for any external compilers. I used a Debug box form to display variables for debugging and that's it...

C#
function ConvertLongitude(Longitude)
{
 /* ====================================================================== 
 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 : int Return Value [0]- the function success or failure.
                               "1" = success otherwise fail                 
      string ReturnString [1] - a six chars string representing 
                                           the translated Longitude
 ========================================================================= */
 
 var TempFloat;  
 var FractPart;
 var TempFractPart;
 var IntPart;
 var Multiply;
 var Add;
 var Fail = 0;
 var Sign;
 var LongitudeString;

Check for longitude validity:

C#
if (Longitude<-180 || Longitude>180)
{
 ShowError('Longitude parameter out of limits. -180 to 180');
 return [0,0];
}
if (Longitude<0)
{
 Longitude-=0.00005;
 Sign=-1;
}
else
{
 Longitude+=0.00005;
 Sign=1;
}

Get the integer part:

C#
IntPart=MakeInteg(Longitude);

Get the fraction part:

C#
FractPart=Math.abs(Longitude - IntPart)*10000;

Get the two letters of the integer part:

C#
TempFloat=MakeInteg((IntPart+180)/26);
Multiply=TempFloat+65;

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

C#
if (MakeInteg(Longitude)==0 && Sign== -1)
 Multiply=90; LongitudeString=String.fromCharCode(Multiply);
TempFloat=((((IntPart+180)/26) - MakeInteg((IntPart+180)/26))*26)+0.1;
Add = Math.floor(TempFloat)+65;
LongitudeString+=String.fromCharCode(Add);

Get the first two letters of the fract part:

C#
TempFractPart = FractPart/100;
TempFloat = MakeInteg(TempFractPart/26);
Multiply = TempFloat+65;
LongitudeString+=String.fromCharCode(Multiply);
TempFloat=(((TempFractPart/26) - MakeInteg(TempFractPart/26))*26);
Add = Math.floor(TempFloat)+65;
LongitudeString+=String.fromCharCode(Add);

Get the second two letters of the fract part:

C#
TempFractPart = (FractPart/100 - MakeInteg(FractPart/100))*100;
TempFloat = MakeInteg(TempFractPart/26);
Multiply = TempFloat+65;
LongitudeString+=String.fromCharCode(Multiply);
TempFloat=(((TempFractPart/26) - MakeInteg(TempFractPart/26))*26);
Add = Math.floor(TempFloat)+65;
LongitudeString+=String.fromCharCode(Add);

Return the longitude string:

C#
 return[1,LongitudeString];
}
C#
function ConvertLatitude(Latitude)
{
 /* ====================================================================== 
 function name : ConvertLatitude                                  
 function activity : convert Latitude parameter to string according to
                     Base26GPS standard
 input parameters : float Latitude - the Longitude to be translated 
 output parameters : int Return Value [0]- the function success or failure.
                               "1" = success otherwise fail                 
      string ReturnString [1] - a six chars string representing 
                                           the translated Latitude
 ========================================================================= */
 var TempFloat;  
 var FractPart;
 var TempFractPart;
 var IntPart;
 var Multiply;
 var Add;
 var Fail = 0;
 var Sign;
 var LatitudeString;

Check for validity:

C#
if (Latitude<-90 || Latitude>90)
{
 ShowError('Latitude parameter out of limits. -90 to 90');
 return [0,0];
}

if (Latitude<0)
{
 Latitude-=0.00005;
 Sign=-1;
}
else
{
 Latitude+=0.00005;
 Sign=1;
}

Get the integer part:

C#
IntPart=MakeInteg(Latitude);

Get the fract part:

C#
FractPart=Math.abs(Latitude - IntPart)*10000;

Get the two letters of the integer part:

C#
TempFloat=MakeInteg((IntPart+90)/26);
Multiply=TempFloat+65;

If Latitude is between -0.9999 to -0.001, use the letter 'Z':

C#
if (MakeInteg(Latitude)==0 && Sign== -1)
 Multiply=90;
LatitudeString=String.fromCharCode(Multiply);

TempFloat=((((IntPart+90)/26) - MakeInteg((IntPart+90)/26))*26)+0.1;
Add = MakeInteg(TempFloat)+65;
LatitudeString+=String.fromCharCode(Add);
TempFractPart = FractPart/100;
TempFloat = MakeInteg(TempFractPart/26);
 Multiply = TempFloat+65;
 LatitudeString+=String.fromCharCode(Multiply);

Get the first two letters of the fract part:

C#
TempFloat=(((TempFractPart/26) - MakeInteg(TempFractPart/26))*26);
Add = MakeInteg(TempFloat)+65;
LatitudeString+=String.fromCharCode(Add);
TempFractPart = (FractPart/100 - MakeInteg(FractPart/100))*100;
TempFloat = Math.floor(TempFractPart/26);
Multiply = TempFloat+65;
LatitudeString+=String.fromCharCode(Multiply);

Get the second two letters of the fract part:

C#
TempFloat=(((TempFractPart/26) - Math.floor(TempFractPart/26))*26);
Add = Math.floor(TempFloat)+65;
LatitudeString+=String.fromCharCode(Add);

Return the latitude string:

C#
 return[1,LatitudeString];
}
C#
function ConvertLocToBase26()
{
 /* ====================================================================== 
 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: int Return Value [0] - the function success or failure.
                "1" = success otherwise fail 
        string Base26GPSString [1] - a 15 chars string representing 
                the Base26GPS standard.      
 ========================================================================= */ 
  
 var Longitude;
 var Latitude;
 var ReturnArray;
 
 
 ReturnArray = GetLongitudeLatitude()
 if (ReturnArray[0]==0)
  return 0;
 Longitude = parseFloat(ReturnArray[1]);
 Latitude = parseFloat(ReturnArray[2]);

Set the string header to GPS:

C#
var Base26GPSString='GPS';

Get the longitude string:

C#
ReturnArray=ConvertLongitude(Longitude);
if (ReturnArray[0]==0)
 return 0;

Base26GPSString+=ReturnArray[1];

Get the latitude string:

C#
ReturnArray=ConvertLatitude(Latitude);
if (ReturnArray[0]==0)
 return 0;
Base26GPSString+=ReturnArray[1];

Combined string:

C#
 ShowBase26GPSString(Base26GPSString);
}
C#
function ConvertBase26ToLoc()
{
 var LongitudeString;
 var NewLongitudeString="";
 var LatitudeString;
 var NewLatitudeString="";
 var SetStringMultiply;
 var SetStringAdd;
 var SetString;
 var RetNum;
 var count;
 var PassFail;
 var Fail = 0;
 var Sign;
 var SignForZero;
 var GPSString;
 var ReturnArray;
 var ReturnLongitude;
 var ReturnLatitude;
 
 Base26GPSString = GetBase26GPS();

Check the length. It must be 15.

C#
if (Base26GPSString.length!=15)
{
 ShowError('String must have 15 characters');
 return [0,0,0];
}
GPSString = Base26GPSString.slice(0,3);

// check for GPS header
if (GPSString !='GPS')
{
 ShowError('GPS Header is missing');
 return [0,0,0];
}
LongitudeString = Base26GPSString.slice(3,9);
LatitudeString = Base26GPSString.slice(9,16);

Change the lower case chars to upper case and check for legal characters

C#
for (count=0;count<6;count++)
{
if (!((LongitudeString.slice(count,count+1)).charCodeAt(0)>64 &&
(LongitudeString.slice(count,count+1)).charCodeAt(0)<91 ||
(LongitudeString.slice(count,count+1)).charCodeAt(0)>96 &&
(LongitudeString.slice(count,count+1)).charCodeAt(0)<123))
 {
  ShowError('Longitude string has illegal characters');
  return [0,0,0];
 }
 if ((LongitudeString.slice(count,count+1)).charCodeAt(0)>96)
  NewLongitudeString+=String.fromCharCode
  ((LongitudeString.slice(count,count+1).charCodeAt(0)) -32);
 else
  NewLongitudeString+=LongitudeString.slice(count,count+1);

if (!((LatitudeString.slice(count,count+1)).charCodeAt(0)>64 &&
(LatitudeString.slice(count,count+1)).charCodeAt(0)<91 ||
(LatitudeString.slice(count,count+1)).charCodeAt(0)>96 &&
(LatitudeString.slice(count,count+1)).charCodeAt(0)<123))
 {
  ShowError('Latitude string has illegal characters');
  return [0,0,0];
 }
 if ((LatitudeString.slice(count,count+1)).charCodeAt(0)>96)
  NewLatitudeString+=String.fromCharCode
  (LatitudeString.slice(count,count+1).charCodeAt(0) -32);
 else
  NewLatitudeString+=LatitudeString.slice(count,count+1);
}

Longitude Activity

Extract the integer part:

C#
SetStringMultiply = (NewLongitudeString.slice(0,1));
 SetStringAdd = (NewLongitudeString.slice(1,2));
 
 SignForZero = 1;

Check if the number is between -0.0001 to -0.9999:

C#
if (SetStringMultiply.charCodeAt(0) == (90))
{
 SignForZero = -1;
 SetStringMultiply = String.fromCharCode(71);
}
SetString = SetStringMultiply+SetStringAdd;

RetNum = Base26ToNum(SetString);

Substract the longitude minimum value:

C#
RetNum -=180;

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

Check validity:

C#
if (RetNum<-180 || RetNum>180)
{
 ShowError('string parameters out of limits');
 return [0,0,0];
}
ReturnLongitude=RetNum;

Extract the first fract part pair:

C#
SetString = NewLongitudeString.slice(2,4);
RetNum = Base26ToNum(SetString);


if (RetNum<0 || RetNum>99)
{
 ShowError('string parameters out of limits');
 return 0;
}
ReturnLongitude+=RetNum*0.01*Sign;

Extract the last fract part pair:

C#
SetString = NewLongitudeString.slice(4,6);

RetNum = Base26ToNum(SetString);

if (RetNum<0 || RetNum>99)
{
 ShowError('string parameters out of limits');
 return 0;
}
ReturnLongitude+=RetNum*0.0001*Sign;

ReturnLongitude*=SignForZero;

ShowLongitude(ReturnLongitude);

Latitude Activity

Extract the integer part:

C#
SetStringMultiply = (NewLatitudeString.slice(0,1));
SetStringAdd = (NewLatitudeString.slice(1,2));

SignForZero = 1;

Check if the number is between -0.0001 to -0.9999:

C#
if (SetStringMultiply.charCodeAt(0) == (90))
{
 SignForZero = -1;
 SetStringMultiply = String.fromCharCode(68);
}
SetString = SetStringMultiply+SetStringAdd;

// subasract the latitude minimum value

RetNum = Base26ToNum(SetString);

RetNum -=90;

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

if (RetNum<-90 || RetNum>90)
{
 ShowError('string parameters out of limits');
 return [0,0,0];
}
ReturnLatitude=RetNum;

Extract the first fract part pair:

C#
SetString = NewLatitudeString.slice(2,4);

RetNum = Base26ToNum(SetString);


if (RetNum<0 || RetNum>99)
{
 ShowError('string parameters out of limits');
 return 0;
}
ReturnLatitude+=RetNum*0.01*Sign;

Extract the last fract part pair:

C#
  SetString = NewLatitudeString.slice(4,6);
 
 RetNum = Base26ToNum(SetString);
  
 
 if (RetNum<0 || RetNum>99)
 {
  ShowError('string parameters out of limits');
  return 0;  
 }
 ReturnLatitude+=RetNum*0.0001*Sign;
 
 ReturnLatitude*=SignForZero;
 
 ShowLatitude(ReturnLatitude);
}
C#
function Base26ToNum(InputString)
{
 /* ====================================================================== 
 function name : Base26ToNum   
 function activity : convert a string value to integer according to 
      Base26
 input parameters : InputString - the string to be translated
 output parameters: int Return Value - the integer of the value                
 ========================================================================= */
var Multiply;
var Add;
var RetNum;
Multiply =  (InputString.slice(0,1)).charCodeAt(0) - 65;
Add = (InputString.slice(1,2)).charCodeAt(0) - 65;
RetNum = Multiply * 26 + Add;
return RetNum;
}

I didn't find any function that makes flooring while maintaining the sign bit. So I built one of my own:

C#
function MakeInteg(Value)
{
 /* ====================================================================== 
 function name : MakeInteg                                  
 function activity : convert a value to its integer value with the sign 
 input parameters : float Value - the value to be converted
 output parameters: int Return Value - the integer of the value      
 ========================================================================= */ 
 var ReturnValue;
 var Sign;
 if (Value<0)
  Sign=-1;
 else
  Sign=1
 
 ReturnValue=Math.floor(Math.abs(Value))*Sign;
return ReturnValue;
}

This is the HTML to support the JavaScript:

C#
<form name="LocationToBase26GPSform" 
OnSubmit="javascript:test()">
Location to Base26GPS Online Calculator - 
<br><br><br>
<table border="0">
<tr><td>
Longitude Input : </td><td><input type="text" 
name="LongitudeInput">
</td></tr>
<tr><td>
Latitude Input  : </td><td><input type="text" 
name="LatitudeInput">
</td></tr>
<tr><td>
</td><td><input type="button" 
value="Convert Location " OnClick="javascript:ConvertLocToBase26()">
</td></tr>
<tr><td>
Base26GPS       : </td><td><input type="text" 
size="30" name="Base26GPSInput">
</td></tr>
<tr><td>
</td><td><input type="button" 
value="Convert Base26GPS" OnClick="javascript:ConvertBase26ToLoc()">
</td></tr>
<tr><td>
Longitude Result : </td><td><input type="text" 
name="LongitudeTranslate">
</td></tr>
<tr><td>
Latitude Result  : </td><td><input type="text" 
name="LatitudeTranslate">
</td></tr>
</table>
<br><br>
<!-- Debug = <input type="text" name="DebugText"> -->
<br><br><br>
</form>

These are the JavaScript functions to support the HTML Form:

C#
function ShowLongitude(LongitudeVal)
{
 /* ======================================================================   
 function name : ShowLongitude              
 function activity : display the Longitude
 input parameters : float LongitudeVal - rhe longitude to be displayed
 output parameters: null
 ========================================================================= */
 //document.getElementById('LongitudeTranslate').value = LongitudeVal;
 document.forms['LocationToBase26GPSform']['LongitudeTranslate'].value = LongitudeVal;
}
C#
function ShowLatitude(LatitudeVal)
{
 /* ======================================================================   
 function name : ShowLatitude              
 function activity : display the Latitude
 input parameters : float LatitudeVal - rhe latitude to be displayed
 output parameters: null
 ========================================================================= */
 //document.getElementById('LatitudeTranslate').value = LatitudeVal;
 document.forms['LocationToBase26GPSform']['LatitudeTranslate'].value = LatitudeVal;
}
C#
function ShowBase26GPSString(Base26GPSString)
{
 /* ======================================================================   
 function name : ShowBase26String              
 function activity : display the Base26String
 input parameters : string Base26String - rhe string to be displayed
 output parameters: null
 ========================================================================= */ 
 
 //document.getElementById('Base26GPSInput').value = Base26GPSString;
 document.forms['LocationToBase26GPSform']['Base26GPSInput'].value = Base26GPSString;
 
}
C#
function GetBase26GPS()
{
 //return document.getElementById('Base26GPSInput').value;
 return document.forms['LocationToBase26GPSform']['Base26GPSInput'].value
 
}
C#
function GetLongitudeLatitude(){
 var LongitudeString;
 var LatitudeString;
 
 
 //LongitudeString = document.getElementById('LongitudeInput').value;
 LongitudeString = document.forms['LocationToBase26GPSform']['LongitudeInput'].value;
 
 //LatitudeString = document.getElementById('LatitudeInput').value;
 LatitudeString = document.forms['LocationToBase26GPSform']['LatitudeInput'].value;
 
 if  (isNaN(parseFloat(LongitudeString)))
 {
  ShowError('Longitude parameter illegal');
  return [0,0,0]; 
 }
 
 if  (isNaN(parseFloat(LatitudeString)))
 {
  ShowError('Longitude parameter illegal');
  return [0,0,0]; 
 }
 
 return [1,LongitudeString,LatitudeString];
 
}

History

  • This is the second version of this tip. The first one was in ANSI C.

License

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