>>> from pyproj import Proj
>>> proj1 = Proj(proj='utm',zone=10,ellps='WGS84') # use kwargs
>>> proj2 = Proj('+proj=utm +zone=10 +ellps=WGS84') # use proj4 string
>>> proj3 = Proj("+init=epsg:32667")
/usr/lib/python3/dist-packages/pyproj/crs/crs.py:141: FutureWarning: '+init=<authority>:<code>' syntax is deprecated. '<authority>:<code>' is the preferred initialization method. When making the change, be mindful of axis order changes: https://pyproj4.github.io/pyproj/stable/gotchas.html#axis-order-changes-in-proj-6
in_crs_string = _prepare_from_proj_string(in_crs_string)
>>> proj4 = Proj("epsg:32667",preserve_units=True)
转换不同的格式。
>>> proj4.definition_string()
'proj=tmerc lat_0=0 lon_0=-81 k=0.9996 x_0=500000.001016002 y_0=0 datum=WGS84 units=us-ft no_defs ellps=WGS84 towgs84=0,0,0'
>>> proj4.srs
'+proj=tmerc +lat_0=0 +lon_0=-81 +k=0.9996 +x_0=500000.001016002 +y_0=0 +datum=WGS84 +units=us-ft +no_defs'
6.3.2. 转换
首先看一下如何转换成平面坐标:
>>> p=Proj('+proj=aea +lon_0=105 +lat_1=25 +lat_2=47 +ellps=krass')
>>> x,y=p(105,36)
>>> print('%.3f,%.3f' %(x,y))
0.000,3847866.973
Proj4 投影控制参数必须在字典 projparams 或关键字参数给定。
查看页面( https://proj4.org/usage/projections.html
)了解有关指定投影参数的更多信息。
当调用一个经纬度的 Proj 类的实例时,
将会把十进制的经纬度,转换成为地图的 (x, y) 投影。
上面第1行导入Proj类; 第2行则使用 proj4
格式初使化一个投影(中国等积投影); 第3行则是进行转换。
逆变换
>>> lon,lat=p(x,y,inverse=True)
>>> print('%.3f,%.3f' %(lon,lat))
105.000,36.000
如果可选的关键字 inverse 等于 True
的时候(默认为假),则进行相反的转换。
第1行重新进行转换; 第2行则是打印输出转换的结果。
从结果来看,与最开始的输入结果是一致的。
弧度变换
pyproj.Proj类除了使用度作为单位输入之外,pyproj.Proj类还接受弧度作为单位的输入。
>>> import math #验证关键字 radians
>>> x,y=p(math.radians(105),math.radians(36),radians=True)
>>> print( '%.3f,%.3f' %(x,y) )
0.000,3847866.973
使用math模块,将度转换为弧度。
如果关键字 radians 为 True 的话(默认为假),
则经纬度的单位则是弧度,而不是度。
使用数组进行批量转换
pyproj.Proj类除进行单个值的处理, pyproj.Proj
类还接受数组的输入,进行批量转换。 这个在实际的开发中是非常实用的。
>>> lons=(105,106,104)
>>> lats=(36,35,34)
>>> x,y=p(lons,lats) #将经纬度放入元组中
>>> print('%.3f,%.3f,%.3f' %x) #普通打印
0.000,89660.498,-90797.784
>>> print('%.3f,%.3f,%.3f' %y)
3847866.973,3735328.476,3622421.811
>>> type(x) #输出的类型为元组
tuple
>>> zip(x,y) #用 zip函数包装
<zip at 0x7f3fb3e4b880>
可以将经纬度分别存入一个 list或 array。可以进行更高效率的转换。
输入的值应当是双精度(如果输入的不是,它们将会被转为双精度)。
虽然 Proj 可以与numpy和常规python数组对象, python序列和标量,但是使用
array 对象速度快一些
使用关键字定义投影
pyproj除了使用 proj4 字符串进行投影的定义之外,
pyproj还支持使用关键字来定义投影。
>>> utm=Proj(proj='utm',zone=48,ellps='WGS84')
>>> x,y=utm(105,36) #用关键字定义一个投影。
>>> x,y
(499999.99999999773, 3983948.4533356656)
初始化一个投影: Proj4投影控制参数或者是以字典形式给出,
或者是以关键字参数给出,也可以用 proj4的形式给出字符串。
两个 Proj实例的函数
is_geocent(self) 返回 True当投影为 geocentric (x/y) coordinates。
is_latlong(self) 返回 True当为地理坐标系经纬度时。
6.3.3. 投影转换
transform()函数是在pyproj库下,
可以进行两个不同投影的转换。
相当于proj程序里的cs2cs子程序。用法如下:
transform(p1, p2, x, y, z=None, radians=False)
x2, y2, z2 = transform(p1, p2, x1, y1, z1, radians=False)
这里p1与p2都是Proj对象。
在 p1,p2两个投影之间进行投影转换。 把
p1坐标系下的点(x1,y1,z1)转换到 p2所定义的投影中去。
z1是可选的,如果没有设 z1的话,将假定为 0, 并返回
x2,y2。
使用这个函数的时候要注意不要进行基准面的变换(datum)。
关键字radians只有在 p1,p2中有一个为地理坐标系时才起作用,
并且是把地理坐标系的投影的值当作弧度。 判断是否为地理坐标可以用
p1.is_latlong() 和 p2.is_latlong()函数。输入的
(x,y,z)可以分别是数组或序列的某一种形式。
>>>
from pyproj import Proj
>>> albers=Proj('+proj=aea +lon_0=105 +lat_1=25 +lat_2=47 +ellps=krass')
>>> utm=Proj(proj='utm',zone=48,ellps='krass')
>>> albers_x,albers_y=albers(105,36)
>>> albers_x,albers_y
(0.0, 3847866.972516728)
>>> utm_x,utm_y=utm(105,36)
>>> print(utm_x,utm_y )
499999.99999999773 3984019.058813517
下边直接从 albers转为 utm坐标
>>> from pyproj import transform
>>> to_utm_x,to_utm_y = transform(albers,utm,albers_x ,albers_y)
>>> print(to_utm_x,to_utm_y )
499999.99999999773 3984019.058813516
/tmp/ipykernel_257081/1887088792.py:2: FutureWarning: This function is deprecated. See: https://pyproj4.github.io/pyproj/stable/gotchas.html#upgrading-to-pyproj-2-from-pyproj-1
to_utm_x,to_utm_y = transform(albers,utm,albers_x ,albers_y)
fwd()函数可以进行正转换,返回经纬度。也可以用 NumPy
与常规的Python数组对象,Python序列和标量。如果
弧度为真,把输入的经纬度单位当作弧度,而不是度。距离单位为米。
fwd(self,lons,lats,az,dist,radians=False)
参数为经度,纬度,相对方位,距离。
逆变换
inv()函数可以进行逆变换,已知两点经纬度,返回其前方位解,后方位角,以及距离。
inv(self, lons1, lats1, lons2, lats2, radians=False)
>>> from pyproj import Geod
>>> g = Geod(ellps='clrk66') # Use Clarke 1966 ellipsoid.
specify the lat/lons of Boston and Portland.
>>> boston_lat = 42.+(15./60.); boston_lon = -71.-(7./60.)
>>> portland_lat = 45.+(31./60.); portland_lon = -123.-(41./60.)
find ten equally spaced points between Boston and Portland.
>>> lonlats = g.npts(boston_lon,boston_lat,portland_lon,portland_lat,10)
>>> for lon,lat in lonlats: print('%6.3f %7.3f' % (lat, lon))
43.528 -75.414
44.637 -79.883
45.565 -84.512
46.299 -89.279
46.830 -94.156
47.149 -99.112
47.251 -104.106
47.136 -109.100
46.805 -114.051
46.262 -118.924
>>> from pyproj import Geod
>>> g = Geod(ellps='clrk66') # Use Clarke 1966 ellipsoid.
>>> boston_lat = 42.+(15./60.); boston_lon = -71.-(7./60.)
>>> portland_lat = 45.+(31./60.); portland_lon = -123.-(41./60.)
>>> newyork_lat = 40.+(47./60.); newyork_lon = -73.-(58./60.)
>>> london_lat = 51.+(32./60.); london_lon = -(5./60.)
compute forward and back azimuths, plus distance between Boston and
Portland.
>>> az12,az21,dist = g.inv(boston_lon,boston_lat,portland_lon,portland_lat)
>>> print ("%7.3f %6.3f %12.3f" % (az12,az21,dist))
-66.531 75.654 4164192.708
compute latitude, longitude and back azimuth of Portland, given Boston
lat/lon, forward azimuth and distance to Portland.
>>> endlon, endlat, backaz = g.fwd(boston_lon,boston_lat, az12, dist)
>>> print("%6.3f %6.3f %13.3f" % (endlat,endlon,backaz))
45.517 -123.683 75.654
compute the azimuths, distances from New York to several cities (pass a
list)
>>> lons1 = 3*[newyork_lon]; lats1 = 3*[newyork_lat]
>>> lons2 = [boston_lon, portland_lon, london_lon]
>>> lats2 = [boston_lat, portland_lat, london_lat]
>>> az12,az21,dist = g.inv(lons1,lats1,lons2,lats2)
>>> for faz,baz,d in zip(az12,az21,dist): print("%7.3f %7.3f %9.3f" % (faz,baz,d))
54.663 -123.448 288303.720
-65.463 79.342 4013037.318
51.254 -71.576 5579916.651