Google maps api 3 如何转换为谷歌编码的多段线算法格式?

Google maps api 3 如何转换为谷歌编码的多段线算法格式?,google-maps-api-3,polyline,Google Maps Api 3,Polyline,谷歌地图的地图存储了纬度/经度信息以及缩放级别 我有一个包含lat/lon对的大型文本文件,我希望将其转换为这种格式,并用于多段线的不同部分(即,我需要执行批转换) 有人知道执行此操作的代码吗 我不知道你需要什么语言。你可以从谷歌那里得到大致的想法。然而,我发现说明书并非100%准确。这就是我理解它的方式,使用同一文本中的示例。我用Java实现了它,它应该很容易转换成JavaScript或PHP 公共类MapMath{ 私人最终静态双乘数=100000; 专用最终静态整数五位掩码=0x1f; 公

谷歌地图的地图存储了纬度/经度信息以及缩放级别

我有一个包含lat/lon对的大型文本文件,我希望将其转换为这种格式,并用于多段线的不同部分(即,我需要执行批转换)


有人知道执行此操作的代码吗

我不知道你需要什么语言。你可以从谷歌那里得到大致的想法。然而,我发现说明书并非100%准确。这就是我理解它的方式,使用同一文本中的示例。我用Java实现了它,它应该很容易转换成JavaScript或PHP

公共类MapMath{
私人最终静态双乘数=100000;
专用最终静态整数五位掩码=0x1f;
公共地图数学(){
双精度[]坐标=新双精度[][]{
{-12.422187,130.854922},
{-12.422445,130.854937},
{-12.422234,130.854886}
};
StringBuilder encodedStrings=新的StringBuilder();
对于(int i=0;i<3;i++){
encodedStrings.append(
编码坐标(坐标[i][0])+
编码坐标(坐标[i][1])+“\n”
);
}
System.out.println(编码字符串);
}
专用字符串编码坐标(双坐标){
StringBuilder encodedCoordinate=新的StringBuilder();
布尔hasnet;
坐标*=乘数;
int值=(int)坐标;
价值5);
hasNext=(next>0);
int encVal=值和五位掩码;
如果(hasNext)encVal |=0x20;
encVal+=0x3f;
值=下一个;
encodedCoordinate.append((char)(encVal));
}while(hasnet);
返回encodedCoordination.toString();
} 
公共静态双toradian(双度){
返回值(度*数学PI)/180;
}
公共静态void main(字符串[]args){
新MapMath();
}
}
请注意,连续坐标应为上一个坐标的偏移量。
希望这对你有用,如果需要进一步的帮助,请告诉我

关于编码和解码多段线的权威参考文献是马克·麦克卢尔教授在

它包含实用程序、算法讨论和Javascript代码到Perl、Ruby、PHP、Java和Mathematica的端口


注意:对于版本3,您不需要版本2所需的
levels
字符串。版本3自己计算级别。

我也看到了一些算法的不精确实现(还有一些非常糟糕的代码)。这是我的编码函数(用VB.NET编写)。此函数只对传递给它的一个值进行编码,因此您必须在其他位置执行所有差分计算。返回的结果与谷歌网页上显示的结果完全一致。(我的一些代码可以精简和优化,但我试图让算法的每一步都清晰明了)。我希望有人觉得这很有用

