作者觉得选择第二、第三个方案更好
第一种,高德会限额问题,但是可以选择直线,驾车,骑行等
第二种,你只要引入了高德服务,就可以用高德的计算距离的方法,但是app种,有可能会有问题
第三种的话,只能做直线距离
uniapp h5地图必须选择腾讯地图,这是uniapp规定的
这里的规定是指的是获取位置的时候需要腾讯,如果需要得到两个位置的距离可以用高德的服务
1.引入定位服务
首先来到腾讯地图开放平台,申请一个key
这是可以多选的,但必须勾选webservice api,如果你报这个问题了,就是没勾选
如果需要具体信息,只能为app端,因为H5只有经纬度
https://uniapp.dcloud.io/api/location/location.html#getlocation
uni.getLocation({
type: 'gcj02',
geocode: true,
success: (res) => {
console.log(res)
},
complete: (e) => {
console.log(e);
},
fail: (e) => {
console.log(e);
}
});
点击跳转到腾讯地图api
外部数据结构
onLoad() {
computeDistance(
[
{
id: 1, lat: 38.831977, lon: 121.502809
}
]
).then((res)=>{
console.log(res);
})
}
//这是一个js内
import { jsonp } from 'vue-jsonp'
export const computeDistance = (fromList) => {
return new Promise((resolve, reject) => {
if (!isAvailableArray(fromList)) {
reject('数据格式错误');
return;
}
// 获取当前位置
uni.getLocation({
type: 'gcj02',
geocode: true,
success: (res) => {
// 获取位置的经纬度
const latitude = res.latitude;
const longitude = res.longitude;
getDistanceData([longitude, latitude], fromList);
},
fail: (e) => {
reject(e);
},
complete(e) {
if (e.errMsg === 'getLocation:ok') {
console.log('定位成功');
} else {
console.error('定位失败');
}
}
});
// 判断当前是否是一个可用数组
function isAvailableArray(arr) {
return arr && Array.isArray(arr) && arr.length > 0;
}
// 数组内部个数不同,拼接的字符串是不同的
// 来到这里说明一定是一个数组,并且长度一定大于0,可用
function parmaHandler(from, to) {
let distanceFrom = '';
let distanceTo = '';
// 起点
distanceFrom = [...from].toString();
// 如果外界传递参数只有一个数组
if (to.length === 1) {
distanceTo = to.reduce((str, cur) => {
return str += `${cur.lon},${cur.lat}`
}, '')
}
// 到腾讯地图的时候需要成对出现,目前业务起点from只有一个
// 数据格式 to 需要多个拼接的字符串,最后一个不需要 |
if (to.length > 1) {
to.forEach((item) => {
distanceTo += `${item.lon},${item.lat}|`
})
distanceTo = distanceTo.substring(0, distanceTo.length - 1);
}
return {
distanceFrom: distanceFrom,
distanceTo: distanceTo
}
}
function getDistanceData(from, to) {
// 距离集合
let distanceData = [];
// 没有值,返回
if (!from || !to) {
reject('未传递必须数组');
return;
}
// 不是一个可用数组,返回
if (!isAvailableArray(from) || !isAvailableArray(to)) {
reject('传递的数组为空');
return;
}
// 参数处理
let data = parmaHandler(from, to);
// 获取距离,当前为测试key
jsonp('https://restapi.amap.com/v3/distance', {
type: 1,
origins: data.distanceTo,
destination: data.distanceFrom,
key: '你的key',
output: 'JSON'
}).then((data) => {
const result = data.results;
if (data.status !== '1') {
reject('获取距离数据错误:' + data.infocode);
return;
}
//不是一个可用的数组返回
if (!result || !isAvailableArray(result)) {
reject('获取位置数据错误');
return;
}
distanceData = result.map((item, index) => {
return {
id: to[index].id,
longitude: to[index].lon,
latitude: to[index].lat,
distance: item.distance
}
})
resolve(distanceData);
}).catch((e) => {
reject(e);
});
}
})
};
// https://www.hhlink.com/%E7%BB%8F%E7%BA%AC%E5%BA%A6 这个网站可以算距离
只想获取距离高德中有方法获取两点距离 注意:这是直线距离
https://lbs.amap.com/api/javascript-api/guide/geometry/geometry
var p1 = [116.434027, 39.941037];
var p2 = [116.461665, 39.941564];
// 返回 p1 到 p2 间的地面距离,单位:米
var dis = AMap.GeometryUtil.distance(p1, p2);
自己写 这样的好处,你可以自己做一个npm 包,这样就不用担心AMap实例不能用的问题 注意:这是直线距离
// https://www.hhlink.com/%E7%BB%8F%E7%BA%AC%E5%BA%A6 这个网站可以算距离
// 直线距离
const rad = (d) => {
return d * Math.PI / 180.0;
}
const GetDistance = (lat1, lng1, lat2, lng2) => {
const EARTH_RADIUS = 6378.137;
let radLat1 = rad(lat1);
let radLat2 = rad(lat2);
let a = radLat1 - radLat2;
let b = rad(lng1) - 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 = (s * 10000) / 10;
return Math.round(s);
}
调用 GetDistance() 返回米
你也可用 作者的写好的包,直接调用
npm install swc-lib
import {getDistance } from "swc-lib/esm"
getDistance([38.8626430801, 121.5300857178],[38.831994, 121.502954])