Last active
May 8, 2024 18:52
-
-
Save MBARIMike/d50599df972813b81ebce44d42a0dee5 to your computer and use it in GitHub Desktop.
Modification to bathymetry.cpp/h to support more .grd metadata formats
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
➜ MB-System git:(capstone-spring2024) ✗ git diff src/mbgrd2gltf/bathymetry.h src/mbgrd2gltf/bathymetry.cpp | |
diff --git a/src/mbgrd2gltf/bathymetry.cpp b/src/mbgrd2gltf/bathymetry.cpp | |
index 6287bee51..db8a17adc 100644 | |
--- a/src/mbgrd2gltf/bathymetry.cpp | |
+++ b/src/mbgrd2gltf/bathymetry.cpp | |
@@ -40,6 +40,7 @@ | |
// external libraries | |
#include <netcdf.h> | |
+#include <iostream> | |
namespace mbgrd2gltf | |
{ | |
@@ -47,23 +48,96 @@ namespace mbgrd2gltf | |
{ | |
int netcdf_id = get_netcdf_id(options.input_filepath().c_str()); | |
- try | |
+ // Support various arbitrary versions of metadata describing the grid through try-catch blocks | |
+ std::string x_name = "x"; | |
+ std::string y_name = "y"; | |
+ try | |
+ { | |
+ _side = get_dimension_length(netcdf_id, "side"); | |
+ } | |
+ catch (const std::exception&) | |
{ | |
- _side = get_dimension_length(netcdf_id, "side"); | |
+ _side = 2; | |
+ } | |
+ try | |
+ { | |
_xysize = get_dimension_length(netcdf_id, "xysize"); | |
+ } | |
+ catch (const std::exception&) | |
+ { | |
+ std::cout << "Failed to get xysize = " << std::string() << std::endl; | |
+ try | |
+ { | |
+ _x = get_dimension_length(netcdf_id, x_name.c_str()); | |
+ _y = get_dimension_length(netcdf_id, y_name.c_str()); | |
+ _xysize = _x * _y; | |
+ } | |
+ catch(const std::exception& e) | |
+ { | |
+ // As produced by `gmt6 grdproject` command | |
+ std::cout << "Trying lon and lat..." << e.what() << '\n'; | |
+ _x = get_dimension_length(netcdf_id, "lon"); | |
+ _y = get_dimension_length(netcdf_id, "lat"); | |
+ _xysize = _x * _y; | |
+ x_name = "lon"; | |
+ y_name = "lat"; | |
+ } | |
+ | |
+ } | |
+ try | |
+ { | |
get_variable_double_array(netcdf_id, "x_range", _x_range, _side); | |
get_variable_double_array(netcdf_id, "y_range", _y_range, _side); | |
get_variable_double_array(netcdf_id, "z_range", _z_range, _side); | |
+ } | |
+ catch (const std::exception&) | |
+ { | |
+ // Use actual_range variable attributes | |
+ get_variable_attribute_double(netcdf_id, x_name.c_str(), "actual_range", _x_range); | |
+ get_variable_attribute_double(netcdf_id, y_name.c_str(), "actual_range", _y_range); | |
+ get_variable_attribute_double(netcdf_id, "z", "actual_range", _z_range); | |
+ double temp = _y_range[0]; | |
+ _y_range[0] = _y_range[1]; | |
+ _y_range[1] = temp; | |
+ } | |
+ try | |
+ { | |
get_variable_double_array(netcdf_id, "spacing", _spacing, _side); | |
- get_variable_uint_array(netcdf_id, "dimension", _dimension, _side); | |
- _z = Matrix<float>(_dimension[0], _dimension[1]); | |
- get_variable_float_array(netcdf_id, "z", _z.data(), _xysize); | |
+ } | |
+ catch (const std::exception&) | |
+ { | |
+ _spacing[0] = (_x_range[1] - _x_range[0]) / _x; | |
+ _spacing[1] = (_y_range[1] - _y_range[0]) / _y; | |
+ } | |
+ try | |
+ { | |
+ _start[0] = _xysize - _xysize; | |
+ _length[0] = _side; | |
+ get_variable_uint_array(netcdf_id, "dimension", _dimension, _start, _length); | |
+ } | |
+ catch (const std::exception&) | |
+ { | |
+ _dimension[0] = _x; | |
+ _dimension[1] = _y; | |
+ } | |
+ try | |
+ { | |
+ // The z array in Monterey25.grd is 1-dimensional array: float z(xysize) | |
+ _start[0] = _xysize - _xysize; | |
+ _length[0] = _xysize; | |
+ size_t _zero = 0; | |
+ _z = Matrix<float>(_dimension[0], _dimension[1]); | |
+ get_variable_float_array(netcdf_id, "z", _z.data(), &_zero, &_xysize); | |
} | |
catch (const std::exception&) | |
{ | |
- nc_close(netcdf_id); | |
- | |
- throw; | |
+ // The z array is recent mbgrid generated .grd files is 2-dimensional array: float z(y, x) | |
+ _start[1] = _x - _x; | |
+ _start[0] = _y - _y; | |
+ _length[1] = _x; | |
+ _length[0] = _y; | |
+ _z = Matrix<float>(_length[1], _length[0]); | |
+ get_variable_float_array(netcdf_id, "z", _z.data(), _start, _length); | |
} | |
int return_value = nc_close(netcdf_id); | |
@@ -135,6 +209,19 @@ namespace mbgrd2gltf | |
+ "'"); | |
} | |
+ void Bathymetry::get_variable_attribute_double(int netcdf_id, const char *var_name, const char *att_name, double *out) | |
+ { | |
+ int variable_id = get_variable_id(netcdf_id, var_name); | |
+ int return_value = nc_get_att_double(netcdf_id, variable_id, att_name, out); | |
+ | |
+ if (return_value != NC_NOERR) | |
+ throw NetCdfError(return_value, "failed to get double value(s) for attribute '" | |
+ + std::string(att_name) | |
+ + "'" | |
+ + " for var_name " | |
+ + std::string(var_name)); | |
+ } | |
+ | |
size_t Bathymetry::get_dimension_length(int netcdf_id, const char *name) | |
{ | |
size_t out; | |
@@ -162,11 +249,10 @@ namespace mbgrd2gltf | |
+ "'"); | |
} | |
- void Bathymetry::get_variable_float_array(int netcdf_id, const char *name, float *out, size_t length) | |
+ void Bathymetry::get_variable_float_array(int netcdf_id, const char *name, float *out, size_t *start, size_t *length) | |
{ | |
- size_t start = 0; | |
int variable_id = get_variable_id(netcdf_id, name); | |
- int return_value = nc_get_vara_float(netcdf_id, variable_id, &start, &length, out); | |
+ int return_value = nc_get_vara_float(netcdf_id, variable_id, start, length, out); | |
if (return_value != NC_NOERR) | |
throw NetCdfError(return_value, "failed to get float array data for variable '" | |
@@ -174,11 +260,10 @@ namespace mbgrd2gltf | |
+ "'"); | |
} | |
- void Bathymetry::get_variable_uint_array(int netcdf_id, const char *name, unsigned *out, size_t length) | |
+ void Bathymetry::get_variable_uint_array(int netcdf_id, const char *name, unsigned int *out, size_t *start, size_t *length) | |
{ | |
- size_t start = 0; | |
int variable_id = get_variable_id(netcdf_id, name); | |
- int return_value = nc_get_vara_uint(netcdf_id, variable_id, &start, &length, out); | |
+ int return_value = nc_get_vara_uint(netcdf_id, variable_id, start, length, out); | |
if (return_value != NC_NOERR) | |
throw NetCdfError(return_value, "failed to get uint array data for variable '" | |
@@ -197,8 +282,9 @@ namespace mbgrd2gltf | |
_xysize = _z.count(); | |
_dimension[0] = _z.size_x(); | |
_dimension[1] = _z.size_y(); | |
- _spacing[0] = std::abs(_x_range[1] - _x_range[0]) / (double)(_dimension[0] - 1); | |
- _spacing[1] = std::abs(_y_range[1] - _y_range[0]) / (double)(_dimension[1] - 1); | |
+ // Allow negative values for when one or more grid axes are reversed | |
+ _spacing[0] = (_x_range[1] - _x_range[0]) / (double)(_dimension[0] - 1); | |
+ _spacing[1] = (_y_range[1] - _y_range[0]) / (double)(_dimension[1] - 1); | |
} | |
std::string Bathymetry::to_string() const | |
diff --git a/src/mbgrd2gltf/bathymetry.h b/src/mbgrd2gltf/bathymetry.h | |
index 72f2bdc0d..6d61b6009 100644 | |
--- a/src/mbgrd2gltf/bathymetry.h | |
+++ b/src/mbgrd2gltf/bathymetry.h | |
@@ -78,7 +78,11 @@ namespace mbgrd2gltf | |
double _spacing[2]; | |
size_t _side; | |
size_t _xysize; | |
- unsigned _dimension[2]; | |
+ size_t _x; | |
+ size_t _y; | |
+ size_t _start[2]; | |
+ unsigned int _dimension[2]; | |
+ size_t _length[2]; | |
private: // methods | |
@@ -87,10 +91,11 @@ namespace mbgrd2gltf | |
static int get_dimension_id(int netcdf_id, const char *name); | |
static size_t get_attribute_length(int netcdf_id, const char *name); | |
static void get_attribute_text(int netcdf_id, const char *name, char *out); | |
+ static void get_variable_attribute_double(int netcdf_id, const char *var_name, const char *att_name, double *out); | |
static size_t get_dimension_length(int netcdf_id, const char *name); | |
static void get_variable_double_array(int netcdf_id, const char *name, double *out, size_t length); | |
- static void get_variable_float_array(int netcdf_id, const char *name, float *out, size_t length); | |
- static void get_variable_uint_array(int netcdf_id, const char *name, unsigned *out, size_t length); | |
+ static void get_variable_float_array(int netcdf_id, const char *name, float *out, size_t *start, size_t *length); | |
+ static void get_variable_uint_array(int netcdf_id, const char *name, unsigned int *out, size_t *start, size_t *length); | |
void compress(const Options& options); | |
@@ -109,8 +114,8 @@ namespace mbgrd2gltf | |
inline double altitude_max() const { return _z_range[1]; } | |
inline double longitude_spacing() const { return _spacing[0]; } | |
inline double latitude_spacing() const { return _spacing[1]; } | |
- inline unsigned size_x() const { return _dimension[0]; } | |
- inline unsigned size_y() const { return _dimension[1]; } | |
+ inline size_t size_x() const { return _dimension[0]; } | |
+ inline size_t size_y() const { return _dimension[1]; } | |
inline size_t side_count() const { return _side; } | |
inline size_t altitudes_length() const { return _xysize; } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment