diff --git a/lib/io/netcdf_io.h b/lib/io/netcdf_io.h index 6d978b8..671bce0 100644 --- a/lib/io/netcdf_io.h +++ b/lib/io/netcdf_io.h @@ -310,21 +310,22 @@ namespace gctl * @param[in] xname 文件中 x 坐标轴的变量名,默认为 x * @param[in] yname 文件中 y 坐标轴的变量名,默认为 y * @param[in] dataname 文件中网格数据的变量名,默认为 z + * @param[in] cor 文件中网格数据排序方式(默认是从左下到右上) */ template void save_netcdf_grid(std::string filename, const array &out_data, int xnum, int ynum, - P xmin, P dx, P ymin, P dy, std::string xname = "x", std::string yname = "y", - std::string dataname = "z", T zmin = NAN, T zmax = NAN) + P xmin, P dx, P ymin, P dy, matrix_corner_e cor = BtmLeft, std::string xname = "x", + std::string yname = "y", std::string dataname = "z", T zmin = NAN, T zmax = NAN) { // 准备写出数据 - if (out_data.empty()) + if (out_data.empty() || xnum*ynum != out_data.size()) { - throw runtime_error("The output data is empty. From save_netcdf_grid(...)"); + throw std::runtime_error("[gctl::save_netcdf_grid] Invalid data dimensions."); } if (filename == "") { - throw domain_error("The input filename is empty. From save_netcdf_grid(...)"); + throw std::domain_error("[gctl::save_netcdf_grid] Empty filename empty."); } // 判断文件名结尾是否为.nc如果不是则添加.nc结尾 @@ -338,7 +339,7 @@ namespace gctl NcFile nc_outfile(full_name.c_str(), NcFile::Replace); if (!nc_outfile.is_valid()) { - throw runtime_error("Can't not open file: " + full_name + ". From save_netcdf_grid(...)"); + throw runtime_error("[gctl::save_netcdf_grid] Can't not open file: " + full_name + "."); } if (std::isnan(zmin)) @@ -418,7 +419,21 @@ namespace gctl dVar->add_att("valid_range", 2, &data_range[0]); dVar->add_att("missing_value", GCTL_BDL_MAX); - array tmp_data(out_data); + array tmp_data; + if (cor == BtmLeft) tmp_data = out_data; + else if (cor == TopLeft) + { + tmp_data.resize(xnum*ynum); + for (int i = 0; i < ynum; i++) + { + for (int j = 0; j < xnum; j++) + { + tmp_data[j + i*xnum] = out_data[j + (ynum - 1 - i)*xnum]; + } + } + } + else throw std::runtime_error("[gctl::save_netcdf_grid] Invalid data ordering type."); + for (int i = 0; i < tmp_data.size(); i++) { if (tmp_data[i] < zmin || tmp_data[i] > zmax) @@ -458,7 +473,7 @@ namespace gctl out_data.reform(tmpdata); save_netcdf_grid(filename, tmpdata, out_data.col_size(), out_data.row_size(), - xmin, dx, ymin, dy, xname, yname, dataname, zmin, zmax); + xmin, dx, ymin, dy, TopLeft, xname, yname, dataname, zmin, zmax); return; } @@ -474,21 +489,21 @@ namespace gctl * @param[in] xname 文件中 x 坐标轴的变量名,默认为 x * @param[in] yname 文件中 y 坐标轴的变量名,默认为 y * @param[in] dataname 文件中网格数据的变量名,默认为 z + * @param[in] cor 文件中网格数据排序方式(默认是从左下到右上) */ template void save_netcdf_grid(std::string filename, const array &out_data, const array

&out_x, - const array

&out_y, std::string xname = "x", std::string yname = "y", std::string dataname = "z", - T zmin = NAN, T zmax = NAN) + const array

