我使用的是不规则二维网格组织的卫星数据,其维度为扫描线(沿轨道方向)和地面像素(横向跨越方向)。每个地面像素的纬度和经度信息存储在辅助坐标变量中。
给定一个(纬度,经度)点,我想要确定我的数据集中最接近的地面像素。
让我们构建一个10x10的玩具数据集:
现在,假设我想要确定离罗马最近的地面像素。
到目前为止,我想到的最好方法是在堆叠的平铺的lat/lon数组上使用scipy的kdtree:
然后我需要使用`unravel_index`函数来获取我的扫描线/地面像素索引:
这段话的意思是:“这里给出了扫描线/地面像素坐标,即与罗马最近(理论上)的地面像素。”
给定一个(纬度,经度)点,我想要确定我的数据集中最接近的地面像素。
让我们构建一个10x10的玩具数据集:
import numpy as np
import xarray as xr
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
%matplotlib inline
lon, lat = np.meshgrid(np.linspace(-20, 20, 10),
np.linspace(30, 60, 10))
lon += lat/10
lat += lon/10
da = xr.DataArray(data = np.random.normal(0,1,100).reshape(10,10),
dims=['scanline', 'ground_pixel'],
coords = {'lat': (('scanline', 'ground_pixel'), lat),
'lon': (('scanline', 'ground_pixel'), lon)})
ax = plt.subplot(projection=ccrs.PlateCarree())
da.plot.pcolormesh('lon', 'lat', ax=ax, cmap=plt.cm.get_cmap('Blues'),
infer_intervals=True);
ax.scatter(lon, lat, transform=ccrs.PlateCarree())
ax.coastlines()
ax.gridlines(draw_labels=True)
plt.tight_layout()
请注意,lat/lon坐标标识中心像素,并且像素边界由xarray自动推断。现在,假设我想要确定离罗马最近的地面像素。
到目前为止,我想到的最好方法是在堆叠的平铺的lat/lon数组上使用scipy的kdtree:
from scipy import spatial
pixel_center_points = np.stack((da.lat.values.flatten(), da.lon.values.flatten()), axis=-1)
tree = spatial.KDTree(pixel_center_points)
rome = (41.9028, 12.4964)
distance, index = tree.query(rome)
print(index)
# 36
然后我需要使用`unravel_index`函数来获取我的扫描线/地面像素索引:
pixel_coords = np.unravel_index(index, da.shape)
print(pixel_coords)
# (3, 6)
这段话的意思是:“这里给出了扫描线/地面像素坐标,即与罗马最近(理论上)的地面像素。”
ax = plt.subplot(projection=ccrs.PlateCarree())
da.plot.pcolormesh('lon', 'lat', ax=ax, cmap=plt.cm.get_cmap('Blues'),
infer_intervals=True);
ax.scatter(da.lon[pixel_coords], da.lat[pixel_coords],
marker='x', color='r', transform=ccrs.PlateCarree())
ax.coastlines()
ax.gridlines(draw_labels=True)
plt.tight_layout()
我相信一定有更优雅的方法来解决这个问题。特别是,我想摆脱展平/解开步骤(我尝试在二维数组上构建kdtree的所有尝试都失败了),尽可能利用我的xarray数据集的变量(例如添加新的center_pixel维度,并将其用作输入到KDTree
)。