diff --git a/README.md b/README.md index fd02dabf..d3b8fba3 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ QGIS contains internal copy of MDAL library in following versions: | 3.30.0 | 1.0.2 | | | 3.36.0 | 1.1.0 | Mike21 format support read/write | | 3.38.0 | 1.2.0 | Groundwater / surface water meshes for 3Di format | -| 3.42.0 | 1.3.0 | Fix 2dm format coordinates saving | +| 3.42.0 | 1.3.0 | Fix 2dm format coordinates saving, Support Dataset Group Removal From Mesh | versions `X.Y.9Z` are development versions or alpha/beta releases (e.g. `0.4.90`, `0.4.91`, ...) diff --git a/mdal/api/mdal.h b/mdal/api/mdal.h index 305e4d56..df91756e 100644 --- a/mdal/api/mdal.h +++ b/mdal/api/mdal.h @@ -442,6 +442,14 @@ MDAL_EXPORT MDAL_DatasetGroupH MDAL_M_addDatasetGroup( MDAL_DriverH driver, const char *datasetGroupFile ); +/** + * Removes DatasetGroup from Mesh based on it's index. On error see MDAL_LastStatus + * for error type. + * + * \since MDAL 1.3.0 + */ +MDAL_EXPORT void MDAL_M_RemoveDatasetGroup( MDAL_MeshH mesh, int index ); + /** * Returns name of MDAL driver * not thread-safe and valid only till next call @@ -587,6 +595,13 @@ MDAL_EXPORT void MDAL_G_setMetadata( MDAL_DatasetGroupH group, const char *key, */ MDAL_EXPORT const char *MDAL_G_name( MDAL_DatasetGroupH group ); +/** + * Sets dataset group name + * + * \since MDAL 1.3.0 + */ +MDAL_EXPORT void MDAL_G_setName( MDAL_DatasetGroupH group, const char *name ); + /** * Returns name of MDAL driver * not thread-safe and valid only till next call diff --git a/mdal/mdal.cpp b/mdal/mdal.cpp index 5ab0756a..6ac3107a 100644 --- a/mdal/mdal.cpp +++ b/mdal/mdal.cpp @@ -580,6 +580,34 @@ MDAL_DatasetGroupH MDAL_M_addDatasetGroup( return nullptr; } +void MDAL_M_RemoveDatasetGroup( MDAL_MeshH mesh, int index ) +{ + MDAL::Log::resetLastStatus(); + + if ( !mesh ) + { + MDAL::Log::error( MDAL_Status::Err_IncompatibleMesh, "Mesh is not valid (null)" ); + return; + } + + if ( index < 0 ) + { + MDAL::Log::error( MDAL_Status::Err_IncompatibleMesh, "Requested index is not valid: " + std::to_string( index ) ); + return; + } + + MDAL::Mesh *m = static_cast< MDAL::Mesh * >( mesh ); + int len = static_cast( m->datasetGroups.size() ); + if ( len <= index ) + { + MDAL::Log::error( MDAL_Status::Err_IncompatibleMesh, "Requested index " + std::to_string( index ) + " is bigger than datasets count" ); + return; + } + size_t i = static_cast( index ); + + m->datasetGroups.erase( m->datasetGroups.begin() + i ); +} + const char *MDAL_M_driverName( MDAL_MeshH mesh ) { if ( !mesh ) @@ -847,6 +875,18 @@ const char *MDAL_G_name( MDAL_DatasetGroupH group ) return _return_str( g->name() ); } +void MDAL_G_setName( MDAL_DatasetGroupH group, const char *name ) +{ + if ( !group ) + { + MDAL::Log::error( MDAL_Status::Err_IncompatibleDataset, "Dataset Group is not valid (null)" ); + return; + } + + MDAL::DatasetGroup *g = static_cast< MDAL::DatasetGroup * >( group ); + g->setName( name ); +} + bool MDAL_G_hasScalarData( MDAL_DatasetGroupH group ) { if ( !group ) diff --git a/tests/test_api.cpp b/tests/test_api.cpp index b44a9620..eff38d60 100644 --- a/tests/test_api.cpp +++ b/tests/test_api.cpp @@ -635,6 +635,101 @@ TEST( ApiTest, MeshCreationApi ) EXPECT_EQ( std::strcmp( MDAL_DR_saveMeshSuffix( driver ), "slf" ), 0 ); } +TEST( ApiTest, DatasetRemoval ) +{ + MDAL_SetLoggerCallback( &_testLoggerCallback ); + + std::string meshFile = test_file( "/2dm/quad_and_line.2dm" ); + MDAL_MeshH m = MDAL_LoadMesh( meshFile.c_str() ); + EXPECT_NE( m, nullptr ); + MDAL_Status s = MDAL_LastStatus(); + EXPECT_EQ( MDAL_Status::None, s ); + ASSERT_EQ( 2, MDAL_M_datasetGroupCount( m ) ); + + std::string vertexPath = test_file( "/ascii_dat/quad_and_triangle_vertex_scalar.dat" ); + + // add the same dataset multiple times + MDAL_M_LoadDatasets( m, vertexPath.c_str() ); + s = MDAL_LastStatus(); + EXPECT_EQ( MDAL_Status::None, s ); + ASSERT_EQ( 3, MDAL_M_datasetGroupCount( m ) ); + + MDAL_M_LoadDatasets( m, vertexPath.c_str() ); + s = MDAL_LastStatus(); + EXPECT_EQ( MDAL_Status::None, s ); + ASSERT_EQ( 4, MDAL_M_datasetGroupCount( m ) ); + + MDAL_M_LoadDatasets( m, vertexPath.c_str() ); + s = MDAL_LastStatus(); + EXPECT_EQ( MDAL_Status::None, s ); + ASSERT_EQ( 5, MDAL_M_datasetGroupCount( m ) ); + + // try to remove from bad mesh + MDAL_M_RemoveDatasetGroup( nullptr, -1 ); + s = MDAL_LastStatus(); + EXPECT_EQ( MDAL_Status::Err_IncompatibleMesh, s ); + + // remove non existing dataset + MDAL_M_RemoveDatasetGroup( m, -1 ); + s = MDAL_LastStatus(); + EXPECT_EQ( MDAL_Status::Err_IncompatibleMesh, s ); + ASSERT_EQ( 5, MDAL_M_datasetGroupCount( m ) ); + + // remove non existing dataset + MDAL_M_RemoveDatasetGroup( m, 99 ); + s = MDAL_LastStatus(); + EXPECT_EQ( MDAL_Status::Err_IncompatibleMesh, s ); + ASSERT_EQ( 5, MDAL_M_datasetGroupCount( m ) ); + + // remove existing dataset + MDAL_M_RemoveDatasetGroup( m, 3 ); + s = MDAL_LastStatus(); + EXPECT_EQ( MDAL_Status::None, s ); + ASSERT_EQ( 4, MDAL_M_datasetGroupCount( m ) ); + + // remove existing dataset + MDAL_M_RemoveDatasetGroup( m, 3 ); + s = MDAL_LastStatus(); + EXPECT_EQ( MDAL_Status::None, s ); + ASSERT_EQ( 3, MDAL_M_datasetGroupCount( m ) ); + + // remove existing dataset + MDAL_M_RemoveDatasetGroup( m, 2 ); + s = MDAL_LastStatus(); + EXPECT_EQ( MDAL_Status::None, s ); + ASSERT_EQ( 2, MDAL_M_datasetGroupCount( m ) ); + + MDAL_CloseMesh( m ); +} + +TEST( ApiTest, DatasetGroupSetName ) +{ + std::string path = test_file( "/2dm/regular_grid.2dm" ); + MDAL_MeshH m = MDAL_LoadMesh( path.c_str() ); + EXPECT_NE( m, nullptr ); + MDAL_Status s = MDAL_LastStatus(); + ASSERT_EQ( MDAL_Status::None, s ); + ASSERT_EQ( MDAL_M_datasetGroupCount( m ), 1 ); + + // get group and test name + MDAL_DatasetGroupH g = MDAL_M_datasetGroup( m, 0 ); + + std::string name = std::string( MDAL_G_name( g ) ); + ASSERT_EQ( name, "Bed Elevation" ); + + // set new name + std::string newName = "Z-Value"; + MDAL_G_setName( g, newName.c_str() ); + + // get the group again and test if the name is changed + MDAL_DatasetGroupH g1 = MDAL_M_datasetGroup( m, 0 ); + + name = std::string( MDAL_G_name( g1 ) ); + ASSERT_EQ( name, newName ); + + MDAL_CloseMesh( m ); +} + int main( int argc, char **argv ) { testing::InitGoogleTest( &argc, argv );