【代码】根据矢量裁剪NetCDF 时间序列数据

之前写了

1.矢量裁剪栅格

2.矢量裁剪矢量

其实还有另一种裁剪数据的类型,那就是矢量裁剪NetCDF,下面简称为NC数据。

常见的NC数据,就我个人遇到的情况来说,有以下几个:

1.美国的jason3海洋数据

2.中国的风云三号、风云四号气象数据

3.欧空局的哨兵3海洋数据、哨兵5气象数据

还有很多,只是我还没遇到,暂时不写。

通俗地来说,nc数据与tif数据对比,nc的特点是多维的。

一个nc文件可能包含了一份30天的海洋温度数据和60天的海洋高度数据,每一天的海洋温度数据的大小为1000x1000,每一天的海洋高度数据的大小为2000x2000。所以,这份nc文件就是30x1000x1000和60x2000x2000的数据的集合。

tif文件一般是固定大小,即第一个波段的大小与其他波段的大小是保持一致。如果要把上面的数据保存为tif,此时,tif的大小就变成了90x2000x2000。

如果要用tif格式去保存这种形式的数据,会使数据量提高,所以nc格式一般是被视为高效率存储的格式。

除此之外,nc的复杂性与文件内部的不统一性也是处理nc数据的难点。我就觉得是nc文件内部的数据命名简直是,乱七八糟得一塌糊涂!

反正每次读取不同类型nc都需要打印一下nc内部的名字,比如说,有时候FY4 的经度的名字是lon,有时候Sentinel3的经度用Lon表示,有时候也用longitude。

别的不多说,下面正式介绍nc文件。

NetCDF官方定义

NetCDF(Network Common Data Form)是一种用于存储和分享科学数据的文件格式和库集合。这种格式广泛用于气候科学、地理学、气象学、海洋科学等领域,特别适合于存储大量的多维数组数据。

NetCDF的主要特点包括自描述性、可扩展性和可移植性。自描述性意味着NetCDF文件包含了数据的元信息,例如数据的单位、坐标轴信息等。可扩展性意味着可以在不影响已有数据和程序的情况下向NetCDF文件中添加新的数据。可移植性意味着NetCDF文件可以在不同的硬件和操作系统之间无缝地共享和传输。

NetCDF支持多种数据类型,并且可以处理大规模的数据集。它提供了一套简单但强大的接口,使得用户可以方便地创建、访问和共享科学数据。此外,NetCDF还支持无损压缩和分块存储,这使得它可以高效地处理大规模的数据。

需求

现有一个 3D 时间序列降水数据 (187 x 1800 x 3600),存储在 NetCDF 文件中。我需要获取 指定shapefile 范围内的降水数据。即根据shp数据去裁剪nc数据。

值得说明的是,咱写代码一般是先分析需求,再根据需求去编程。

代码

import geopandas
import rioxarray
import xarray
from shapely.geometry import mapping

def clip_to_shape(nc_file_path, shp_file_path):
    # Load the NetCDF
    data = xarray.open_dataarray(nc_file_path)
    data.rio.set_spatial_dims(x_dim="lon", y_dim="lat", inplace=True)
    data.rio.write_crs("epsg:4326", inplace=True)

    # Load the Shapefile
    shape = geopandas.read_file(shp_file_path, crs="epsg:4326")

    # Clip the DataArray to the shape
    clipped = data.rio.clip(shape.geometry.apply(mapping), shape.crs, drop=False)

    return clipped

分析

上一段代码,我们使用Python的几个主要地理数据处理库(包括geopandas,rioxarray和xarray)来进行一些地理数据的操作。

让我们逐行解释一下这段代码的作用:

  1. 导入需要的库:geopandas用于处理地理空间数据,rioxarray和xarray用于处理NetCDF数据,shapely.geometry用于处理几何对象。
  2. 定义函数clip_to_shape,它接受两个参数:NetCDF文件路径和Shapefile文件路径。
  3. 加载NetCDF文件:使用xarray的open_dataarray函数打开NetCDF文件,并将结果存储在变量data中。然后,使用rioxarray的set_spatial_dims函数设置空间维度,这里设置的是经度(”lon”)和纬度(”lat”)。最后,使用write_crs函数写入坐标参考系统(CRS),这里设置的是”epsg:4326”,即WGS84地理坐标系统。
  4. 加载Shapefile文件:使用geopandas的read_file函数打开Shapefile文件,并将结果存储在变量shape中。这里也设置了坐标参考系统为”epsg:4326”。
  5. 裁剪:使用rioxarray的clip函数将NetCDF数据裁剪以适应Shapefile的几何形状。shape.geometry.apply(mapping)将Shapefile的每个几何对象转换为可以用于裁剪的格式。shape.crs指定了裁剪操作的坐标参考系统。drop=False表示如果裁剪后的数据为空,仍然保留原始数据的元数据。
  6. 返回裁剪后的数据。

总的来说,这段代码的主要目的是读取一个NetCDF文件和一个Shapefile文件,然后将NetCDF文件的数据裁剪到Shapefile文件定义的区域。

今天不吹水,认认真真写代码。