• 微信小程序如何使用地球半径计算两组经纬度点之间的距离(自身位置与接口返回位置)【上】


    目录

    1.配置位置权限 

    2.获取当前自身经纬度 

    3. 请求接口拿到返回经纬

    4. 循环取每一项的经纬

    5.如何判断是否打开了定位权限 

    6.进行距离计算操作 

    7.运行效果

    8.完整代码

    首先在使用小程序时,请求的接口一定要去配置合法域名,才能够进行接下来的操作。 

    1.配置位置权限 

    在app.json中添加如下代码:

    1. "permission": {
    2. "scope.userLocation": {
    3. "desc": "你的位置信息将用于小程序位置接口的效果展示"
    4. },
    5. }

    2.获取当前自身经纬度 

    我们通过wx.getLocation这个api进行获取: 

    1. wx.getLocation({
    2. type: 'gcj02',
    3. success(res) {
    4. that.setData({
    5. currentLatitude: res.latitude,
    6. currentLongitude: res.longitude
    7. });
    8. })

    在这里我们使用了变量来存放当前经纬度,并且使用that.setData({})方法来赋值,因为this的指向可能不明确,配置如下:

    1. data: {
    2. currentLatitude:'',
    3. currentLongitude:'',
    4. }
    5. onLoad(options) {
    6. let that = this;
    7. }

    除了gcj02,还有以下几种地理位置坐标系类型可以选择:

    • wgs84:表示使用WGS84坐标系,也是全球卫星定位系统(GPS)所采用的坐标系。
    • bd09:表示使用百度坐标系,在国内常用的一种坐标系,适用于百度地图。
    • bd09ll:表示使用百度经纬度坐标系,与bd09相似,但在经度上更接近真实的经度值。

    3. 请求接口拿到返回经纬

    1. wx.request({
    2. url: '自己所使用的接口',
    3. method: 'POST',
    4. data: {},
    5. success: function(res) {
    6. console.log(res);
    7. that.setData({
    8. list: res.data.data.list
    9. });
    10. }
    11. })

    上述代码呢list是我在data中的一个变量,用来存放我包含经纬度数据的数组,声明方式为list:[]

    4. 循环取每一项的经纬

     list数据格式如下: 

    1. for (let i = 0; i < that.data.list.length; i++) {
    2. let item = that.data.list[i];
    3. let lat = parseFloat(item.latitude);
    4. let lon = parseFloat(item.longitude);
    5. }
    6. that.setData({
    7. list: that.data.list
    8. });

    item.latitudeitem.longitude转换为浮点数(parseFloat())的目的是将字符串转换为数值型数据。这是因为经纬度通常以字符串的形式存储,在进行距离计算等数值操作时,需要将其转换为数值类型进行计算。通过使用parseFloat()函数,可以将字符串解析成浮点数,以便后续的数值计算。 

    5.如何判断是否打开了定位权限 

     在每一次打开此页面的时候都进行一次权限排查,如果没有打开定位权限,则会调起设置打开权限

    1. checkLocationPermission() {
    2. let that = this;
    3. wx.getSetting({
    4. success(res) {
    5. if (!res.authSetting['scope.userLocation']) {
    6. wx.showModal({
    7. title: '提示',
    8. content: '您还没有启用定位权限,是否前往设置开启?',
    9. success(res) {
    10. if (res.confirm) {
    11. // User confirmed opening settings
    12. wx.openSetting({
    13. success(res) {
    14. if (res.authSetting['scope.userLocation']) {
    15. // User granted location permission in settings
    16. that.onLoad(); // Reload the page to fetch data with location permission
    17. } else {
    18. // User did not grant location permission in settings
    19. wx.showToast({
    20. title: '您还未开启定位权限',
    21. icon: 'none'
    22. });
    23. }
    24. }
    25. });
    26. } else if (res.cancel) {
    27. console.log(res.cancel);
    28. // User canceled opening settings
    29. wx.showToast({
    30. title: '您还未开启定位权限',
    31. icon: 'none'
    32. });
    33. }
    34. }
    35. });
    36. }
    37. }
    38. });
    39. },

    因为此代码是排查权限信息,所以单独写了个函数,你可以选择在onshow或者onload中调用

    1. onShow() {
    2. this.checkLocationPermission();
    3. },

    6.进行距离计算操作 

    1. getDistance: function(lat1, lon1, lat2, lon2) {
    2. var R = 6371;
    3. var dLat = (lat2 - lat1) * Math.PI / 180;
    4. var dLon = (lon2 - lon1) * Math.PI / 180;
    5. var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    6. Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
    7. Math.sin(dLon / 2) * Math.sin(dLon / 2);
    8. var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    9. var distance = R * c;
    10. return distance.toFixed(2);
    11. },

    详解代码:

    • var R = 6371;:定义地球的半径,单位为公里。这是用于计算两点间距离的基准。

    • var dLat = (lat2 - lat1) * Math.PI / 180;:计算两点纬度差值,并将其转换为弧度值。

    • var dLon = (lon2 - lon1) * Math.PI / 180;:计算两点经度差值,并将其转换为弧度值。

    • var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) * Math.sin(dLon / 2) * Math.sin(dLon / 2);:根据Haversine公式,计算两点间的距离。

      • Math.sin(dLat / 2) * Math.sin(dLat / 2):计算纬度差值的一半的正弦平方。
      • Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180):计算两点纬度的余弦乘积。
      • Math.sin(dLon / 2) * Math.sin(dLon / 2):计算经度差值的一半的正弦平方。
      • 将上述三个部分相加得到a的值,表示两点间的角距离。
    • var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));:根据球面三角学公式,计算角距离对应的弧长。

      • Math.sqrt(a):计算a的平方根。
      • Math.sqrt(1 - a):计算1 - a的平方根。
      • Math.atan2():计算给定坐标的反正切值。
    • var distance = R * c;:将弧长乘以地球半径,得到两点间的直线距离,单位为公里。

    • return distance.toFixed(2);:返回计算得到的距离,并将其保留两位小数。

     最后需要调用函数到接口操作中(上述的for循环):

    1. for (let i = 0; i < that.data.list.length; i++) {
    2. let item = that.data.list[i];
    3. let lat = parseFloat(item.latitude);
    4. let lon = parseFloat(item.longitude);
    5. let distance = that.getDistance(that.data.currentLatitude, that.data.currentLongitude, lat, lon);
    6. item.distance = distance;
    7. }
    8. that.setData({
    9. list: that.data.list
    10. });

    7.运行效果

    8.完整代码

    1. Page({
    2. /**
    3. * 页面的初始数据
    4. */
    5. data: {
    6. list:[],
    7. currentLatitude:'',
    8. currentLongitude:'',
    9. },
    10. /**
    11. * 生命周期函数--监听页面加载
    12. */
    13. handleImageError(e){
    14. onLoad(options) {
    15. let that = this;
    16. wx.getLocation({
    17. type: 'gcj02',
    18. success(res) {
    19. that.setData({
    20. currentLatitude: res.latitude,
    21. currentLongitude: res.longitude
    22. });
    23. wx.request({
    24. url: '',
    25. method: 'POST',
    26. data: {},
    27. success: function(res) {
    28. console.log(res);
    29. that.setData({
    30. list: res.data.data.list
    31. });
    32. for (let i = 0; i < that.data.list.length; i++) {
    33. let item = that.data.list[i];
    34. let lat = parseFloat(item.latitude);
    35. let lon = parseFloat(item.longitude);
    36. let distance = that.getDistance(that.data.currentLatitude, that.data.currentLongitude, lat, lon);
    37. item.distance = distance;
    38. }
    39. that.setData({
    40. list: that.data.list
    41. });
    42. },
    43. });
    44. },
    45. fail(res) {
    46. wx.showModal({
    47. title: '提示',
    48. content: '您还没有启用定位权限,是否前往设置开启?',
    49. success(res) {
    50. if (res.confirm) {
    51. wx.openSetting({
    52. success(res) {
    53. if (res.authSetting['scope.userLocation']) {
    54. that.onLoad(options);
    55. } else {
    56. wx.showToast({
    57. title: '您还未开启定位权限',
    58. icon: 'none'
    59. });
    60. }
    61. }
    62. });
    63. } else if (res.cancel) {
    64. console.log(res.cancel);
    65. wx.showToast({
    66. title: '您还未开启定位权限',
    67. icon: 'none'
    68. });
    69. }
    70. }
    71. });
    72. }
    73. });
    74. },
    75. onShow() {
    76. this.checkLocationPermission();
    77. },
    78. checkLocationPermission() {
    79. let that = this;
    80. wx.getSetting({
    81. success(res) {
    82. if (!res.authSetting['scope.userLocation']) {
    83. wx.showModal({
    84. title: '提示',
    85. content: '您还没有启用定位权限,是否前往设置开启?',
    86. success(res) {
    87. if (res.confirm) {
    88. wx.openSetting({
    89. success(res) {
    90. if (res.authSetting['scope.userLocation']) {
    91. that.onLoad();
    92. } else {
    93. wx.showToast({
    94. title: '您还未开启定位权限',
    95. icon: 'none'
    96. });
    97. }
    98. }
    99. });
    100. } else if (res.cancel) {
    101. console.log(res.cancel);
    102. wx.showToast({
    103. title: '您还未开启定位权限',
    104. icon: 'none'
    105. });
    106. }
    107. }
    108. });
    109. }
    110. }
    111. });
    112. },
    113. getDistance: function(lat1, lon1, lat2, lon2) {
    114. var R = 6371;
    115. var dLat = (lat2 - lat1) * Math.PI / 180;
    116. var dLon = (lon2 - lon1) * Math.PI / 180;
    117. var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    118. Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
    119. Math.sin(dLon / 2) * Math.sin(dLon / 2);
    120. var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    121. var distance = R * c;
    122. return distance.toFixed(2);
    123. },
    124. /**
    125. * 生命周期函数--监听页面初次渲染完成
    126. */
    127. onReady() {
    128. },
    129. /**
    130. * 生命周期函数--监听页面显示
    131. */
    132. onShow() {
    133. },
    134. /**
    135. * 生命周期函数--监听页面隐藏
    136. */
    137. onHide() {
    138. },
    139. /**
    140. * 生命周期函数--监听页面卸载
    141. */
    142. onUnload() {
    143. },
    144. /**
    145. * 页面相关事件处理函数--监听用户下拉动作
    146. */
    147. onPullDownRefresh() {
    148. },
    149. /**
    150. * 页面上拉触底事件的处理函数
    151. */
    152. onReachBottom() {
    153. },
    154. /**
    155. * 用户点击右上角分享
    156. */
    157. onShareAppMessage() {
    158. }
    159. })

    微信小程序如何利用接口返回经纬计算实际位置并且进行导航功能【下】
    https://blog.csdn.net/m0_71966801/article/details/134084525?spm=1001.2014.3001.5502 

  • 相关阅读:
    链表去重Java
    CentOS7 设置 MySQL 主备同步
    前端根据目录生成模块化路由routes
    什么?Postman也能测WebSocket接口了?
    “Boxing-StraightFist“ app Tech Support(URL)
    uniapp实战项目 (仿知识星球App) - - 配置开发工具和全局css样式
    C++设计模式之单例模式
    Springboot毕设项目校园缴费平台dzyxyjava+VUE+Mybatis+Maven+Mysql+sprnig)
    老卫带你学---leetcode刷题(128. 最长连续序列)
    mysql外键(foreign key)
  • 原文地址:https://blog.csdn.net/m0_71966801/article/details/134083967