Skip to content

Instantly share code, notes, and snippets.

@MBARIMike
Last active May 8, 2024 18:52
Show Gist options
  • Save MBARIMike/d50599df972813b81ebce44d42a0dee5 to your computer and use it in GitHub Desktop.
Save MBARIMike/d50599df972813b81ebce44d42a0dee5 to your computer and use it in GitHub Desktop.
Modification to bathymetry.cpp/h to support more .grd metadata formats
➜ 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