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.

165 lines
4.0 KiB

10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
10 months ago
9 months ago
10 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. if(uni.getStorageSync('open_address') == 0){
  25. return fn && fn({})
  26. }
  27. wxGetLocation() //此方法只用于提示用户打开gps
  28. uni.getLocation({
  29. type: 'gcj02',
  30. isHighAccuracy: true,
  31. highAccuracyExpireTime: 1000,
  32. success: function(position) {
  33. fn(position)
  34. },
  35. fail: function() { //使用ip获取定位
  36. let key = import.meta.env.VITE_MAP_KEY; //腾讯地图key
  37. getUserAddressByIp(key).then(res => {
  38. fn(res.position) //返回经纬度
  39. })
  40. }
  41. })
  42. }
  43. function getLocationDetail() { //获取用户详细地址
  44. if(uni.getStorageSync('open_address') == 0){
  45. return {}
  46. }
  47. wxGetLocation()
  48. return new Promise((resolve, reject) => {
  49. let key = import.meta.env.VITE_MAP_KEY; //腾讯地图key
  50. uni.getLocation({
  51. type: 'gcj02',
  52. isHighAccuracy: true,
  53. highAccuracyExpireTime: 1000,
  54. success: function(position) {
  55. getUserAddress(position.latitude, position.longitude, key).then(res => {
  56. resolve(res)
  57. })
  58. },
  59. fail: function() { //使用ip获取定位
  60. getUserAddressByIp(key).then(res => {
  61. resolve(res)
  62. })
  63. }
  64. })
  65. })
  66. }
  67. function getUserAddress(latitude, longitude, key) { //通过经纬度获取用户详细地址
  68. return new Promise((resolve, reject) => {
  69. uni.request({
  70. url: `/ws/geocoder/v1/?location=${latitude},${longitude}&key=${key}`,
  71. success: (res) => {
  72. let {
  73. lat,
  74. lng
  75. } = res.data.result.ad_info.location;
  76. let data = {
  77. position: {
  78. latitude: lat,
  79. longitude: lng
  80. },
  81. addressDetail: res.data.result.ad_info
  82. }
  83. resolve(data)
  84. },
  85. fail(err) {
  86. reject(err)
  87. }
  88. })
  89. })
  90. }
  91. function getUserAddressByIp(key) { //根据IP获取当前用户位置
  92. return new Promise((resolve, reject) => {
  93. uni.request({
  94. url: 'https://api.ipify.org?format=json',
  95. success: (ipInfo) => {
  96. uni.request({
  97. url: `/ws/location/v1/ip?ip=${ipInfo.data.ip}&key=${key}`,
  98. success: (res) => {
  99. let {
  100. lat,
  101. lng
  102. } = res.data.result.location;
  103. let data = {
  104. addressDetail: res.data.result.ad_info,
  105. ip: res.data.result.ip,
  106. position: {
  107. latitude: lat,
  108. longitude: lng
  109. }
  110. }
  111. resolve(data)
  112. },
  113. fail(err) {
  114. reject(err)
  115. }
  116. })
  117. }
  118. })
  119. })
  120. }
  121. //打开地图让用户选择位置
  122. function selectAddress(successCallback) {
  123. if(uni.getStorageSync('open_address') == 0){
  124. return
  125. }
  126. uni.chooseLocation({
  127. // longitude, //经度
  128. // latitude, //纬度
  129. success: function(res) {
  130. successCallback && successCallback(res)
  131. }
  132. });
  133. }
  134. //sdk自带获取位置方法(只支持微信环境),这里只当提示在用了(具体获取地址逻辑上面几个方法已完成)
  135. function wxGetLocation(successCallback, failCallback) {
  136. console.log('wx.getLocation');
  137. wx.getLocation({
  138. type: 'gcj02',
  139. isHighAccuracy: true,
  140. highAccuracyExpireTime: 2000,
  141. success(res) {},
  142. fail(err) {
  143. if(err.errMsg == 'getLocation:gps closed'){
  144. uni.showToast({
  145. title: '请打开GPS定位,否则定位不准确',
  146. icon: 'none'
  147. })
  148. }
  149. }
  150. })
  151. }
  152. export default {
  153. calculateDistance, //计算两点距离
  154. getLocationDetail, //获取用户详细地址
  155. getLocation, //获取用户经纬度
  156. selectAddress, //打开地图让用户选择位置
  157. wxGetLocation,
  158. }