This function encodes a gerneric List of LatLong objects into a string for simplicity and performance.
/// <summary>
/// encoded a list of latlon objects into a string
/// </summary>
/// <param name="points">the list of latlon objects to encode</param>
/// <returns>the encoded string</returns>
public static string EncodeLatLong(List<LatLong> points)
{
int plat = 0;
int plng = 0;
int len = points.Count;
StringBuilder encoded_points = new StringBuilder();
for (int i = 0; i < len; ++i)
{
//Round to 5 decimal places and drop the decimal
int late5 = (int)(points[i].Lat * 1e5);
int lnge5 = (int)(points[i].Lon * 1e5);
//encode the differences between the points
encoded_points.Append(encodeSignedNumber(late5 - plat));
encoded_points.Append(encodeSignedNumber(lnge5 - plng));
//store the current point
plat = late5;
plng = lnge5;
}
return encoded_points.ToString();
}
/// <summary>
/// Encode a signed number in the encode format.
/// </summary>
/// <param name="num">the signed number</param>
/// <returns>the encoded string</returns>
private static string encodeSignedNumber(int num)
{
int sgn_num = num << 1; //shift the binary value
if (num < 0) //if negative invert
{
sgn_num = ~(sgn_num);
}
return (encodeNumber(sgn_num));
}
/// <summary>
/// Encode an unsigned number in the encode format.
/// </summary>
/// <param name="num">the unsigned number</param>
/// <returns>the encoded string</returns>
private static string encodeNumber(int num)
{
StringBuilder encodeString = new StringBuilder();
while (num >= 0x20)
{
//while another chunk follows
encodeString.Append((char)((0x20 | (num & 0x1f)) + minASCII));
//OR value with 0x20, convert to decimal and add 63
num >>= binaryChunkSize; //shift to next chunk
}
encodeString.Append((char)(num + minASCII));
return encodeString.ToString();
}