火星坐标、百度坐标、WGS84坐标转换代码(JS、python版)

给大家分享下坐标转换的代码的JS和Python两个版本的源码

一、JS版本源码

 
  1. /**

  2. * Created by Wandergis on 2015/7/8.

  3. * 提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换

  4. */

  5.  
  6. //定义一些常量

  7. var x_PI = 3.14159265358979324 * 3000.0 / 180.0;

  8. var PI = 3.1415926535897932384626;

  9. var a = 6378245.0;

  10. var ee = 0.00669342162296594323;

  11.  
  12. /**

  13. * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换

  14. * 即 百度 转 谷歌、高德

  15. * @param bd_lon

  16. * @param bd_lat

  17. * @returns {*[]}

  18. */

  19. function bd09togcj02(bd_lon, bd_lat) {

  20. var x_pi = 3.14159265358979324 * 3000.0 / 180.0;

  21. var x = bd_lon - 0.0065;

  22. var y = bd_lat - 0.006;

  23. var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);

  24. var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);

  25. var gg_lng = z * Math.cos(theta);

  26. var gg_lat = z * Math.sin(theta);

  27. return [gg_lng, gg_lat]

  28. }

  29.  
  30. /**

  31. * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换

  32. * 即谷歌、高德 转 百度

  33. * @param lng

  34. * @param lat

  35. * @returns {*[]}

  36. */

  37. function gcj02tobd09(lng, lat) {

  38. var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);

  39. var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);

  40. var bd_lng = z * Math.cos(theta) + 0.0065;

  41. var bd_lat = z * Math.sin(theta) + 0.006;

  42. return [bd_lng, bd_lat]

  43. }

  44.  
  45. /**

  46. * WGS84转GCj02

  47. * @param lng

  48. * @param lat

  49. * @returns {*[]}

  50. */

  51. function wgs84togcj02(lng, lat) {

  52. if (out_of_china(lng, lat)) {

  53. return [lng, lat]

  54. }

  55. else {

  56. var dlat = transformlat(lng - 105.0, lat - 35.0);

  57. var dlng = transformlng(lng - 105.0, lat - 35.0);

  58. var radlat = lat / 180.0 * PI;

  59. var magic = Math.sin(radlat);

  60. magic = 1 - ee * magic * magic;

  61. var sqrtmagic = Math.sqrt(magic);

  62. dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);

  63. dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);

  64. var mglat = lat + dlat;

  65. var mglng = lng + dlng;

  66. return [mglng, mglat]

  67. }

  68. }

  69.  
  70. /**

  71. * GCJ02 转换为 WGS84

  72. * @param lng

  73. * @param lat

  74. * @returns {*[]}

  75. */

  76. function gcj02towgs84(lng, lat) {

  77. if (out_of_china(lng, lat)) {

  78. return [lng, lat]

  79. }

  80. else {

  81. var dlat = transformlat(lng - 105.0, lat - 35.0);

  82. var dlng = transformlng(lng - 105.0, lat - 35.0);

  83. var radlat = lat / 180.0 * PI;

  84. var magic = Math.sin(radlat);

  85. magic = 1 - ee * magic * magic;

  86. var sqrtmagic = Math.sqrt(magic);

  87. dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);

  88. dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);

  89. mglat = lat + dlat;

  90. mglng = lng + dlng;

  91. return [lng * 2 - mglng, lat * 2 - mglat]

  92. }

  93. }

  94.  
  95. function transformlat(lng, lat) {

  96. var ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng));

  97. ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;

  98. ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;

  99. ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;

  100. return ret

  101. }

  102.  
  103. function transformlng(lng, lat) {

  104. var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));

  105. ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;

  106. ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;

  107. ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;

  108. return ret

  109. }

  110.  
  111. /**

  112. * 判断是否在国内,不在国内则不做偏移

  113. * @param lng

  114. * @param lat

  115. * @returns {boolean}

  116. */

  117. function out_of_china(lng, lat) {

  118. return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);

  119. }

  120.  

