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

本文主要是介绍微信小程序如何使用地球半径计算两组经纬度点之间的距离(自身位置与接口返回位置)【上】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

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.chinasem.cn/article/289730

相关文章

springboot security快速使用示例详解

《springbootsecurity快速使用示例详解》:本文主要介绍springbootsecurity快速使用示例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录创www.chinasem.cn建spring boot项目生成脚手架配置依赖接口示例代码项目结构启用s

Python如何使用__slots__实现节省内存和性能优化

《Python如何使用__slots__实现节省内存和性能优化》你有想过,一个小小的__slots__能让你的Python类内存消耗直接减半吗,没错,今天咱们要聊的就是这个让人眼前一亮的技巧,感兴趣的... 目录背景:内存吃得满满的类__slots__:你的内存管理小助手举个大概的例子:看看效果如何?1.

java中使用POI生成Excel并导出过程

《java中使用POI生成Excel并导出过程》:本文主要介绍java中使用POI生成Excel并导出过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求说明及实现方式需求完成通用代码版本1版本2结果展示type参数为atype参数为b总结注:本文章中代码均为

Spring Boot3虚拟线程的使用步骤详解

《SpringBoot3虚拟线程的使用步骤详解》虚拟线程是Java19中引入的一个新特性,旨在通过简化线程管理来提升应用程序的并发性能,:本文主要介绍SpringBoot3虚拟线程的使用步骤,... 目录问题根源分析解决方案验证验证实验实验1:未启用keep-alive实验2:启用keep-alive扩展建

使用Java实现通用树形结构构建工具类

《使用Java实现通用树形结构构建工具类》这篇文章主要为大家详细介绍了如何使用Java实现通用树形结构构建工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录完整代码一、设计思想与核心功能二、核心实现原理1. 数据结构准备阶段2. 循环依赖检测算法3. 树形结构构建4. 搜索子

GORM中Model和Table的区别及使用

《GORM中Model和Table的区别及使用》Model和Table是两种与数据库表交互的核心方法,但它们的用途和行为存在著差异,本文主要介绍了GORM中Model和Table的区别及使用,具有一... 目录1. Model 的作用与特点1.1 核心用途1.2 行为特点1.3 示例China编程代码2. Tab

SpringBoot使用OkHttp完成高效网络请求详解

《SpringBoot使用OkHttp完成高效网络请求详解》OkHttp是一个高效的HTTP客户端,支持同步和异步请求,且具备自动处理cookie、缓存和连接池等高级功能,下面我们来看看SpringB... 目录一、OkHttp 简介二、在 Spring Boot 中集成 OkHttp三、封装 OkHttp

使用Python实现获取网页指定内容

《使用Python实现获取网页指定内容》在当今互联网时代,网页数据抓取是一项非常重要的技能,本文将带你从零开始学习如何使用Python获取网页中的指定内容,希望对大家有所帮助... 目录引言1. 网页抓取的基本概念2. python中的网页抓取库3. 安装必要的库4. 发送HTTP请求并获取网页内容5. 解

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

使用Python实现网络设备配置备份与恢复

《使用Python实现网络设备配置备份与恢复》网络设备配置备份与恢复在网络安全管理中起着至关重要的作用,本文为大家介绍了如何通过Python实现网络设备配置备份与恢复,需要的可以参考下... 目录一、网络设备配置备份与恢复的概念与重要性二、网络设备配置备份与恢复的分类三、python网络设备配置备份与恢复实