提要

我们知道GPS坐标是由经度,纬度,海拔组成,精度和纬度都是角度,海报是高度。

在进行基于地理的搜索的时候,常用到KDTree,在构建在KDTree的时候,不能直接用GPS的坐标,要将GPS坐标转换成笛卡尔坐标才能用于构建KDTree。下面就是相关的转换算法。

注:GPS信息由几种标准,这里的采用的是google map的经纬度信息。

js实现

geodecy.js

/*             geodesy routines in JavaScriptJames R. Clynch NPS / 2003Done for support of web education pages== must convert inputs to numbers for safety ==== if string comes in - sometimes works, sometimes not !==
*/<!--// =======================================================================function geodGBL()//             test and ensure geodesy globals loaded{var  tstglobaltstglobal = typeof EARTH_A;if ( tstglobal == "undefined" )  wgs84() }// =======================================================================function earthcon(ai,bi)/*        Sets Earth Constants as globals--  input a,b--  Leaves Globals EARTH_A      EARTH_B   EARTH_F  EARTH_Ecc
*/{var  f,ecc, eccsq, a,ba        =  Number(ai);b        =  Number(bi);f        =  1-b/a;eccsq    =  1 - b*b/(a*a);ecc      =  Math.sqrt(eccsq);EARTH_A  =  a;EARTH_B  =  b;EARTH_F  =  f;EARTH_Ecc=  ecc;EARTH_Esq=  eccsq;}// =======================================================================function wgs84()/*        WGS84 Earth Constants--  returns a,b,f,e  ----  Leaves Globals EARTH_A      EARTH_B   EARTH_F  EARTH_Ecc*/{var  wgs84a, wgs84b, wgs84fwgs84a         =  6378.137;wgs84f         =  1.0/298.257223563;wgs84b         =  wgs84a * ( 1.0 - wgs84f );earthcon (wgs84a, wgs84b );}          // =======================================================================function  radcur(lati)/*compute the radii at the geodetic latitude lat (in degrees)input:lat       geodetic latitude in degreesoutput:   rrnrm     an array 3 longr,  rn,  rm   in km*/{var rrnrm = new Array(3)var dtr   = Math.PI/180.0var  a,b,latvar  asq,bsq,eccsq,ecc,clat,slatvar  dsq,d,rn,rm,rho,rsq,r,z//        -------------------------------------geodGBL();a     = EARTH_A;b     = EARTH_B;asq   = a*a;bsq   = b*b;eccsq  =  1 - bsq/asq;ecc = Math.sqrt(eccsq);lat   =  Number(lati);clat  =  Math.cos(dtr*lat);slat  =  Math.sin(dtr*lat);dsq   =  1.0 - eccsq * slat * slat;d     =  Math.sqrt(dsq);rn    =  a/d;rm    =  rn * (1.0 - eccsq ) / dsq;rho   =  rn * clat;z     =  (1.0 - eccsq ) * rn * slat;rsq   =  rho*rho + z*z;r     =  Math.sqrt( rsq );rrnrm[0]  =  r;rrnrm[1]  =  rn;rrnrm[2]  =  rm;return ( rrnrm );}// =======================================================================//        physical radius of earth from geodetic latitudefunction  rearth (lati){var    rrnrm, r,latlat   =  Number(lati);rrnrm =  radcur ( lat );r     =  rrnrm[0];return ( r );}// =======================================================================function  gc2gd (flatgci, altkmi )/*        geocentric latitude to geodetic latitudeInput:flatgc    geocentric latitude deg.altkm     altitide in kmouput:flatgd    geodetic latitude in deg*/{var dtr   = Math.PI/180.0;var rtd   = 1/dtr;var  flatgd,flatgc,altkmvar  rrnrm = new Array(3)var  re,rn,ecc, esq;var  slat,clat,tlatvar  altnow,ratiogeodGBL();flatgc=  Number(flatgci);altkm =  Number(altkmi);ecc   =  EARTH_Ecc;esq   =  ecc*ecc;//             approximation by stages
//             1st use gc-lat as if is gd, then correct alt dependencealtnow  =  altkm;rrnrm   =  radcur (flatgc);rn      =  rrnrm[1];ratio   = 1 - esq*rn/(rn+altnow);tlat    = Math.tan(dtr*flatgc) / ratio;flatgd  = rtd * Math.atan(tlat);//        now use this approximation for gd-lat to get rn etc.rrnrm   =  radcur ( flatgd );rn      =  rrnrm[1];ratio   =  1  - esq*rn/(rn+altnow)tlat    =  Math.tan(dtr*flatgc)/ratio;flatgd  =  rtd * Math.atan(tlat);return  flatgd}// =======================================================================function  gd2gc (flatgdi, altkmi )/*        geodetic latitude to geocentric latitudeInput:flatgd    geodetic latitude deg.altkm     altitide in kmouput:flatgc    geocentric latitude in deg*/{var dtr   = Math.PI/180.0;var rtd   = 1/dtr;var  flatgc,flatgd,altkmvar  rrnrm = new Array(3)var  re,rn,ecc, esq;var  slat,clat,tlatvar  altnow,ratiogeodGBL();flatgd=  Number(flatgdi);altkm =  Number(altkmi);ecc   =  EARTH_Ecc;esq   =  ecc*ecc;altnow  =  altkm;rrnrm   =  radcur (flatgd);rn      =  rrnrm[1];ratio   = 1 - esq*rn/(rn+altnow);tlat    = Math.tan(dtr*flatgd) * ratio;flatgc  = rtd * Math.atan(tlat);return  flatgc;}// =======================================================================function  llenu ( flati,floni)/*        latitude longitude to east,north,up unit vectorsinput:flat      latitude in degees N[ gc -> gc enu,  gd usual enu ]flon      longitude in degrees Eoutput:enu[3[3]]  packed 3-unit vectors / each a 3 vector*/{var  flat,flon;var  dtr,clat,slat,clon,slon  ;var  ee = new Array(3);var  en = new Array(3);var  eu = new Array(3);var  enu = new Array(3);var dtr   = Math.PI/180.0//             --------------------------------flat = Number(flati);flon = Number(floni);clat = Math.cos(dtr*flat);slat = Math.sin(dtr*flat);clon = Math.cos(dtr*flon);slon = Math.sin(dtr*flon);ee[0]  =  -slon;ee[1]  =   clon;ee[2]  =   0.0;en[0]  =  -clon * slat;en[1]  =  -slon * slat;en[2]  =          clat;eu[0]  =   clon * clat;eu[1]  =   slon * clat;eu[2]  =          slat;enu[0] =  ee;enu[1] =  en;enu[2] =  eu;return  enu ;}// =======================================================================function llhxyz (flati,floni, altkmi )/*        lat,lon,height to xyz vectorinput:flat      geodetic latitude in degflon      longitude in degaltkm     altitude in kmoutput:returns vector x 3 long ECEF in km*/{var  dtr =  Math.PI/180.0;var  flat,flon,altkm;var  clat,clon,slat,slon;var  rrnrm = new Array(3);var  rn,esq;var  x,y,z;var  xvec = new Array(3);geodGBL();flat  = Number(flati);flon  = Number(floni);altkm = Number(altkmi);clat = Math.cos(dtr*flat);slat = Math.sin(dtr*flat);clon = Math.cos(dtr*flon);slon = Math.sin(dtr*flon);rrnrm  = radcur (flat);rn     = rrnrm[1];re     = rrnrm[0];ecc    = EARTH_Ecc;esq    = ecc*eccx      =  (rn + altkm) * clat * clon;y      =  (rn + altkm) * clat * slon;z      =  ( (1-esq)*rn + altkm ) * slat;xvec[0]  = x;xvec[1]  = y;xvec[2]  = z;return  xvec ;}// =======================================================================function xyzllh ( xvec )/*        xyz vector  to  lat,lon,heightinput:xvec[3]   xyz ECEF locationoutput:llhvec[3] with componentsflat      geodetic latitude in degflon      longitude in degaltkm     altitude in km*/{var  dtr =  Math.PI/180.0;var  flatgc,flatn,dlat;var  rnow,rp;var  x,y,z,p;var  tangc,tangd;var  testval,kount;var  rn,esq;var  clat,slat;var  rrnrm = new Array(3);var  flat,flon,altkm;var  llhvec = new Array(3);geodGBL();esq    =  EARTH_Esq;x      = xvec[0];y      = xvec[1];z      = xvec[2];x      = Number(x);y      = Number(y);z      = Number(z);rp     = Math.sqrt ( x*x + y*y + z*z );flatgc = Math.asin ( z / rp )/dtr;testval= Math.abs(x) + Math.abs(y);if ( testval < 1.0e-10){flon = 0.0 }else{flon = Math.atan2 ( y,x )/dtr } if (flon < 0.0 )  { flon = flon + 360.0 }p      =  Math.sqrt( x*x + y*y );//             on pole special caseif ( p < 1.0e-10 ){  flat = 90.0if ( z < 0.0 ) { flat = -90.0 }altkm = rp - rearth(flat);llhvec[0]  = flat;llhvec[1]  = flon;llhvec[2]  = altkm;return  llhvec;}//        first iteration, use flatgc to get altitude
//        and alt needed to convert gc to gd lat.rnow  =  rearth(flatgc);altkm =  rp - rnow;flat  =  gc2gd (flatgc,altkm);rrnrm =  radcur(flat);rn    =  rrnrm[1];for ( var kount = 0; kount< 5 ; kount++ ){slat  =  Math.sin(dtr*flat);tangd =  ( z + rn*esq*slat ) / p;flatn =  Math.atan(tangd)/dtr;dlat  =  flatn - flat;flat  =  flatn;clat  =  Math.cos( dtr*flat );rrnrm =  radcur(flat);rn    =  rrnrm[1];altkm =  (p/clat) - rn;if ( Math.abs(dlat) < 1.0e-12 ) { break }}llhvec[0]  = flat;llhvec[1]  = flon;llhvec[2]  = altkm;return  llhvec ;}// =======================================================================//-->

