Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle metadata in mike21 format #486

Merged
merged 5 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading