5

我有一些 C# 代码可以解码使用 Google 的折线算法编码的地图路径,并试图将其转换为 VB.NET。

这是 C# 代码,它完全可以工作:

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;
    }

这是 VB.NET 代码 - 适用于经度但不适用于纬度。

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

少了什么东西?

编辑:解决了这个问题(在下面我的答案中更正了代码,我不能再选择 2 天作为答案)。

4

3 回答 3

2

如果您不了解目标语言,最好的方法是在调试模式下编译您的源代码,然后使用 Reflector 进行反编译。这样您就可以保留 var 名称,并确保生成的代码有效。

请注意,VB.Net 具有“微妙”的逻辑运算符,可能会破坏您的代码逻辑:OR vs OrElse ...

于 2011-02-27T09:00:19.583 回答
2

啊所以问题是 C#++运算符增加变量但返回原始值,而我上面的 VB.NET 转换是增加索引然后使用增加的值。不知何故,这仍然适用于经度,但搞砸了纬度解码。

这是更正后的 VB.NET 代码:

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
于 2011-02-27T10:07:10.260 回答
0

Telerik 有一个在线转换器:Convert VB to C# or C# to VB

于 2011-02-27T09:50:13.173 回答