C++实现

就是根据将JS代码转成C艹.

GPS 转笛卡尔

void GPSTransform::gpsPoint2DescartesPoint(const double latitude, const double longitude, const double altitude, double &x, double &y, double &z)
{//wgs84 WGS84 Earth Constantsdouble wgs84a = 6378.137;double wgs84f = 1.0 / 298.257223563;double wgs84b = wgs84a * (1.0 - wgs84f);//earthcondouble f = 1 - wgs84b / wgs84a;double eccsq = 1 - (wgs84b* wgs84b) / (wgs84a * wgs84a);double ecc = sqrt(eccsq);double esq = ecc * ecc;//llhxyzdouble dtr = M_PI / 180.0;//qDebug() << dtr << gpsPoint.latitude << endl;double clat = cos(dtr * latitude);double slat = sin(dtr * latitude);double clon = cos(dtr * longitude);double slon = sin(dtr * longitude);//qDebug() << clat << slon << endl;//radcur compute the radii at the geodetic latitude lat (in degrees)double dsq = 1.0 - eccsq * slat *slat;double d = sqrt(dsq);//qDebug() << d;double rn = wgs84a / d;double rm = rn * (1.0 - eccsq) / dsq;double rho = rn * clat;double zz = (1.0 - eccsq) * rn *slat;double rsq = rho * rho + zz*zz;double r = sqrt(rsq);x = (rn + altitude) * clat * clon;y = (rn + altitude) * clat * slon;z = ((1 - esq)*rn + altitude) * slat;
}

