为什么Basemap南极立体地图投影坐标与同一投影下的数据集坐标不一致?
Why are Basemap south polar stereographic map projection coordinates not agreeing with those of data sets in the same projection?
一些基于卫星的地球观测产品提供 latitude/longitude 信息,而其他产品提供给定网格投影内的 X/Y 坐标(也有一些两者兼有,请参见示例)。
在第二种情况下,我的方法是设置一个 Basemap 地图,该地图具有与数据提供者以给定 X/Y 值等于 Basemap 坐标的方式给出的相同参数(投影、椭圆体、地图原点)。但是,如果我这样做,地理位置与其他数据集(包括底图海岸线)不一致。
我使用来自不同可信来源的三个不同数据集体验过这种情况。对于最小的示例,我使用 U.S. Geological Survey 提供的 Landsat 数据,其中包括南极立体网格的 X/Y 坐标和图像所有四个角的相应 lat/lon 坐标。
从 Landsat 图元文件我们得到(ID:LC82171052016079LGN00):
CORNER_UL_LAT_PRODUCT = -66.61490 CORNER_UL_LON_PRODUCT = -61.31816
CORNER_UR_LAT_PRODUCT = -68.74325 CORNER_UR_LON_PRODUCT = -58.04533
CORNER_LL_LAT_PRODUCT = -67.68721 CORNER_LL_LON_PRODUCT = -67.01109
CORNER_LR_LAT_PRODUCT = -69.94052 CORNER_LR_LON_PRODUCT = -64.18581
CORNER_UL_PROJECTION_X_PRODUCT = -2259300.000
CORNER_UL_PROJECTION_Y_PRODUCT = 1236000.000
CORNER_UR_PROJECTION_X_PRODUCT = -1981500.000
CORNER_UR_PROJECTION_Y_PRODUCT = 1236000.000
CORNER_LL_PROJECTION_X_PRODUCT = -2259300.000
CORNER_LL_PROJECTION_Y_PRODUCT = 958500.000
CORNER_LR_PROJECTION_X_PRODUCT = -1981500.000
CORNER_LR_PROJECTION_Y_PRODUCT = 958500.000
...
GROUP = PROJECTION_PARAMETERS MAP_PROJECTION = "PS" DATUM = "WGS84"
ELLIPSOID = "WGS84" VERTICAL_LON_FROM_POLE = 0.00000 TRUE_SCALE_LAT =
-71.00000 FALSE_EASTING = 0 FALSE_NORTHING = 0 GRID_CELL_SIZE_PANCHROMATIC = 15.00 GRID_CELL_SIZE_REFLECTIVE = 30.00
GRID_CELL_SIZE_THERMAL = 30.00 ORIENTATION = "NORTH_UP"
RESAMPLING_OPTION = "CUBIC_CONVOLUTION" END_GROUP =
PROJECTION_PARAMETERS
通过使用具有正确地图投影的底图,我们应该能够从 X/Y 值导出角点 lat/lon 值:
import numpy as np
from mpl_toolkits.basemap import Basemap
m=Basemap(resolution='h',projection='spstere', ellps='WGS84', boundinglat=-60,lon_0=180, lat_ts=-71)
x_crn=np.array([-2259300,-1981500,-2259300,-1981500])# upper left, upper right, lower left, lower right
y_crn=np.array([1236000, 1236000, 958500, 958500])# upper left, upper right, lower left, lower right
x0, y0= m(0, -90)
#Basemap coordinates at the south pole
#note that (0,0) of the Basemap is in a corner of the map,
#while other data sets use the south pole.
#This is easy to take into account:
lon_crn, lat_crn = m(x0-x_crn, y0-y_crn, inverse=True)
print 'lon_crn: '+str(lon_crn)
print 'lat_crn: '+str(lat_crn)
哪个returns:
lon_crn: [-61.31816102 -58.04532791 -67.01108782 -64.1858106 ]
lat_crn: [-67.23548626 -69.3099076 -68.28071626 -70.47651326]
如您所见,经度与图元文件中的给定精度一致,但纬度太低。
我可以通过以下方式估算纬度:
lat_crn=(lat_crn+90.)*1.0275-90.
但这确实不尽如人意
如果使用图元文件中的 X/Y 角坐标,这就是图像的定位方式(红色底图 drawcoastlines()
):
这就是使用角 lat/lon 的样子:
在这种情况下,我可以简单地使用 lat/lon 坐标,但如前所述,有些数据集(如 this)仅由 X/Y 坐标提供,这使得它依赖底图投影非常重要。我知道还有其他模块可以重新投影数据作为潜在的解决方法,但它应该可以在没有其他模块的情况下工作,并且重新投影本身可能会引入错误。
由于这个问题出现在不同的数据集上,我倾向于认为这是 Basemap 模块中的一个错误,但我也可能会一次又一次地犯同样的错误或者有错误的期望。
我做了一些实验,似乎更改 lat_ts
对 projection='spstere'
没有影响。事实上,无论您分配什么值,投影纬度似乎都被隐式假定为 lat_ts=-90.
。
我使用 projection='stere'
取得了更大的成功,因此您可以按如下方式在示例中构建底图:
m=Basemap(width=5400000., height=5400000., projection='stere',
ellps='WGS84', lon_0=180., lat_0=-90., lat_ts=-71.)
您可能更愿意为您的应用程序设置拐角的纬度和经度,而不是绘图的宽度和高度。
一些基于卫星的地球观测产品提供 latitude/longitude 信息,而其他产品提供给定网格投影内的 X/Y 坐标(也有一些两者兼有,请参见示例)。 在第二种情况下,我的方法是设置一个 Basemap 地图,该地图具有与数据提供者以给定 X/Y 值等于 Basemap 坐标的方式给出的相同参数(投影、椭圆体、地图原点)。但是,如果我这样做,地理位置与其他数据集(包括底图海岸线)不一致。 我使用来自不同可信来源的三个不同数据集体验过这种情况。对于最小的示例,我使用 U.S. Geological Survey 提供的 Landsat 数据,其中包括南极立体网格的 X/Y 坐标和图像所有四个角的相应 lat/lon 坐标。
从 Landsat 图元文件我们得到(ID:LC82171052016079LGN00):
CORNER_UL_LAT_PRODUCT = -66.61490 CORNER_UL_LON_PRODUCT = -61.31816 CORNER_UR_LAT_PRODUCT = -68.74325 CORNER_UR_LON_PRODUCT = -58.04533 CORNER_LL_LAT_PRODUCT = -67.68721 CORNER_LL_LON_PRODUCT = -67.01109 CORNER_LR_LAT_PRODUCT = -69.94052 CORNER_LR_LON_PRODUCT = -64.18581 CORNER_UL_PROJECTION_X_PRODUCT = -2259300.000 CORNER_UL_PROJECTION_Y_PRODUCT = 1236000.000 CORNER_UR_PROJECTION_X_PRODUCT = -1981500.000 CORNER_UR_PROJECTION_Y_PRODUCT = 1236000.000 CORNER_LL_PROJECTION_X_PRODUCT = -2259300.000 CORNER_LL_PROJECTION_Y_PRODUCT = 958500.000 CORNER_LR_PROJECTION_X_PRODUCT = -1981500.000 CORNER_LR_PROJECTION_Y_PRODUCT = 958500.000
...
GROUP = PROJECTION_PARAMETERS MAP_PROJECTION = "PS" DATUM = "WGS84" ELLIPSOID = "WGS84" VERTICAL_LON_FROM_POLE = 0.00000 TRUE_SCALE_LAT = -71.00000 FALSE_EASTING = 0 FALSE_NORTHING = 0 GRID_CELL_SIZE_PANCHROMATIC = 15.00 GRID_CELL_SIZE_REFLECTIVE = 30.00 GRID_CELL_SIZE_THERMAL = 30.00 ORIENTATION = "NORTH_UP" RESAMPLING_OPTION = "CUBIC_CONVOLUTION" END_GROUP = PROJECTION_PARAMETERS
通过使用具有正确地图投影的底图,我们应该能够从 X/Y 值导出角点 lat/lon 值:
import numpy as np
from mpl_toolkits.basemap import Basemap
m=Basemap(resolution='h',projection='spstere', ellps='WGS84', boundinglat=-60,lon_0=180, lat_ts=-71)
x_crn=np.array([-2259300,-1981500,-2259300,-1981500])# upper left, upper right, lower left, lower right
y_crn=np.array([1236000, 1236000, 958500, 958500])# upper left, upper right, lower left, lower right
x0, y0= m(0, -90)
#Basemap coordinates at the south pole
#note that (0,0) of the Basemap is in a corner of the map,
#while other data sets use the south pole.
#This is easy to take into account:
lon_crn, lat_crn = m(x0-x_crn, y0-y_crn, inverse=True)
print 'lon_crn: '+str(lon_crn)
print 'lat_crn: '+str(lat_crn)
哪个returns:
lon_crn: [-61.31816102 -58.04532791 -67.01108782 -64.1858106 ]
lat_crn: [-67.23548626 -69.3099076 -68.28071626 -70.47651326]
如您所见,经度与图元文件中的给定精度一致,但纬度太低。
我可以通过以下方式估算纬度:
lat_crn=(lat_crn+90.)*1.0275-90.
但这确实不尽如人意
如果使用图元文件中的 X/Y 角坐标,这就是图像的定位方式(红色底图 drawcoastlines()
):
在这种情况下,我可以简单地使用 lat/lon 坐标,但如前所述,有些数据集(如 this)仅由 X/Y 坐标提供,这使得它依赖底图投影非常重要。我知道还有其他模块可以重新投影数据作为潜在的解决方法,但它应该可以在没有其他模块的情况下工作,并且重新投影本身可能会引入错误。
由于这个问题出现在不同的数据集上,我倾向于认为这是 Basemap 模块中的一个错误,但我也可能会一次又一次地犯同样的错误或者有错误的期望。
我做了一些实验,似乎更改 lat_ts
对 projection='spstere'
没有影响。事实上,无论您分配什么值,投影纬度似乎都被隐式假定为 lat_ts=-90.
。
我使用 projection='stere'
取得了更大的成功,因此您可以按如下方式在示例中构建底图:
m=Basemap(width=5400000., height=5400000., projection='stere',
ellps='WGS84', lon_0=180., lat_0=-90., lat_ts=-71.)
您可能更愿意为您的应用程序设置拐角的纬度和经度,而不是绘图的宽度和高度。