zoukankan      html  css  js  c++  java
  • 计算3个地理坐标点之间的夹角

    火车地图搞了有半年了,在做火车地图的过程中,遇到了一个问题,就是由于火车站点的地理坐标是直接请求api拿到的,部分api返回的结果可能千差万别。所以我需要一个方法,来在地图显示的过程中,判断出某个站点的坐标有误,并上报到服务器端,从而便于我的修正。一个典型的站点错误如下面这张图片所示:

    uploading-image-560783.png

    我最开始的思路是计算站点之间的距离,然后根据两站点之间的到站时间算出速度,如果超出某个值,比如300km/h,就判断该站点中有错误。

    但是这种方法适用于坐标差出去比较多的站点,对于坐标差别比较少的站点就无能为力了,所以接下来,我要提到第二种方法,就是计算站点夹角的方法。

    从上图可以看出,错误的站点会形成一个很小的锐角,如果我们能计算出这个锐角的大小,问题就解决了。

    那么问题可以描述如下:

    有3个站点坐标P1,P2,P3,求角⦣P1P2P3的大小。

    问题很简单,解出来不容易,因为高中所学的功夫,由于很长时间没有使用,基本已经忘完了。好在有搜索引擎,一番搜索之后,终于找到了一个方案,计算夹角可以分为下面两步:

    1. 将经纬度转换成笛卡尔坐标系下的值
    2. 利用向量求夹角
      θ=acos(v1⋅v2/||v1||||v2||)

    代码如下:

    // lat,lng为弧度表示的经纬度,r为地球半径,由于是算夹角,r是多少不重要
    function ball2xyz(lat, lng, r = 6400) {
      return {
        x: r * Math.cos(lat) * Math.cos(lng),
        y: r * Math.cos(lat) * Math.sin(lng),
        z: r * Math.sin(lat)
      };
    }
    // https://blog.csdn.net/reborn_lee/article/details/82497577
    // 将地理经纬度转换成笛卡尔坐标系
    function geo2xyz({ lat, lng }) {
      let thera = (Math.PI * lat) / 180;
      let fie = (Math.PI * lng) / 180;
      return ball2xyz(thera, fie);
    }
    
    // 计算3个地理坐标点之间的夹角
    function angleOflocation(l1, l2, l3) {
      let p1 = geo2xyz(l1);
      let p2 = geo2xyz(l2);
      let p3 = geo2xyz(l3);
    
      let { x: x1, y: y1, z: z1 } = p1;
      let { x: x2, y: y2, z: z2 } = p2;
      let { x: x3, y: y3, z: z3 } = p3;
    
      // 计算向量 P2P1 和 P2P3 的夹角 https://www.zybang.com/question/3379a30c0dd3041b3ef966803f0bf758.html
      let _P1P2 = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2 + (z2 - z1) ** 2);
      let _P2P3 = Math.sqrt((x3 - x2) ** 2 + (y3 - y2) ** 2 + (z3 - z2) ** 2);
    
      let P = (x1 - x2) * (x3 - x2) + (y1 - y2) * (y3 - y2) + (z1 - z2) * (z3 - z2); //P2P1*P2P3
    
      return (Math.acos(P / (_P1P2 * _P2P3)) / Math.PI) * 180;
    }
    
    console.log(
      angleOflocation(
        { lat: "40.80072", lng: "124.459351" },
        { lat: "40.64016", lng: "124.314117" },
        { lat: "40.876438", lng: "124.581062" }
      )
    );
    
    console.log(
      angleOflocation(
        { lat: "40.823978", lng: "124.639313" }, // 龙爪沟
        { lat: "40.71986", lng: "124.78175" }, // 宽甸
        { lat: "40.484791", lng: "124.81823" } // 永甸
      )
    );
    
    
  • 相关阅读:
    Excel Rendering Limitations
    Output Caching and VaryByParam, VaryByCustom
    ajaxToolkit:AutoCompleteExtender 使用键值对
    Sql Server 2005 存储过程分页
    WEB前端优化
    processModel Element in Machine.config
    如何监测虚拟内存
    MemoryLimit Tuning (ASP.NET v1.1)
    缓存之SqlDependency
    SQL产生随机字符串
  • 原文地址:https://www.cnblogs.com/imgss/p/10707150.html
Copyright © 2011-2022 走看看