如何将纬度和经度转换为x和y网格系统?

问题描述 投票:0回答:6

我有一个包含纬度和经度值的文件,我想使用Python将x和y以公里为单位转换。 我想测量到每个点的距离。

例如我制作第一个纬度和经度点(分别是51.58,-124.6)

到我的 x 和 y 系统中的 (0,0) 所以基本上我想找出其他点是什么以及它们距原点的位置所以我想找到 51.56(lat) -123.64(long) 位于 ( x,y) 以公里为单位,依此类推文件的其余部分。

我想用Python完成这一切,有一些排序代码吗?

例如,我在网上找到了网站

http://www.whoi.edu/marine/ndsf/cgi-bin/NDSFutility.cgi?form=0&from=LatLon&to=XY

确实是我想做的事,我只是不知道他们是怎么做到的。

python latitude-longitude coordinate-systems
6个回答
13
投票

以下内容让您非常接近(答案以公里为单位)。如果您需要比这更好,您必须在数学上更加努力 - 例如通过遵循给出的一些链接。

import math
dx = (lon1-lon2)*40000*math.cos((lat1+lat2)*math.pi/360)/360
dy = (lat1-lat2)*40000/360

变量名称应该非常明显。这给你

dx = 66.299 km (your link gives 66.577)
dy = 2.222 km (link gives 2.225)

一旦选择坐标(例如,

lon1, lat1
)作为原点,就应该很容易了解如何计算所有其他 XY 坐标。

注意 - 系数 40,000 是以公里为单位的地球周长(跨两极测量)。这让你很接近。如果您查看您提供的链接的来源(您必须深入挖掘才能找到位于单独文件中的 javascript ),您会发现他们使用了更复杂的方程:

function METERS_DEGLON(x)
{  
   with (Math)
   {
      var d2r=DEG_TO_RADIANS(x);
      return((111415.13 * cos(d2r))- (94.55 * cos(3.0*d2r)) + (0.12 * cos(5.0*d2r)));
   }
}

function METERS_DEGLAT(x)
{
   with (Math)
   {
      var d2r=DEG_TO_RADIANS(x);
      return(111132.09 - (566.05 * cos(2.0*d2r))+ (1.20 * cos(4.0*d2r)) - (0.002 * cos(6.0*d2r)));
   }
}

在我看来,他们实际上考虑到了地球并不完全是一个球体的事实......但即便如此,当你做出假设时,你可以将地球的一部分视为一个平面,你将拥有一些错误。我确信他们的公式误差会更小......


4
投票

UTM 投影以米为单位。所以你可以在这个链接中使用类似 utm lib 的东西:

https://pypi.python.org/pypi/utm

谷歌搜索 python lat lon 到 UTM 将指向几个选项。

UTM 区域的经度宽为 6 度,从本初子午线的 0 点开始。每个 UTM 区域的原点位于赤道(x 轴),y 轴位于最西经度。这使得网格向北和向东倾斜。您可以根据这些结果计算出您的距离。 UTM 区域中间的值最准确。

您还应该知道您的原始经纬度值基于什么基准,并在转换中使用相同的基准。


3
投票

如果您要使用 3D 系统,这些功能就可以了:

def arc_to_deg(arc):
    """convert spherical arc length [m] to great circle distance [deg]"""
    return float(arc)/6371/1000 * 180/math.pi

def deg_to_arc(deg):
    """convert great circle distance [deg] to spherical arc length [m]"""
    return float(deg)*6371*1000 * math.pi/180

def latlon_to_xyz(lat,lon):
    """Convert angluar to cartesian coordiantes

    latitude is the 90deg - zenith angle in range [-90;90]
    lonitude is the azimuthal angle in range [-180;180] 
    """
    r = 6371 # https://en.wikipedia.org/wiki/Earth_radius
    theta = math.pi/2 - math.radians(lat) 
    phi = math.radians(lon)
    x = r * math.sin(theta) * math.cos(phi) # bronstein (3.381a)
    y = r * math.sin(theta) * math.sin(phi)
    z = r * math.cos(theta)
    return [x,y,z]

def xyz_to_latlon (x,y,z):
    """Convert cartesian to angular lat/lon coordiantes"""
    r = math.sqrt(x**2 + y**2 + z**2)
    theta = math.asin(z/r) # https://stackoverflow.com/a/1185413/4933053
    phi = math.atan2(y,x)
    lat = math.degrees(theta)
    lon = math.degrees(phi)
    return [lat,lon]

2
投票

您可以使用大圆距离公式获取 GPS 点之间的距离。纬度和经度位于大地坐标系中,因此您不能仅转换为平面二维网格并使用欧几里德距离。您可以将足够接近的点转换为近似网格,方法是采用任意点(X,Y),将其设置为原点(就像您所做的那样),然后使用大圆距离和bearing来绘制平面上彼此相对的点,但这是一个近似值。


0
投票

您可以使用UTM:

pip install utm

这是一个例子:

>>> import utm
>>> utm.from_latlon(51.2, 7.5)
(395201.3103811303, 5673135.241182375, 32, 'U')

退货的形式为

(EASTING, NORTHING, ZONE_NUMBER, ZONE_LETTER)

注释

它也适用于 NumPy 数组:

>>> utm.from_latlon(np.array([51.2, 49.0]), np.array([7.5, 8.4]))
(array([395201.31038113, 456114.59586214]),
 array([5673135.24118237, 5427629.20426126]),
 32,
 'U')

反过来:

>>> utm.to_latlon(340000, 5710000, 32, 'U')
(51.51852098408468, 6.693872395145327)

0
投票
import pyproj

P = pyproj.Proj(proj='utm', zone=32, ellps='WGS84', preserve_units=True) # You can modify your zone

XY=P(your_long, your_lat)
© www.soinside.com 2019 - 2024. All rights reserved.