&out_y, matrix_corner_e cor = BtmLeft, std::string xname = "x", + std::string yname = "y", std::string dataname = "z", T zmin = NAN, T zmax = NAN) { - // 准备写出数据 - if (out_data.empty()) + if (out_data.empty() || out_x.size()*out_y.size() != out_data.size()) { - throw runtime_error("The output data is empty. From save_netcdf_grid(...)"); + throw std::runtime_error("[gctl::save_netcdf_grid] Invalid data dimensions."); } if (filename == "") { - throw domain_error("The input filename is empty. From save_netcdf_grid(...)"); + throw std::domain_error("[gctl::save_netcdf_grid] Empty filename empty."); } // 判断文件名结尾是否为.nc如果不是则添加.nc结尾 @@ -502,7 +517,7 @@ namespace gctl NcFile nc_outfile(full_name.c_str(), NcFile::Replace); if (!nc_outfile.is_valid()) { - throw runtime_error("Can't not open file: " + full_name + ". From save_netcdf_grid(...)"); + throw runtime_error("[gctl::save_netcdf_grid] Can't not open file: " + full_name + "."); } if (std::isnan(zmin)) @@ -571,7 +586,21 @@ namespace gctl dVar->add_att("valid_range", 2, &data_range[0]); dVar->add_att("missing_value", GCTL_BDL_MAX); - array tmp_data(out_data.get(), out_data.size()); + array tmp_data; + if (cor == BtmLeft) tmp_data = out_data; + else if (cor == TopLeft) + { + tmp_data.resize(xnum*ynum); + for (int i = 0; i < ynum; i++) + { + for (int j = 0; j < xnum; j++) + { + tmp_data[j + i*xnum] = out_data[j + (ynum - 1 - i)*xnum]; + } + } + } + else throw std::runtime_error("[gctl::save_netcdf_grid] Invalid data ordering type."); + for (int i = 0; i < tmp_data.size(); i++) { if (tmp_data[i] < zmin || tmp_data[i] > zmax) @@ -608,7 +637,7 @@ namespace gctl gctl::array tmpdata; out_data.reform(tmpdata); - save_netcdf_grid(filename, tmpdata, out_x, out_y, xname, yname, dataname, zmin, zmax); + save_netcdf_grid(filename, tmpdata, out_x, out_y, TopLeft, xname, yname, dataname, zmin, zmax); return; } @@ -624,10 +653,12 @@ namespace gctl * @param[in] dataname 保存的数据名称,注意不要与已有数据重名 * @param[in] zmin 网格数据的最小值,默认为 NAN 。 此时函数会自动计算数组的最小值 * @param[in] zmax 网格数据的最大值,默认为 NAN 。 此时函数会自动计算数组的最大值 + * @param[in] cor 文件中网格数据排序方式(默认是从左下到右上) */ template void append_netcdf_grid(std::string filename, const array &out_data, std::string xname, - std::string yname, std::string dataname, T zmin = NAN, T zmax = NAN) + std::string yname, std::string dataname, matrix_corner_e cor = BtmLeft, + T zmin = NAN, T zmax = NAN) { // 准备写出数据 if (out_data.empty()) @@ -730,14 +761,27 @@ namespace gctl dVar->add_att("valid_range", 2, &data_range[0]); dVar->add_att("missing_value", GCTL_BDL_MAX); - array tmp_data(out_data.get(), out_data.size()); + array tmp_data; + if (cor == BtmLeft) tmp_data = out_data; + else if (cor == TopLeft) + { + tmp_data.resize(xnum*ynum); + for (int i = 0; i < ynum; i++) + { + for (int j = 0; j < xnum; j++) + { + tmp_data[j + i*xnum] = out_data[j + (ynum - 1 - i)*xnum]; + } + } + } + else throw std::runtime_error("[gctl::append_netcdf_grid] Invalid data ordering type."); + for (int i = 0; i < tmp_data.size(); i++) { if (tmp_data[i] < zmin || tmp_data[i] > zmax) tmp_data[i] = GCTL_BDL_MAX; } dVar->put(tmp_data.get(), ynum, xnum); - return; }