From 8e7fa75c50ba02372c59fdf030130a6932a2eb1f Mon Sep 17 00:00:00 2001 From: Peter Petrik Date: Thu, 4 Oct 2018 12:19:20 +0200 Subject: [PATCH] [feature] add NetCDF format, fixes #11 --- mdal/CMakeLists.txt | 13 ++- .../{mdal_grib.cpp => mdal_gdal_grib.cpp} | 12 +-- .../{mdal_grib.hpp => mdal_gdal_grib.hpp} | 10 +-- mdal/frmts/mdal_gdal_netcdf.cpp | 79 ++++++++++++++++++ mdal/frmts/mdal_gdal_netcdf.hpp | 34 ++++++++ mdal/mdal_loader.cpp | 25 ++++-- tests/CMakeLists.txt | 8 +- tests/data/netcdf/indonesia_nc3.nc | Bin 0 -> 30564 bytes tests/data/netcdf/indonesia_nc4.nc | Bin 0 -> 58868 bytes tests/{test_grib.cpp => test_gdal_grib.cpp} | 4 +- tests/test_gdal_netcdf.cpp | 67 +++++++++++++++ tools/mdalinfo.cpp | 19 +++-- 12 files changed, 242 insertions(+), 29 deletions(-) rename mdal/frmts/{mdal_grib.cpp => mdal_gdal_grib.cpp} (75%) rename mdal/frmts/{mdal_grib.hpp => mdal_gdal_grib.hpp} (81%) create mode 100644 mdal/frmts/mdal_gdal_netcdf.cpp create mode 100644 mdal/frmts/mdal_gdal_netcdf.hpp create mode 100644 tests/data/netcdf/indonesia_nc3.nc create mode 100644 tests/data/netcdf/indonesia_nc4.nc rename tests/{test_grib.cpp => test_gdal_grib.cpp} (97%) create mode 100644 tests/test_gdal_netcdf.cpp diff --git a/mdal/CMakeLists.txt b/mdal/CMakeLists.txt index 8614011c..188675c2 100644 --- a/mdal/CMakeLists.txt +++ b/mdal/CMakeLists.txt @@ -34,11 +34,11 @@ ENDIF(HDF5_FOUND) IF(GDAL_FOUND) SET(MDAL_SOURCES ${MDAL_SOURCES} frmts/mdal_gdal.cpp - frmts/mdal_grib.cpp + frmts/mdal_gdal_grib.cpp ) SET(MDAL_HEADERS ${MDAL_HEADERS} frmts/mdal_gdal.hpp - frmts/mdal_grib.hpp + frmts/mdal_gdal_grib.hpp ) ENDIF(GDAL_FOUND) @@ -54,6 +54,15 @@ IF(NETCDF_FOUND) ) ENDIF(NETCDF_FOUND) +IF(GDAL_FOUND AND NETCDF_FOUND) + SET(MDAL_SOURCES ${MDAL_SOURCES} + frmts/mdal_gdal_netcdf.cpp + ) + SET(MDAL_HEADERS ${MDAL_HEADERS} + frmts/mdal_gdal_netcdf.hpp + ) +ENDIF(GDAL_FOUND AND NETCDF_FOUND) + ADD_LIBRARY(mdal SHARED ${MDAL_SOURCES} ${MDAL_HEADERS} diff --git a/mdal/frmts/mdal_grib.cpp b/mdal/frmts/mdal_gdal_grib.cpp similarity index 75% rename from mdal/frmts/mdal_grib.cpp rename to mdal/frmts/mdal_gdal_grib.cpp index 26559673..6c5b8d8a 100644 --- a/mdal/frmts/mdal_grib.cpp +++ b/mdal/frmts/mdal_gdal_grib.cpp @@ -4,20 +4,20 @@ */ -#include "mdal_grib.hpp" +#include "mdal_gdal_grib.hpp" #include "mdal_utils.hpp" #include #include -MDAL::LoaderGrib::LoaderGrib( const std::string &gribFile ) +MDAL::LoaderGdalGrib::LoaderGdalGrib( const std::string &gribFile ) : MDAL::LoaderGdal( gribFile, "GRIB" ), mRefTime( std::numeric_limits::min() ) {} -bool MDAL::LoaderGrib::parseBandInfo( const MDAL::GdalDataset *cfGDALDataset, - const metadata_hash &metadata, std::string &band_name, - double *time, bool *is_vector, bool *is_x - ) +bool MDAL::LoaderGdalGrib::parseBandInfo( const MDAL::GdalDataset *cfGDALDataset, + const metadata_hash &metadata, std::string &band_name, + double *time, bool *is_vector, bool *is_x + ) { MDAL_UNUSED( cfGDALDataset ); diff --git a/mdal/frmts/mdal_grib.hpp b/mdal/frmts/mdal_gdal_grib.hpp similarity index 81% rename from mdal/frmts/mdal_grib.hpp rename to mdal/frmts/mdal_gdal_grib.hpp index fd869160..7cdc528b 100644 --- a/mdal/frmts/mdal_grib.hpp +++ b/mdal/frmts/mdal_gdal_grib.hpp @@ -3,8 +3,8 @@ Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com) */ -#ifndef MDAL_GRIB_HPP -#define MDAL_GRIB_HPP +#ifndef MDAL_GDAL_GRIB_HPP +#define MDAL_GDAL_GRIB_HPP #include "mdal_gdal.hpp" #include "mdal_data_model.hpp" @@ -14,10 +14,10 @@ namespace MDAL { - class LoaderGrib: public LoaderGdal + class LoaderGdalGrib: public LoaderGdal { public: - LoaderGrib( const std::string &gribFile ); + LoaderGdalGrib( const std::string &gribFile ); private: bool parseBandInfo( const MDAL::GdalDataset *cfGDALDataset, const metadata_hash &metadata, std::string &band_name, @@ -35,4 +35,4 @@ namespace MDAL }; } // namespace MDAL -#endif // MDAL_GRIB_HPP +#endif // MDAL_GDAL_GRIB_HPP diff --git a/mdal/frmts/mdal_gdal_netcdf.cpp b/mdal/frmts/mdal_gdal_netcdf.cpp new file mode 100644 index 00000000..e9024afc --- /dev/null +++ b/mdal/frmts/mdal_gdal_netcdf.cpp @@ -0,0 +1,79 @@ +/* + MDAL - Mesh Data Abstraction Library (MIT License) + Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com) +*/ + +#include "mdal_gdal_netcdf.hpp" +#include "mdal_utils.hpp" + +MDAL::LoaderGdalNetCDF::LoaderGdalNetCDF( const std::string &netCDFFile ) + : MDAL::LoaderGdal( netCDFFile, "GRIB" ) + , mTimeDiv( 1.0 ) +{ +} + +std::string MDAL::LoaderGdalNetCDF::GDALFileName( const std::string &fileName ) +{ +#ifdef WIN32 + // Force usage of the predefined GDAL driver + // http://gis.stackexchange.com/a/179167 + // on Windows, HDF5 driver is checked before NETCDF driver in GDAL + return "NETCDF:\"" + fileName + "\""; +#else + return fileName; +#endif +} + +bool MDAL::LoaderGdalNetCDF::parseBandInfo( const MDAL::GdalDataset *cfGDALDataset, const MDAL::LoaderGdal::metadata_hash &metadata, std::string &band_name, double *time, bool *is_vector, bool *is_x ) +{ + MDAL_UNUSED( cfGDALDataset ); + + metadata_hash::const_iterator iter; + + iter = metadata.find( "netcdf_dim_time" ); + if ( iter == metadata.end() ) return true; //FAILURE, skip no-time bands + *time = parseMetadataTime( iter->second ) / mTimeDiv; + + // NAME + iter = metadata.find( "long_name" ); + if ( iter == metadata.end() ) + { + iter = metadata.find( "netcdf_varname" ); + if ( iter == metadata.end() ) return true; //FAILURE, should be always present + band_name = iter->second; + } + else + { + band_name = iter->second; + } + + // Loop throught all additional dimensions but time + for ( iter = metadata.begin(); iter != metadata.end(); ++iter ) + { + std::string key = iter->first; + if ( MDAL::contains( key, "netcdf_dim_" ) ) + { + key = MDAL::replace( key, "netcdf_dim_", "" ); + if ( key != "time" ) + { + band_name += "_" + key + ":" + iter->second; + } + } + } + + // Parse X, Y components if present + parseBandIsVector( band_name, is_vector, is_x ); + + return false; // SUCCESS +} + +void MDAL::LoaderGdalNetCDF::parseGlobals( const MDAL::LoaderGdal::metadata_hash &metadata ) +{ + metadata_hash::const_iterator iter = metadata.find( "time#units" ); + if ( iter != metadata.end() ) + { + std::string units = iter->second; + mTimeDiv = MDAL::parseTimeUnits( units ); + // TODO store reference time from iter->second too, see crayfish_netcdf.cpp + } +} diff --git a/mdal/frmts/mdal_gdal_netcdf.hpp b/mdal/frmts/mdal_gdal_netcdf.hpp new file mode 100644 index 00000000..cee50321 --- /dev/null +++ b/mdal/frmts/mdal_gdal_netcdf.hpp @@ -0,0 +1,34 @@ +/* + MDAL - Mesh Data Abstraction Library (MIT License) + Copyright (C) 2018 Peter Petrik (zilolv at gmail dot com) +*/ + +#ifndef MDAL_GDAL_NETCDF_HPP +#define MDAL_GDAL_NETCDF_HPP + +#include "mdal_gdal.hpp" +#include "mdal_data_model.hpp" +#include "mdal.h" +#include + +namespace MDAL +{ + + class LoaderGdalNetCDF: public LoaderGdal + { + public: + LoaderGdalNetCDF( const std::string &netCDFFile ); + private: + std::string GDALFileName( const std::string &fileName ) override; + bool parseBandInfo( const MDAL::GdalDataset *cfGDALDataset, + const metadata_hash &metadata, std::string &band_name, + double *time, bool *is_vector, bool *is_x + ) override; + void parseGlobals( const metadata_hash &metadata ) override; + + //! delimiter to get time in hours + double mTimeDiv; + }; + +} // namespace MDAL +#endif // MDAL_GDAL_NETCDF_HPP diff --git a/mdal/mdal_loader.cpp b/mdal/mdal_loader.cpp index b02fe2ba..a7cb9ad7 100644 --- a/mdal/mdal_loader.cpp +++ b/mdal/mdal_loader.cpp @@ -15,13 +15,17 @@ #endif #ifdef HAVE_GDAL -#include "frmts/mdal_grib.hpp" +#include "frmts/mdal_gdal_grib.hpp" #endif #ifdef HAVE_NETCDF #include "frmts/mdal_3di.hpp" #endif +#if defined HAVE_GDAL && defined HAVE_NETCDF +#include "frmts/mdal_gdal_netcdf.hpp" +#endif + std::unique_ptr MDAL::Loader::load( const std::string &meshFile, MDAL_Status *status ) { if ( !MDAL::fileExists( meshFile ) ) @@ -44,11 +48,22 @@ std::unique_ptr MDAL::Loader::load( const std::string &meshFile, MDA #ifdef HAVE_GDAL if ( !mesh && status && *status == MDAL_Status::Err_UnknownFormat ) { - MDAL::LoaderGrib loader( meshFile ); - mesh = loader.load( status ); +#ifdef HAVE_NETCDF + if ( MDAL::endsWith( meshFile, ".nc" ) ) + { + MDAL::LoaderGdalNetCDF loader( meshFile ); + mesh = loader.load( status ); + } + else + { +#endif // HAVE_GDAL && HAVE_NETCDF + MDAL::LoaderGdalGrib loader( meshFile ); + mesh = loader.load( status ); + } +#ifdef HAVE_NETCDF } -#endif - +#endif // HAVE_GDAL && HAVE_NETCDF +#endif // HAVE_GDAL return mesh; } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index dfcd1bc8..a8fdffb8 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -80,7 +80,7 @@ ENDIF(HDF5_FOUND) IF(GDAL_FOUND) SET(TESTS ${TESTS} - test_grib.cpp + test_gdal_grib.cpp ) ENDIF(GDAL_FOUND) @@ -90,6 +90,12 @@ SET(TESTS ${TESTS} ) ENDIF(NETCDF_FOUND) +IF(GDAL_FOUND AND NETCDF_FOUND) + SET(TESTS ${TESTS} + test_gdal_netcdf.cpp + ) +ENDIF(GDAL_FOUND AND NETCDF_FOUND) + FOREACH(TESTSRC ${TESTS}) ADD_MDAL_TEST(${TESTSRC}) ENDFOREACH(TESTSRC) diff --git a/tests/data/netcdf/indonesia_nc3.nc b/tests/data/netcdf/indonesia_nc3.nc new file mode 100644 index 0000000000000000000000000000000000000000..22120005abf4837f2c7f80eddf4cc96b44aab478 GIT binary patch literal 30564 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 U@h!h5nx5517PA)nwxzuMKLf8_(EtDd literal 0 HcmV?d00001 diff --git a/tests/data/netcdf/indonesia_nc4.nc b/tests/data/netcdf/indonesia_nc4.nc new file mode 100644 index 0000000000000000000000000000000000000000..9730d98bcf4f4c5a18fb6813598fd081aa1f7af6 GIT binary patch literal 58868 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

