coordtransform.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /**
  2. * Created by Wandergis on 2015/7/8.
  3. * 提供了百度坐标(BD-09)、国测局坐标(火星坐标,GCJ-02)、和 WGS-84 坐标系之间的转换
  4. */
  5. // UMD 魔法代码
  6. // if the module has no dependencies, the above pattern can be simplified to
  7. (function (root, factory) {
  8. if (typeof define === 'function' && define.amd) {
  9. // AMD. Register as an anonymous module.
  10. define([], factory);
  11. } else if (typeof module === 'object' && module.exports) {
  12. // Node. Does not work with strict CommonJS, but
  13. // only CommonJS-like environments that support module.exports,
  14. // like Node.
  15. module.exports = factory();
  16. } else {
  17. // Browser globals (root is window)
  18. root.coordtransform = factory();
  19. }
  20. }(this, function () {
  21. // 定义一些常量
  22. var x_PI = 3.14159265358979324 * 3000.0 / 180.0;
  23. var PI = 3.1415926535897932384626;
  24. var a = 6378245.0;
  25. var ee = 0.00669342162296594323;
  26. /**
  27. * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02) 的转换
  28. * 即 百度 转 谷歌、高德
  29. * @param bd_lng
  30. * @param bd_lat
  31. * @returns {*[]}
  32. */
  33. var bd09togcj02 = function bd09togcj02(bd_lng, bd_lat) {
  34. var bd_lng = +bd_lng;
  35. var bd_lat = +bd_lat;
  36. var x = bd_lng - 0.0065;
  37. var y = bd_lat - 0.006;
  38. var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);
  39. var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI);
  40. var gg_lng = z * Math.cos(theta);
  41. var gg_lat = z * Math.sin(theta);
  42. return [gg_lng, gg_lat]
  43. };
  44. /**
  45. * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
  46. * 即 谷歌、高德 转 百度
  47. * @param lng
  48. * @param lat
  49. * @returns {*[]}
  50. */
  51. var gcj02tobd09 = function gcj02tobd09(lng, lat) {
  52. var lat = +lat;
  53. var lng = +lng;
  54. var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
  55. var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
  56. var bd_lng = z * Math.cos(theta) + 0.0065;
  57. var bd_lat = z * Math.sin(theta) + 0.006;
  58. return [bd_lng, bd_lat]
  59. };
  60. /**
  61. * WGS-84 转 GCJ-02
  62. * @param lng
  63. * @param lat
  64. * @returns {*[]}
  65. */
  66. var wgs84togcj02 = function wgs84togcj02(lng, lat) {
  67. var lat = +lat;
  68. var lng = +lng;
  69. // if (out_of_china(lng, lat)) {
  70. // return [lng, lat]
  71. // } else {
  72. var dlat = transformlat(lng - 105.0, lat - 35.0);
  73. var dlng = transformlng(lng - 105.0, lat - 35.0);
  74. var radlat = lat / 180.0 * PI;
  75. var magic = Math.sin(radlat);
  76. magic = 1 - ee * magic * magic;
  77. var sqrtmagic = Math.sqrt(magic);
  78. dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
  79. dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
  80. var mglat = lat + dlat;
  81. var mglng = lng + dlng;
  82. return [mglng, mglat]
  83. // }
  84. };
  85. /**
  86. * GCJ-02 转换为 WGS-84
  87. * @param lng
  88. * @param lat
  89. * @returns {*[]}
  90. */
  91. var gcj02towgs84 = function gcj02towgs84(lng, lat) {
  92. var lat = +lat;
  93. var lng = +lng;
  94. // if (out_of_china(lng, lat)) {
  95. // return [lng, lat]
  96. // } else {
  97. var dlat = transformlat(lng - 105.0, lat - 35.0);
  98. var dlng = transformlng(lng - 105.0, lat - 35.0);
  99. var radlat = lat / 180.0 * PI;
  100. var magic = Math.sin(radlat);
  101. magic = 1 - ee * magic * magic;
  102. var sqrtmagic = Math.sqrt(magic);
  103. dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
  104. dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
  105. var mglat = lat + dlat;
  106. var mglng = lng + dlng;
  107. console.log('ok');
  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. }));