Skip to main content

OPeNDAP格式

QE框架中内置了解析OPeNDAP数据规范的数据解析器,可以在项目中直接使用。

构建DAPService

DAPService是框架封装的用来访问OPeNDAP数据规范的数据服务,构建时需要如下参数:

  • baseUrl 不含服务后缀的请求路径,注意大部分OPeNDAP服务并不支持跨域,需要自行代理。

  • varList 要素列表,默认为空表示请求全部要素头信息;

  • load 是否构建的时候就请求头信息。默认为false。

import { DAPService } from "quickearth";
const dapService = new DAPService("https://thredds.ucar.edu/thredds/dodsC/grib/NCEP/GFS/Global_onedeg/GFS_Global_onedeg_20220427_0000.grib2");

加载文件头信息

如果构建DAPService时,load参数传true,会在初始化DAPService时就加载文件头信息。由于加载文件头信息是个异步的过程,为确保加载完文件头信息后,再去获取数据,我们可以将这一步独立出来,也就是不在初始化DAPService时加载。

const service = new DAPService(url, undefined, false);
const info = await service.loadDataInfo(); //加载文件头信息
...

获取数据

加载数据并生成provider

DAPService 中封装了 loadData 方法来加载数据并生成provider。传入要素过滤器,其接口为IDAPFilter。返回的结果为IDAPServiceResult,其中包含我们创建格点图层时需要的格点数据解析器。

一份OPeNDAP数据规范的数据是可以包含多要素,多时次,多高度的二维格点场数据。通过要素过滤器可以针对性地只获取其中一部分数据。
  • varName 要素名称
  • tIdx 时间层次
  • zIdx 高度层次
  • xStartIdx 经度开始索引
  • xEndIdx 经度结束索引
  • yStartIdx 维度开始索引
  • yEndIdx 维度结束索引
function testDAPTempLayer(map: LMap) {
    const dapService = new DAPService("https://thredds.ucar.edu/thredds/dodsC/grib/NCEP/GFS/Global_onedeg/GFS_Global_onedeg_20220328_0000.grib2");
    dapService.loadData({ varName: "Temperature_isobaric", tIdx: 7, zIdx: 0 }).then(res => {
        previewLayer(map, res);
    });
}

function previewLayer(map: LMap, res: IDAPServiceResult) {
    const maxMin = res.provider.getGrid().maxMin;
    const colorScale = await getPredefinedBitmapScale(predefinedLegendNames["3gauss"], maxMin.min, maxMin.max, true);
    const style: IPixelLayerStyleOptions = {
        colorScale: colorScale,
        fillMode: GridDataGLFillMode.shaded1
    }
    const layer = new LPixelLayer().setDrawOptions(style).setDataSource(res.provider);
    map.addLayer(layer);
}
使用原生过滤器获取数据

loadDataByFullFilter 是使用原生过滤器获取数据的方法, 传入符合接口IDAPFullFilter的参数,未传递的字段默认为所有长度。这边过滤器与 OPeNDAP Dataset Access Form 中的过滤方式一致。

  • varName 要素名称
  • tFilter 时间过滤
  • zFilter 高度过滤
  • xFilter 经度过滤
  • yFilter 维度过滤

其中filter过滤的规则是:

[1] 表示只取第二个

[0:1:0] 表示只取第一个与[0]相同

[0:1:9] 表示取0-9这10个,[0:2:9] 表示取 0 2 4 6 8这5个

下面示例表示取要素为Temperature_isobaric,高度层是第29层的格点场中第一个经纬度格点的所有时序数据。

function testDAPSeries(map: LMap) {
    const dapService = new DAPService("https://thredds.ucar.edu/thredds/dodsC/grib/NCEP/GFS/Global_onedeg/GFS_Global_onedeg_20220427_0000.grib2");
    const res= await dapService.loadDataByFullFilter({
        varName: "Temperature_isobaric",
        xFilter: "[0]",
        yFilter: "[0]",
        zFilter: "[28]"
    });
}
加载数据返回数据原始信息

DAPServiceloadDataByRawFilter 方法来加载数据,返回数据原始信息IDODSResult

比如我们想取第29层第一个经纬度格点上u和v的前10个时次的时序数据:

const dapService = new DAPService("https://thredds.ucar.edu/thredds/dodsC/grib/NCEP/GFS/Global_onedeg/GFS_Global_onedeg_20220427_0000.grib2");
const info = await dapService.loadDataInfo();
const filter = "u-component_of_wind_isobaric[0:1:9][28][0][0],v-component_of_wind_isobaric[0:1:9][28][0][0]";
const res= await dapService.loadDataByRawFilter(filter);

返回的res结果如下图,红框中就是我们所需要的时序数据

dap_result.jpg

将dods结果解析为provider

dapResultToProvider 方法是将dods结果解析为provider,如果获取数据时固定了经纬度点,则无法将结果解析为二维格点场。返回的结果为IDAPServiceResult。该方法需要两个参数:

  • 数据原始信息,其接口IDODSResult。也就是 loadDataByRawFilter 方法加载到的数据

  • 数据区域名称。也就是过滤器中的varName

下面的示例是使用 loadDataByRawFilter 方法获取到第1个时次的第29层的原始uv数据后,再使用 dapResultToProvider 方法解析为provider,最后创建图层显示。

我们也可以直接使用前面介绍的 loadData 方法来加载数据并生成数据解析器,这里只是为了演示 dapResultToProvider 方法的用法。