运行结果

验证网站

Geodetic to Cartesian Converter - http://www.apsalin.com/convert-geodetic-to-cartesian.aspx

atitude,Longitude,Height to/from ECEF (X,Y,Z) - http://www.oc.nps.edu/oc2902w/coord/llhxyz.htm

GPS坐标转笛卡尔坐标相关推荐

  1. 四旋翼利用mavros进行GPS坐标指点飞行

    先介绍一般px4飞控的xyz坐标指点飞行: 利用mavros的 /mavros/setpoint_raw/local 话题可以发送东北天(ENU)坐标给px4飞控进行指点飞行.ENU坐标原点在起飞点, ...

  2. gps两点距离 php,PHP应用:PHP计算百度地图两个GPS坐标之间距离的方法

    <PHP应用:PHP计算百度地图两个GPS坐标之间距离的方法>要点: 本文介绍了PHP应用:PHP计算百度地图两个GPS坐标之间距离的方法,希望对您有用.如果有疑问,可以联系我们. 本文实 ...

  3. [python] 从GPS坐标获取国家名

    目标比较明确,就是从GPS坐标得到它所在的国家. 网上可以找的比较典型的解决方案是利用一些网站(例如Google)的webservice来完成这个任务,但是这些解决方案有一个比较大的弱点,就是这些we ...

  4. PHP+百度地图API+JAVASCRIPT实现GPS坐标与百度坐标转换的实例

    PHP+百度地图API+JAVASCRIPT实现GPS坐标与百度坐标转换的实例 原文:PHP+百度地图API+JAVASCRIPT实现GPS坐标与百度坐标转换的实例 <!--小幅的坐标转换点位程 ...

  5. php 地图 距离,PHP计算百度地图两个GPS坐标之间距离的方法

    这篇文章主要介绍了PHP计算百度地图两个GPS坐标之间距离的方法,是针对百度地图接口开发的典型应用,需要的朋友可以参考下 本文实例讲述了PHP计算百度地图两个GPS坐标之间距离的方法.分享给大家供大家 ...

  6. 百度地图批量转换 GPS坐标转百度地图坐标 问题

    百度地图的官方网址 官方批量转换的demo 花了几天时间了解了一下百度地图,之前是后端的一个小伙伴在负责,他跟我吐槽这是前端的东西,让我来写(之前他们老大交给他了,我也以为是后端的任务(๑′ᴗ‵๑). ...

  7. 计算坐标点的距离计算机公式,计算两个GPS坐标点的距离

    原标题:计算两个GPS坐标点的距离 在日常开发中,我们难免要计算两个左边之间的距离,但是地图软件api的接口普遍要求我们必须要先将坐标点传递到他们服务器,然后计算出一个距离返还给我们,使用起来太不方便 ...

  8. java gps 距离计算_Java教程之地图中计算两个GPS坐标点的距离

    原标题:Java教程之地图中计算两个GPS坐标点的距离 在日常开发中,我们难免要计算两个左边之间的距离,但是地图软件api的接口普遍要求我们必须要先将坐标点传递到他们服务器,然后计算出一个距离返还给我 ...

  9. GPS坐标对应地图坐标偏移问题

    各个地图的坐标和GPS坐标计算方式是不同的,因此有时候需要进行坐标转化再进行定位,坐标转化算法如下: //定义一些常量 var x_PI = 3.14159265358979324 * 3000.0 ...

最新文章

  1. 变焦即可判断物体的距离
  2. UNIX环境高级编程--第七章
  3. 基于语言模型的少样本学习 / 深度学习优化器基准测试 | 本周值得读
  4. 990. Satisfiability of Equality Equations
  5. 【数学基础】拉格朗日乘子法
  6. Java Thread Status(转)
  7. oracle 12c 翻页,Oracle 12c新特性之翻页查询
  8. 什么是面向服务的体系结构(SOA)?(转载)
  9. (42)JS运动之多物体框架--多个div变宽
  10. 【MySQL】关系型数据库基本知识点
  11. 转录组测序技术及结果解读(一)——测序样品设置及选择
  12. echarts考勤图表
  13. python 实现省全称和省的简称互相转换
  14. 将iGoogle-Style新标签页添加到Chrome
  15. 高压均质机原理、使用方法及维护注意事项
  16. Linux系统进程查看命令
  17. java 调用 mahout_(转)Mahout使用入门
  18. 报错:“TypeError: Cannot read property ‘0‘ of undefined“的原因
  19. 申宝策略-行业与概念板块跌多涨少
  20. linux shell取得秒级时间戳

热门文章

  1. 《人人都能用英语》新稿节选(2)我们有可能把外语用得比母语更好吗?
  2. docker镜像和仓库
  3. delphi中的.dpr、.pas和.dfm文件都怎么解释?
  4. 微信小程序:函数回调
  5. SpringBoot+Vue项目医院挂号系统的设计与实现
  6. 2022年煤炭生产经营单位(地质地测安全管理人员)考试内容及煤炭生产经营单位(地质地测安全管理人员)复审考试
  7. 计算机无法启动 主板,电脑主板不能启动的解决方法
  8. mysql 5.6 启用utf8mb4
  9. C语言实现一到十的阶乘的和。
  10. LaTeX / OverLeaf 入门(一)