前端vue uni-app地图定位并测算当前定位离目标位置距离

随着技术的发展,开发的复杂度也越来越高,传统开发方式将一个系统做成了整块应用,经常出现的情况就是一个小小的改动或者一个小功能的增加可能会引起整体逻辑的修改,造成牵一发而动全身。通过组件化开发,可以有效实现单独开发,单独维护,而且他们之间可以随意的进行组合。大大提升开发效率低,降低维护成本。

组件化对于任何一个业务场景复杂的前端应用以及经过多次迭代之后的产品来说都是必经之路。组件化要做的不仅仅是表面上看到的模块拆分解耦,其背后还有很多工作来支撑组件化的进行,例如结合业务特性的模块拆分策略、模块间的交互方式和构建系统等等 。

本文给大家介绍的一款组件是:

前端vue uni-app地图定位并测算当前定位离目标位置距离, 

 

 小程序体验地址(已上线):

阅读全文下载完整组件代码请关注微信公众号: 前端组件开发

d848d5658a07453c843277846948c608.png

效果图如下:

d95e35342460841463a2fa578308d326.jpeg

277d4767dd33e898e80f06299b5f20b5.jpeg


#

#### 使用方法

```使用方法

<!--

// 腾讯地图key注册地址(针对H5端,manifest.json中web配置,配置定位与地图 若是微信小程序只需配置微信小程序权限配置):

  https://lbs.qq.com/dev/console/application/mine

-->

<!-- scale缩放级别,取值范围为3-20 longitude:地图中心精度 latitude:地图中心纬度 markers:覆盖物 show-location:是否显示定位-->

<map class="mapV" :latitude="infoDict.lat"

:longitude="infoDict.lon" scale='6' :markers="covers" show-location=false>

</map>

<!--

        page.json配置以下

// 权限设置

"permission": {

"scope.userLocation": {

"desc": "您的位置信息将用于该活动签到"

}

}

-->

```

#### HTML代码部分

```html

<template>

<view class="content">

<scroll-view class="scrollV" scroll-y="true">

<view class="inputView">

<text class="leftTitle">活动内容</text>

</view>

<view class="inputView">

{{"去清远古龙峡漂流"}}

</view>

<view class="inputView">

<text class="leftTitle">签到须知</text>

</view>

<view class="inputView">

{{'距离活动地10km内可签到成功'}}

</view>

<!--

// 腾讯地图key注册地址(针对H5端,manifest.json中web配置,配置定位与地图 若是微信小程序只需配置微信小程序权限配置):

  https://lbs.qq.com/dev/console/application/mine

-->

<!-- scale缩放级别,取值范围为3-20 longitude:地图中心精度 latitude:地图中心纬度 markers:覆盖物 show-location:是否显示定位-->

<map class="mapV" :latitude="infoDict.lat" :longitude="infoDict.lon" scale='6' :markers="covers"

show-location=false>

</map>

</scroll-view>

<view class="btnview" @tap="goSignIn">{{'签到' + distanceStr}}</view>

</view>

</template>

```

#### JS代码 (引入组件 填充数据)

```javascript

<script>

import Vue from 'vue'

export default {

data() {

return {

// 覆盖物

covers: [],

// 目标经纬度信息

infoDict: {

'lon': '113.17',

'lat': '23.8'

},

// 我的定位经纬度信息

myPinInfo: {},

// 默认距离为负数

distance: -9999,

distanceStr: ''

}

},

onShow() {

// 获取当前位置

this.getlocation();

},

methods: {

getlocation() {

let myThis = this;

console.log('获取位置开始');

uni.getLocation({

type: 'gcj02',

success: function(res) {

myThis.myPinInfo = res;

console.log('当前位置的经度:' + res.longitude);

console.log('当前位置的纬度:' + res.latitude);

myThis.covers = [{

latitude: myThis.infoDict.lat,

longitude: myThis.infoDict.lon,

width: 30,

height: 30,

id: 20000,

iconPath: '../../static/activity_pin.png'

},

{

latitude: myThis.myPinInfo.latitude,

longitude: myThis.myPinInfo.longitude,

width: 30,

height: 30,

id: 20001,

iconPath: '../../static/people_pin.png'

}

];

myThis.distance = myThis.getDistance(myThis.infoDict.lat, myThis.infoDict.lon, myThis

.myPinInfo.latitude, myThis.myPinInfo.longitude)

myThis.distanceStr = '(当前距离' + myThis.distance + '米)';

}

});

},

// 计算两点距离

getDistance(lat1, lng1, lat2, lng2) {

let EARTH_RADIUS = 6378.137;

let radLat1 = this.rad(lat1);

let radLat2 = this.rad(lat2);

let a = radLat1 - radLat2;

let b = this.rad(lng1) - this.rad(lng2);

let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +

Math.cos(radLat1) * Math.cos(radLat2) *

Math.pow(Math.sin(b / 2), 2)));

s = s * EARTH_RADIUS;

//s = Math.round(s * 10000d) / 10000d;

s = Math.round(s * 10000) / 10000;

s = s * 1000; //乘以1000是换算成米

return s;

},

// 弧度计算

rad(d) {

return d * Math.PI / 180.0;

},

// 立即签到

goSignIn(e) {

if (this.distance > 10000) {

uni.showModal({

title: '温馨提示',

content: '您的当前位置距离活动目的地太远, 无法签到',

showCancel: false

})

return;

} else if (this.distance < 0) {

uni.showModal({

title: '温馨提示',

content: '您的定位权限未打开, 请点击小程序右上角···菜单按钮, 然后点击设置,打开定位权限',

showCancel: false

})

return

}

},

}

}

</script>

```

