看起来你已经开始了!从 shapefile 加载的几何图形公开了各种地理空间比较方法,在这种情况下,您需要该contains
方法。您可以使用它来测试立方体水平网格中的每个点是否包含在不列颠哥伦比亚省几何体中。(请注意,这不是一个快速操作!)您可以使用此比较来构建一个 2D 掩码数组,该数组可以应用于您的多维数据集的数据或以其他方式使用。
我编写了一个 Python 函数来执行上述操作——它需要一个立方体和一个几何图形,并为立方体的(指定)水平坐标生成一个掩码,并将掩码应用于立方体的数据。功能如下:
def geom_to_masked_cube(cube, geometry, x_coord, y_coord,
mask_excludes=False):
"""
Convert a shapefile geometry into a mask for a cube's data.
Args:
* cube:
The cube to mask.
* geometry:
A geometry from a shapefile to define a mask.
* x_coord: (str or coord)
A reference to a coord describing the cube's x-axis.
* y_coord: (str or coord)
A reference to a coord describing the cube's y-axis.
Kwargs:
* mask_excludes: (bool, default False)
If False, the mask will exclude the area of the geometry from the
cube's data. If True, the mask will include *only* the area of the
geometry in the cube's data.
.. note::
This function does *not* preserve lazy cube data.
"""
# Get horizontal coords for masking purposes.
lats = cube.coord(y_coord).points
lons = cube.coord(x_coord).points
lon2d, lat2d = np.meshgrid(lons,lats)
# Reshape to 1D for easier iteration.
lon2 = lon2d.reshape(-1)
lat2 = lat2d.reshape(-1)
mask = []
# Iterate through all horizontal points in cube, and
# check for containment within the specified geometry.
for lat, lon in zip(lat2, lon2):
this_point = gpd.geoseries.Point(lon, lat)
res = geometry.contains(this_point)
mask.append(res.values[0])
mask = np.array(mask).reshape(lon2d.shape)
if mask_excludes:
# Invert the mask if we want to include the geometry's area.
mask = ~mask
# Make sure the mask is the same shape as the cube.
dim_map = (cube.coord_dims(y_coord)[0],
cube.coord_dims(x_coord)[0])
cube_mask = iris.util.broadcast_to_shape(mask, cube.shape, dim_map)
# Apply the mask to the cube's data.
data = cube.data
masked_data = np.ma.masked_array(data, cube_mask)
cube.data = masked_data
return cube
如果您只需要 2D 蒙版,则可以在上述函数将其应用于立方体之前将其返回。
要在原始代码中使用此函数,请在代码末尾添加以下内容:
geometry = BritishColumbia.geometry
masked_cube = geom_to_masked_cube(cube, geometry,
'longitude', 'latitude',
mask_excludes=True)
如果这没有掩盖任何东西,则很可能意味着您的立方体和几何图形是在不同范围内定义的。也就是说,您的立方体的经度坐标从 0°–360° 运行,如果几何的经度值从 -180°–180° 运行,则包含测试将永远不会返回True
。您可以通过使用以下方法更改多维数据集的范围来解决此问题:
cube = cube.intersection(longitude=(-180, 180))