Why are Basemap south polar stereographic map projection coordinates not agreeing with those of data sets in the same projection?

时间:2016-04-04 16:45:12

标签: python matplotlib-basemap map-projections

Some satellite based earth observation products provide latitude/longitude information while others provide the X/Y coordinates within a given grid projection (and there are also some having both, see example). My approach in the second case is to set up a Basemap map which has the same parameters (projection, ellipsoid, origin of map) as given by the data provider in a way that the given X/Y values equal the Basemap coordinates. However if I do so the geolocation does not agree with other data sets including the Basemap coastline. I have experienced this with three different data sets from different trustworthy sources. For the minimal example I use Landsat data provided by the U.S. Geological Survey which includes both, X/Y coordinates of a South Polar Stereographic grid and the corresponding lat/lon coordinates for all four corners of the image.

From a Landsat metafile we get (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

By using Basemap with the right map projection we should be able to derive the corner lat/lon values from the X/Y values:

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)

Which returns:

lon_crn: [-61.31816102 -58.04532791 -67.01108782 -64.1858106 ]
lat_crn: [-67.23548626 -69.3099076  -68.28071626 -70.47651326]

As you can see the longitudes agree to the given precision with those from the metafile, but the latitudes are to low.

I can approximate the latitudes by:

lat_crn=(lat_crn+90.)*1.0275-90.

But this is really not satisfying.

This is how the image is located if using the X/Y corner coordinates from the metafile (in red the Basemap drawcoastlines()): enter image description here and this is how it looks like using the corner lat/lon: enter image description here

In this case I can simply use the lat/lon coordinates, but as mentioned before there are datasets (like this) which is provided by X/Y coordinates only, which makes it very important to rely on the Basemap projection. I know that there are other modules to re-project the data as a potential workaround, but it should work without other modules and a re-projection could introduce errors itself.

As this problem appears with different data sets I like to believe that it is a bug in the Basemap module, but I might also make the same mistake again and again or have wrong expectations.

1 个答案:

答案 0 :(得分:2)

我做了一些实验,似乎改变lat_tsprojection='spstere'无效。实际上,无论您指定的值是什么,似乎隐式假设投影纬度为lat_ts=-90.

我使用projection='stere'取得了更大的成功,因此您将在示例中构建Basemap,如下所示:

m=Basemap(width=5400000., height=5400000., projection='stere',
          ellps='WGS84', lon_0=180., lat_0=-90., lat_ts=-71.)

您可能更喜欢设置角落的纬度和经度,而不是应用场景的宽度和高度。