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

目录

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 settingswx.openSetting({success(res) {if (res.authSetting['scope.userLocation']) {// User granted location permission in settingsthat.onLoad(); // Reload the page to fetch data with location permission} else {// User did not grant location permission in settingswx.showToast({title: '您还未开启定位权限',icon: 'none'});}}});} else if (res.cancel) {console.log(res.cancel);// User canceled opening settingswx.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.hqwc.cn/news/151121.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RPA除了和OCR、NLP技术结合,还能和什么技术结合?

鉴于业内现在也经常把RPA称为数字员工&#xff0c;就虚拟一个人的形象来解答吧。 首先是头部&#xff0c;实现人的“听看说想”能力&#xff1a; 听&#xff1a;ASR&#xff08;语音识别技术&#xff09;&#xff0c;主要用于听取和理解语音输入&#xff0c;让RPA能处理语音数…

读高性能MySQL(第4版)笔记21_读后总结与感想兼导读

1. 基本信息 高性能MySQL&#xff1a;经过大规模运维验证的策略&#xff08;第4版&#xff09; High Performance MySQL, Fourth Edition [美] Silvia Botros(西尔维亚博特罗斯)&#xff1b;Jeremy Tinley(杰里米廷利) 电子工业出版社,2022年10月出版 1.1. 读薄率 书籍总字…

vue3.0运行npm run dev 报错Cannot find module node:url

vue3.0运行npm run dev 报错Cannot find module 问题背景 近期用vue3.0写项目&#xff0c;npm init vuelatest —> npm install 都正常,npm run dev的时候报错如下&#xff1a; failed to load config from F:\code\testVue\vue-demo\vite.config.js error when starting…

EtherNet/IP转profienrt协议网关连接EtherNet/IP协议的川崎机器人配置方法

EthernetIP 协议一般用于采集机器人&#xff0c;控制器等设备的数据。 下面介绍通过远创智控YC-EIPM-PN网关把EtherNet/IP协议的川崎机器人通过西门子1500PLC的控制方法。有些 EIP 的从站设备提供了 EDS 文件&#xff0c;可以从EDS 文件中获取点位信息。这些信息是需要填写到网…

供应 JOSEF约瑟 电源监视继电器 HJZZ-92/2A HJZZ-91 DC220V

品牌&#xff1a;JOSEF约瑟名称:监视综合继电器型号:HJZZ-91、HJZZ-92/2A额定电压:48,110,220VDC/110,220,380VAC功率消耗:≤10W触点容量:250V5A 系列型号&#xff1a; HJZZ-91分闸、合闸、电源监视综合装置&#xff1b; HJZZ-92/1分闸、合闸、电源监视综合装置&#xff1b;…

【计算机网络笔记】Cookie技术

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

Unity Spine 指定导入新Spine动画的默认材质

指定导入新Spine动画的默认材质 找到Spine的Editor导入配置如何修改方法一: 你可以通过脚本 去修改Assets/Editor/SpineSettings.asset文件方法二&#xff1a;通过面板手动设置 找到Spine的Editor导入配置 通常在 Assets/Editor/SpineSettings.asset 配置文件对应着 Edit/Prefe…

Web攻防06_sqlmap的使用

文章目录 参考链接&#xff1a; SQLMAP简介支持五种不同的注入模式 数据猜解-库表列数据权限操作引出权限&#xff1a;引出文件&#xff1a;引出命令&#xff08;执行命令&#xff09;&#xff1a; 提交方法-POST&HEAD&JSONPost注入cookie注入注入请求头中&#xff08;…

基于 nodejs+vue旅游推荐系统 mysql

目 录 摘 要 I ABSTRACT II 目 录 II 第1章 绪论 1 1.1背景及意义 1 1.2 国内外研究概况 1 1.3 研究的内容 1 第2章 相关技术 3 2.1 nodejs简介 4 2.2 express框架介绍 6 2.4 MySQL数据库 4 第3章 系统分析 5 3.1 需求分析 5 3.2 系统可行性分析 5 3.2.1技术可行性&#xff1a;…

【随机过程】布朗运动

这里写目录标题 Brownian motion Brownian motion The brownian motion 1D and brownian motion 2D functions, written with the cumsum command and without for loops, are used to generate a one-dimensional and two-dimensional Brownian motion, respectively. 使用cu…

主动调度是如何发生的

计算机主要处理计算、网络、存储三个方面。计算主要是 CPU 和内存的合作&#xff1b;网络和存储则多是和外部设备的合作&#xff1b;在操作外部设备的时候&#xff0c;往往需要让出 CPU&#xff0c;就像上面两段代码一样&#xff0c;选择调用 schedule() 函数。 上下文切换主要…

Stable Diffusion WebUI linux部署问题

当我部署好环境后&#xff0c;准备大张旗鼓开搞时&#xff0c;进入项目地址运行python launch.py后发现 下面连接着的报错是 OSError: Cant load tokenizer for openai/clip-vit-large-patch14. If you were trying to load it from https://huggingface.co/models, make sure…