You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
3.7 KiB

8 months ago
8 months ago
8 months ago
  1. function calculateDistance(lat1, lon1, lat2, lon2) { //计算两点距离
  2. let distance = 0
  3. if (!lat2 || !lon2) return distance
  4. //先强制转换一下(后端给的字符串)
  5. lat1 = parseFloat(lat1)
  6. lon1 = parseFloat(lon1)
  7. lat2 = parseFloat(lat2)
  8. lon2 = parseFloat(lon2)
  9. // 将角度转换为弧度
  10. const R = 6371; // 地球半径,单位公里
  11. const dLat = (lat2 - lat1) * Math.PI / 180;
  12. const dLon = (lon2 - lon1) * Math.PI / 180;
  13. lat1 = lat1 * Math.PI / 180;
  14. lat2 = lat2 * Math.PI / 180;
  15. // Haversine公式
  16. const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
  17. Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
  18. const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  19. // 计算距离
  20. distance = R * c;
  21. return distance.toFixed(0)
  22. }
  23. function getLocation(fn) { //获取用户经纬度
  24. wxGetLocation() //此方法只用于提示用户打开gps
  25. uni.getLocation({
  26. type: 'gcj02',
  27. isHighAccuracy: true,
  28. highAccuracyExpireTime: 1000,
  29. success: function(position) {
  30. fn(position)
  31. },
  32. fail: function() { //使用ip获取定位
  33. let key = import.meta.env.VITE_MAP_KEY; //腾讯地图key
  34. getUserAddressByIp(key).then(res => {
  35. fn(res.position) //返回经纬度
  36. })
  37. }
  38. })
  39. }
  40. function getLocationDetail() { //获取用户详细地址
  41. wxGetLocation()
  42. return new Promise((resolve, reject) => {
  43. let key = import.meta.env.VITE_MAP_KEY; //腾讯地图key
  44. uni.getLocation({
  45. type: 'gcj02',
  46. isHighAccuracy: true,
  47. highAccuracyExpireTime: 1000,
  48. success: function(position) {
  49. getUserAddress(position.latitude, position.longitude, key).then(res => {
  50. resolve(res)
  51. })
  52. },
  53. fail: function() { //使用ip获取定位
  54. getUserAddressByIp(key).then(res => {
  55. resolve(res)
  56. })
  57. }
  58. })
  59. })
  60. }
  61. function getUserAddress(latitude, longitude, key) { //通过经纬度获取用户详细地址
  62. return new Promise((resolve, reject) => {
  63. uni.request({
  64. url: `/ws/geocoder/v1/?location=${latitude},${longitude}&key=${key}`,
  65. success: (res) => {
  66. let {
  67. lat,
  68. lng
  69. } = res.data.result.ad_info.location;
  70. let data = {
  71. position: {
  72. latitude: lat,
  73. longitude: lng
  74. },
  75. addressDetail: res.data.result.ad_info
  76. }
  77. resolve(data)
  78. },
  79. fail(err) {
  80. reject(err)
  81. }
  82. })
  83. })
  84. }
  85. function getUserAddressByIp(key) { //根据IP获取当前用户位置
  86. return new Promise((resolve, reject) => {
  87. uni.request({
  88. url: 'https://api.ipify.org?format=json',
  89. success: (ipInfo) => {
  90. uni.request({
  91. url: `/ws/location/v1/ip?ip=${ipInfo.data.ip}&key=${key}`,
  92. success: (res) => {
  93. let {
  94. lat,
  95. lng
  96. } = res.data.result.location;
  97. let data = {
  98. addressDetail: res.data.result.ad_info,
  99. ip: res.data.result.ip,
  100. position: {
  101. latitude: lat,
  102. longitude: lng
  103. }
  104. }
  105. resolve(data)
  106. },
  107. fail(err) {
  108. reject(err)
  109. }
  110. })
  111. }
  112. })
  113. })
  114. }
  115. //打开地图让用户选择位置
  116. function selectAddress(longitude, latitude, successCallback) {
  117. uni.chooseLocation({
  118. longitude, //经度
  119. latitude, //纬度
  120. success: function(res) {
  121. successCallback && successCallback(res)
  122. }
  123. });
  124. }
  125. //sdk自带获取位置方法(只支持微信环境),这里只当提示在用了(具体获取地址逻辑上面几个方法已完成)
  126. function wxGetLocation(successCallback, failCallback) {
  127. console.log('wx.getLocation');
  128. wx.getLocation({
  129. type: 'gcj02',
  130. isHighAccuracy: true,
  131. highAccuracyExpireTime: 2000,
  132. success(res) {},
  133. fail(err) {
  134. if(err.errMsg == 'getLocation:gps closed'){
  135. uni.showToast({
  136. title: '请打开GPS定位,否则定位不准确',
  137. icon: 'none'
  138. })
  139. }
  140. }
  141. })
  142. }
  143. export default {
  144. calculateDistance,
  145. getLocationDetail,
  146. getLocation,
  147. selectAddress,
  148. wxGetLocation
  149. }