我正在分析GOES-16卫星数据,需要计算每个网格坐标的基础纬度,经度,作为进一步分析的一部分。我目前正在尝试使用pyproj来执行此操作,并且遇到了超出图像预期范围的经度值,该经度值在预期范围内。
下载图像:
import boto3
import xarray as xr
s3 = boto3.client('s3')
s3.download_file('noaa-goes17', 'ABI-L1b-RadC/2019/022/21/OR_ABI-L1b-RadC-M3C02_G17_s20190222102189_e20190222104562_c20190222104588.nc',
'test.nc')
ds = xr.open_dataset('test.nc')
转换投影:
from pyproj import Proj
p = Proj(proj='geos', h='35786023.0', lon_0='-137.0', sweep='x')
dat = ds.metpy.parse_cf('Rad')
cord_grid = np.meshgrid(dat['x'].values, dat['y'].values)
lons, lats = p(cord_grid[0], cord_grid[1], inverse=True)
此处的最小和最大lon值分别为-179.99和179.9。我只希望此图像包含介于-89.6和175.6之间的数据,如下所示。
当我检查此图像的预期地理范围时,将得到以下信息:
ds['geospatial_lat_lon_extent']
Out[61]:
<xarray.DataArray 'geospatial_lat_lon_extent' ()>
array(9.96921e+36, dtype=float32)
Coordinates:
t datetime64[ns] ...
y_image float32 ...
x_image float32 ...
Attributes:
long_name: geospatial latitude and longitude refere...
geospatial_westbound_longitude: 175.62358
geospatial_northbound_latitude: 53.50006
geospatial_eastbound_longitude: -89.62357
geospatial_southbound_latitude: 14.57134
geospatial_lat_center: 29.967
geospatial_lon_center: -137.0
geospatial_lat_nadir: 0.0
geospatial_lon_nadir: -137.0
geospatial_lat_units: degrees_north
geospatial_lon_units: degrees_east
我对地理空间数据操作还比较陌生。我在这里做什么错了?
答案 0 :(得分:0)
查看您的数据,看起来它越过了antimeridian(-180/180经度)。 使用rioxarray检查数据。
常规检查可能不会发现以下内容:
import numpy as np
from pyproj import Transformer
import rioxarray
rds = rioxarray.open_rasterio("test.nc", masked=True)
<xarray.Dataset>
Dimensions: (band: 1, x: 10000, y: 6000)
Coordinates:
* y (y) float64 1.583e+06 1.584e+06 ... 4.588e+06 4.589e+06
* x (x) float64 -2.505e+06 -2.504e+06 ... 2.504e+06 2.505e+06
* band (band) int64 1
spatial_ref int64 0
Data variables:
Rad (band, y, x) float64 ...
DQF (band, y, x) float64 ...
rds.rio.crs
CRS.from_wkt('PROJCS["unnamed",GEOGCS["unknown",DATUM["unnamed",SPHEROID["Spheroid",6378137,298.2572221]],PRIMEM["Greenwich",0],UNIT["degree",0.0174532925199433,AUTHORITY["EPSG","9122"]]],PROJECTION["Geostationary_Satellite"],PARAMETER["central_meridian",-137],PARAMETER["satellite_height",35786023],PARAMETER["false_easting",0],PARAMETER["false_northing",0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AXIS["Easting",EAST],AXIS["Northing",NORTH],EXTENSION["PROJ4","+proj=geos +lon_0=-137 +h=35786023 +x_0=0 +y_0=0 +ellps=GRS80 +units=m +no_defs +sweep=x"]]')
rds.Rad.rio.transform_bounds("epsg:4326")
(-177.77133129663548,
14.561801004390198,
179.99792429593583,
53.52729472471354)
但是,一旦转换了数据: (旁注,这就是为什么我使用Transformer代替Proj https://pyproj4.github.io/pyproj/stable/gotchas.html#proj-not-a-generic-latitude-longitude-to-projection-converter的原因)
transformer = Transformer.from_crs(rds.rio.crs, "epsg:4326", always_xy=True)
x_coords, y_coords = np.meshgrid(
rds.coords[rds.rio.x_dim], rds.coords[rds.rio.y_dim]
)
lon, lat = transformer.transform(x_coords, y_coords)
您会看到拐角不在线的同一侧:
(lon[0][0], lat[0][0]), (lon[-1][-1], lat[-1][-1]), (lon[0][-1], lat[0][-1]), (lon[-1][0], lat[-1][0])```
((-161.57648657675344, 14.798043104222199),
(-89.56850957728933, 53.5204809865526),
(-112.4235101487757, 14.798043165552787),
(175.56851955360526, 53.52047990993389))
由于这一点,当您使用最小值和最大值来获取界限时,这会产生误导,因为经度的最小值和最大值都位于经纬度(-180/180)的纬度/经度旁边。
lon.min(), lat.min(), lon.max(), lat.max()
(-179.99994221231273, 14.564185533235145, 179.9999815862486, 53.5204809865526)
答案 1 :(得分:0)