python3实现GPS经纬度坐标(WGS84)国测局火星坐标(GCJ02)百度坐标(BD09)相互转换

  • A+
所属分类:编程语言

python3实现GPS经纬度坐标(WGS84)国测局火星坐标(GCJ02)百度坐标(BD09)相互转换

在进行坐标转换前先来了解一下目前的的坐标体系分类:

一是GPS坐标,也即WGS-84坐标是一个国际的标准,一般卫星导航,原始的GPS设备中的数据都是采用这一坐标系。国外的Google地图、OSM等采用的都是这一坐标。

二是国测局坐标,国测局坐标GCJ-02坐标也叫火星坐标是国家测绘局为了国家安全在原始坐标的基础上进行偏移得到的坐标,基本国内的电子地图、导航设备都是采用的这一坐标系,如:高德、搜搜、51地图MapABC地图,谷歌中国地图也是。

三是百度坐标,百度坐标BD-09坐标是百度公司出于商业保护在国测局坐标基础上进行的二次加密。

另外,还有一些其他公司也进行了二次加密形成了自己的坐标如:图吧坐标、搜狗坐标等。

知道了上述坐标的基本情况后下面具体怎么进行相互转换,直接上代码:

  1. #?-*-?coding:?utf-8?-*-
  2. import?json
  3. import?requests
  4. import?math
  5. x_pi?=?3.14159265358979324?*?3000.0?/?180.0
  6. pi?=?3.1415926535897932384626??#?π
  7. a?=?6378245.0??#?长半轴
  8. ee?=?0.00669342162296594323??#?偏心率平方
  9. class?Geocoding:
  10. ????def?__init__(self,?api_key):
  11. ????????self.api_key?=?api_key
  12. ????def?geocode(self,?address):
  13. ????????"""
  14. ????????利用高德geocoding服务解析地址获取位置坐标
  15. ????????:param?address:需要解析的地址
  16. ????????:return:
  17. ????????"""
  18. ????????geocoding?=?{'s':?'rsv3',
  19. ?????????????????????'key':?self.api_key,
  20. ?????????????????????'city':?'全国',
  21. ?????????????????????'address':?address}
  22. ????????#?geocoding?=?urllib.urlencode(geocoding)
  23. ????????#?ret?=?urllib.urlopen("http://restapi.amap.com/v3/geocode/geo{}".format(geocoding))
  24. ????????url?=?"http://restapi.amap.com/v3/geocode/geo?"
  25. ????????ret?=?requests.get(url,?params=geocoding)
  26. ????????if?ret.status_code?==?200:
  27. ????????????#?res?=?ret.json()
  28. ????????????#?json_obj?=?json.loads(res)
  29. ????????????json_obj?=?ret.json()
  30. ????????????if?json_obj['status']?==?'1'?and?int(json_obj['count'])?>=?1:
  31. ????????????????geocodes?=?json_obj['geocodes'][0]
  32. ????????????????lng?=?float(geocodes.get('location').split(',')[0])
  33. ????????????????lat?=?float(geocodes.get('location').split(',')[1])
  34. ????????????????return?[lng,?lat]
  35. ????????????else:
  36. ????????????????return?None
  37. ????????else:
  38. ????????????return?None
  39. def?gcj02_to_bd09(lng,?lat):
  40. ????"""
  41. ????火星坐标系(GCJ-02)转百度坐标系(BD-09)
  42. ????谷歌、高德——>百度
  43. ????:param?lng:火星坐标经度
  44. ????:param?lat:火星坐标纬度
  45. ????:return:
  46. ????"""
  47. ????z?=?math.sqrt(lng?*?lng?+?lat?*?lat)?+?0.00002?*?math.sin(lat?*?x_pi)
  48. ????theta?=?math.atan2(lat,?lng)?+?0.000003?*?math.cos(lng?*?x_pi)
  49. ????bd_lng?=?z?*?math.cos(theta)?+?0.0065
  50. ????bd_lat?=?z?*?math.sin(theta)?+?0.006
  51. ????return?[bd_lng,?bd_lat]
  52. def?bd09_to_gcj02(bd_lon,?bd_lat):
  53. ????"""
  54. ????百度坐标系(BD-09)转火星坐标系(GCJ-02)
  55. ????百度——>谷歌、高德
  56. ????:param?bd_lat:百度坐标纬度
  57. ????:param?bd_lon:百度坐标经度
  58. ????:return:转换后的坐标列表形式
  59. ????"""
  60. ????x?=?bd_lon?-?0.0065
  61. ????y?=?bd_lat?-?0.006
  62. ????z?=?math.sqrt(x?*?x?+?y?*?y)?-?0.00002?*?math.sin(y?*?x_pi)
  63. ????theta?=?math.atan2(y,?x)?-?0.000003?*?math.cos(x?*?x_pi)
  64. ????gg_lng?=?z?*?math.cos(theta)
  65. ????gg_lat?=?z?*?math.sin(theta)
  66. ????return?[gg_lng,?gg_lat]
  67. def?wgs84_to_gcj02(lng,?lat):
  68. ????"""
  69. ????WGS84转GCJ02(火星坐标系)
  70. ????:param?lng:WGS84坐标系的经度
  71. ????:param?lat:WGS84坐标系的纬度
  72. ????:return:
  73. ????"""
  74. ????if?out_of_china(lng,?lat):??#?判断是否在国内
  75. ????????return?[lng,?lat]
  76. ????dlat?=?_transformlat(lng?-?105.0,?lat?-?35.0)
  77. ????dlng?=?_transformlng(lng?-?105.0,?lat?-?35.0)
  78. ????radlat?=?lat?/?180.0?*?pi
  79. ????magic?=?math.sin(radlat)
  80. ????magic?=?1?-?ee?*?magic?*?magic
  81. ????sqrtmagic?=?math.sqrt(magic)
  82. ????dlat?=?(dlat?*?180.0)?/?((a?*?(1?-?ee))?/?(magic?*?sqrtmagic)?*?pi)
  83. ????dlng?=?(dlng?*?180.0)?/?(a?/?sqrtmagic?*?math.cos(radlat)?*?pi)
  84. ????mglat?=?lat?+?dlat
  85. ????mglng?=?lng?+?dlng
  86. ????return?[mglng,?mglat]
  87. def?gcj02_to_wgs84(lng,?lat):
  88. ????"""
  89. ????GCJ02(火星坐标系)转GPS84
  90. ????:param?lng:火星坐标系的经度
  91. ????:param?lat:火星坐标系纬度
  92. ????:return:
  93. ????"""
  94. ????if?out_of_china(lng,?lat):
  95. ????????return?[lng,?lat]
  96. ????dlat?=?_transformlat(lng?-?105.0,?lat?-?35.0)
  97. ????dlng?=?_transformlng(lng?-?105.0,?lat?-?35.0)
  98. ????radlat?=?lat?/?180.0?*?pi
  99. ????magic?=?math.sin(radlat)
  100. ????magic?=?1?-?ee?*?magic?*?magic
  101. ????sqrtmagic?=?math.sqrt(magic)
  102. ????dlat?=?(dlat?*?180.0)?/?((a?*?(1?-?ee))?/?(magic?*?sqrtmagic)?*?pi)
  103. ????dlng?=?(dlng?*?180.0)?/?(a?/?sqrtmagic?*?math.cos(radlat)?*?pi)
  104. ????mglat?=?lat?+?dlat
  105. ????mglng?=?lng?+?dlng
  106. ????return?[lng?*?2?-?mglng,?lat?*?2?-?mglat]
  107. def?bd09_to_wgs84(bd_lon,?bd_lat):
  108. ????lon,?lat?=?bd09_to_gcj02(bd_lon,?bd_lat)
  109. ????return?gcj02_to_wgs84(lon,?lat)
  110. def?wgs84_to_bd09(lon,?lat):
  111. ????lon,?lat?=?wgs84_to_gcj02(lon,?lat)
  112. ????return?gcj02_to_bd09(lon,?lat)
  113. def?_transformlat(lng,?lat):
  114. ????ret?=?-100.0?+?2.0?*?lng?+?3.0?*?lat?+?0.2?*?lat?*?lat?+?\
  115. ??????????0.1?*?lng?*?lat?+?0.2?*?math.sqrt(math.fabs(lng))
  116. ????ret?+=?(20.0?*?math.sin(6.0?*?lng?*?pi)?+?20.0?*
  117. ????????????math.sin(2.0?*?lng?*?pi))?*?2.0?/?3.0
  118. ????ret?+=?(20.0?*?math.sin(lat?*?pi)?+?40.0?*
  119. ????????????math.sin(lat?/?3.0?*?pi))?*?2.0?/?3.0
  120. ????ret?+=?(160.0?*?math.sin(lat?/?12.0?*?pi)?+?320?*
  121. ????????????math.sin(lat?*?pi?/?30.0))?*?2.0?/?3.0
  122. ????return?ret
  123. def?_transformlng(lng,?lat):
  124. ????ret?=?300.0?+?lng?+?2.0?*?lat?+?0.1?*?lng?*?lng?+?\
  125. ??????????0.1?*?lng?*?lat?+?0.1?*?math.sqrt(math.fabs(lng))
  126. ????ret?+=?(20.0?*?math.sin(6.0?*?lng?*?pi)?+?20.0?*
  127. ????????????math.sin(2.0?*?lng?*?pi))?*?2.0?/?3.0
  128. ????ret?+=?(20.0?*?math.sin(lng?*?pi)?+?40.0?*
  129. ????????????math.sin(lng?/?3.0?*?pi))?*?2.0?/?3.0
  130. ????ret?+=?(150.0?*?math.sin(lng?/?12.0?*?pi)?+?300.0?*
  131. ????????????math.sin(lng?/?30.0?*?pi))?*?2.0?/?3.0
  132. ????return?ret
  133. def?out_of_china(lng,?lat):
  134. ????"""
  135. ????判断是否在国内,不在国内不做偏移
  136. ????:param?lng:
  137. ????:param?lat:
  138. ????:return:
  139. ????"""
  140. ????return?not?(lng?>?73.66?and?lng?<?135.05?and?lat?>?3.86?and?lat?<?53.55)
  141. if?__name__?==?'__main__':
  142. ????lng?=?116.382997
  143. ????lat?=?39.915156
  144. ????result1?=?gcj02_to_bd09(lng,?lat)
  145. ????result2?=?bd09_to_gcj02(lng,?lat)
  146. ????result3?=?wgs84_to_gcj02(lng,?lat)
  147. ????result4?=?gcj02_to_wgs84(lng,?lat)
  148. ????result5?=?bd09_to_wgs84(lng,?lat)
  149. ????result6?=?wgs84_to_bd09(lng,?lat)
  150. ????g?=?Geocoding('apikey')??#?这里填写你的高德api的key
  151. ????result7?=?g.geocode('广东省深圳市南山区')
  152. print(result1,?result2,?result3,?result4,?result5,?result6,?result7)
  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: