Skip to content

Commit

Permalink
handle metadata in mike21 format (#486)
Browse files Browse the repository at this point in the history
* handle metadata in mike21 format

* don't use macos-latest for ci

* update ubuntu used for docs ci

* add mike21 to docs index

* revert ff31e0e
  • Loading branch information
uclaros authored May 20, 2024
1 parent dd52e9e commit ac1531b
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 46 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/osx_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ env:
QGIS_DEPS_VERSION: 0.4.0
jobs:
osx_tests:
runs-on: macos-latest
runs-on: macos-12
steps:
- name: Checkout MDAL
uses: actions/checkout@v2
Expand Down
1 change: 1 addition & 0 deletions docs/source/drivers/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ MDAL drivers
dfsu
dfs2
h2i
mike21
73 changes: 34 additions & 39 deletions mdal/frmts/mdal_mike21.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,48 +133,30 @@ bool MDAL::DriverMike21::canReadMesh( const std::string &uri )
return true;
}

size_t MDAL::DriverMike21::getVertexCount( const std::string &line )
void MDAL::DriverMike21::parseHeader( const std::string &line )
{
auto matchResults = std::smatch{};
if ( std::regex_search( line, matchResults, mRegexHeader2012 ) )
{
if ( matchResults.size() > 4 )
{
return std::stoi( matchResults[3].str() );
mDataType = matchResults[1].str();
mDataUnit = matchResults[2].str();
mVertexCount = std::stoi( matchResults[3].str() );
mCrs = matchResults[4].str();
return;
}
}

if ( std::regex_search( line, matchResults, mRegexHeader2011 ) )
{
if ( matchResults.size() > 2 )
{
return std::stoi( matchResults[1].str() );
mVertexCount = std::stoi( matchResults[1].str() );
mCrs = matchResults[2].str();
return;
}
}

return 0;
}

std::string MDAL::DriverMike21::getCrs( const std::string &line )
{
auto matchResults = std::smatch{};
if ( std::regex_search( line, matchResults, mRegexHeader2012 ) )
{
if ( matchResults.size() > 5 )
{
return matchResults[4].str();
}
}

if ( std::regex_search( line, matchResults, mRegexHeader2011 ) )
{
if ( matchResults.size() > 3 )
{
return matchResults[2].str();
}
}

return "";
}

std::unique_ptr<MDAL::Mesh> MDAL::DriverMike21::load( const std::string &meshFile, const std::string & )
Expand All @@ -192,17 +174,16 @@ std::unique_ptr<MDAL::Mesh> MDAL::DriverMike21::load( const std::string &meshFil
return nullptr;
}

std::string crs = getCrs( line );
parseHeader( line );

size_t vertexCount = getVertexCount( line );
size_t faceCount = 0;
size_t maxVerticesPerFace = 2;

size_t lineNumber = 1;

while ( std::getline( in, line ) )
{
if ( lineNumber == vertexCount + 1 )
if ( lineNumber == mVertexCount + 1 )
{
auto matchResults = std::smatch{};
if ( std::regex_search( line, matchResults, mRegexElementHeader ) )
Expand Down Expand Up @@ -236,7 +217,7 @@ std::unique_ptr<MDAL::Mesh> MDAL::DriverMike21::load( const std::string &meshFil
}

// number of lines in file does not match number of vertices and faces specifed in first and element line
if ( lineNumber > 2 + vertexCount + faceCount )
if ( lineNumber > 2 + mVertexCount + faceCount )
{
MDAL::Log::error( MDAL_Status::Err_InvalidData, name(), "Number of lines in file does not fit with number of vertexes and faces specified." );
return nullptr;
Expand All @@ -245,11 +226,11 @@ std::unique_ptr<MDAL::Mesh> MDAL::DriverMike21::load( const std::string &meshFil
in.clear();
in.seekg( 0, std::ios::beg );

Vertices vertices( vertexCount );
Vertices vertices( mVertexCount );
Faces faces( faceCount );

std::map<size_t, size_t> vertexIDtoIndex;
std::vector<double> vertexType( vertexCount );
std::vector<double> vertexType( mVertexCount );

std::vector<double> nativeVertexIds;
std::vector<double> nativeFaceIds;
Expand All @@ -263,7 +244,7 @@ std::unique_ptr<MDAL::Mesh> MDAL::DriverMike21::load( const std::string &meshFil

while ( std::getline( in, line ) )
{
if ( 0 < lineNumber && lineNumber < vertexCount + 1 )
if ( 0 < lineNumber && lineNumber < mVertexCount + 1 )
{
chunks = regex_split( MDAL::trim( line ) );
if ( chunks.size() != 5 )
Expand All @@ -288,10 +269,10 @@ std::unique_ptr<MDAL::Mesh> MDAL::DriverMike21::load( const std::string &meshFil
}

// in case we have gaps/reorders in native indexes, store it
persist_native_index( nativeVertexIds, nodeID, vertexIndex, vertexCount );
persist_native_index( nativeVertexIds, nodeID, vertexIndex, mVertexCount );
parse_vertex_id_gaps( vertexIDtoIndex, vertexIndex, nodeID - 1 );

assert( vertexIndex < vertexCount );
assert( vertexIndex < mVertexCount );
Vertex &vertex = vertices[vertexIndex];
vertex.x = toDouble( chunks[1] );
vertex.y = toDouble( chunks[2] );
Expand All @@ -300,7 +281,7 @@ std::unique_ptr<MDAL::Mesh> MDAL::DriverMike21::load( const std::string &meshFil
vertexIndex++;
}

if ( vertexCount + 1 < lineNumber )
if ( mVertexCount + 1 < lineNumber )
{
chunks = regex_split( MDAL::trim( line ) );
assert( faceIndex < faceCount );
Expand Down Expand Up @@ -375,7 +356,13 @@ std::unique_ptr<MDAL::Mesh> MDAL::DriverMike21::load( const std::string &meshFil
if ( !nativeVertexIds.empty() )
MDAL::addVertexScalarDatasetGroup( mesh.get(), nativeVertexIds, "NativeVertexIds" );

mesh->setSourceCrs( crs );
mesh->setSourceCrs( mCrs );
mesh->setMetadata( "crs", mCrs );
if ( !mDataType.empty() )
mesh->setMetadata( "data_type", mDataType );

if ( !mDataUnit.empty() )
mesh->setMetadata( "data_unit", mDataUnit );

return std::unique_ptr<Mesh>( mesh.release() );
}
Expand All @@ -391,7 +378,15 @@ void MDAL::DriverMike21::save( const std::string &fileName, const std::string &,
MDAL::Log::error( MDAL_Status::Err_FailToWriteToDisk, name(), "Could not open file " + fileName );
}

std::string line = std::to_string( mesh->verticesCount() ) + " " + mesh->crs();
std::string line;

const std::string dataType = mesh->getMetadata( "data_type" );
const std::string dataUnit = mesh->getMetadata( "data_unit" );
if ( !dataType.empty() && !dataUnit.empty() )
line.append( dataType + " " + dataUnit + " " );

line.append( std::to_string( mesh->verticesCount() ) + " " + mesh->getMetadata( "crs" ) );

file << line << std::endl;

std::vector<double> vertexTypes;
Expand Down
7 changes: 5 additions & 2 deletions mdal/frmts/mdal_mike21.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ namespace MDAL

private:
std::string mMeshFile;
std::string mCrs;
std::string mDataType;
std::string mDataUnit;
size_t mVertexCount = 0;
// regex for header line in form of - integer string
const std::regex mRegexHeader2011 = std::regex( "(\\d+)\\s+(.+)(\\s+)?" );
// regex for header line in form of - integer integer integer string
Expand All @@ -96,8 +100,7 @@ namespace MDAL
const std::regex mRegexElementHeader = std::regex( "(\\d+)\\s+(\\d)\\s+(\\d{2})(\\s+)?" );

bool canReadHeader( const std::string &line );
size_t getVertexCount( const std::string &line );
std::string getCrs( const std::string &line );
void parseHeader( const std::string &line );
};

} // namespace MDAL
Expand Down
29 changes: 28 additions & 1 deletion tests/mdal_testutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,31 @@ void compareMeshFrames( MDAL_MeshH meshA, MDAL_MeshH meshB )
EXPECT_TRUE( compareVectors( verticesA, verticesB ) );
}

void compareMeshMetadata( MDAL_MeshH meshA, MDAL_MeshH meshB )
{
// Metadata count
const int orignal_m_count = MDAL_M_metadataCount( meshA );
const int saved_m_count = MDAL_M_metadataCount( meshB );
EXPECT_EQ( orignal_m_count, saved_m_count );

// Metadata values
for ( int i = 0; i < orignal_m_count; ++i )
{
const std::string keyA( MDAL_M_metadataKey( meshA, i ) );
const std::string valA( MDAL_M_metadataValue( meshA, i ) );
for ( int j = 0; j < saved_m_count; ++j )
{
const std::string keyB( MDAL_M_metadataKey( meshB, j ) );
const std::string valB( MDAL_M_metadataValue( meshB, j ) );

if ( keyA == keyB && valA == valB )
break;
else if ( j == saved_m_count - 1 )
FAIL() << "Mesh metadata do not match: " << keyA << ": " << valA;
}
}
}

std::vector<double> getCoordinates( MDAL_MeshH mesh, int verticesCount )
{
MDAL_MeshVertexIteratorH iterator = MDAL_M_vertexIterator( mesh );
Expand Down Expand Up @@ -399,7 +424,7 @@ bool compareReferenceTime( MDAL_DatasetGroupH group, const char *referenceTime )
return std::strcmp( MDAL_G_referenceTime( group ), referenceTime ) == 0;
}

void saveAndCompareMesh( const std::string &filename, const std::string &savedFile, const std::string &driver, const std::string &meshName )
void saveAndCompareMesh( const std::string &filename, const std::string &savedFile, const std::string &driver, const std::string &meshName, bool compareMetadata )
{
//test driver capability
EXPECT_TRUE( MDAL_DR_saveMeshCapability( MDAL_driverFromName( driver.c_str() ) ) );
Expand Down Expand Up @@ -433,6 +458,8 @@ void saveAndCompareMesh( const std::string &filename, const std::string &savedFi

// Compare saved with the original mesh
compareMeshFrames( meshToSave, savedMesh );
if ( compareMetadata )
compareMeshMetadata( meshToSave, savedMesh );

MDAL_CloseMesh( savedMesh );

Expand Down
3 changes: 2 additions & 1 deletion tests/mdal_testutils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ bool compareVectors( const std::vector<int> &a, const std::vector<int> &b );

//! Same vertices (coords), faces, edges and connectivity between them
void compareMeshFrames( MDAL_MeshH meshA, MDAL_MeshH meshB );
void saveAndCompareMesh( const std::string &filename, const std::string &savedFile, const std::string &driver, const std::string &meshName = "" );
void compareMeshMetadata( MDAL_MeshH meshA, MDAL_MeshH meshB );
void saveAndCompareMesh( const std::string &filename, const std::string &savedFile, const std::string &driver, const std::string &meshName = "", bool compareMetadata = false );

//! Compare duration with millisecond precision
bool compareDurationInHours( double h1, double h2 );
Expand Down
16 changes: 14 additions & 2 deletions tests/test_mike21.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,16 +190,28 @@ TEST( MeshMike21Test, ReadOdenseRough )

TEST( MeshMike21Test, SaveMike21MeshToFile )
{
saveAndCompareMesh(
test_file( "/mike21/small.mesh" ),
tmp_file( "/small_saved.mesh" ),
"Mike21",
"",
true
);

saveAndCompareMesh(
test_file( "/mike21/odense_rough_comparison.mesh" ),
tmp_file( "/odense_rough_saved.mesh" ),
"Mike21"
"Mike21",
"",
true
);

saveAndCompareMesh(
test_file( "/mike21/odense_rough_quads_comparion.mesh" ),
tmp_file( "/odense_rough_quads_saved.mesh" ),
"Mike21"
"Mike21",
"",
true
);
}

Expand Down

0 comments on commit ac1531b

Please sign in to comment.