ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: cuiyuguo9

[求助] 求助GPS经纬度与百度经纬度的转换方法。

[复制链接]

TA的精华主题

TA的得分主题

发表于 2018-8-10 16:13 | 显示全部楼层
  1. '---------------------------------------------------------------------------------------
  2. '---------------------------------------------------------------------------------------
  3. '--------------------------------------坐标转换----------------------------------
  4. '---------------------------------------------------------------------------------------
  5. '---------------------------------------------------------------------------------------
  6. Public Const pi As Double = 3.14159265358979
  7. Public Const a As Double = 6378245#
  8. Public Const ee As Double = 6.69342162296594E-03
  9. Public Const X_pi As Double = 3.14159265358979 * 3000# / 180#


  10. Function wgs2bd(lat, lon)
  11.     wgs2gcj = wgs2gcj(lat, lon)
  12.     gcj2bd = gcj2bd(wgs2gcj(0), wgs2gcj(1))
  13. End Function

  14. Function gcj2bd(lat, lon)
  15.     x = lon: y = lat
  16.     Z = Sqr(x * x + y * y) + 0.00002 * Sin(y * X_pi)
  17.     theta = Application.Atan2(y, x) + 0.000003 * Cos(x * X_pi)
  18.     bd_lon = Z * Cos(theta) + 0.00644        '***?
  19.     bd_lat = Z * Sin(theta) + 0.00633       '***?
  20. '    bd_lon = Z * Cos(theta) + 0.0065
  21. '   bd_lat = Z * Sin(theta) + 0.006
  22.     gcj2bd = bd_lat & "," & bd_lon
  23. End Function

  24. Function bd2gcj(lat, lon)
  25.     x = lon - 0.0065: y = lat - 0.006
  26.     Z = Sqr(x * x + y * y) - 0.00002 * Sin(y * X_pi) '***
  27.     theta = Application.Atan2(y, x) - 0.000003 * Cos(x * X_pi)
  28.     gg_lon = Z * Cos(theta)
  29.     gg_lat = Z * Sin(theta)
  30.     bd2gcj = gg_lat & "," & gg_lon
  31. End Function

  32. Function wgs2gcj(lat, lon)
  33.     dLat = transformLat(lon - 105#, lat - 35#)
  34.     dLon = transformLon(lon - 105#, lat - 35#)
  35.     radLat = lat / 180# * pi
  36.     magic = Sin(radLat)
  37.     magic = 1 - ee * magic * magic
  38.     sqrtMagic = Sqr(magic) '***
  39.     dLat = (dLat * 180#) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi)
  40.     dLon = (dLon * 180#) / (a / sqrtMagic * Cos(radLat) * pi)
  41.     mgLat = lat + dLat
  42.     mgLon = lon + dLon
  43.     wgs2gcj = mgLat & "," & mgLon ' Loc
  44. End Function

  45. Function transformLat(lat, lon)
  46.     ret = -100# + 2# * lat + 3# * lon + 0.2 * lon * lon + 0.1 * lat * lon + 0.2 * Sqr(Abs(lat))
  47.     ret = ret + (20# * Sin(6# * lat * pi) + 20# * Sin(2# * lat * pi)) * 2# / 3#
  48.     ret = ret + (20# * Sin(lon * pi) + 40# * Sin(lon / 3# * pi)) * 2# / 3#
  49.     ret = ret + (160# * Sin(lon / 12# * pi) + 320 * Sin(lon * pi / 30#)) * 2# / 3#
  50.     transformLat = ret
  51. End Function

  52. Function transformLon(lat, lon)
  53.     ret = 300# + lat + 2# * lon + 0.1 * lat * lat + 0.1 * lat * lon + 0.1 * Sqr(Abs(lat))
  54.     ret = ret + (20# * Sin(6# * lat * pi) + 20# * Sin(2# * lat * pi)) * 2# / 3#
  55.     ret = ret + (20# * Sin(lat * pi) + 40# * Sin(lat / 3# * pi)) * 2# / 3#
  56.     ret = ret + (150# * Sin(lat / 12# * pi) + 300# * Sin(lat / 30# * pi)) * 2# / 3#
  57.     transformLon = ret
  58. End Function
  59. Function Base64Decode(strEncoded) As String
  60.     On Error Resume Next
  61.     Dim arrB() As Byte, bTmp(3) As Byte, bT As Long, bRet() As Byte
  62.     Dim I As Long, j As Long
  63.     arrB = StrConv(strEncoded, vbFromUnicode)
  64.     j = InStr(strEncoded & "=", "=") - 2
  65.     ReDim bRet(j - j \ 4 - 1)
  66.     For I = 0 To j Step 4
  67.         Erase bTmp
  68.         bTmp(0) = (InStr(cstBase64, Chr(arrB(I))) - 1) And 63
  69.         bTmp(1) = (InStr(cstBase64, Chr(arrB(I + 1))) - 1) And 63
  70.         bTmp(2) = (InStr(cstBase64, Chr(arrB(I + 2))) - 1) And 63
  71.         bTmp(3) = (InStr(cstBase64, Chr(arrB(I + 3))) - 1) And 63

  72.         bT = bTmp(0) * 2 ^ 18 + bTmp(1) * 2 ^ 12 + bTmp(2) * 2 ^ 6 + bTmp(3)

  73.         bRet((I \ 4) * 3) = bT \ 65536
  74.         bRet((I \ 4) * 3 + 1) = (bT And 65280) \ 256
  75.         bRet((I \ 4) * 3 + 2) = bT And 255
  76.     Next
  77.     Base64Decode = StrConv(bRet, vbUnicode)
  78. End Function
  79. '---------------------------------------------------------------------------------------
  80. '---------------------------------------------------------------------------------------
  81. '--------------------------------------坐标转换结束----------------------------------
  82. '---------------------------------------------------------------------------------------
复制代码

论坛上大神给的自定义函数,记不住哪个帖子了,实测好用。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2018-8-10 16:27 | 显示全部楼层

TA的精华主题

TA的得分主题

 楼主| 发表于 2018-8-20 10:55 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2018-8-20 15:15 | 显示全部楼层
应该这样
Function wgs2bd(lat, lon)
    wgs2gcj1 = wgs2gcj(lat, lon)
    gcj2bd1 = gcj2bd(Split(wgs2gcj1, ",")(0), Split(wgs2gcj1, ",")(1))
    wgs2bd = gcj2bd1
End Function

TA的精华主题

TA的得分主题

发表于 2018-8-20 16:41 | 显示全部楼层
C列是用的自定义函数公式,D、E列是将C列内容数值粘贴到D列后,再分列得到。

实例.rar

72.46 KB, 下载次数: 65

TA的精华主题

TA的得分主题

发表于 2018-8-20 16:48 | 显示全部楼层
YZC51 发表于 2018-8-20 15:15
应该这样
Function wgs2bd(lat, lon)
    wgs2gcj1 = wgs2gcj(lat, lon)

加密算法 不可能这么简单破解。

TA的精华主题

TA的得分主题

发表于 2018-8-20 19:20 | 显示全部楼层
zopey 发表于 2018-8-20 16:48
加密算法 不可能这么简单破解。

请老师指教,这样可以不?
    Dim strText As String
    Dim gpspoi As String
    URL = "http://api.map.baidu.com/ag/coord/convert?from=0&to=4&x=" & lng & "&y=" & lat
    With CreateObject("MSXML2.XMLHTTP")
        .Open "GET", URL, False
        .Send
        strText = .responsetext
    End With
    '百度数据返回分析并赋值和解码
    If x Then
        GPS2BD = Base64Decode(Split(strText, """")(5))
    Else
        GPS2BD = Base64Decode(Split(strText, """")(9))
    End If
End Function

'VBA Base64 解码/解密函数:
Function Base64Decode(B64) As String                                   'Base64 解码
    On Error GoTo over                                                          '排错
    Dim OutStr() As Byte, i As Long, j As Long
    Const B64_CHAR_DICT = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
    If InStr(1, B64, "=") <> 0 Then B64 = Left(B64, InStr(1, B64, "=") - 1)     '判断Base64真实长度,除去补位
    Dim kk, length As Long, mods As Long
    mods = Len(B64) Mod 4
    length = Len(B64) - mods
    ReDim OutStr(length / 4 * 3 - 1 + Switch(mods = 0, 0, mods = 2, 1, mods = 3, 2))
    For i = 1 To length Step 4
        Dim buf(3) As Byte
        For j = 0 To 3
            buf(j) = InStr(1, B64_CHAR_DICT, Mid(B64, i + j, 1)) - 1            '根据字符的位置取得索引值
        Next
        OutStr((i - 1) / 4 * 3) = buf(0) * &H4 + (buf(1) And &H30) / &H10
        OutStr((i - 1) / 4 * 3 + 1) = (buf(1) And &HF) * &H10 + (buf(2) And &H3C) / &H4
        OutStr((i - 1) / 4 * 3 + 2) = (buf(2) And &H3) * &H40 + buf(3)
    Next
    If mods = 2 Then
        OutStr(length / 4 * 3) = (InStr(1, B64_CHAR_DICT, Mid(B64, length + 1, 1)) - 1) * &H4 + ((InStr(1, B64_CHAR_DICT, Mid(B64, length + 2, 1)) - 1) And &H30) / 16
    ElseIf mods = 3 Then
        OutStr(length / 4 * 3) = (InStr(1, B64_CHAR_DICT, Mid(B64, length + 1, 1)) - 1) * &H4 + ((InStr(1, B64_CHAR_DICT, Mid(B64, length + 2, 1)) - 1) And &H30) / 16
        OutStr(length / 4 * 3 + 1) = ((InStr(1, B64_CHAR_DICT, Mid(B64, length + 2, 1)) - 1) And &HF) * &H10 + ((InStr(1, B64_CHAR_DICT, Mid(B64, length + 3, 1)) - 1) And &H3C) / &H4
    End If
    For i = 0 To UBound(OutStr)
        Base64Decode = Base64Decode & Chr(OutStr(i))
    Next i                                                       '读取解码结果
over:
End Function

TA的精华主题

TA的得分主题

发表于 2018-8-20 19:26 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
代码审核中,先上附件
经纬度实例.rar (79.97 KB, 下载次数: 82)

TA的精华主题

TA的得分主题

发表于 2018-8-21 17:24 | 显示全部楼层
YZC51 发表于 2018-8-20 19:26
代码审核中,先上附件

经调试,发现 函数 application.atan2() 有严重误差,替换如下

Public Function Atan2(ByVal y As Double, ByVal x As Double) As Double
  Const PI As Double = 3.1415926535
   If y > 0 Then
     If x >= y Then
       Atan2 = Atn(y / x)
     ElseIf x <= -y Then
       Atan2 = Atn(y / x) + PI
     Else
       Atan2 = PI / 2 - Atn(x / y)
     End If
   Else
     If x >= -y Then
       Atan2 = Atn(y / x)
     ElseIf x <= y Then
       Atan2 = Atn(y / x) - PI
     Else
       Atan2 = -Atn(x / y) - PI / 2
     End If
   End If
End Function


百度坐标转换.zip (27.02 KB, 下载次数: 130)

评分

3

查看全部评分

TA的精华主题

TA的得分主题

发表于 2018-8-21 17:32 | 显示全部楼层
在替换atan2 函数后,代码调试 对比结果 如下图
1、wgs2gcj 、gcj2bd 函数转换 结果与网页转换结果 gps2bd 基本一致
2、gcj2bd 与 bd2gcj 互相转换结果 基本相同。

54321.JPG

评分

1

查看全部评分

您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-26 15:13 , Processed in 0.036248 second(s), 16 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表