首页 > 其他分享 >计算3个经纬度坐标点之间的夹角

计算3个经纬度坐标点之间的夹角

时间:2024-07-03 17:31:14浏览次数:18  
标签:经纬度 站点 let 坐标 lat lng 夹角 Math

原文地址:https://www.cnblogs.com/imgss/p/10707150.html

火车地图搞了有半年了,在做火车地图的过程中,遇到了一个问题,就是由于火车站点的地理坐标是直接请求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" } // 永甸
  )
);

cnblogs-md-editor编辑器,用Markdown写博客就用它

标签:经纬度,站点,let,坐标,lat,lng,夹角,Math
From: https://www.cnblogs.com/fswhq/p/18089640

相关文章

  • unity 从list中获取最近的坐标 / 获取最接近的角度(数值)
    ///<summary>///从列表points中获取距离targetPoint最近的坐标///</summary>///<paramname="points"></param>///<paramname="targetPoint"></param>///<returns><......
  • Qt/C++编写地图应用/离线地图下载/路径规划/轨迹回放/海量点/坐标转换
    一、前言说明这个地图组件写了很多年了,最初设计的比较粗糙,最开始只是为了满足项目需要,并没有考虑太多拓展性,比如最初都是按照百度地图写死在代码中,经过这几年大量的现场实际应用,以及大量的用户提出的改进意见,逐渐萌生了彻底重新编写对应地图相关的代码,比如基类子类的设计,各种功能......
  • 高德坐标转gps坐标
    vue3实现高德坐标和gps坐标互转:/** *高德地图坐标转GPS坐标算法 */constpi=3.1415926535897932384626;consta=6378245.0;//长半轴constee=0.00669342162296594323;//扁率//地球坐标系(WGS-84)转火星坐标系(GCJ)exportfunctionWgsToGcj02(wglng,wglat){......
  • 百度坐标转gps坐标
    vue3页面实现:利用百度api的jsapi中的 BMap.Convertor()此方法通过计算取巧算出gps坐标误差非常小;假设百度坐标:lng1:113.94620475687566 lat1:22.56028856475092把这个坐标当成GPS坐标,通过接口获得他的百度坐标:lng2=113.95764483473,lat2=22.562997980443通过计算就可以得到......
  • 火星坐标转换
     出处:火星坐标、百度坐标、WGS84坐标转换代码(JS版)/***CreatedbyWandergison2015/7/8.*提供了百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换*///定义一些常量varx_PI=3.14159265358979324*3000.0/180.0;varPI=3.1415926535897932......
  • RAS坐标与IJK世界坐标转换
    RAS坐标与IJK世界坐标转换RAS是解剖坐标系,单位mmIJk是像素/体素坐标系,单位像素pixel/体素Voxel需要了解的另外两个概念是origin和spacingorigin原点表示第一个体素Voxel(0,0,0)在解剖坐标系中的位置间距spacing表示沿指定轴上两个体素之间的距离使用origi......
  • MySQL计算两个地理坐标点之间的球面距离
    st_distance_sphere函数是mysql5.7提供的,可以直接查询两个经纬度之间相距多少米,它接受两个参数,每个参数是一个点的经度和纬度表结构:CREATETABLE`video_alarm`(`alarm_id`char(50)NOTNULL,`alarm_type`varchar(20)DEFAULTNULLCOMMENT'预警类型',`alarm_t......
  • 13-Matplotlib坐标轴格式
    Matplotlib坐标轴格式在一个函数图像中,有时自变量x与因变量y是指数对应关系,这时需要将坐标轴刻度设置为对数刻度。Matplotlib通过axes对象的xscale或yscale属性来实现对坐标轴的格式设置。示例:右侧的子图显示对数刻度,左侧子图则显示标量刻度。importmatplotlib.p......
  • cesium 点击事件转经纬度坐标
    lethandler=newCesium.ScreenSpaceEventHandler(viewer.scene.canvas); handler.setInputAction(function(e){ console.log('cli',e);//letpickId=viewer.scene.pick(e.position); //点击监听三维数据服务的实体 varcartesian=viewer.camera.......
  • 【YOLOv10改进[注意力]】在YOLOv10中添加坐标注意力CoordAtt + 含全部代码和详细修改
    本文将进行在YOLOv10中添加坐标注意力CoordAtt的实践,助力YOLOv10目标检测效果的实践,文中含全部代码、详细修改方式以及手撕结构图。助您轻松理解改进的方法。改进前和改进后的参数对比: 目录一CoordAtt二在YOLOv10中添加注意力CoordAtt的实践1整体修改......