Mapping 从经度\纬度转换为笛卡尔坐标
我有一些以地球为中心的坐标点,如纬度和经度()Mapping 从经度\纬度转换为笛卡尔坐标,mapping,geometry,geospatial,Mapping,Geometry,Geospatial,我有一些以地球为中心的坐标点,如纬度和经度() 如何将它们转换为原点位于地球中心的笛卡尔坐标(x,y,z)?以下是我找到的答案: 为了使定义完整,在笛卡尔坐标系中: x轴穿过长纬度(0,0),因此经度0与赤道相交 y轴穿过(0,90) z轴穿过两极 转换为: x = R * cos(lat) * cos(lon) y = R * cos(lat) * sin(lon) z = R *sin(lat) 其中R为(例如6371 km) 如果三角函数需要弧度(它们可能需要弧度),则需要首先将
如何将它们转换为原点位于地球中心的笛卡尔坐标(x,y,z)?以下是我找到的答案: 为了使定义完整,在笛卡尔坐标系中:
- x轴穿过长纬度(0,0),因此经度0与赤道相交李>
- y轴穿过(0,90)李>
- z轴穿过两极李>
x = R * cos(lat) * cos(lon)
y = R * cos(lat) * sin(lon)
z = R *sin(lat)
其中R为(例如6371 km)
如果三角函数需要弧度(它们可能需要弧度),则需要首先将经度和纬度转换为弧度。显然,您需要的是十进制表示,而不是度\分\秒(请参阅关于转换)
反向转换公式:
lat = asin(z / R)
lon = atan2(y, x)
asin当然是正弦弧。不要忘记将弧度转换回度
给出了c#代码(注意它与公式非常不同),并给出了一些解释和图表,说明了为什么这是正确的,为什么要实现一些已经实现并经过测试验证的东西 例如,C#具有JTS拓扑套件的.NET端口 具体来说,您的计算有一个严重的缺陷。地球不是一个完美的球体,地球半径的近似值可能无法精确测量
如果在某些情况下可以使用自制函数,那么GIS就是一个很好的例子,在这个领域,人们更喜欢使用可靠的、经过测试的库。我最近使用 WGS-84数据上的“哈弗斯公式”,是“哈弗斯定律”的一个衍生物,结果非常令人满意 是的,WGS-84假设地球是一个椭球体,但我相信使用类似“哈弗森公式”的方法只能得到大约0.5%的平均误差,在你的情况下,这可能是一个可接受的误差量。你总是会有一定的误差,除非你说的是几英尺的距离,甚至理论上还有地球的曲率。。。如果您需要更严格的WGS-84兼容方法,请检查“Vincenty公式” 我知道starblue从何而来,但好的软件工程通常是权衡取舍,所以这一切都取决于您所做工作所需的准确性。例如,在某些情况下,根据“曼哈顿距离公式”计算的结果与根据“距离公式”计算的结果相比可能更好,因为计算成本更低。想一想“哪一点最近?”这样的场景,你不需要精确的距离测量 关于“哈弗森公式”,它很容易实现,也很好,因为它使用的是“球面三角法”,而不是基于二维三角法的“余弦定律”,因此你可以在精度和复杂性之间取得很好的平衡
一位名叫Chris的先生有一本很棒的书,解释了您感兴趣的一些概念,并演示了各种编程实现;这应该也能回答您的x/y转换问题。如果您关心基于椭球体而不是球体获取坐标,请看一看-它给出了公式。具有转换所需的WGS84常量
其中的公式还考虑了相对于参考椭球面的高度(如果您从GPS设备获取高度数据,则非常有用)。将
GPS(WGS84)
转换为笛卡尔坐标的理论
以下是我正在使用的内容:
- GPS(WGS84)和笛卡尔坐标中的经度相同
- 纬度需要通过WGS 84椭球参数转换,半长轴为6378137 m,并且
- 展平的倒数为298.257223563
h
高度高于WGS 84椭球体
通常GPS
会给我们提供H
以上的MSL
高度。
必须使用位势模型将MSL
高度转换为WGS 84椭球体上方的高度h
(Lemoine等人,1998)。
这是通过以15弧分的空间分辨率插值大地水准面高度文件的栅格来完成的
或者,如果您有某个级别的专业人员GPS
具有高度H
(msl,高于平均海平面的高度)和起伏
,则大地水准面
和从内部表格输出的所选基准的椭球面(m)
之间的关系。您可以获得H=H(msl)+起伏
通过笛卡尔坐标到XYZ:
x = R * cos(lat) * cos(lon)
y = R * cos(lat) * sin(lon)
z = R *sin(lat)
该软件提供了一个命令行程序,可以进行转换,例如
LAT=40
LON=-110
echo $LON $LAT | cs2cs +proj=latlong +datum=WGS84 +to +proj=geocent +datum=WGS84
它还提供了一个。特别是,函数pj_geodetic_to_geocentric
将进行转换,而无需首先设置投影对象。您可以在Java上以这种方式进行转换
public List<Double> convertGpsToECEF(double lat, double longi, float alt) {
double a=6378.1;
double b=6356.8;
double N;
double e= 1-(Math.pow(b, 2)/Math.pow(a, 2));
N= a/(Math.sqrt(1.0-(e*Math.pow(Math.sin(Math.toRadians(lat)), 2))));
double cosLatRad=Math.cos(Math.toRadians(lat));
double cosLongiRad=Math.cos(Math.toRadians(longi));
double sinLatRad=Math.sin(Math.toRadians(lat));
double sinLongiRad=Math.sin(Math.toRadians(longi));
double x =(N+0.001*alt)*cosLatRad*cosLongiRad;
double y =(N+0.001*alt)*cosLatRad*sinLongiRad;
double z =((Math.pow(b, 2)/Math.pow(a, 2))*N+0.001*alt)*sinLatRad;
List<Double> ecef= new ArrayList<>();
ecef.add(x);
ecef.add(y);
ecef.add(z);
return ecef;
}
public List convertGpsToECEF(双lat、双longi、float-alt){
双a=6378.1;
双b=6356.8;
双N;
双e=1-(数学功率(b,2)/数学功率(a,2));
N=a/(数学sqrt(1.0-(e*Math.pow(Math.sin(Math.toRadians,lat)),2));
double-cosLatRad=Math.cos(Math.toRadians(lat));
双余弦长=数学余弦(数学余弦长);
double sinLatRad=Math.sin(Math.toRadians(lat));
double sinLongiRad=Math.sin(Math.toRadians(longi));
双x=(N+0.001*alt)*余弦*余弦;
双y=(N+0.001*alt)*共轴*正弦;
双z=((数学功率(b,2)/数学功率(a,2))*N+0.001*alt)*sinLatRad;
List ecef=new ArrayList();
ecef.添加(x);
ecef.添加(y);
ecef.添加(z);
返回ecef;
}
LAT=40
LON=-110
echo $LON $LAT | cs2cs +proj=latlong +datum=WGS84 +to +proj=geocent +datum=WGS84
public List<Double> convertGpsToECEF(double lat, double longi, float alt) {
double a=6378.1;
double b=6356.8;
double N;
double e= 1-(Math.pow(b, 2)/Math.pow(a, 2));
N= a/(Math.sqrt(1.0-(e*Math.pow(Math.sin(Math.toRadians(lat)), 2))));
double cosLatRad=Math.cos(Math.toRadians(lat));
double cosLongiRad=Math.cos(Math.toRadians(longi));
double sinLatRad=Math.sin(Math.toRadians(lat));
double sinLongiRad=Math.sin(Math.toRadians(longi));
double x =(N+0.001*alt)*cosLatRad*cosLongiRad;
double y =(N+0.001*alt)*cosLatRad*sinLongiRad;
double z =((Math.pow(b, 2)/Math.pow(a, 2))*N+0.001*alt)*sinLatRad;
List<Double> ecef= new ArrayList<>();
ecef.add(x);
ecef.add(y);
ecef.add(z);
return ecef;
}
# Converting lat/long to cartesian
import numpy as np
def get_cartesian(lat=None,lon=None):
lat, lon = np.deg2rad(lat), np.deg2rad(lon)
R = 6371 # radius of the earth
x = R * np.cos(lat) * np.cos(lon)
y = R * np.cos(lat) * np.sin(lon)
z = R *np.sin(lat)
return x,y,z