Skip to content
Permalink
Browse files

MDAL update 0.6.0 (#36703)

MDAL update 0.6.0
  • Loading branch information
vcloarec committed May 27, 2020
1 parent 0ea7187 commit 1df077a95084bbcd77339925a362ced8cc509862
@@ -11,6 +11,8 @@

#cmakedefine HAVE_XML

#cmakedefine HAVE_SQLITE3

#endif // MDAL_CONFIG_HPP


@@ -4,8 +4,12 @@
*/

#include "mdal_3di.hpp"
#include "mdal_logger.hpp"
#include <cmath>
#include <netcdf.h>
#include <assert.h>
#include "mdal_sqlite3.hpp"


MDAL::Driver3Di::Driver3Di()
: DriverCF(
@@ -21,9 +25,49 @@ MDAL::Driver3Di *MDAL::Driver3Di::create()
return new Driver3Di();
}

MDAL::CFDimensions MDAL::Driver3Di::populateDimensions( )
std::string MDAL::Driver3Di::buildUri( const std::string &meshFile )
{
mNcFile.reset( new NetCDFFile );

try
{
mNcFile->openFile( meshFile );
}
catch ( MDAL::Error &err )
{
err.setDriver( name() );
MDAL::Log::error( err );
return std::string();
}

std::vector<std::string> meshNames;

CFDimensions dims;
bool sqliteFileExist = check1DConnection( meshFile );
if ( sqliteFileExist )
{
populate1DMeshDimensions( dims );
if ( dims.size( CFDimensions::Vertex ) > 0 && dims.size( CFDimensions::Edge ) > 0 )
{
meshNames.push_back( "Mesh1D" );
}
}

populate2DMeshDimensions( dims );
if ( dims.size( CFDimensions::Face ) > 0 )
meshNames.push_back( "Mesh2D" );

if ( !meshNames.size() )
{
MDAL::Log::error( MDAL_Status::Err_UnknownFormat, name(), "No meshes found in file" + meshFile );
return std::string( "" );
}

return MDAL::buildAndMergeMeshUris( meshFile, meshNames, name() );
}

void MDAL::Driver3Di::populate2DMeshDimensions( MDAL::CFDimensions &dims )
{
size_t count;
int ncid;

@@ -36,6 +80,23 @@ MDAL::CFDimensions MDAL::Driver3Di::populateDimensions( )

// Vertices count is populated later in populateElements
// it is not known from the array dimensions
}

MDAL::CFDimensions MDAL::Driver3Di::populateDimensions( )
{
CFDimensions dims;
size_t count;
int ncid;

if ( mRequestedMeshName == "Mesh1D" )
{
populate1DMeshDimensions( dims );
}
else
{
// Default loaded mesh is the 2D mesh
populate2DMeshDimensions( dims );
}

// Time
mNcFile->getDimension( "time", &count, &ncid );
@@ -44,7 +105,15 @@ MDAL::CFDimensions MDAL::Driver3Di::populateDimensions( )
return dims;
}

void MDAL::Driver3Di::populateElements( Vertices &vertices, Edges &, Faces &faces )
void MDAL::Driver3Di::populateElements( Vertices &vertices, Edges &edges, Faces &faces )
{
if ( mRequestedMeshName == "Mesh1D" )
populateMesh1DElements( vertices, edges );
else
populateMesh2DElements( vertices, faces );
}

void MDAL::Driver3Di::populateMesh2DElements( MDAL::Vertices &vertices, MDAL::Faces &faces )
{
assert( vertices.empty() );
size_t faceCount = mDimensions.size( CFDimensions::Face );
@@ -259,3 +328,129 @@ std::vector<std::pair<double, double>> MDAL::Driver3Di::parseClassification( int
MDAL_UNUSED( varid );
return std::vector<std::pair<double, double>>();
}

void MDAL::Driver3Di::populate1DMeshDimensions( MDAL::CFDimensions &dims )
{
size_t count;
int ncid;

mNcFile->getDimension( "nMesh1D_nodes", &count, &ncid );
dims.setDimension( CFDimensions::Vertex, count, ncid );

mNcFile->getDimension( "nMesh1D_lines", &count, &ncid );
dims.setDimension( CFDimensions::Edge, count, ncid );
}

void MDAL::Driver3Di::populateMesh1DElements( MDAL::Vertices &vertices, MDAL::Edges &edges )
{
assert( vertices.empty() && edges.empty() );
size_t vertexCount = mDimensions.size( CFDimensions::Vertex );
size_t edgesCount = mDimensions.size( CFDimensions::Edge );
vertices.resize( vertexCount );
edges.resize( edgesCount );

// X coordinate
int ncidX = mNcFile->getVarId( "Mesh1DNode_xcc" );
double fillX = mNcFile->getFillValue( ncidX );
std::vector<double> verticesX( vertexCount );
if ( nc_get_var_double( mNcFile->handle(), ncidX, verticesX.data() ) ) throw MDAL::Error( MDAL_Status::Err_UnknownFormat, "Unknown format" );

// Y coordinate
int ncidY = mNcFile->getVarId( "Mesh1DNode_ycc" );
double fillY = mNcFile->getFillValue( ncidY );
std::vector<double> verticesY( vertexCount );
if ( nc_get_var_double( mNcFile->handle(), ncidY, verticesY.data() ) ) throw MDAL::Error( MDAL_Status::Err_UnknownFormat, "Unknown format" );

// Z coordinate
int ncidZ = mNcFile->getVarId( "Mesh1DNode_zcc" );
double fillZ = mNcFile->getFillValue( ncidZ );
std::vector<double> verticesZ( vertexCount );
if ( nc_get_var_double( mNcFile->handle(), ncidZ, verticesZ.data() ) ) throw MDAL::Error( MDAL_Status::Err_UnknownFormat, "Unknown format" );

// Node Id
int ncidNodeId = mNcFile->getVarId( "Mesh1DNode_id" );
std::vector<int> verticesId( vertexCount );
if ( nc_get_var_int( mNcFile->handle(), ncidNodeId, verticesId.data() ) ) throw MDAL::Error( MDAL_Status::Err_UnknownFormat, "Unknown format" );

// Edge Id
int ncidEgeId = mNcFile->getVarId( "Mesh1DLine_id" );
std::vector<int> edgesId( edgesCount );
if ( nc_get_var_int( mNcFile->handle(), ncidEgeId, edgesId.data() ) ) throw MDAL::Error( MDAL_Status::Err_UnknownFormat, "Unknown format" );

for ( size_t i = 0; i < vertexCount; ++i )
{
Vertex vertex;
vertex.x = verticesX[i];
if ( vertex.x == fillX )
vertex.x = std::numeric_limits<double>::quiet_NaN();
vertex.y = verticesY[i];
if ( vertex.y == fillY )
vertex.y = std::numeric_limits<double>::quiet_NaN();
vertex.z = verticesZ[i];
if ( vertex.z == fillZ )
vertex.z = std::numeric_limits<double>::quiet_NaN();
vertices[i] = vertex;
}

parse1DConnection( verticesId, edgesId, edges );
}


bool MDAL::Driver3Di::check1DConnection( std::string fileName )
{
std::string sqliteFile = dirName( fileName ) + "/gridadmin.sqlite";

if ( !fileExists( sqliteFile ) )
return false;

Sqlite3Db sqliteDb;
return sqliteDb.open( sqliteFile );

}

void MDAL::Driver3Di::parse1DConnection( const std::vector<int> &nodesId,
const std::vector<int> &edgesId,
Edges &edges )
{
std::string sqliteFileName = dirName( mNcFile->getFileName() ) + "/gridadmin.sqlite";

//construct id map
std::map<int, size_t> edgeMap;
std::map<int, size_t> nodeMap;
for ( size_t edgeIndex = 0; edgeIndex < edges.size(); ++edgeIndex )
edgeMap[edgesId.at( edgeIndex )] = edgeIndex;

for ( size_t nodeIndex = 0; nodeIndex < nodesId.size(); ++nodeIndex )
nodeMap[nodesId.at( nodeIndex )] = nodeIndex;


Sqlite3Db db;
if ( !db.open( sqliteFileName ) || !( db.get() ) )
throw MDAL::Error( MDAL_Status::Err_UnknownFormat, "Unable to open sqlite database" );

Sqlite3Statement stmt;

if ( ! stmt.prepare( &db, "SELECT id, start_node_idx, end_node_idx FROM flowlines" ) )
throw MDAL::Error( MDAL_Status::Err_UnknownFormat, "Unable to read edges connectivity from sqlite database" );

if ( stmt.columnCount() < 0 || stmt.columnCount() != 3 )
throw MDAL::Error( MDAL_Status::Err_UnknownFormat, "Invalid edges connectivity schema in sqlite database" );

while ( stmt.next() )
{
int idEdge, idStartNode, idEndNode;
idEdge = stmt.getInt( 0 );
idStartNode = stmt.getInt( 1 );
idEndNode = stmt.getInt( 2 );

auto itEdge = edgeMap.find( idEdge );
auto itStart = nodeMap.find( idStartNode );
auto itEnd = nodeMap.find( idEndNode );

if ( itEdge != edgeMap.end() && itStart != nodeMap.end() && itEnd != nodeMap.end() )
{
edges[itEdge->second].startVertex = itStart->second;
edges[itEdge->second].endVertex = itEnd->second;
}
}
}
@@ -10,6 +10,7 @@
#include <string>
#include <stddef.h>

#include "mdal_config.hpp"
#include "mdal_cf.hpp"
#include "mdal_driver.hpp"

@@ -42,10 +43,12 @@ namespace MDAL
Driver3Di();
~Driver3Di() override = default;
Driver3Di *create() override;

std::string buildUri( const std::string &meshFile ) override;
private:
CFDimensions populateDimensions( ) override;
void populate2DMeshDimensions( MDAL::CFDimensions &dims );
void populateElements( Vertices &vertices, Edges &edges, Faces &faces ) override;
void populateMesh2DElements( Vertices &vertices, Faces &faces );
void addBedElevation( MemoryMesh *mesh ) override;
std::string getCoordinateSystemVariableName() override;
std::string getTimeVariableName() const override;
@@ -62,6 +65,11 @@ namespace MDAL
size_t parse2DMesh();

void addBedElevationDatasetOnFaces();

void populate1DMeshDimensions( MDAL::CFDimensions &dims );
void populateMesh1DElements( Vertices &vertices, Edges &edges );
bool check1DConnection( std::string fileName );
void parse1DConnection( const std::vector<int> &nodesId, const std::vector<int> &edgesId, Edges &edges );
};

} // namespace MDAL
@@ -147,10 +147,8 @@ MDAL::cfdataset_info_map MDAL::DriverCF::parseDatasetGroupInfo()

