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

news2024/11/15 17:45:26

目录

1.配置位置权限 

2.获取当前自身经纬度 

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

4. 循环取每一项的经纬

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

6.进行距离计算操作 

7.运行效果

8.完整代码

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

1.配置位置权限 

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

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

2.获取当前自身经纬度 

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

 wx.getLocation({
      type: 'gcj02',
      success(res) {
        that.setData({
          currentLatitude: res.latitude,
          currentLongitude: res.longitude
        });
})

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

 data: {
      currentLatitude:'',
      currentLongitude:'',
}

  onLoad(options) {
    let that = this;
}

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

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

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

wx.request({
          url: '自己所使用的接口',
          method: 'POST',
          data: {},
          success: function(res) {
            console.log(res);
            that.setData({
              list: res.data.data.list
            });
}
})

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

4. 循环取每一项的经纬

 list数据格式如下: 

 for (let i = 0; i < that.data.list.length; i++) {
              let item = that.data.list[i];
              let lat = parseFloat(item.latitude);
              let lon = parseFloat(item.longitude);
            }
            that.setData({
              list: that.data.list
            });

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

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

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

checkLocationPermission() {
    let that = this;
    wx.getSetting({
      success(res) {
        if (!res.authSetting['scope.userLocation']) {
          wx.showModal({
            title: '提示',
            content: '您还没有启用定位权限,是否前往设置开启?',
            success(res) {
              if (res.confirm) {
                // User confirmed opening settings
                wx.openSetting({
                  success(res) {
                    if (res.authSetting['scope.userLocation']) {
                      // User granted location permission in settings
                      that.onLoad(); // Reload the page to fetch data with location permission
                    } else {
                      // User did not grant location permission in settings
                      wx.showToast({
                        title: '您还未开启定位权限',
                        icon: 'none'
                      });
                    }
                  }
                });
              } else if (res.cancel) {
                console.log(res.cancel);
                // User canceled opening settings
                wx.showToast({
                  title: '您还未开启定位权限',
                  icon: 'none'
                });
              }
            }
          });
        }
      }
    });
  },

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

  onShow() {
    this.checkLocationPermission();
  },

6.进行距离计算操作 

  getDistance: function(lat1, lon1, lat2, lon2) {
    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);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var distance = R * c; 
    return distance.toFixed(2);
  },

详解代码:

  • 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循环):

for (let i = 0; i < that.data.list.length; i++) {
              let item = that.data.list[i];
              let lat = parseFloat(item.latitude);
              let lon = parseFloat(item.longitude);
              let distance = that.getDistance(that.data.currentLatitude, that.data.currentLongitude, lat, lon);
              item.distance = distance;
            }
            that.setData({
              list: that.data.list
            });

7.运行效果

8.完整代码

Page({

  /**
   * 页面的初始数据
   */
  data: {
      list:[],
      currentLatitude:'',
      currentLongitude:'',
     
  },

  /**
   * 生命周期函数--监听页面加载
   */
  handleImageError(e){
  onLoad(options) {
    let that = this;
    wx.getLocation({
      type: 'gcj02',
      success(res) {
        that.setData({
          currentLatitude: res.latitude,
          currentLongitude: res.longitude
        });
        
        wx.request({
          url: '',
          method: 'POST',
          data: {},
          success: function(res) {
            console.log(res);
            that.setData({
              list: res.data.data.list
            });
            
            for (let i = 0; i < that.data.list.length; i++) {
              let item = that.data.list[i];
              let lat = parseFloat(item.latitude);
              let lon = parseFloat(item.longitude);
              let distance = that.getDistance(that.data.currentLatitude, that.data.currentLongitude, lat, lon);
              item.distance = distance;
            }
            that.setData({
              list: that.data.list
            });
          },
        });
      },
      fail(res) {
        wx.showModal({
          title: '提示',
          content: '您还没有启用定位权限,是否前往设置开启?',
          success(res) {
            if (res.confirm) {
              wx.openSetting({
                success(res) {
                  if (res.authSetting['scope.userLocation']) {
                    that.onLoad(options); 
                  } else {
                    wx.showToast({
                      title: '您还未开启定位权限',
                      icon: 'none'
                    });
                  }
                }
              });
            } else if (res.cancel) {
              console.log(res.cancel);
              wx.showToast({
                title: '您还未开启定位权限',
                icon: 'none'
              });
            }
          }
        });
      }
    });
  },
  
  onShow() {
    this.checkLocationPermission();
  },
  
  checkLocationPermission() {
    let that = this;
    wx.getSetting({
      success(res) {
        if (!res.authSetting['scope.userLocation']) {
          wx.showModal({
            title: '提示',
            content: '您还没有启用定位权限,是否前往设置开启?',
            success(res) {
              if (res.confirm) {
                wx.openSetting({
                  success(res) {
                    if (res.authSetting['scope.userLocation']) {
                      that.onLoad(); 
                    } else {
                      wx.showToast({
                        title: '您还未开启定位权限',
                        icon: 'none'
                      });
                    }
                  }
                });
              } else if (res.cancel) {
                console.log(res.cancel);
                wx.showToast({
                  title: '您还未开启定位权限',
                  icon: 'none'
                });
              }
            }
          });
        }
      }
    });
  },
  
  getDistance: function(lat1, lon1, lat2, lon2) {
    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);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var distance = R * c;
    return distance.toFixed(2);
  },
  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  

  onReady() {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow() {

  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide() {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload() {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh() {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom() {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage() {

  }
})

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1141412.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【开源】基于SpringBoot的车险自助理赔系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 角色管理模块2.3 车辆档案模块2.4 车辆理赔模块2.5 理赔照片模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 角色表3.2.2 车辆表3.2.3 理赔表3.2.4 理赔照片表 四、系统展示五、核心代码5.1 查询车…

基于机器视觉的行人口罩佩戴检测 计算机竞赛

简介 2020新冠爆发以来&#xff0c;疫情牵动着全国人民的心&#xff0c;一线医护工作者在最前线抗击疫情的同时&#xff0c;我们也可以看到很多科技行业和人工智能领域的从业者&#xff0c;也在贡献着他们的力量。近些天来&#xff0c;旷视、商汤、海康、百度都多家科技公司研…

【C++初阶】类和对象——构造函数析构函数拷贝构造函数

个人主页点击直达&#xff1a;小白不是程序媛 C系列专栏&#xff1a;C头疼记 目录 前言 类的6个默认成员函数 构造函数 概念 构造函数的特性 析构函数 概念 析构函数特性 拷贝构造函数 概念 拷贝构造函数特性 总结 前言 上篇文章我们对于C中的类有了初步的认识和…

【运维知识大神篇】两种方法,一键部署ElasticSearch集群(Shell+Ansible自动化部署)

本篇文章给大家介绍一下用Shell和Ansible两种方式&#xff0c;去一键部署ES&#xff08;ElasticSearch&#xff09;集群&#xff0c;实现在集群部署中的批量化操作&#xff0c;享受自动化部署的魅力。 准备主机 主机名IPcpudiskmemoryAnsible10.0.0.612C20G2GELK10410.0.0.10…

Linux必备技能:掌握的必会命令

1 rpm查看程序配置文件 rpm -qc httpd2 rpm查看系统已经安装的相关的包 rpm -qa | grep httpd3 netstat查看服务支持的端口 netstat -anltupe | grep httpd

初识HTML超文本标记语言

文章目录 前端简介引入前端三剑客什么是HTML&#xff1f;超文本传输协议前戏HTTP超文本传输协议1.什么是HTTP协议2.四大特性3.数据格式4.响应状态码 基于HTTP协议搭建HTMLHTML简介 前端简介 引入 前端&#xff1a;与用户直接打交道的操作界面都可以称之为前端(那些炫酷的页面)…

自动化工具-文件清单对比

博客主页&#xff1a;https://tomcat.blog.csdn.net 博主昵称&#xff1a;农民工老王 主要领域&#xff1a;Java、Linux、K8S 期待大家的关注&#x1f496;点赞&#x1f44d;收藏⭐留言&#x1f4ac; 目录 背景代码使用 背景 最近的工作中&#xff0c;领导需要比较指定两个文…

太古妖皇诀攻略,太古妖皇诀什么职业厉害

感受国风手游的魅力&#xff0c;畅游于以山海经为背景的太古妖皇诀。游戏地图广阔&#xff0c;洪荒异兽众多&#xff0c;技能配置酷炫&#xff0c;带来成吨伤害的打击感。与山海经中的精怪为伴&#xff0c;踏上修真之路。此外&#xff0c;万人在线竞技&#xff0c;让您尽情享受…

UG\NX二次开发 清除所有对象高亮

文章作者:里海 来源网站:王牌飞行员_里海_里海NX二次开发3000例,里海BlockUI专栏,C\C++-CSDN博客 感谢粉丝订阅 感谢 qq419469101 订阅本专栏,非常感谢。 简介 UG\NX二次开发 清除所有对象高亮 效果 代码 #include "me.hpp" extern DllExport void ufusr(char* p…

服务网络基础

服务网络基础 目录 前言 从今天开始我们将进入服务网格的学习&#xff0c;服务网格是微服务架构中的一种重要的技术&#xff0c;它可以解决微服务架构中的一些问题&#xff0c;比如服务发现、服务治理、服务监控等等&#xff0c;我们将从服务网格的基础开始&#xff0c;逐步深…

图像特征Vol.1:计算机视觉特征度量【纹理区域特征】

一、前言 &#x1f34a;什么是计算机视觉特征&#xff1f; 简单来说就是图像特征&#xff0c;对于我们来说&#xff0c;看到一张图片&#xff0c;能很自然的说出和描述图像中的一些特征&#xff0c;但是同样的图片&#xff0c;丢给计算机&#xff0c;只是一个二维矩阵&#xf…

场效应管器件

在面试硬件方面的工作时&#xff0c;我们通常会被提问模电方面的知识。 场效应管简称FET,有三级&#xff1a;源极(S)、漏极(D)、栅极&#xff08;G&#xff09;&#xff1b;可以实现电压控制电流源&#xff1b;“源极和漏极之间的漏极电流Id&#xff0c;由栅极的负电压进行控制…

Nerfies:可变形神经辐射场

Park K, Sinha U, Barron J T, et al. Nerfies: Deformable neural radiance fields[C]//Proceedings of the IEEE/CVF International Conference on Computer Vision. 2021: 5865-5874. Nerfies 是 Keunhong Park 在 Google 实习时基于 NeRF 模型开发的 可变形神经辐射场 (Def…

Qt界面实现中英文切换

要实现的效果&#xff0c;是下拉列表切换中文和English实现按钮文本中英文内容切换。 实现步骤&#xff1a; 1.在VS中鼠标对Translation Files文件右击&#xff0c;选择“添加”--->“模块”. 在弹窗的窗口中选择“Qt”--->“Qt Translation File”。 添加Translation_e…

操作系统(02326)考试题库

博客主页&#xff1a;https://tomcat.blog.csdn.net 博主昵称&#xff1a;农民工老王 主要领域&#xff1a;Java、Linux、K8S 期待大家的关注&#x1f496;点赞&#x1f44d;收藏⭐留言&#x1f4ac; 目录 单选题多选题主观题 单选题 把并发进程中与共享变量有关的程序段称为…

DoLa:对比层解码提高大型语言模型的事实性

DoLa&#xff1a;对比层解码提高大型语言模型的事实性 摘要1 引言2 方法2.1 事实知识在不同层级上演化2.2 动态早期层选择2.3 预测对比 3 实验3.1 任务3.2 实验设置3.3 多项选择3.3.1 TruthfulQA&#xff1a;多项选择3.3.2 FACTOR&#xff1a;维基、新闻 3.4 开放式文本生成3.4…

polyloss详解

1、常见的泰勒展开公式 2、polyloss引入动机 2.1、polyloss定义 polyloss通过泰勒展开来逼近损失函数的简单框架&#xff0c;将损失函数设计为多项式函数的线性组合 2.2、polyloss主要贡献 提出了一个新的框架来理解和设计损失函数 PolyLoss可以让多项式基根据目标任务和数…

JVM虚拟机:Java对象的头信息有什么?

本文重点 在前面的课程中,我们学习了对象头,其中对象头包含Mark Word和class pointer,当然数组还会有一个数组长度。本文主要分析Mark Work中包含的信息。 Mark Word 以下两张图是一个意思: 32位 32位 64位 以上就是Mark Word会存储的信息,这个意思是说Java对象在不同…

如何使用手机蓝牙设备作为电脑的解锁工具像动态锁那样,蓝牙接近了电脑,电脑自动解锁无需输入开机密码

环境&#xff1a; Win10 专业版 远程解锁 蓝牙解锁小程序 问题描述&#xff1a; 如何使用手机蓝牙设备作为电脑的解锁工具像动态锁那样&#xff0c;蓝牙接近了电脑&#xff0c;电脑自动解锁无需输入开机密码 手机不需要拿出来&#xff0c;在口袋里就可以自动解锁&#xff…

「林曦的亲子美育」讲讲关于阅读的那些事儿

「林曦的亲子美育」是“林曦的小世界”2023年策划的一档新栏目。林曦老师作为一个“小男生的妈妈”,在这些年分享了许多关于亲子教育的心得&#xff1a;以“美”作为连接和最高标准&#xff0c;会护持着小朋友的选择和人生。教育是一个生活的过程。做一餐饭、读一本书、看一张画…