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

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

目录

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

相关文章

W外链微信推广短连接怎么做?

制作微信推广链接的难点分析 一、内容创作难度 制作微信推广链接时,首先需要创作有吸引力的内容。这不仅要求内容本身有趣、有价值,还要能够激起人们的分享欲望。对于许多企业和个人来说,尤其是那些缺乏创意和写作能力的人来说,这是制作微信推广链接的一大难点。 二、精准定位难度 微信用户群体庞大,不同用户的需求和兴趣各异。因此,制作推广链接时需要精准定位目标受众,以便更有效地吸引他们点击并分享链接

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

day-51 合并零之间的节点

思路 直接遍历链表即可,遇到val=0跳过,val非零则加在一起,最后返回即可 解题过程 返回链表可以有头结点,方便插入,返回head.next Code /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode() {}*