coordtransform.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /**
  2. * Created by Wandergis on 2015/7/8.
  3. * 提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
  4. * coordtransform.js
  5. */
  6. //UMD魔法代码
  7. // if the module has no dependencies, the above pattern can be simplified to
  8. (function (root, factory) {
  9. if (typeof define === 'function' && define.amd) {
  10. // AMD. Register as an anonymous module.
  11. define([], factory);
  12. } else if (typeof module === 'object' && module.exports) {
  13. // Node. Does not work with strict CommonJS, but
  14. // only CommonJS-like environments that support module.exports,
  15. // like Node.
  16. module.exports = factory();
  17. } else {
  18. // Browser globals (root is window)
  19. root.coordtransform = factory();
  20. }
  21. }(this, function () {
  22. //定义一些常量
  23. var x_PI = 3.14159265358979324 * 3000.0 / 180.0;
  24. var PI = 3.1415926535897932384626;
  25. var a = 6378245.0;
  26. var ee = 0.00669342162296594323;
  27. /**
  28. * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
  29. * 即 百度 转 谷歌、高德
  30. * @param bd_lon
  31. * @param bd_lat
  32. * @returns {*[]}
  33. */
  34. var bd09togcj02 = function bd09togcj02(bd_lon, bd_lat) {
  35. var bd_lon = +bd_lon;
  36. var bd_lat = +bd_lat;
  37. var x = bd_lon - 0.0065;
  38. var y = bd_lat - 0.006;
  39. var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);
  40. var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI);
  41. var gg_lng = z * Math.cos(theta);
  42. var gg_lat = z * Math.sin(theta);
  43. return [gg_lng, gg_lat]
  44. };
  45. /**
  46. * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
  47. * 即谷歌、高德 转 百度
  48. * @param lng
  49. * @param lat
  50. * @returns {*[]}
  51. */
  52. var gcj02tobd09 = function gcj02tobd09(lng, lat) {
  53. var lat = +lat;
  54. var lng = +lng;
  55. var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
  56. var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
  57. var bd_lng = z * Math.cos(theta) + 0.0065;
  58. var bd_lat = z * Math.sin(theta) + 0.006;
  59. return [bd_lng, bd_lat]
  60. };
  61. /**
  62. * WGS84转GCj02
  63. * @param lng
  64. * @param lat
  65. * @returns {*[]}
  66. */
  67. var wgs84togcj02 = function wgs84togcj02(lng, lat) {
  68. var lat = +lat;
  69. var lng = +lng;
  70. if (out_of_china(lng, lat)) {
  71. return [lng, lat]
  72. } else {
  73. var dlat = transformlat(lng - 105.0, lat - 35.0);
  74. var dlng = transformlng(lng - 105.0, lat - 35.0);
  75. var radlat = lat / 180.0 * PI;
  76. var magic = Math.sin(radlat);
  77. magic = 1 - ee * magic * magic;
  78. var sqrtmagic = Math.sqrt(magic);
  79. dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
  80. dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
  81. var mglat = lat + dlat;
  82. var mglng = lng + dlng;
  83. return [mglng, mglat]
  84. }
  85. };
  86. /**
  87. * GCJ02 转换为 WGS84
  88. * @param lng
  89. * @param lat
  90. * @returns {*[]}
  91. */
  92. var gcj02towgs84 = function gcj02towgs84(lng, lat) {
  93. var lat = +lat;
  94. var lng = +lng;
  95. if (out_of_china(lng, lat)) {
  96. return [lng, lat]
  97. } else {
  98. var dlat = transformlat(lng - 105.0, lat - 35.0);
  99. var dlng = transformlng(lng - 105.0, lat - 35.0);
  100. var radlat = lat / 180.0 * PI;
  101. var magic = Math.sin(radlat);
  102. magic = 1 - ee * magic * magic;
  103. var sqrtmagic = Math.sqrt(magic);
  104. dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
  105. dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
  106. var mglat = lat + dlat;
  107. var mglng = lng + dlng;
  108. return [lng * 2 - mglng, lat * 2 - mglat]
  109. }
  110. };
  111. var transformlat = function transformlat(lng, lat) {
  112. var lat = +lat;
  113. var lng = +lng;
  114. 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));
  115. ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
  116. ret += (20.0 * Math.sin(lat * PI) + 40.0 * Math.sin(lat / 3.0 * PI)) * 2.0 / 3.0;
  117. ret += (160.0 * Math.sin(lat / 12.0 * PI) + 320 * Math.sin(lat * PI / 30.0)) * 2.0 / 3.0;
  118. return ret
  119. };
  120. var transformlng = function transformlng(lng, lat) {
  121. var lat = +lat;
  122. var lng = +lng;
  123. var ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng));
  124. ret += (20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0 / 3.0;
  125. ret += (20.0 * Math.sin(lng * PI) + 40.0 * Math.sin(lng / 3.0 * PI)) * 2.0 / 3.0;
  126. ret += (150.0 * Math.sin(lng / 12.0 * PI) + 300.0 * Math.sin(lng / 30.0 * PI)) * 2.0 / 3.0;
  127. return ret
  128. };
  129. /**
  130. * 判断是否在国内,不在国内则不做偏移
  131. * @param lng
  132. * @param lat
  133. * @returns {boolean}
  134. */
  135. var out_of_china = function out_of_china(lng, lat) {
  136. var lat = +lat;
  137. var lng = +lng;
  138. // 纬度3.86~53.55,经度73.66~135.05
  139. return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
  140. };
  141. return {
  142. bd09togcj02: bd09togcj02,
  143. gcj02tobd09: gcj02tobd09,
  144. wgs84togcj02: wgs84togcj02,
  145. gcj02towgs84: gcj02towgs84
  146. }
  147. }));