#### CSS

```CSS

<style>

.content {

display: flex;

flex-direction: column;

height: 100%;

}

.scrollV {

width: 100vw;

}

.mapV {

width: calc(100vw);

height: 320px;

margin-top: 14px;

}

.leftTitle {

width: 284px;

height: 44px;

line-height: 44px;

font-size: 14px;

color: #333333;

}

.inputView {

flex-direction: row;

display: flex;

height: auto;

align-items: center;

margin-left: 13px;

width: calc(100vw - 30px);

padding: 2px 0px;

font-size: 13px;

color: #666666;

}

.btnview {

display: flex;

background-color: #FF731E;

justify-content: center;

align-items: center;

color: #ffffff;

width: 100%;

height: 50px;

margin-top: 20px;

}

</style>

```

 小程序体验地址(已上线):

### 距离计算前端开发中的重要性 在前端开发中,距离计算对于许多应用场景来说至关重要。例如,在物流配送系统中,需要计算送货员当前位置与目的地之间的直线距离;在旅游网站上,则可能要显示景点间的实际路程长度[^1]。 ### 实现方法概述 为了满足这些需求,开发者通常会采用地理信息系统(GIS)提供的服务来完成这项工作。具体而言,可以调用第三方的地图API接口来进行两点间最短路径规划或是直接获取经纬度坐标下的球面距离测量结果。这里将以腾讯地图 API 作为例子说明如何利用它所提供的工具函数轻松达成此目的。 ### 使用腾讯地图API进行距离计算的具体操作 #### 获取两个地点的经纬度信息 首先,确保已经成功引入了腾讯地图 JavaScript SDK 初始化好 map 对象之后,可以通过 `geocoder` 类型对象查询任意地址对应的经度和纬度值: ```javascript // 创建 geocoder 实例 var myGeocoder = new TMap.service.Geocoder({ // 设置参数 }); myGeocoder.getAddress({location: {lat: latitude, lng: longitude}}, function (status, result) { console.log(result); }) ``` #### 计算两组经纬度之间的大圆弧线距离 接着就是核心部分——根据所得到的位置数据求解它们彼此相隔多远。此时可借助于 Haversine 公式 或者 Vincenty's formulae 来近似估算地球表面上任意两点沿表面连线的距离。幸运的是,腾讯地图也提供了便捷的方式来做这件事: ```javascript function calculateDistance(lat1, lon1, lat2, lon2){ var pointA = new TMap.LatLng(lat1,lon1); var pointB = new TMap.LatLng(lat2,lon2); return Math.round(TMap.geometry.spherical.computeDistanceBetween(pointA ,pointB)); } console.log(calculateDistance(39.984722,116.304167,31.229152,121.479723)); // 输出单位为米 ``` 上述代码片段展示了怎样定义一个名为 `calculateDistance()` 的辅助函数接收四个浮点数类型的输入参数代表起点和终点各自的维度及经度数值,返回二者间距的结果(以整数形式表示)。最后打印出来的即是从北京天安门广场到上海外滩这段行程大约有多少公里长。 ### 组件化实现方案 除了直接编写逻辑处理程序之外,还可以考虑将此类功能封装成易于重用的小部件以便更好地适应现代 Web 应用架构的要求。比如基于 Vueuni-app 构建的地图定位距离测算插件就很好地体现了这一点。这种方式有助于简化项目结构增强代码可读性和移植性[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端组件开发

你的钟意将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值