coordinate_change.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /**
  2. * Created by Wandergis on 2015/7/8.
  3. * 提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
  4. */
  5. //定义一些常量
  6. var x_PI = 3.14159265358979324 * 3000.0 / 180.0;
  7. var PI = 3.1415926535897932384626;
  8. var a = 6378245.0;
  9. var ee = 0.00669342162296594323;
  10. /**
  11. * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
  12. * 即 百度 转 谷歌、高德
  13. * @param bd_lon
  14. * @param bd_lat
  15. * @returns {*[]}
  16. */
  17. function bd09togcj02(bd_lon, bd_lat) {
  18. var x_pi = 3.14159265358979324 * 3000.0 / 180.0;
  19. var x = bd_lon - 0.0065;
  20. var y = bd_lat - 0.006;
  21. var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
  22. var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
  23. var gg_lng = z * Math.cos(theta);
  24. var gg_lat = z * Math.sin(theta);
  25. return {
  26. lng: gg_lng,
  27. lat: 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 {
  43. lng: bd_lng,
  44. lat: bd_lat,
  45. }
  46. }
  47. /**
  48. * WGS84转GCj02
  49. * @param lng
  50. * @param lat
  51. * @returns {*[]}
  52. */
  53. function wgs84togcj02(lng, lat) {
  54. if (out_of_china(lng, lat)) {
  55. return [lng, lat]
  56. } else {
  57. var dlat = transformlat(lng - 105.0, lat - 35.0);
  58. var dlng = transformlng(lng - 105.0, lat - 35.0);
  59. var radlat = lat / 180.0 * PI;
  60. var magic = Math.sin(radlat);
  61. magic = 1 - ee * magic * magic;
  62. var sqrtmagic = Math.sqrt(magic);
  63. dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
  64. dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
  65. var mglat = lat + dlat;
  66. var mglng = lng + dlng;
  67. return {
  68. lng: mglng,
  69. lat: mglat,
  70. }
  71. }
  72. }
  73. /**
  74. * GCJ02 转换为 WGS84
  75. * @param lng
  76. * @param lat
  77. * @returns {*[]}
  78. */
  79. function gcj02towgs84(lng, lat) {
  80. if (out_of_china(lng, lat)) {
  81. return [lng, lat]
  82. } else {
  83. var dlat = transformlat(lng - 105.0, lat - 35.0);
  84. var dlng = transformlng(lng - 105.0, lat - 35.0);
  85. var radlat = lat / 180.0 * PI;
  86. var magic = Math.sin(radlat);
  87. magic = 1 - ee * magic * magic;
  88. var sqrtmagic = Math.sqrt(magic);
  89. dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
  90. dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
  91. mglat = lat + dlat;
  92. mglng = lng + dlng;
  93. return {
  94. lng: lng * 2 - mglng,
  95. lat: lat * 2 - mglat,
  96. }
  97. }
  98. }
  99. function transformlat(lng, lat) {
  100. 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));
  101. ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
  102. ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
  103. ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
  104. return ret
  105. }
  106. function transformlng(lng, lat) {
  107. var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
  108. ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
  109. ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
  110. ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
  111. return ret
  112. }
  113. /**
  114. * 判断是否在国内,不在国内则不做偏移
  115. * @param lng
  116. * @param lat
  117. * @returns {boolean}
  118. */
  119. function out_of_china(lng, lat) {
  120. return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
  121. }
  122. //将腾讯/高德地图经纬度转换为百度地图经纬度
  123. function qqMapTransBMap(lng, lat) {
  124. let x_pi = 3.14159265358979324 * 3000.0 / 180.0;
  125. let x = lng;
  126. let y = lat;
  127. let z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi);
  128. let theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi);
  129. let lngs = z * Math.cos(theta) + 0.0065;
  130. let lats = z * Math.sin(theta) + 0.006;
  131. return {
  132. lng: lngs,
  133. lat: lats
  134. }
  135. }
  136. // 将百度地图经纬度转换为腾讯/高德地图经纬度
  137. function bMapTransQQMap(lng, lat) {
  138. let x_pi = 3.14159265358979324 * 3000.0 / 180.0;
  139. let x = lng - 0.0065;
  140. let y = lat - 0.006;
  141. let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
  142. let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
  143. let lngs = z * Math.cos(theta);
  144. let lats = z * Math.sin(theta);
  145. return {
  146. lng: lngs,
  147. lat: lats
  148. }
  149. }
  150. function qqmapTowgs84(lng, lat) {
  151. var location = qqMapTransBMap(lng, lat) //腾讯转百度
  152. location = bd09togcj02(location.lng, location.lat) //百度转火星
  153. location = gcj02towgs84(location.lng, location.lat) //火星转Wgs
  154. return {
  155. lng: location.lng,
  156. lat: location.lat
  157. }
  158. }