CJi8v&8-PhZjT*lNbm{=wDa5Sd-J@bik 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 hJLc5D`PI +#include + +//mdal +#include "mdal.h" +#include "mdal_testutils.hpp" + +TEST( MeshGdalNetCDFTest, Indonesia ) +{ + std::vector files; + files.push_back( "indonesia_nc3.nc" ); + files.push_back( "indonesia_nc4.nc" ); + for ( const std::string &file : files ) + { + std::string path = test_file( std::string( "/netcdf/" ) + file ); + MeshH m = MDAL_LoadMesh( path.c_str() ); + ASSERT_NE( m, nullptr ); + MDAL_Status s = MDAL_LastStatus(); + EXPECT_EQ( MDAL_Status::None, s ); + ASSERT_EQ( 2, MDAL_M_datasetGroupCount( m ) ); + + DatasetGroupH g = MDAL_M_datasetGroup( m, 1 ); + ASSERT_NE( g, nullptr ); + + int meta_count = MDAL_G_metadataCount( g ); + ASSERT_EQ( 1, meta_count ); + + const char *name = MDAL_G_name( g ); + EXPECT_EQ( std::string( "Total cloud cover" ), std::string( name ) ); + + bool scalar = MDAL_G_hasScalarData( g ); + EXPECT_EQ( true, scalar ); + + bool onVertices = MDAL_G_isOnVertices( g ); + EXPECT_EQ( true, onVertices ); + + ASSERT_EQ( 31, MDAL_G_datasetCount( g ) ); + DatasetH ds = MDAL_G_dataset( g, 10 ); + ASSERT_NE( ds, nullptr ); + + bool valid = MDAL_D_isValid( ds ); + EXPECT_EQ( true, valid ); + + bool active = MDAL_D_active( ds, 50 ); + EXPECT_EQ( true, active ); + + int count = MDAL_D_valueCount( ds ); + ASSERT_EQ( 234, count ); + + double value = MDAL_D_value( ds, 50 ); + EXPECT_DOUBLE_EQ( 32759, value ); + + MDAL_CloseMesh( m ); + } +} + +int main( int argc, char **argv ) +{ + testing::InitGoogleTest( &argc, argv ); + return RUN_ALL_TESTS(); +} + diff --git a/tools/mdalinfo.cpp b/tools/mdalinfo.cpp index 621704cc..a3b8f8fe 100644 --- a/tools/mdalinfo.cpp +++ b/tools/mdalinfo.cpp @@ -31,10 +31,10 @@ int main( int argc, char *argv[] ) std::string mesh_file = argv[1]; std::vector extraDatasets; - if (argc > 2) // additional dataset arguments + if ( argc > 2 ) // additional dataset arguments { - for (int i=2; i