2011-02-27 49 views
5

我有一些C#代碼解碼使用谷歌的折線算法編碼的地圖路徑,並試圖將其轉換爲VB.NET。C#到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天以上的答案)。

+0

(刪除我的回答,因爲我不認爲這是幫助你和我的VB已經墮落爲只讀,所以由我不能修復它只看一眼) – 2011-02-27 09:56:52

+0

它以什麼方式不起作用?它是否編譯?顯示錯誤的結果,與C#版本不同? – tiago2014 2011-02-27 10:01:39

+0

給緯度輸出錯誤。 – amb9800 2011-02-27 10:02:36

回答

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 
2

如果您不知道目標語言,請在調試模式下編譯源代碼,然後使用反射器對其進行反編譯。這樣你保持var名稱,並確保生成的代碼是有效的。

注意,VB.Net有可能破壞你的代碼邏輯「微妙」的邏輯運算符:或VS OrElse運算...

+2

邏輯運算符不「微妙」。 OrElse增加了短路。 '或'是一個按位運算符,並且邏輯比較*沒有*短路。僅僅因爲它要求程序員理解它的工作原理,稱之爲「微妙」是不公平的。 – 2011-02-27 09:02:30

+0

嗯,他們是。如果你不知道目標語言,並且你想要某些功能,你不必閱讀一本大書來完成這項工作。 – Lotfi 2011-02-27 09:06:49

+1

我真的很好奇,哪種編程語言可以編寫功能代碼,而不必知道它的操作符是如何工作的。你能爲我說一個嗎? *保證*關於VB的綜合性書籍並不像C++那樣「巨大」。 – 2011-02-27 09:13:50

0

有Telerik的通過在線轉換器:Convert VB to C# or C# to VB

+0

是的,這是我開始的地方 - 清理了VB.NET輸出以獲得我上面發佈的內容。 – amb9800 2011-02-27 09:54:28

+0

@ amb9800你的VB.NET代碼和Telerik生成的代碼看起來不一樣。你把'while循環'改成'for循環'等等。爲什麼? – tiago2014 2011-02-27 10:02:59