I have some C# code that decodes map paths encoded using Google's polyline algorithm and am trying to convert it to VB.NET.
Here's the C# code, which works fully:
Collection<Double> decodePolyline(string polyline)
{
if (polyline == null || polyline == "") return null;
char[] polylinechars = polyline.ToCharArray();
int index = 0;
Collection<Double> points = new Collection<Double>();
int currentLat = 0;
int currentLng = 0;
int next5bits;
int sum;
int shifter;
while (index < polylinechars.Length)
{
// calculate next latitude
sum = 0;
shifter = 0;
do
{
next5bits = (int)polylinechars[index++] - 63;
sum |= (next5bits & 31) << shifter;
shifter += 5;
} while (next5bits >= 32 && index < polylinechars.Length);
if (index >= polylinechars.Length)
break;
currentLat += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1);
//calculate next longitude
sum = 0;
shifter = 0;
do
{
next5bits = (int)polylinechars[index++] - 63;
sum |= (next5bits & 31) << shifter;
shifter += 5;
} while (next5bits >= 32 && index < polylinechars.Length);
if (index >= polylinechars.Length && next5bits >= 32)
break;
currentLng += (sum & 1) == 1 ? ~(sum >> 1) : (sum >> 1);
points.Add(Convert.ToDouble(currentLat) / 100000.0);
points.Add(Convert.ToDouble(currentLng) / 100000.0);
}
return points;
}
Here's the VB.NET code- works for the longitudes but not latitudes.
Public Function decodePolyline(ByVal polyline As String) As Collection(Of Double)
If polyline Is Nothing OrElse polyline = "" Then Return Nothing
Dim polylinechars As Char() = polyline.ToCharArray()
Dim points As New Collection(Of Double)
Dim currentLat As Integer = 0
Dim currentLng As Integer = 0
Dim next5bits As Integer
Dim sum As Integer
Dim shifter As Integer
For index As Integer = 0 To polylinechars.Length - 1
'calculate next latitude
sum = 0
shifter = 0
Do
index += 1
next5bits = AscW(polylinechars(index)) - 63
sum = sum Or (next5bits And 31) << shifter
shifter += 5
Loop While next5bits >= 32 AndAlso index < polylinechars.Length
If index >= polylinechars.Length Then
Exit For
End If
currentLat += If((sum And 1) = 1, Not (sum >> 1), (sum >> 1))
'calculate next longitude
sum = 0
shifter = 0
Do
index += 1
next5bits = AscW(polylinechars(index)) - 63
sum = sum Or (next5bits And 31) << shifter
shifter += 5
Loop While next5bits >= 32 AndAlso index < polylinechars.Length
If index >= polylinechars.Length AndAlso next5bits >= 32 Then
Exit For
End If
currentLng += If((sum And 1) = 1, Not (sum >> 1), (sum >> 1))
points.Add(Convert.ToDouble(currentLat) / 100000.0)
points.Add(Convert.ToDouble(currentLng) / 100000.0)
Next
Return points
End Function
What's missing?
EDIT: Resolved the issue (corrected code in my answer below, which I can't select as an answer for 2 more days).
The best way to do it if you don't know the target language, compile your source code in debug mode, and then decompile it using Reflector. That way you keep the var names, and your sure the generated code is valid.
Be aware that VB.Net has "delicate" logical operators that could break your code logic : OR vs OrElse...
Ah so the issue was that the C# ++
operator increments the variable but returns the original value, whereas my VB.NET conversion above was incrementing index and then using the incremented value. That somehow still worked for longitudes but messed up the latitude decoding.
Here's the corrected VB.NET code:
Public Function decodePolyline(ByVal polyline As String) As Collection(Of Double)
If polyline Is Nothing OrElse polyline = "" Then Return Nothing
Dim polylinechars As Char() = polyline.ToCharArray()
Dim points As New Collection(Of Double)
Dim currentLat As Integer = 0
Dim currentLng As Integer = 0
Dim next5bits As Integer
Dim sum As Integer
Dim shifter As Integer
Dim index As Integer = 0
While index < polylinechars.Length
' calculate next latitude
sum = 0
shifter = 0
Do
index += 1
next5bits = AscW(polylinechars(index - 1)) - 63
sum = sum Or (next5bits And 31) << shifter
shifter += 5
Loop While next5bits >= 32 AndAlso index < polylinechars.Length
If index >= polylinechars.Length Then
Exit While
End If
currentLat += If((sum And 1) = 1, Not (sum >> 1), (sum >> 1))
'calculate next longitude
sum = 0
shifter = 0
Do
index += 1
next5bits = AscW(polylinechars(index - 1)) - 63
sum = sum Or (next5bits And 31) << shifter
shifter += 5
Loop While next5bits >= 32 AndAlso index < polylinechars.Length
If index >= polylinechars.Length AndAlso next5bits >= 32 Then
Exit While
End If
currentLng += If((sum And 1) = 1, Not (sum >> 1), (sum >> 1))
points.Add(Convert.ToDouble(currentLat) / 100000.0)
points.Add(Convert.ToDouble(currentLng) / 100000.0)
End While
Return points
End Function
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With