JS 计算两个点(经纬度)的距离;判断某一点是否在某一区域范围内

JS 计算两个点(经纬度)的距离;判断某一点是否在某一区域范围内

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() };
},

JS 判断某一点是否在某一区域范围内

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;
},

行政区域边界经纬度可以点击此链接下载

$(function(){ $.fn.extend({ SimpleTree:function(options){ //初始化参数 var option = $.extend({ click:function(a){ } },options); option.tree=this; /* 在参数对象中添加对当前菜单树的引用,以便在对象中使用该菜单树 */ option._init=function(){ /* * 初始化菜单展开状态,以及分叉节点的样式 */ this.tree.find("ul ul").hide(); /* 隐藏所有子级菜单 */ this.tree.find("ul ul").prev("li").removeClass("open"); /* 移除所有子级菜单父节点的 open 样式 */ this.tree.find("ul ul[show='true']").show(); /* 显示 show 属性为 true 的子级菜单 */ this.tree.find("ul ul[show='true']").prev("li").addClass("open"); /* 添加 show 属性为 true 的子级菜单父节点的 open 样式 */ }/* option._init() End */ /* 设置所有超链接不响应单击事件 */ this.find("a").click(function(){ $(this).parent("li").click(); return false; }); /* 菜单项 接受单击 */ this.find("li").click(function(){ /* * 当单击菜单项 * 1.触发用户自定义的单击事件,将该 标签中的第一个超链接做为参数传递过去 * 2.修改当前菜单项所属的子菜单的显示状态(如果等于 true 将其设置为 false,否则将其设置为 true) * 3.重新初始化菜单 */ option.click($(this).find("a")[0]); /* 触发单击 */ /* * 如果当前节点下面包含子菜单,并且其 show 属性的值为 true,则修改其 show 属性为 false * 否则修改其 show 属性为 true */ /* if($(this).next("ul").attr("show")=="true"){ $(this).next("ul").attr("show","false"); }else{ $(this).next("ul").attr("show","true"); }*/ /* 初始化菜单 */ option._init(); }); /* 设置所有父节点样式 */ this.find("ul").prev("li").addClass("folder"); /* 设置节点“是否包含子节点”属性 */ this.find("li").find("a").attr("hasChild",false); this.find("ul").prev("li").find("a").attr("hasChild",true); /* 初始化菜单 */ option._init(); }/* SimpleTree Function End */ }); });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值