JS 计算两个点(经纬度)的距离
经度相同,纬度不同
纬度每隔0.00001度,距离相差约1.1米。
纬度每隔0.0001度,距离相差约11米。
纬度每隔0.001度,距离相差约111米。
纬度每隔0.01度,距离相差约1113米。
纬度每隔0.1度,距离相差约11132米。
纬度相同,经度不同
经度每隔0.00001度,距离相差约1米。
经度每隔0.0001度,距离相差约10米。
经度每隔0.001度,距离相差约100米。
经度每隔0.01度,距离相差约1000米。
经度每隔0.1度,距离相差约10000米。
方法一(精度比方法二要高)
const staVal = { lng: "106.64647211048887", lat: "26.619020177917346" };
const endVal = { lng: "106.65148784134672", lat: "26.615442440608998" };
this.calcCoordsDistance(staVal, endVal) // {mVal: '638.59m', kmVal: '0.63859km', originVal: '638.5888697736245'}
/** 计算两个点(经纬度)的距离
* @param startDot 开始点的经纬度(lng.经度 lat.纬度)
* @param endDot 结束点的经纬度(lng.经度 lat.纬度)
* @returns {{originVal: string, mVal: string, kmVal: string}} originVal.原始值单位为米
*/
calcCoordsDistance(startDot, endDot) {
if (!startDot || !endDot) {
return { mVal: "", kmVal: "", originVal: "两点的经纬度为必传" };
}
const earthRadius = 6378137.0, // 地球半径
PI = Math.PI, // 圆周率π
startRadianLat = getRadian(startDot.lat), // 纬度 - 开始
endRadianLat = getRadian(endDot.lat), // 纬度 - 结束
latDiffVal = startRadianLat - endRadianLat, // 维度差值
lngDiffVal = getRadian(startDot.lng) - getRadian(endDot.lng), // 经度差值
latDiffSinVal = Math.sin(latDiffVal / 2), // 维度差值的正弦值
lngDiffSinVal = Math.sin(lngDiffVal / 2), // 经度差值的正弦值
latCosProduct = Math.cos(startRadianLat) * Math.cos(endRadianLat), // 维度的余弦值乘积
powVal = latCosProduct * Math.pow(lngDiffSinVal, 2),
sqrtVal = Math.pow(latDiffSinVal, 2) + powVal, // 开平方根的值
result = 2 * Math.asin(Math.sqrt(sqrtVal)) * earthRadius, // 结果值
mUnit = result.toFixed(2) + "m", // 单位米
kmUnit = (result / 1000).toFixed(5) + "km"; // 单位千米
function getRadian(d) {
return (d * PI) / 180.0;
}
return { mVal: mUnit, kmVal: kmUnit, originVal: result.toString() };
},
方法二
const staVal = { lng: "106.64647211048887", lat: "26.619020177917346" };
const endVal = { lng: "106.65148784134672", lat: "26.615442440608998" };
this.calcCoordsDistance(staVal, endVal); // {mVal: '640.63m', kmVal: '0.64063km', originVal: '640.6309389968611'}
/** 计算两个点(经纬度)的距离
* @param startDot 开始点的经纬度(lng.经度 lat.纬度)
* @param endDot 结束点的经纬度(lng.经度 lat.纬度)
* @returns {{originVal: string, mVal: string, kmVal: string}} originVal.原始值单位为米
*/
calcCoordsDistance(startDot, endDot) {
if (!startDot || !endDot) {
return { mVal: "", kmVal: "", originVal: "两点的经纬度为必传" };
}
const lngDiffVal = Math.round((startDot.lng - endDot.lng) * 100000), // 经度的距离差(单位m)
latDiffVal = Math.round((startDot.lat - endDot.lat) * 111320), // 纬度的距离差(单位m)
result = Math.sqrt(Math.pow(lngDiffVal, 2) + Math.pow(latDiffVal, 2)), // 结果值
mUnit = result.toFixed(2) + "m", // 单位米
kmUnit = (result / 1000).toFixed(5) + "km"; // 单位千米
return { mVal: mUnit, kmVal: kmUnit, originVal: result.toString() };
},
const point = [121.65628910064697, 31.14649210398973];
const areaList = [
[121.64199829101561, 31.128897282106205],
[121.6805362701416, 31.128897282106205],
[121.685362701416, 31.157914133949994],
[121.64199829101561, 31.157914133949994],
[121.64199829101561, 31.128897282106205],
];
this.judgeCoordsInArea(point, areaList) // true
/** 判断某一点是否在某一区域范围内(lng.经度 lat.纬度)
* @param dot 需要判断的点(格式:[lng, lat])
* @param range 区域范围(格式:[[lng, lat], [lng, lat]])
* @returns {boolean} true.存在 false.不存在
*/
judgeCoordsInArea(dot, range) {
let count = 0,
t1,
t2,
term,
r1 = range[0],
r2;
for (let i = 1; i <= range.length; i++) {
r2 = range[i % range.length];
t1 = dot[0] > Math.min(r1[0], r2[0]) && dot[0] <= Math.max(r1[0], r2[0]);
t2 = dot[1] <= Math.max(r1[1], r2[1]) && r1[0] !== r2[0];
if (t1 && t2) {
term = ((dot[0] - r1[0]) * (r2[1] - r1[1])) / (r2[0] - r1[0]) + r1[1];
if (r1[1] === r2[1] || dot[1] <= term) count++;
}
r1 = r2;
}
return count % 2 !== 0;
},
行政区域边界经纬度可以点击此链接下载