二、python版本源码

 
  1. # -*- coding: utf-8 -*-

  2. import json

  3. import requests

  4. import math

  5.  
  6. key = 'your key here' # 这里填写你的百度开放平台的key

  7. x_pi = 3.14159265358979324 * 3000.0 / 180.0

  8. pi = 3.1415926535897932384626 # π

  9. a = 6378245.0 # 长半轴

  10. ee = 0.00669342162296594323 # 扁率

  11.  
  12.  
  13. def geocode(address):

  14. """

  15. 利用百度geocoding服务解析地址获取位置坐标

  16. :param address:需要解析的地址

  17. :return:

  18. """

  19. geocoding = {'s': 'rsv3',

  20. 'key': key,

  21. 'city': '全国',

  22. 'address': address}

  23. res = requests.get(

  24. "http://restapi.amap.com/v3/geocode/geo", params=geocoding)

  25. if res.status_code == 200:

  26. json = res.json()

  27. status = json.get('status')

  28. count = json.get('count')

  29. if status == '1' and int(count) >= 1:

  30. geocodes = json.get('geocodes')[0]

  31. lng = float(geocodes.get('location').split(',')[0])

  32. lat = float(geocodes.get('location').split(',')[1])

  33. return [lng, lat]

  34. else:

  35. return None

  36. else:

  37. return None

  38.  
  39.  
  40. def gcj02tobd09(lng, lat):

  41. """

  42. 火星坐标系(GCJ-02)转百度坐标系(BD-09)

  43. 谷歌、高德——>百度

  44. :param lng:火星坐标经度

  45. :param lat:火星坐标纬度

  46. :return:

  47. """

  48. z = math.sqrt(lng * lng + lat * lat) + 0.00002 * math.sin(lat * x_pi)

  49. theta = math.atan2(lat, lng) + 0.000003 * math.cos(lng * x_pi)

  50. bd_lng = z * math.cos(theta) + 0.0065

  51. bd_lat = z * math.sin(theta) + 0.006

  52. return [bd_lng, bd_lat]

  53.  
  54.  
  55. def bd09togcj02(bd_lon, bd_lat):

  56. """

  57. 百度坐标系(BD-09)转火星坐标系(GCJ-02)

  58. 百度——>谷歌、高德

  59. :param bd_lat:百度坐标纬度

  60. :param bd_lon:百度坐标经度

  61. :return:转换后的坐标列表形式

  62. """

  63. x = bd_lon - 0.0065

  64. y = bd_lat - 0.006

  65. z = math.sqrt(x * x + y * y) - 0.00002 * math.sin(y * x_pi)

  66. theta = math.atan2(y, x) - 0.000003 * math.cos(x * x_pi)

  67. gg_lng = z * math.cos(theta)

  68. gg_lat = z * math.sin(theta)

  69. return [gg_lng, gg_lat]

  70.  
  71.  
  72. def wgs84togcj02(lng, lat):

  73. """

  74. WGS84转GCJ02(火星坐标系)

  75. :param lng:WGS84坐标系的经度

  76. :param lat:WGS84坐标系的纬度

  77. :return:

  78. """

  79. if out_of_china(lng, lat): # 判断是否在国内

  80. return lng, lat

  81. dlat = transformlat(lng - 105.0, lat - 35.0)

  82. dlng = transformlng(lng - 105.0, lat - 35.0)

  83. radlat = lat / 180.0 * pi

  84. magic = math.sin(radlat)

  85. magic = 1 - ee * magic * magic

  86. sqrtmagic = math.sqrt(magic)

  87. dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)

  88. dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)

  89. mglat = lat + dlat

  90. mglng = lng + dlng

  91. return [mglng, mglat]

  92.  
  93.  
  94. def gcj02towgs84(lng, lat):

  95. """

  96. GCJ02(火星坐标系)转GPS84

  97. :param lng:火星坐标系的经度

  98. :param lat:火星坐标系纬度

  99. :return:

  100. """

  101. if out_of_china(lng, lat):

  102. return lng, lat

  103. dlat = transformlat(lng - 105.0, lat - 35.0)

  104. dlng = transformlng(lng - 105.0, lat - 35.0)

  105. radlat = lat / 180.0 * pi

  106. magic = math.sin(radlat)

  107. magic = 1 - ee * magic * magic

  108. sqrtmagic = math.sqrt(magic)

  109. dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * pi)

  110. dlng = (dlng * 180.0) / (a / sqrtmagic * math.cos(radlat) * pi)

  111. mglat = lat + dlat

  112. mglng = lng + dlng

  113. return [lng * 2 - mglng, lat * 2 - mglat]

  114.  
  115.  
  116. def transformlat(lng, lat):

  117. ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + \

  118. 0.1 * lng * lat + 0.2 * math.sqrt(math.fabs(lng))

  119. ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *

  120. math.sin(2.0 * lng * pi)) * 2.0 / 3.0

  121. ret += (20.0 * math.sin(lat * pi) + 40.0 *

  122. math.sin(lat / 3.0 * pi)) * 2.0 / 3.0

  123. ret += (160.0 * math.sin(lat / 12.0 * pi) + 320 *

  124. math.sin(lat * pi / 30.0)) * 2.0 / 3.0

  125. return ret

  126.  
  127.  
  128. def transformlng(lng, lat):

  129. ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + \

  130. 0.1 * lng * lat + 0.1 * math.sqrt(math.fabs(lng))

  131. ret += (20.0 * math.sin(6.0 * lng * pi) + 20.0 *

  132. math.sin(2.0 * lng * pi)) * 2.0 / 3.0

  133. ret += (20.0 * math.sin(lng * pi) + 40.0 *

  134. math.sin(lng / 3.0 * pi)) * 2.0 / 3.0

  135. ret += (150.0 * math.sin(lng / 12.0 * pi) + 300.0 *

  136. math.sin(lng / 30.0 * pi)) * 2.0 / 3.0

  137. return ret

  138.  
  139.  
  140. def out_of_china(lng, lat):

  141. """

  142. 判断是否在国内,不在国内不做偏移

  143. :param lng:

  144. :param lat:

  145. :return:

  146. """

  147. if lng < 72.004 or lng > 137.8347:

  148. return True

  149. if lat < 0.8293 or lat > 55.8271:

  150. return True

  151. return False

  152.  
  153.  
  154. if __name__ == '__main__':

  155. lng = 128.543

  156. lat = 37.065

  157. result1 = gcj02tobd09(lng, lat)

  158. result2 = bd09togcj02(lng, lat)

  159. result3 = wgs84togcj02(lng, lat)

  160. result4 = gcj02towgs84(lng, lat)

  161. result5 = geocode('北京市朝阳区朝阳公园')

  162. print result1, result2, result3, result4, result5

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值