''' <summary>
''' Encodes a latitude or longitude value by using Google's Polyline algorithm
''' </summary>
''' <param name="ToEnc">Latitude or Longitude to encode (or a difference value) (Single)</param>
''' <returns>Polyline encoded point (String)</returns>
''' <remarks>This function doesn't care what value you pass it, whether it's an absolute coordinate or a difference.  Make sure you do all of the point difference calculations somewhere else before calling this method.</remarks>
Private Function Encode(ByVal ToEnc As Single) As String
    Dim Coord As Integer 'The integer version of the coordinate, as per steps 2 and 3
    Dim B(5) As Byte 'The 5-bit chunks, as per steps 6 and 7.  Note that all 6 bytes may not be used
    Dim I As Integer 'Generic counter
    Dim C(5) As Char 'The chunks converted from bytes to characters

    '2., 3. Take the decimal value and multiply is by 1e5, rounding the result.  Convert the decimal value to binary.
    Coord = Math.Sign(ToEnc) * Int(Math.Abs(ToEnc) * 100000.0)

    '4. Left-shift the binary value one bit
    Coord <<= 1

    '5. If the original decimal value is negative, invert this encoding
    If ToEnc < 0 Then Coord = Not Coord

    '6. Break the binary value out into 5-bit chunks (starting from the right hand side)
    '7. Place the 5-bit chunks in reverse order
    'Steps 6 and 7 are done at the same time
    B(0) = Coord And &H1F
    B(1) = (Coord And &H3E0) >> 5
    B(2) = (Coord And &H7C00) >> 10
    B(3) = (Coord And &HF8000) >> 15
    B(4) = (Coord And &H1F00000) >> 20
    B(5) = (Coord And &H3E000000) >> 25

    '8. OR each value with 0x20 if another bit chunk follows
    'Go through the 5-bit chunks looking for the first one that isn't zero
    'When we find it, that means the one BEFORE that is the last to get the 0x20 modification
    Dim E As Integer = -1 'Penultimate byte that contains data, the last one to get ORed by 0x20
    For I = 5 To 1 Step -1
        If B(I) <> 0 Then
            'This is the first nonzero value we've encountered, so keep track of this position and exit the loop
            E = I - 1
            Exit For
        End If
    Next
    'Apply the 0x20 modification
    For I = 0 To E
        B(I) = B(I) Or &H20
    Next

    '10. Add 63 to each value
    For I = 0 To 5
        If B(I) > 0 Then B(I) += 63
    Next

    '11. Convert each value to its ASCII equivalent
    For I = 0 To 5
        C(I) = Chr(B(I))
    Next

    'Turn the char array into a string and return it
    Return New String(C, 0, E + 2)
End Function
“”
''使用谷歌的多段线算法对纬度或经度值进行编码
''' 
''要编码的纬度或经度(或差值)(单个)
''多段线编码点(字符串)
''此函数不关心传递的值,无论是绝对坐标还是差值。在调用此方法之前,请确保在其他位置执行所有的点差计算。
私有函数编码(ByVal-ToEnc为单个)为字符串
Dim Coord As Integer“坐标的整数版本,按照步骤2和3
按照步骤6和7,将B(5)调为5位块的字节。请注意,可能不使用所有6个字节
Dim I作为“整数”通用计数器
Dim C(5)作为Char'将块从字节转换为字符
'2., 3. 取十进制值,乘以1e5,将结果四舍五入。将十进制值转换为二进制。
坐标=数学符号(ToEnc)*Int(数学绝对值(ToEnc)*100000.0)
'4.将二进制值左移一位
合作5
B(2)=(Coord和&H7C00)>>10
B(3)=(Coord和HF8000)>>15
B(4)=(坐标和&H1F00000)>>20
B(5)=(协调和&H3E000000)>>25
'8.如果后面有另一个位块,则每个值都带有0x20
'遍历5位块,寻找第一个不是零的块
'当我们找到它时,这意味着之前的一个是最后一个得到0x20修改的
Dim E作为整数=-1'包含数据的倒数第二个字节,最后一个被0x20或
对于I=5到1步骤-1
如果B(I)0那么
'这是我们遇到的第一个非零值,因此请跟踪此位置并退出循环
E=I-1
退出
如果结束
下一个
'应用0x20修改
对于I=0到E
B(I)=B(I)或&H20
下一个
'10.每个值加63
对于I=0到5
如果B(I)>0,则B(I)+=63
下一个
'11.将每个值转换为其ASCII等效值
对于I=0到5
C(I)=Chr(B(I))
下一个
'将字符数组转换为字符串并返回它
返回新字符串(C、0、E+2)
端函数

这里有一个很好的PHP实现:

它基于上可用的一些代码,但经过了适当的修改,成为一个合适的类。

谢谢Jonathan, 经过一些调整,我的VBA版本在这里。。。。从这里开始。。。

“”
''使用谷歌的多段线算法对纬度或经度值进行编码
''' 
''要编码的纬度或经度(或差值)(单个)
''多段线编码点(字符串)
''此函数不关心传递的值,无论是绝对坐标还是差值。在调用此方法之前,请确保在其他位置执行所有的点差计算。
函数编码(ByVal ToEnc为单个)为字符串
按照步骤2和步骤3,将坐标标注为“双精度”坐标的整数版本
按照步骤6和7,将B(5)调为5位块的字节。请注意,所有6个
   ''' <summary>
''' Encodes a latitude or longitude value by using Google's Polyline algorithm
''' </summary>
''' <param name="ToEnc">Latitude or Longitude to encode (or a difference value) (Single)</param>
''' <returns>Polyline encoded point (String)</returns>
''' <remarks>This function doesn't care what value you pass it, whether it's an absolute coordinate or a difference.  Make sure you do all of the point difference calculations somewhere else before calling this method.</remarks>
Function Encode(ByVal ToEnc As Single) As String
    Dim Coord As Double 'The integer version of the coordinate, as per steps 2 and 3
    Dim B(5) As Byte 'The 5-bit chunks, as per steps 6 and 7.  Note that all 6 bytes may not be used
    Dim i As Integer 'Generic counter
    Dim C(5) As String 'The chunks converted from bytes to characters
    Dim E As Integer
    E = -1 'Penultimate byte that contains data, the last one to get ORed by 0x20

    '2., 3. Take the decimal value and multiply is by 1e5, rounding the result.  Convert the decimal value to binary.
    Coord = Math.Sgn(ToEnc) * Int(Math.Abs(ToEnc) * 100000)

    '4. Left-shift the binary value one bit
    Coord = shl(Coord, 1)

    '5. If the original decimal value is negative, invert this encoding
    If ToEnc < 0 Then Coord = Not Coord

    '6. Break the binary value out into 5-bit chunks (starting from the right hand side)
    '7. Place the 5-bit chunks in reverse order
    'Steps 6 and 7 are done at the same time
    B(0) = Coord And &H1F
    B(1) = shr((Coord And &H3E0), 5)
    B(2) = shr((Coord And &H7C00), 10)
    B(3) = shr((Coord And &HF8000), 15)
    B(4) = shr((Coord And &H1F00000), 20)
    B(5) = shr((Coord And &H3E000000), 25)

    '8. OR each value with 0x20 if another bit chunk follows
    'Go through the 5-bit chunks looking for the first one that isn't zero
    'When we find it, that means the one BEFORE that is the last to get the 0x20 modification
    For i = 5 To 1 Step -1
        If B(i) <> 0 Then
            'This is the first nonzero value we've encountered, so keep track of this position and exit the loop
            E = i - 1
            Exit For
        End If
    Next
    'Apply the 0x20 modification
    For i = 0 To E
        B(i) = B(i) Or &H20
    Next

    '10. Add 63 to each value
    For i = 0 To 5
        If B(i) > 0 Then B(i) = B(i) + 63
    Next

    '11. Convert each value to its ASCII equivalent
    For i = 0 To 5
        C(i) = Chr(B(i))
    Encode = Encode + C(i)
    Next

    'Turn the char array into a string and return it
 End Function

Public Function shr(ByVal Value As Long, ByVal Shift As Byte) As Long
    Dim i As Byte
    shr = Value
    If Shift > 0 Then
        shr = Int(shr / (2 ^ Shift))
    End If
End Function
Public Function shl(ByVal Value As Long, ByVal Shift As Byte) As Long
    shl = Value
    If Shift > 0 Then
        Dim i As Byte
        Dim m As Long
        For i = 1 To Shift
            m = shl And &H40000000
            shl = (shl And &H3FFFFFFF) * 2
            If m <> 0 Then
                shl = shl Or &H80000000
            End If
        Next i
    End If
End Function