//construct classification metadata
if ( isClassified && !is_vector )
{

meta.push_back( metadataFromClassification( classes ) );
}


// Add dsinfo to the map
auto it = dsinfo_map.find( vectorName );
@@ -127,6 +127,18 @@ std::string HdfAttribute::readString() const
return res;
}

double HdfAttribute::readDouble() const
{
HdfDataType datatype( H5Aget_type( id() ) );
double value;
herr_t status = H5Aread( d->id, H5T_NATIVE_DOUBLE, &value );
if ( status < 0 )
{
return std::numeric_limits<double>::quiet_NaN();
}
return value;
}

void HdfAttribute::write( const std::string &value )
{
if ( !isValid() || !mType.isValid() )
@@ -151,6 +151,7 @@ class HdfAttribute
hid_t id() const;

std::string readString() const;
double readDouble() const;

void write( const std::string &value );
void write( int value );
@@ -37,6 +37,7 @@ void NetCDFFile::openFile( const std::string &fileName )
{
throw MDAL::Error( MDAL_Status::Err_UnknownFormat, "Could not open file " + fileName );
}
mFileName = fileName;
}

std::vector<int> NetCDFFile::readIntArr( const std::string &name, size_t dim ) const
@@ -446,3 +447,8 @@ void NetCDFFile::putDataArrayInt( int varId, size_t line, size_t faceVerticesMax
throw MDAL::Error( MDAL_Status::Err_FailToWriteToDisk, nc_strerror( res ) );
}
}

std::string NetCDFFile::getFileName() const
{
return mFileName;
}
@@ -86,8 +86,11 @@ class NetCDFFile
void putDataDouble( int varId, const size_t index, const double value );
void putDataArrayInt( int varId, size_t line, size_t faceVerticesMax, int *values );

std::string getFileName() const;

private:
int mNcid; // C handle to the file
std::string mFileName;
};

#endif // MDAL_NETCDF_HPP

0 comments on commit 1df077a

Please sign in to comment.
You can’t perform that action at this time.